diff --git a/#pesterchum.py# b/#pesterchum.py# new file mode 100644 index 0000000..3b970e6 --- /dev/null +++ b/#pesterchum.py# @@ -0,0 +1,1561 @@ +# pesterchum +import logging +import os, sys +import os.path +from datetime import * +from string import Template +import random +import json +import re +from PyQt4 import QtGui, QtCore +import pygame + +from menus import PesterChooseQuirks, PesterChooseTheme, \ + PesterChooseProfile, PesterOptions, PesterUserlist, PesterMemoList, \ + LoadingScreen +from dataobjs import PesterProfile, Mood, pesterQuirk, pesterQuirks +from generic import PesterIcon, RightClickList, MultiTextDialog, PesterList +from convo import PesterTabWindow, PesterText, PesterInput, PesterConvo +from parsetools import convertTags +from memos import PesterMemo, MemoTabWindow +from irc import PesterIRC + +class waitingMessageHolder(object): + def __init__(self, mainwindow, **msgfuncs): + self.mainwindow = mainwindow + self.funcs = msgfuncs + self.queue = msgfuncs.keys() + if len(self.queue) > 0: + self.mainwindow.updateSystemTray() + def answerMessage(self): + func = self.funcs[self.queue[0]] + func() + def messageAnswered(self, handle): + if handle not in self.queue: + return + self.queue = [q for q in self.queue if q != handle] + del self.funcs[handle] + if len(self.queue) == 0: + self.mainwindow.updateSystemTray() + def addMessage(self, handle, func): + if not self.funcs.has_key(handle): + self.queue.append(handle) + self.funcs[handle] = func + if len(self.queue) > 0: + self.mainwindow.updateSystemTray() + def __len__(self): + return len(self.queue) + +class NoneSound(object): + def play(self): pass + +class PesterLog(object): + def __init__(self, handle): + self.handle = handle + if not os.path.exists("logs/%s" % (handle)): + os.mkdir("logs/%s" % (handle)) + self.convos = {} + def log(self, handle, msg): + if not self.convos.has_key(handle): + time = datetime.now().strftime("%Y-%m-%d.%H.%M.txt") + if not os.path.exists("logs/%s/%s" % (self.handle, handle)): + os.mkdir("logs/%s/%s" % (self.handle, handle)) + fp = open("logs/%s/%s/%s.%s" % (self.handle, handle, handle, time), 'a') + self.convos[handle] = fp + self.convos[handle].write(msg+"\n") + self.convos[handle].flush() + def finish(self, handle): + if not self.convos.has_key(handle): + return + self.convos[handle].close() + del self.convos[handle] + def close(self): + for h in self.convos.keys(): + self.convos[h].close() + +class PesterProfileDB(dict): + def __init__(self): + try: + fp = open("logs/chums.js", 'r') + chumdict = json.load(fp) + fp.close() + except IOError: + chumdict = {} + fp = open("logs/chums.js", 'w') + json.dump(chumdict, fp) + fp.close() + converted = dict([(handle, PesterProfile(handle, color=QtGui.QColor(c['color']), mood=Mood(c['mood']))) for (handle, c) in chumdict.iteritems()]) + self.update(converted) + + def save(self): + fp = open("logs/chums.js", 'w') + chumdict = dict([p.plaindict() for p in self.itervalues()]) + json.dump(chumdict, fp) + fp.close() + def getColor(self, handle, default=None): + if not self.has_key(handle): + return default + else: + return self[handle].color + def setColor(self, handle, color): + if self.has_key(handle): + self[handle].color = color + else: + self[handle] = PesterProfile(handle, color) + def __setitem__(self, key, val): + dict.__setitem__(self, key, val) + self.save() + +class pesterTheme(dict): + def __init__(self, name): + self.path = "themes/%s" % (name) + self.name = name + fp = open(self.path+"/style.js") + theme = json.load(fp, object_hook=self.pathHook) + self.update(theme) + fp.close() + def __getitem__(self, key): + keys = key.split("/") + v = dict.__getitem__(self, keys.pop(0)) + for k in keys: + v = v[k] + return v + def pathHook(self, d): + for (k, v) in d.iteritems(): + if type(v) is unicode: + s = Template(v) + d[k] = s.safe_substitute(path=self.path) + return d + + +class userConfig(object): + def __init__(self): + fp = open("pesterchum.js") + self.config = json.load(fp) + fp.close() + if self.config.has_key("defaultprofile"): + self.userprofile = userProfile(self.config["defaultprofile"]) + else: + self.userprofile = None + def chums(self): + return self.config['chums'] + def defaultprofile(self): + try: + return self.config['defaultprofile'] + except KeyError: + return None + def tabs(self): + return self.config["tabs"] + def addChum(self, chum): + newchums = self.config['chums'] + [chum.handle] + self.set("chums", newchums) + def removeChum(self, chum): + if type(chum) is PesterProfile: + handle = chum.handle + else: + handle = chum + newchums = [c for c in self.config['chums'] if c != handle] + self.set("chums", newchums) + def getBlocklist(self): + if not self.config.has_key('block'): + self.set('block', []) + return self.config['block'] + def addBlocklist(self, handle): + l = self.getBlocklist() + if handle not in l: + l.append(handle) + self.set('block', l) + def delBlocklist(self, handle): + l = self.getBlocklist() + l.pop(l.index(handle)) + self.set('block', l) + def set(self, item, setting): + self.config[item] = setting + try: + jsonoutput = json.dumps(self.config) + except ValueError, e: + raise e + fp = open("pesterchum.js", 'w') + fp.write(jsonoutput) + fp.close() + def availableThemes(self): + themes = [] + for dirname, dirnames, filenames in os.walk('themes'): + for d in dirnames: + themes.append(d) + themes.sort() + return themes + def availableProfiles(self): + profs = [] + for dirname, dirnames, filenames in os.walk('profiles'): + for filename in filenames: + l = len(filename) + if filename[l-3:l] == ".js": + profs.append(filename[0:l-3]) + profs.sort() + return [userProfile(p) for p in profs] +class userProfile(object): + def __init__(self, user): + if type(user) is PesterProfile: + self.chat = user + self.userprofile = {"handle":user.handle, + "color": unicode(user.color.name()), + "quirks": [], + "theme": "pesterchum"} + self.theme = pesterTheme("pesterchum") + self.chat.mood = Mood(self.theme["main/defaultmood"]) + self.quirks = pesterQuirks([]) + else: + fp = open("profiles/%s.js" % (user)) + self.userprofile = json.load(fp) + fp.close() + try: + self.theme = pesterTheme(self.userprofile["theme"]) + except ValueError, e: + self.theme = pesterTheme("pesterchum") + + self.chat = PesterProfile(self.userprofile["handle"], + QtGui.QColor(self.userprofile["color"]), + Mood(self.theme["main/defaultmood"])) + self.quirks = pesterQuirks(self.userprofile["quirks"]) + def setMood(self, mood): + self.chat.mood = mood + def setTheme(self, theme): + self.theme = theme + self.userprofile["theme"] = theme.name + self.save() + def setColor(self, color): + self.chat.color = color + self.userprofile["color"] = unicode(color.name()) + self.save() + def setQuirks(self, quirks): + self.quirks = quirks + self.userprofile["quirks"] = self.quirks.plainList() + self.save() + def getTheme(self): + return self.theme + def save(self): + handle = self.chat.handle + try: + jsonoutput = json.dumps(self.userprofile) + except ValueError, e: + raise e + fp = open("profiles/%s.js" % (handle), 'w') + fp.write(jsonoutput) + fp.close() + @staticmethod + def newUserProfile(chatprofile): + if os.path.exists("profiles/%s.js" % (chatprofile.handle)): + newprofile = userProfile(chatprofile.handle) + else: + newprofile = userProfile(chatprofile) + newprofile.save() + return newprofile + + +class WMButton(QtGui.QPushButton): + def __init__(self, icon, parent=None): + QtGui.QPushButton.__init__(self, icon, "", parent) + self.setIconSize(icon.realsize()) + self.setFlat(True) + self.setStyleSheet("QPushButton { padding: 0px; }") + self.setAutoDefault(False) + +class chumListing(QtGui.QListWidgetItem): + def __init__(self, chum, window): + QtGui.QListWidgetItem.__init__(self, chum.handle) + self.mainwindow = window + self.chum = chum + self.handle = chum.handle + self.setMood(Mood("offline")) + def setMood(self, mood): + self.chum.mood = mood + self.updateMood() + def setColor(self, color): + self.chum.color = color + def updateMood(self, unblock=False): + mood = self.chum.mood + self.mood = mood + icon = self.mood.icon(self.mainwindow.theme) + self.setIcon(icon) + try: + self.setTextColor(QtGui.QColor(self.mainwindow.theme["main/chums/moods"][self.mood.name()]["color"])) + except KeyError: + self.setTextColor(QtGui.QColor(self.mainwindow.theme["main/chums/moods/chummy/color"])) + def changeTheme(self, theme): + icon = self.mood.icon(theme) + self.setIcon(icon) + try: + self.setTextColor(QtGui.QColor(self.mainwindow.theme["main/chums/moods"][self.mood.name()]["color"])) + except KeyError: + self.setTextColor(QtGui.QColor(self.mainwindow.theme["main/chums/moods/chummy/color"])) + def __lt__(self, cl): + h1 = self.handle.lower() + h2 = cl.handle.lower() + return (h1 < h2) + +class chumArea(RightClickList): + def __init__(self, chums, parent=None): + QtGui.QListWidget.__init__(self, parent) + self.mainwindow = parent + theme = self.mainwindow.theme + geometry = theme["main/chums/loc"] + theme["main/chums/size"] + self.setGeometry(*geometry) + self.setStyleSheet(theme["main/chums/style"]) + self.chums = chums + for c in self.chums: + chandle = c.handle + if not self.findItems(chandle, QtCore.Qt.MatchFlags(0)): + chumLabel = chumListing(c, self.mainwindow) + self.addItem(chumLabel) + + self.optionsMenu = QtGui.QMenu(self) + self.pester = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/pester"], self) + self.connect(self.pester, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('activateChum()')) + self.removechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/removechum"], self) + self.connect(self.removechum, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('removeChum()')) + self.blockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"], self) + self.connect(self.blockchum, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('blockChum()')) + self.optionsMenu.addAction(self.pester) + self.optionsMenu.addAction(self.blockchum) + self.optionsMenu.addAction(self.removechum) + + self.sortItems() + def addChum(self, chum): + if len([c for c in self.chums if c.handle == chum.handle]) != 0: + return + self.chums.append(chum) + chumLabel = chumListing(chum, self.mainwindow) + self.addItem(chumLabel) + self.sortItems() + + def getChums(self, handle): + chums = self.findItems(handle, QtCore.Qt.MatchFlags(0)) + return chums + def updateMood(self, handle, mood): + chums = self.getChums(handle) + for c in chums: + c.setMood(mood) + def updateColor(self, handle, color): + chums = self.findItems(handle, QtCore.Qt.MatchFlags(0)) + for c in chums: + c.setColor(color) + def changeTheme(self, theme): + self.setGeometry(*(theme["main/chums/loc"]+theme["main/chums/size"])) + self.setStyleSheet(theme["main/chums/style"]) + self.pester.setText(theme["main/menus/rclickchumlist/pester"]) + self.removechum.setText(theme["main/menus/rclickchumlist/removechum"]) + self.blockchum.setText(theme["main/menus/rclickchumlist/blockchum"]) + + chumlistings = [self.item(i) for i in range(0, self.count())] + for c in chumlistings: + c.changeTheme(theme) + @QtCore.pyqtSlot() + def activateChum(self): + self.itemActivated.emit(self.currentItem()) + @QtCore.pyqtSlot() + def removeChum(self, handle = None): + if handle: + clistings = self.getChums(handle) + for c in clistings: + self.setCurrentItem(c) + if not self.currentItem(): + return + currentChum = self.currentItem().chum + self.chums = [c for c in self.chums if c.handle != currentChum.handle] + self.removeChumSignal.emit(self.currentItem()) + oldlist = self.takeItem(self.currentRow()) + del oldlist + @QtCore.pyqtSlot() + def blockChum(self): + currentChum = self.currentItem() + if not currentChum: + return + self.blockChumSignal.emit(self.currentItem().chum.handle) + + removeChumSignal = QtCore.pyqtSignal(QtGui.QListWidgetItem) + blockChumSignal = QtCore.pyqtSignal(QtCore.QString) + +class trollSlum(chumArea): + def __init__(self, trolls, mainwindow, parent=None): + QtGui.QListWidget.__init__(self, parent) + self.mainwindow = mainwindow + theme = self.mainwindow.theme + self.setStyleSheet(theme["main/trollslum/chumroll/style"]) + self.chums = trolls + for c in self.chums: + chandle = c.handle + if not self.findItems(chandle, QtCore.Qt.MatchFlags(0)): + chumLabel = chumListing(c, self.mainwindow) + self.addItem(chumLabel) + + self.optionsMenu = QtGui.QMenu(self) + self.unblockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self) + self.connect(self.unblockchum, QtCore.SIGNAL('triggered()'), + self, QtCore.SIGNAL('unblockChumSignal()')) + self.optionsMenu.addAction(self.unblockchum) + + self.sortItems() + def changeTheme(self, theme): + self.setStyleSheet(theme["main/trollslum/chumroll/style"]) + self.removechum.setText(theme["main/menus/rclickchumlist/removechum"]) + self.unblockchum.setText(theme["main/menus/rclickchumlist/blockchum"]) + + chumlistings = [self.item(i) for i in range(0, self.count())] + for c in chumlistings: + c.changeTheme(theme) + + unblockChumSignal = QtCore.pyqtSignal(QtCore.QString) + +class TrollSlumWindow(QtGui.QFrame): + def __init__(self, trolls, mainwindow, parent=None): + QtGui.QFrame.__init__(self, parent) + self.mainwindow = mainwindow + theme = self.mainwindow.theme + self.slumlabel = QtGui.QLabel(self) + self.initTheme(theme) + + self.trollslum = trollSlum(trolls, self.mainwindow, self) + self.connect(self.trollslum, QtCore.SIGNAL('unblockChumSignal()'), + self, QtCore.SLOT('removeCurrentTroll()')) + layout_1 = QtGui.QHBoxLayout() + self.addButton = QtGui.QPushButton("ADD", self) + self.connect(self.addButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('addTrollWindow()')) + self.removeButton = QtGui.QPushButton("REMOVE", self) + self.connect(self.removeButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('removeCurrentTroll()')) + layout_1.addWidget(self.addButton) + layout_1.addWidget(self.removeButton) + + layout_0 = QtGui.QVBoxLayout() + layout_0.addWidget(self.slumlabel) + layout_0.addWidget(self.trollslum) + layout_0.addLayout(layout_1) + self.setLayout(layout_0) + + def initTheme(self, theme): + self.resize(*theme["main/trollslum/size"]) + self.setStyleSheet(theme["main/trollslum/style"]) + self.slumlabel.setText(theme["main/trollslum/label/text"]) + self.slumlabel.setStyleSheet(theme["main/trollslum/label/style"]) + if not self.parent(): + self.setWindowTitle(theme["main/menus/profile/block"]) + self.setWindowIcon(self.mainwindow.windowIcon()) + def changeTheme(self, theme): + self.initTheme(theme) + self.trollslum.changeTheme(theme) + # move unblocked trolls from slum to chumarea + def closeEvent(self, event): + self.mainwindow.closeTrollSlum() + + def updateMood(self, handle, mood): + self.trollslum.updateMood(handle, mood) + def addTroll(self, chum): + self.trollslum.addChum(chum) + def removeTroll(self, handle): + self.trollslum.removeChum(handle) + @QtCore.pyqtSlot() + def removeCurrentTroll(self): + currentListing = self.trollslum.currentItem() + if not currentListing: + return + self.unblockChumSignal.emit(currentListing.chum.handle) + @QtCore.pyqtSlot() + def addTrollWindow(self): + if not hasattr(self, 'addtrolldialog'): + self.addtrolldialog = None + if self.addtrolldialog: + return + self.addtrolldialog = QtGui.QInputDialog(self) + (handle, ok) = self.addtrolldialog.getText(self, "Add Troll", "Enter Troll Handle:") + if ok: + handle = unicode(handle) + if not (PesterProfile.checkLength(handle) and + PesterProfile.checkValid(handle)): + errormsg = QtGui.QErrorMessage(self) + errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!") + self.addchumdialog = None + return + self.blockChumSignal.emit(handle) + self.addtrolldialog = None + + blockChumSignal = QtCore.pyqtSignal(QtCore.QString) + unblockChumSignal = QtCore.pyqtSignal(QtCore.QString) + +class PesterMoodHandler(QtCore.QObject): + def __init__(self, parent, *buttons): + QtCore.QObject.__init__(self) + self.buttons = {} + self.mainwindow = parent + for b in buttons: + self.buttons[b.mood.value()] = b + if b.mood.value() == self.mainwindow.profile().mood.value(): + b.setSelected(True) + self.connect(b, QtCore.SIGNAL('clicked()'), + b, QtCore.SLOT('updateMood()')) + self.connect(b, QtCore.SIGNAL('moodUpdated(int)'), + self, QtCore.SLOT('updateMood(int)')) + def removeButtons(self): + for b in self.buttons.values(): + b.close() + def showButtons(self): + for b in self.buttons.values(): + b.show() + b.raise_() + @QtCore.pyqtSlot(int) + def updateMood(self, m): + oldmood = self.mainwindow.profile().mood + try: + oldbutton = self.buttons[oldmood.value()] + oldbutton.setSelected(False) + except KeyError: + pass + newbutton = self.buttons[m] + newbutton.setSelected(True) + newmood = Mood(m) + self.mainwindow.userprofile.chat.mood = newmood + self.mainwindow.moodUpdated.emit() + +class PesterMoodButton(QtGui.QPushButton): + def __init__(self, parent, **options): + icon = PesterIcon(options["icon"]) + QtGui.QPushButton.__init__(self, icon, options["text"], parent) + self.setIconSize(icon.realsize()) + self.setFlat(True) + self.resize(*options["size"]) + self.move(*options["loc"]) + self.unselectedSheet = options["style"] + self.selectedSheet = options["selected"] + self.setStyleSheet(self.unselectedSheet) + self.mainwindow = parent + self.mood = Mood(options["mood"]) + def setSelected(self, selected): + if selected: + self.setStyleSheet(self.selectedSheet) + else: + self.setStyleSheet(self.unselectedSheet) + @QtCore.pyqtSlot() + def updateMood(self): + self.moodUpdated.emit(self.mood.value()) + moodUpdated = QtCore.pyqtSignal(int) + + +class MovingWindow(QtGui.QFrame): + def __init__(self, *x, **y): + QtGui.QFrame.__init__(self, *x, **y) + self.moving = None + self.moveupdate = 0 + def mouseMoveEvent(self, event): + if self.moving: + move = event.globalPos() - self.moving + self.move(move) + self.moveupdate += 1 + if self.moveupdate > 5: + self.moveupdate = 0 + self.update() + def mousePressEvent(self, event): + if event.button() == 1: + self.moving = event.globalPos() - self.pos() + def mouseReleaseEvent(self, event): + if event.button() == 1: + self.update() + self.moving = None + + +class PesterWindow(MovingWindow): + def __init__(self, parent=None): + MovingWindow.__init__(self, parent, + flags=(QtCore.Qt.CustomizeWindowHint | + QtCore.Qt.FramelessWindowHint)) + + self.convos = {} + self.memos = {} + self.tabconvo = None + self.tabmemo = None + + self.setObjectName("main") + self.config = userConfig() + if self.config.defaultprofile(): + self.userprofile = userProfile(self.config.defaultprofile()) + self.theme = self.userprofile.getTheme() + else: + self.userprofile = userProfile(PesterProfile("pesterClient%d" % (random.randint(100,999)), QtGui.QColor("black"), Mood(0))) + self.theme = self.userprofile.getTheme() + + self.chatlog = PesterLog(self.profile().handle) + + self.move(100, 100) + + opts = QtGui.QAction(self.theme["main/menus/client/options"], self) + self.opts = opts + self.connect(opts, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('openOpts()')) + exitaction = QtGui.QAction(self.theme["main/menus/client/exit"], self) + self.exitaction = exitaction + self.connect(exitaction, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('close()')) + userlistaction = QtGui.QAction(self.theme["main/menus/client/userlist"], self) + self.userlistaction = userlistaction + self.connect(userlistaction, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('showAllUsers()')) + memoaction = QtGui.QAction(self.theme["main/menus/client/memos"], self) + self.memoaction = memoaction + self.connect(memoaction, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('showMemos()')) + self.menu = QtGui.QMenuBar(self) + + filemenu = self.menu.addMenu(self.theme["main/menus/client/_name"]) + self.filemenu = filemenu + filemenu.addAction(opts) + filemenu.addAction(memoaction) + filemenu.addAction(userlistaction) + filemenu.addAction(exitaction) + + changetheme = QtGui.QAction(self.theme["main/menus/profile/theme"], self) + self.changetheme = changetheme + self.connect(changetheme, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('pickTheme()')) + changequirks = QtGui.QAction(self.theme["main/menus/profile/quirks"], self) + self.changequirks = changequirks + self.connect(changequirks, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('openQuirks()')) + loadslum = QtGui.QAction(self.theme["main/menus/profile/block"], self) + self.loadslum = loadslum + self.connect(loadslum, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('showTrollSlum()')) + + changecoloraction = QtGui.QAction(self.theme["main/menus/profile/color"], self) + self.changecoloraction = changecoloraction + self.connect(changecoloraction, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('changeMyColor()')) + + switch = QtGui.QAction(self.theme["main/menus/profile/switch"], self) + self.switch = switch + self.connect(switch, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('switchProfile()')) + + profilemenu = self.menu.addMenu(self.theme["main/menus/profile/_name"]) + self.profilemenu = profilemenu + profilemenu.addAction(changetheme) + profilemenu.addAction(changequirks) + profilemenu.addAction(loadslum) + profilemenu.addAction(changecoloraction) + profilemenu.addAction(switch) + + self.closeButton = WMButton(PesterIcon(self.theme["main/close/image"]), self) + self.connect(self.closeButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('close()')) + self.miniButton = WMButton(PesterIcon(self.theme["main/minimize/image"]), self) + self.connect(self.miniButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('showMinimized()')) + + self.namesdb = {} + self.chumdb = PesterProfileDB() + + chums = [PesterProfile(c, chumdb=self.chumdb) for c in set(self.config.chums())] + self.chumList = chumArea(chums, self) + self.connect(self.chumList, + QtCore.SIGNAL('itemActivated(QListWidgetItem *)'), + self, + QtCore.SLOT('newConversationWindow(QListWidgetItem *)')) + self.connect(self.chumList, + QtCore.SIGNAL('removeChumSignal(QListWidgetItem *)'), + self, + QtCore.SLOT('removeChum(QListWidgetItem *)')) + self.connect(self.chumList, + QtCore.SIGNAL('blockChumSignal(QString)'), + self, + QtCore.SLOT('blockChum(QString)')) + + self.addChumButton = QtGui.QPushButton(self.theme["main/addchum/text"], self) + self.connect(self.addChumButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('addChumWindow()')) + self.pesterButton = QtGui.QPushButton(self.theme["main/pester/text"], self) + self.connect(self.pesterButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('pesterSelectedChum()')) + self.blockButton = QtGui.QPushButton(self.theme["main/block/text"], self) + self.connect(self.blockButton, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('blockSelectedChum()')) + + self.moodsLabel = QtGui.QLabel(self.theme["main/moodlabel/text"], self) + + self.mychumhandleLabel = QtGui.QLabel(self.theme["main/mychumhandle/label/text"], self) + self.mychumhandle = QtGui.QPushButton(self.profile().handle, self) + self.mychumhandle.setFlat(True) + self.connect(self.mychumhandle, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('switchProfile()')) + + self.mychumcolor = QtGui.QPushButton(self) + self.connect(self.mychumcolor, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('changeMyColor()')) + + self.initTheme(self.theme) + + self.waitingMessages = waitingMessageHolder(self) + + if not self.config.defaultprofile(): + self.changeProfile() + self.loadingscreen = LoadingScreen(self) + self.connect(self.loadingscreen, QtCore.SIGNAL('rejected()'), + self, QtCore.SLOT('close()')) + + def profile(self): + return self.userprofile.chat + def closeConversations(self): + if not hasattr(self, 'tabconvo'): + self.tabconvo = None + if self.tabconvo: + self.tabconvo.close() + else: + for c in self.convos.values(): + c.close() + if self.tabmemo: + self.tabmemo.close() + else: + for m in self.memos.values(): + m.close() + + def closeEvent(self, event): + self.closeConversations() + if hasattr(self, 'trollslum') and self.trollslum: + self.trollslum.close() + event.accept() + def newMessage(self, handle, msg): + if handle in self.config.getBlocklist(): + #yeah suck on this + return + if not self.convos.has_key(handle): + if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up + return + matchingChums = [c for c in self.chumList.chums if c.handle == handle] + if len(matchingChums) > 0: + mood = matchingChums[0].mood + else: + mood = Mood(0) + chum = PesterProfile(handle, mood=mood, chumdb=self.chumdb) + self.newConversation(chum, False) + if len(matchingChums) == 0: + self.moodRequest.emit(chum) + convo = self.convos[handle] + convo.addMessage(msg, False) + # play sound here + self.alarm.play() + def newMemoMsg(self, chan, handle, msg): + if not self.memos.has_key(chan): + # silently ignore in case we forgot to /part + return + memo = self.memos[chan] + memo.addMessage(msg, handle) + self.alarm.play() + + def changeColor(self, handle, color): + # pesterconvo and chumlist + self.chumList.updateColor(handle, color) + if self.convos.has_key(handle): + self.convos[handle].updateColor(color) + self.chumdb.setColor(handle, color) + + def updateMood(self, handle, mood): + self.chumList.updateMood(handle, mood) + if self.convos.has_key(handle): + self.convos[handle].updateMood(mood) + if hasattr(self, 'trollslum') and self.trollslum: + self.trollslum.updateMood(handle, mood) + def newConversation(self, chum, initiated=True): + if self.convos.has_key(chum.handle): + self.convos[chum.handle].showChat() + return + if self.config.tabs(): + if not self.tabconvo: + self.createTabWindow() + convoWindow = PesterConvo(chum, initiated, self, self.tabconvo) + self.tabconvo.show() + else: + convoWindow = PesterConvo(chum, initiated, self) + self.connect(convoWindow, QtCore.SIGNAL('messageSent(QString, QString)'), + self, QtCore.SIGNAL('sendMessage(QString, QString)')) + self.connect(convoWindow, QtCore.SIGNAL('windowClosed(QString)'), + self, QtCore.SLOT('closeConvo(QString)')) + self.convos[chum.handle] = convoWindow + self.newConvoStarted.emit(QtCore.QString(chum.handle), initiated) + convoWindow.show() + + def createTabWindow(self): + self.tabconvo = PesterTabWindow(self) + self.connect(self.tabconvo, QtCore.SIGNAL('windowClosed()'), + self, QtCore.SLOT('tabsClosed()')) + def createMemoTabWindow(self): + self.tabmemo = MemoTabWindow(self) + self.connect(self.tabmemo, QtCore.SIGNAL('windowClosed()'), + self, QtCore.SLOT('memoTabsClosed()')) + + def newMemo(self, channel, timestr): + if channel == "#pesterchum": + return + if self.memos.has_key(channel): + self.memos[channel].showChat() + return + # do slider dialog then set + if self.config.tabs(): + if not self.tabmemo: + self.createMemoTabWindow() + memoWindow = PesterMemo(channel, timestr, self, self.tabmemo) + self.tabmemo.show() + else: + memoWindow = PesterMemo(channel, timestr, self, None) + # connect signals + self.connect(memoWindow, QtCore.SIGNAL('messageSent(QString, QString)'), + self, QtCore.SIGNAL('sendMessage(QString, QString)')) + self.connect(memoWindow, QtCore.SIGNAL('windowClosed(QString)'), + self, QtCore.SLOT('closeMemo(QString)')) + self.connect(self, QtCore.SIGNAL('namesUpdated()'), + memoWindow, QtCore.SLOT('namesUpdated()')) + self.connect(self, + QtCore.SIGNAL('userPresentSignal(QString, QString, QString)'), + memoWindow, QtCore.SLOT('userPresentChange(QString, QString, QString)')) + # chat client send memo open + self.memos[channel] = memoWindow + self.joinChannel.emit(channel) # race condition? + memoWindow.sendTimeInfo() + memoWindow.show() + + def addChum(self, chum): + self.chumList.addChum(chum) + self.config.addChum(chum) + self.moodRequest.emit(chum) + + def changeProfile(self, collision=None): + if not hasattr(self, 'chooseprofile'): + self.chooseprofile = None + if not self.chooseprofile: + self.chooseprofile = PesterChooseProfile(self.userprofile, self.config, self.theme, self, collision=collision) + self.chooseprofile.exec_() + + def themePicker(self): + if not hasattr(self, 'choosetheme'): + self.choosetheme = None + if not self.choosetheme: + self.choosetheme = PesterChooseTheme(self.config, self.theme, self) + self.choosetheme.exec_() + def initTheme(self, theme): + self.resize(*theme["main/size"]) + self.setWindowIcon(PesterIcon(theme["main/icon"])) + self.setWindowTitle(theme["main/windowtitle"]) + self.setStyleSheet("QFrame#main { "+theme["main/style"]+" }") + self.menu.setStyleSheet("QMenuBar { background: transparent; %s } QMenuBar::item { background: transparent; %s } " % (theme["main/menubar/style"], theme["main/menu/menuitem"]) + "QMenu { background: transparent; %s } QMenu::item::selected { %s }" % (theme["main/menu/style"], theme["main/menu/selected"])) + newcloseicon = PesterIcon(theme["main/close/image"]) + self.closeButton.setIcon(newcloseicon) + self.closeButton.setIconSize(newcloseicon.realsize()) + self.closeButton.move(*theme["main/close/loc"]) + newminiicon = PesterIcon(theme["main/minimize/image"]) + self.miniButton.setIcon(newminiicon) + self.miniButton.setIconSize(newminiicon.realsize()) + self.miniButton.move(*theme["main/minimize/loc"]) + # menus + self.menu.move(*theme["main/menu/loc"]) + self.opts.setText(theme["main/menus/client/options"]) + self.exitaction.setText(theme["main/menus/client/exit"]) + self.userlistaction.setText(theme["main/menus/client/userlist"]) + self.memoaction.setText(theme["main/menus/client/memos"]) + self.filemenu.setTitle(theme["main/menus/client/_name"]) + self.changetheme.setText(theme["main/menus/profile/theme"]) + self.changequirks.setText(theme["main/menus/profile/quirks"]) + self.loadslum.setText(theme["main/menus/profile/block"]) + self.changecoloraction.setText(theme["main/menus/profile/color"]) + self.switch.setText(theme["main/menus/profile/switch"]) + self.profilemenu.setTitle(theme["main/menus/profile/_name"]) + + # moods + self.moodsLabel.setText(theme["main/moodlabel/text"]) + self.moodsLabel.move(*theme["main/moodlabel/loc"]) + self.moodsLabel.setStyleSheet(theme["main/moodlabel/style"]) + + if hasattr(self, 'moods'): + self.moods.removeButtons() + self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in theme["main/moods"]]) + self.moods.showButtons() + # chum + self.addChumButton.setText(theme["main/addchum/text"]) + self.addChumButton.resize(*theme["main/addchum/size"]) + self.addChumButton.move(*theme["main/addchum/loc"]) + self.addChumButton.setStyleSheet(theme["main/addchum/style"]) + self.pesterButton.setText(theme["main/pester/text"]) + self.pesterButton.resize(*theme["main/pester/size"]) + self.pesterButton.move(*theme["main/pester/loc"]) + self.pesterButton.setStyleSheet(theme["main/pester/style"]) + self.blockButton.setText(theme["main/block/text"]) + self.blockButton.resize(*theme["main/block/size"]) + self.blockButton.move(*theme["main/block/loc"]) + self.blockButton.setStyleSheet(theme["main/block/style"]) + # buttons + self.mychumhandleLabel.setText(theme["main/mychumhandle/label/text"]) + self.mychumhandleLabel.move(*theme["main/mychumhandle/label/loc"]) + self.mychumhandleLabel.setStyleSheet(theme["main/mychumhandle/label/style"]) + self.mychumhandle.setText(self.profile().handle) + self.mychumhandle.move(*theme["main/mychumhandle/handle/loc"]) + self.mychumhandle.resize(*theme["main/mychumhandle/handle/size"]) + self.mychumhandle.setStyleSheet(theme["main/mychumhandle/handle/style"]) + self.mychumcolor.resize(*theme["main/mychumhandle/colorswatch/size"]) + self.mychumcolor.move(*theme["main/mychumhandle/colorswatch/loc"]) + self.mychumcolor.setStyleSheet("background: %s" % (self.profile().colorhtml())) + if theme["main/mychumhandle/colorswatch/text"]: + self.mychumcolor.setText(theme["main/mychumhandle/colorswatch/text"]) + + # sounds + if not pygame.mixer: + self.alarm = NoneSound() + else: + self.alarm = pygame.mixer.Sound(theme["main/sounds/alertsound"]) + + def changeTheme(self, theme): + self.theme = theme + # do self + self.initTheme(theme) + # chum area + self.chumList.changeTheme(theme) + # do open windows + if self.tabconvo: + self.tabconvo.changeTheme(theme) + if self.tabmemo: + self.tabmemo + for c in self.convos.values(): + c.changeTheme(theme) + if hasattr(self, 'trollslum') and self.trollslum: + self.trollslum.changeTheme(theme) + if hasattr(self, 'allusers') and self.allusers: + self.allusers.changeTheme(theme) + # system tray icon + self.updateSystemTray() + + def updateSystemTray(self): + if len(self.waitingMessages) == 0: + self.trayIconSignal.emit(0) + else: + self.trayIconSignal.emit(1) + + def systemTrayFunction(self): + if len(self.waitingMessages) == 0: + if self.isMinimized(): + self.showNormal() + else: + if self.isActiveWindow(): + self.showMinimized() + else: + self.raise_() + self.activateWindow() + else: + self.waitingMessages.answerMessage() + + @QtCore.pyqtSlot() + def connected(self): + if self.loadingscreen: + self.loadingscreen.accept() + self.loadingscreen = None + @QtCore.pyqtSlot() + def blockSelectedChum(self): + curChumListing = self.chumList.currentItem() + if curChumListing: + curChum = curChumListing.chum + self.blockChum(curChum.handle) + @QtCore.pyqtSlot() + def pesterSelectedChum(self): + curChum = self.chumList.currentItem() + if curChum: + self.newConversationWindow(curChum) + @QtCore.pyqtSlot(QtGui.QListWidgetItem) + def newConversationWindow(self, chumlisting): + # check chumdb + chum = chumlisting.chum + color = self.chumdb.getColor(chum) + if color: + chum.color = color + self.newConversation(chum) + @QtCore.pyqtSlot(QtCore.QString) + def closeConvo(self, handle): + h = unicode(handle) + chum = self.convos[h].chum + chumopen = self.convos[h].chumopen + if chumopen: + self.chatlog.log(chum.handle, convertTags(self.profile().pestermsg(chum, QtGui.QColor(self.theme["convo/systemMsgColor"]), self.theme["convo/text/ceasepester"]), "bbcode")) + self.convoClosed.emit(handle) + self.chatlog.finish(h) + del self.convos[h] + @QtCore.pyqtSlot(QtCore.QString) + def closeMemo(self, channel): + c = unicode(channel) + self.chatlog.finish(c) + self.leftChannel.emit(channel) + del self.memos[c] + @QtCore.pyqtSlot() + def tabsClosed(self): + del self.tabconvo + self.tabconvo = None + @QtCore.pyqtSlot() + def memoTabsClosed(self): + del self.tabmemo + self.tabmemo = None + + @QtCore.pyqtSlot(QtCore.QString, Mood) + def updateMoodSlot(self, handle, mood): + h = unicode(handle) + self.updateMood(h, mood) + + @QtCore.pyqtSlot(QtCore.QString, QtGui.QColor) + def updateColorSlot(self, handle, color): + h = unicode(handle) + self.changeColor(h, color) + + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString) + def deliverMessage(self, handle, msg): + h = unicode(handle) + m = unicode(msg) + self.newMessage(h, m) + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) + def deliverMemo(self, chan, handle, msg): + (c, h, m) = (unicode(chan), unicode(handle), unicode(msg)) + self.newMemoMsg(c,h,m) + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) + def timeCommand(self, chan, handle, command): + (c, h, cmd) = (unicode(chan), unicode(handle), unicode(command)) + if self.memos[c]: + self.memos[c].timeUpdate(h, cmd) + + @QtCore.pyqtSlot(QtCore.QString, PesterList) + def updateNames(self, channel, names): + c = unicode(channel) + # update name DB + self.namesdb[c] = names + # warn interested party of names + self.namesUpdated.emit() + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) + def userPresentUpdate(self, handle, channel, update): + c = unicode(channel) + n = unicode(handle) + if update == "quit" or update == "oldnick": + for c in self.namesdb.keys(): + try: + i = self.namesdb[c].index(n) + self.namesdb[c].pop(i) + except ValueError: + pass + except KeyError: + self.namesdb[c] = [] + elif update == "left": + try: + i = self.namesdb[c].index(n) + self.namesdb[c].pop(i) + except ValueError: + pass + except KeyError: + self.namesdb[c] = [] + elif update == "newnick": + for c in self.namesdb.keys(): + try: + i = self.namesdb[c].index(n) + except ValueError: + self.namesdb[c].append(n) + except KeyError: + self.namesdb[c] = [n] + elif update == "join": + try: + i = self.namesdb[c].index(n) + except ValueError: + self.namesdb[c].append(n) + except KeyError: + self.namesdb[c] = [n] + + self.userPresentSignal.emit(handle, channel, update) + + @QtCore.pyqtSlot() + def addChumWindow(self): + if not hasattr(self, 'addchumdialog'): + self.addchumdialog = None + if not self.addchumdialog: + self.addchumdialog = QtGui.QInputDialog(self) + (handle, ok) = self.addchumdialog.getText(self, "New Chum", "Enter Chum Handle:") + if ok: + handle = unicode(handle) + if not (PesterProfile.checkLength(handle) and + PesterProfile.checkValid(handle)): + errormsg = QtGui.QErrorMessage(self) + errormsg.showMessage("THIS IS NOT A VALID CHUMTAG!") + self.addchumdialog = None + return + chum = PesterProfile(handle, chumdb=self.chumdb) + self.addChum(chum) + self.addchumdialog = None + @QtCore.pyqtSlot(QtGui.QListWidgetItem) + def removeChum(self, chumlisting): + self.config.removeChum(chumlisting.chum) + @QtCore.pyqtSlot(QtCore.QString) + def blockChum(self, handle): + h = unicode(handle) + self.config.addBlocklist(h) + self.config.removeChum(h) + if self.convos.has_key(h): + convo = self.convos[h] + msg = self.profile().pestermsg(convo.chum, QtGui.QColor(self.theme["convo/systemMsgColor"]), self.theme["convo/text/blocked"]) + convo.textArea.append(convertTags(msg)) + self.chatlog.log(convo.chum.handle, convertTags(msg, "bbcode")) + convo.updateBlocked() + self.chumList.removeChum(h) + if hasattr(self, 'trollslum') and self.trollslum: + newtroll = PesterProfile(h) + self.trollslum.addTroll(newtroll) + self.moodRequest.emit(newtroll) + self.blockedChum.emit(handle) + + @QtCore.pyqtSlot(QtCore.QString) + def unblockChum(self, handle): + h = unicode(handle) + self.config.delBlocklist(h) + if self.convos.has_key(h): + convo = self.convos[h] + msg = self.profile().pestermsg(convo.chum, QtGui.QColor(self.theme["convo/systemMsgColor"]), self.theme["convo/text/unblocked"]) + convo.textArea.append(convertTags(msg)) + self.chatlog.log(convo.chum.handle, convertTags(msg, "bbcode")) + convo.updateMood(convo.chum.mood, unblocked=True) + chum = PesterProfile(h, chumdb=self.chumdb) + if hasattr(self, 'trollslum') and self.trollslum: + self.trollslum.removeTroll(handle) + self.config.addChum(chum) + self.chumList.addChum(chum) + self.moodRequest.emit(chum) + self.unblockedChum.emit(handle) + + @QtCore.pyqtSlot() + def showMemos(self): + if not hasattr(self, 'memochooser'): + self.memochooser = None + if self.memochooser: + return + self.memochooser = PesterMemoList(self) + self.connect(self.memochooser, QtCore.SIGNAL('accepted()'), + self, QtCore.SLOT('joinSelectedMemo()')) + self.connect(self.memochooser, QtCore.SIGNAL('rejected()'), + self, QtCore.SLOT('memoChooserClose()')) + self.requestChannelList.emit() + self.memochooser.show() + @QtCore.pyqtSlot() + def joinSelectedMemo(self): + newmemo = self.memochooser.newmemoname() + selectedmemo = self.memochooser.selectedmemo() + time = unicode(self.memochooser.timeinput.text()) + if newmemo: + channel = "#"+unicode(newmemo).replace(" ", "_") + self.newMemo(channel, time) + elif selectedmemo: + channel = "#"+unicode(selectedmemo.text()) + self.newMemo(channel, time) + self.memochooser = None + @QtCore.pyqtSlot() + def memoChooserClose(self): + self.memochooser = None + @QtCore.pyqtSlot() + def memoChooserClose(self): + self.memochooser = None + + @QtCore.pyqtSlot(PesterList) + def updateChannelList(self, channels): + if hasattr(self, 'memochooser') and self.memochooser: + self.memochooser.updateChannels(channels) + @QtCore.pyqtSlot() + def showAllUsers(self): + if not hasattr(self, 'allusers'): + self.allusers = None + if not self.allusers: + self.allusers = PesterUserlist(self.config, self.theme, self) + self.connect(self.allusers, QtCore.SIGNAL('accepted()'), + self, QtCore.SLOT('userListClose()')) + self.connect(self.allusers, QtCore.SIGNAL('rejected()'), + self, QtCore.SLOT('userListClose()')) + self.connect(self.allusers, QtCore.SIGNAL('addChum(QString)'), + self, QtCore.SLOT('userListAdd(QString)')) + self.requestNames.emit("#pesterchum") + self.allusers.show() + + @QtCore.pyqtSlot(QtCore.QString) + def userListAdd(self, handle): + h = unicode(handle) + chum = PesterProfile(h, chumdb=self.chumdb) + self.addChum(chum) + @QtCore.pyqtSlot() + def userListClose(self): + self.allusers = None + + @QtCore.pyqtSlot() + def openQuirks(self): + if not hasattr(self, 'quirkmenu'): + self.quirkmenu = None + if not self.quirkmenu: + self.quirkmenu = PesterChooseQuirks(self.config, self.theme, self) + self.connect(self.quirkmenu, QtCore.SIGNAL('accepted()'), + self, QtCore.SLOT('updateQuirks()')) + self.connect(self.quirkmenu, QtCore.SIGNAL('rejected()'), + self, QtCore.SLOT('closeQuirks()')) + self.quirkmenu.show() + self.quirkmenu.raise_() + self.quirkmenu.activateWindow() + @QtCore.pyqtSlot() + def updateQuirks(self): + quirks = pesterQuirks(self.quirkmenu.quirks()) + self.userprofile.setQuirks(quirks) + self.quirkmenu = None + @QtCore.pyqtSlot() + def closeQuirks(self): + self.quirkmenu = None + @QtCore.pyqtSlot() + def openOpts(self): + if not hasattr(self, 'optionmenu'): + self.optionmenu = None + if not self.optionmenu: + self.optionmenu = PesterOptions(self.config, self.theme, self) + self.connect(self.optionmenu, QtCore.SIGNAL('accepted()'), + self, QtCore.SLOT('updateOptions()')) + self.connect(self.optionmenu, QtCore.SIGNAL('rejected()'), + self, QtCore.SLOT('closeOptions()')) + self.optionmenu.show() + self.optionmenu.raise_() + self.optionmenu.activateWindow() + @QtCore.pyqtSlot() + def closeOptions(self): + self.optionmenu.close() + self.optionmenu = None + @QtCore.pyqtSlot() + def updateOptions(self): + # tabs + curtab = self.config.tabs() + tabsetting = self.optionmenu.tabcheck.isChecked() + if curtab and not tabsetting: + # split tabs into windows + windows = [] + if self.tabconvo: + windows = list(self.tabconvo.convos.values()) + if self.tabmemo: + windows += list(self.tabmemo.convos.values()) + + for w in windows: + w.setParent(None) + w.show() + w.raiseChat() + if self.tabconvo: + self.tabconvo.closeSoft() + if self.tabmemo: + self.tabmemo.closeSoft() + # save options + self.config.set("tabs", tabsetting) + elif tabsetting and not curtab: + # combine + self.createTabWindow() + newconvos = {} + for (h,c) in self.convos.iteritems(): + c.setParent(self.tabconvo) + self.tabconvo.addChat(c) + self.tabconvo.show() + newconvos[h] = c + self.convos = newconvos + newmemos = {} + self.createMemoTabWindow() + for (h,m) in self.memos.iteritems(): + m.setParent(self.tabmemo) + self.tabmemo.addChat(m) + self.tabmemo.show() + newmemos[h] = m + self.memos = newmemos + # save options + self.config.set("tabs", tabsetting) + self.optionmenu = None + + @QtCore.pyqtSlot() + def themeSelected(self): + themename = unicode(self.choosetheme.themeBox.currentText()) + if themename != self.theme.name: + try: + self.changeTheme(pesterTheme(themename)) + except ValueError, e: + themeWarning = QtGui.QMessageBox(self) + themeWarning.setText("Theme Error: %s" % (e)) + themeWarning.exec_() + self.choosetheme = None + return + # update profile + self.userprofile.setTheme(self.theme) + self.choosetheme = None + @QtCore.pyqtSlot() + def closeTheme(self): + self.choosetheme = None + @QtCore.pyqtSlot() + def profileSelected(self): + if self.chooseprofile.profileBox and \ + self.chooseprofile.profileBox.currentIndex() > 0: + handle = unicode(self.chooseprofile.profileBox.currentText()) + if handle == self.profile().handle: + self.chooseprofile = None + return + self.userprofile = userProfile(handle) + self.changeTheme(self.userprofile.getTheme()) + else: + handle = unicode(self.chooseprofile.chumHandle.text()) + if handle == self.profile().handle: + self.chooseprofile = None + return + profile = PesterProfile(handle, + self.chooseprofile.chumcolor) + self.userprofile = userProfile.newUserProfile(profile) + self.changeTheme(self.userprofile.getTheme()) + + self.chatlog.close() + self.chatlog = PesterLog(handle) + + # is default? + if self.chooseprofile.defaultcheck.isChecked(): + self.config.set("defaultprofile", self.userprofile.chat.handle) + # this may have to be fixed + self.closeConversations() + if hasattr(self, 'trollslum') and self.trollslum: + self.trollslum.close() + self.chooseprofile = None + self.profileChanged.emit() + @QtCore.pyqtSlot() + def showTrollSlum(self): + if not hasattr(self, 'trollslum'): + self.trollslum = None + if self.trollslum: + return + trolls = [PesterProfile(h) for h in self.config.getBlocklist()] + self.trollslum = TrollSlumWindow(trolls, self) + self.connect(self.trollslum, QtCore.SIGNAL('blockChumSignal(QString)'), + self, QtCore.SLOT('blockChum(QString)')) + self.connect(self.trollslum, + QtCore.SIGNAL('unblockChumSignal(QString)'), + self, QtCore.SLOT('unblockChum(QString)')) + self.moodsRequest.emit(PesterList(trolls)) + self.trollslum.show() + @QtCore.pyqtSlot() + def closeTrollSlum(self): + self.trollslum = None + @QtCore.pyqtSlot() + def changeMyColor(self): + if not hasattr(self, 'colorDialog'): + self.colorDialog = None + if self.colorDialog: + return + self.colorDialog = QtGui.QColorDialog(self) + color = self.colorDialog.getColor(initial=self.profile().color) + if not color.isValid(): + color = self.profile().color + self.mychumcolor.setStyleSheet("background: %s" % color.name()) + self.userprofile.setColor(color) + self.mycolorUpdated.emit() + self.colorDialog = None + @QtCore.pyqtSlot() + def closeProfile(self): + self.chooseprofile = None + @QtCore.pyqtSlot() + def switchProfile(self): + if self.convos: + closeWarning = QtGui.QMessageBox() + closeWarning.setText("WARNING: CHANGING PROFILES WILL CLOSE ALL CONVERSATION WINDOWS!") + closeWarning.setInformativeText("i warned you about windows bro!!!! i told you dog!") + closeWarning.setStandardButtons(QtGui.QMessageBox.Cancel | QtGui.QMessageBox.Ok) + closeWarning.setDefaultButton(QtGui.QMessageBox.Ok) + ret = closeWarning.exec_() + if ret == QtGui.QMessageBox.Cancel: + return + self.changeProfile() + + @QtCore.pyqtSlot(QtCore.QString, QtCore.QString) + def nickCollision(self, handle, tmphandle): + self.mychumhandle.setText(tmphandle) + if not hasattr(self, 'chooseprofile'): + self.chooseprofile = None + if not self.chooseprofile: + h = unicode(handle) + self.changeProfile(collision=h) + + @QtCore.pyqtSlot() + def pickTheme(self): + self.themePicker() + + @QtCore.pyqtSlot(QtGui.QSystemTrayIcon.ActivationReason) + def systemTrayActivated(self, reason): + if reason == QtGui.QSystemTrayIcon.Trigger: + self.systemTrayFunction() + elif reason == QtGui.QSystemTrayIcon.Context: + # show context menu i guess + pass + + newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted") + sendMessage = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) + convoClosed = QtCore.pyqtSignal(QtCore.QString) + profileChanged = QtCore.pyqtSignal() + moodRequest = QtCore.pyqtSignal(PesterProfile) + moodsRequest = QtCore.pyqtSignal(PesterList) + moodUpdated = QtCore.pyqtSignal() + requestChannelList = QtCore.pyqtSignal() + requestNames = QtCore.pyqtSignal(QtCore.QString) + namesUpdated = QtCore.pyqtSignal() + userPresentSignal = QtCore.pyqtSignal(QtCore.QString,QtCore.QString,QtCore.QString) + mycolorUpdated = QtCore.pyqtSignal() + trayIconSignal = QtCore.pyqtSignal(int) + blockedChum = QtCore.pyqtSignal(QtCore.QString) + unblockedChum = QtCore.pyqtSignal(QtCore.QString) + joinChannel = QtCore.pyqtSignal(QtCore.QString) + leftChannel = QtCore.pyqtSignal(QtCore.QString) + +class IRCThread(QtCore.QThread): + def __init__(self, ircobj): + QtCore.QThread.__init__(self) + self.irc = ircobj + def run(self): + irc = self.irc + while 1: + irc.updateIRC() + +class PesterTray(QtGui.QSystemTrayIcon): + def __init__(self, icon, mainwindow, parent): + QtGui.QSystemTrayIcon.__init__(self, icon, parent) + self.mainwindow = mainwindow + traymenu = QtGui.QMenu() + traymenu.addAction("Hi!! HI!!") + self.setContextMenu(traymenu) + + @QtCore.pyqtSlot(int) + def changeTrayIcon(self, i): + if i == 0: + self.setIcon(PesterIcon(self.mainwindow.theme["main/icon"])) + else: + self.setIcon(PesterIcon(self.mainwindow.theme["main/newmsgicon"])) + +def main(): + + app = QtGui.QApplication(sys.argv) + if pygame.mixer: + # we could set the frequency higher but i love how cheesy it sounds + pygame.mixer.init() + else: + print "Warning: No sound!" + widget = PesterWindow() + widget.show() + + trayicon = PesterTray(PesterIcon(widget.theme["main/icon"]), widget, app) + trayicon.show() + + trayicon.connect(trayicon, + QtCore.SIGNAL('activated(QSystemTrayIcon::ActivationReason)'), + widget, + QtCore.SLOT('systemTrayActivated(QSystemTrayIcon::ActivationReason)')) + trayicon.connect(widget, + QtCore.SIGNAL('trayIconSignal(int)'), + trayicon, + QtCore.SLOT('changeTrayIcon(int)')) + + + irc = PesterIRC(widget) + irc.IRCConnect() + irc.connect(widget, QtCore.SIGNAL('sendMessage(QString, QString)'), + irc, QtCore.SLOT('sendMessage(QString, QString)')) + irc.connect(widget, + QtCore.SIGNAL('newConvoStarted(QString, bool)'), + irc, QtCore.SLOT('startConvo(QString, bool)')) + irc.connect(widget, + QtCore.SIGNAL('convoClosed(QString)'), + irc, QtCore.SLOT('endConvo(QString)')) + irc.connect(widget, + QtCore.SIGNAL('profileChanged()'), + irc, + QtCore.SLOT('updateProfile()')) + irc.connect(widget, + QtCore.SIGNAL('moodRequest(PyQt_PyObject)'), + irc, + QtCore.SLOT('getMood(PyQt_PyObject)')) + irc.connect(widget, + QtCore.SIGNAL('moodsRequest(PyQt_PyObject)'), + irc, + QtCore.SLOT('getMoods(PyQt_PyObject)')) + irc.connect(widget, + QtCore.SIGNAL('moodUpdated()'), + irc, + QtCore.SLOT('updateMood()')) + irc.connect(widget, + QtCore.SIGNAL('mycolorUpdated()'), + irc, + QtCore.SLOT('updateColor()')) + irc.connect(widget, + QtCore.SIGNAL('blockedChum(QString)'), + irc, + QtCore.SLOT('blockedChum(QString)')) + irc.connect(widget, + QtCore.SIGNAL('unblockedChum(QString)'), + irc, + QtCore.SLOT('unblockedChum(QString)')) + irc.connect(widget, + QtCore.SIGNAL('requestNames(QString)'), + irc, + QtCore.SLOT('requestNames(QString)')) + irc.connect(widget, + QtCore.SIGNAL('requestChannelList()'), + irc, + QtCore.SLOT('requestChannelList()')) + irc.connect(widget, + QtCore.SIGNAL('joinChannel(QString)'), + irc, + QtCore.SLOT('joinChannel(QString)')) + irc.connect(widget, + QtCore.SIGNAL('leftChannel(QString)'), + irc, + QtCore.SLOT('leftChannel(QString)')) + + +# IRC --> Main window + irc.connect(irc, QtCore.SIGNAL('connected()'), + widget, QtCore.SLOT('connected()')) + irc.connect(irc, + QtCore.SIGNAL('moodUpdated(QString, PyQt_PyObject)'), + widget, + QtCore.SLOT('updateMoodSlot(QString, PyQt_PyObject)')) + irc.connect(irc, + QtCore.SIGNAL('colorUpdated(QString, QColor)'), + widget, + QtCore.SLOT('updateColorSlot(QString, QColor)')) + irc.connect(irc, + QtCore.SIGNAL('messageReceived(QString, QString)'), + widget, + QtCore.SLOT('deliverMessage(QString, QString)')) + irc.connect(irc, + QtCore.SIGNAL('memoReceived(QString, QString, QString)'), + widget, + QtCore.SLOT('deliverMemo(QString, QString, QString)')) + irc.connect(irc, + QtCore.SIGNAL('nickCollision(QString, QString)'), + widget, + QtCore.SLOT('nickCollision(QString, QString)')) + irc.connect(irc, + QtCore.SIGNAL('namesReceived(QString, PyQt_PyObject)'), + widget, + QtCore.SLOT('updateNames(QString, PyQt_PyObject)')) + irc.connect(irc, + QtCore.SIGNAL('userPresentUpdate(QString, QString, QString)'), + widget, + QtCore.SLOT('userPresentUpdate(QString, QString, QString)')) + irc.connect(irc, + QtCore.SIGNAL('channelListReceived(PyQt_PyObject)'), + widget, + QtCore.SLOT('updateChannelList(PyQt_PyObject)')) + irc.connect(irc, + QtCore.SIGNAL('timeCommand(QString, QString, QString)'), + widget, + QtCore.SLOT('timeCommand(QString, QString, QString)')) + + ircapp = IRCThread(irc) + ircapp.start() + status = widget.loadingscreen.exec_() + if status == QtGui.QDialog.Rejected: + sys.exit(0) + sys.exit(app.exec_()) + +main() diff --git a/.#pesterchum.py b/.#pesterchum.py new file mode 120000 index 0000000..c318653 --- /dev/null +++ b/.#pesterchum.py @@ -0,0 +1 @@ +dranger@teradacho.14772:1292218088 \ No newline at end of file diff --git a/TODO b/TODO index c49187e..bce54a7 100644 --- a/TODO +++ b/TODO @@ -1,12 +1,18 @@ Features: -* What if someone switches nick in memo? * memo change theme +* 1 MINUTES FROM NOW +* memo kicking +* user import +* Transparent background? +* tab right-click menu on tabbed convos, chat window +* link to memos +* color text is not being translated to server? +* convo backgrounds -- make them more like http://www.mspaintadventures.com/storyfiles/hs2/02546_2.gif * PESTERLOG: in convo window * help button on quirks menu? * tab recombining gives wrong window icon * help menu -- about and forum * profile switch should say current profile -* Transparent background? * X closes to tray -- release alpha * User commands/stop user from sending commands accidentally @@ -14,7 +20,6 @@ Features: multiple clients share buddy list??? * System tray menu * new sound on CEASE and BEGIN? -* tab right-click menu on tabbed convos * comment history (up button) * page up/down scrolling * get rid of border on chat window? diff --git a/convo.py b/convo.py index 760e17f..c454e71 100644 --- a/convo.py +++ b/convo.py @@ -132,14 +132,14 @@ class PesterTabWindow(QtGui.QFrame): self.tabs.setStyleSheet("QTabBar::tab{ %s } QTabBar::tab:selected { %s }" % (convo["tabs"]["style"], convo["tabs"]["selectedstyle"])) def changeTheme(self, theme): - self.initTheme(theme["convo"]) + self.initTheme(theme["memos"]) for c in self.convos.values(): - tabi = self.tabIndices[c.chum.handle] - self.tabs.setTabIcon(tabi, c.chum.mood.icon(theme)) + tabi = self.tabIndices[c.title()] + self.tabs.setTabIcon(tabi, c.icon()) currenttabi = self.tabs.currentIndex() if currenttabi >= 0: currentHandle = unicode(self.tabs.tabText(self.tabs.currentIndex())) - self.setWindowIcon(self.convos[currentHandle].chum.mood.icon(theme)) + self.setWindowIcon(self.convos[currentHandle].icon()) self.defaultTabTextColor = self.getTabTextColor() @QtCore.pyqtSlot(int) diff --git a/dataobjs.py b/dataobjs.py index 37419d9..4ff8fec 100644 --- a/dataobjs.py +++ b/dataobjs.py @@ -132,7 +132,7 @@ class PesterProfile(object): uppersuffix = suffix.upper() if time is not None: handle = "%s %s" % (time.temporal, self.handle) - initials = time.pcf+self.initials()+uppersuffix + initials = time.pcf+self.initials()+time.number+uppersuffix else: handle = self.handle initials = self.initials()+uppersuffix diff --git a/dataobjs.pyc b/dataobjs.pyc index ae8de03..da4b76c 100644 Binary files a/dataobjs.pyc and b/dataobjs.pyc differ diff --git a/irc.py b/irc.py index 168c06c..6a54f53 100644 --- a/irc.py +++ b/irc.py @@ -169,7 +169,9 @@ class PesterHandler(DefaultCommandHandler): def nick(self, oldnick, newnick): oldhandle = oldnick[0:oldnick.find("!")] newchum = PesterProfile(newnick, chumdb=self.mainwindow.chumdb) - self.parent.moodUpdated.emit(oldhandle, Mood("offline")) + self.parent.moodUpdated.emit(oldhandle, Mood("offline")) + self.parent.userPresentUpdate.emit(oldhandle, "", "oldnick") + self.parent.userPresentUpdate.emit(newnick, "", "newnick") if newnick in self.mainwindow.chumList.chums: self.getMood(newchum) def namreply(self, server, nick, op, channel, names): diff --git a/irc.pyc b/irc.pyc index 76d19a6..bc6e9a6 100644 Binary files a/irc.pyc and b/irc.pyc differ diff --git a/logs/chums.js b/logs/chums.js index af455a4..5a50b36 100644 --- a/logs/chums.js +++ b/logs/chums.js @@ -1 +1 @@ -{"macruralAlchemist": {"color": "#700000", "handle": "macruralAlchemist", "mood": "offline"}, "fireSwallow": {"color": "#80bb9a", "handle": "fireSwallow", "mood": "offline"}, "aquaMarinist": {"color": "#00caca", "handle": "aquaMarinist", "mood": "offline"}, "nitroZealist": {"color": "#ff3737", "handle": "nitroZealist", "mood": "offline"}, "masterG": {"color": "#77003c", "handle": "masterG", "mood": "offline"}, "aquaticMarinist": {"color": "#00caca", "handle": "aquaticMarinist", "mood": "offline"}, "iw": {"color": "#ff0000", "handle": "iw", "mood": "offline"}, "pesterClient394": {"color": "#ff3737", "handle": "pesterClient394", "mood": "offline"}, "absoluteTranquility": {"color": "#000033", "handle": "absoluteTranquility", "mood": "offline"}, "centaursTesticle": {"color": "#000056", "handle": "centaursTesticle", "mood": "offline"}, "agogPorphyry": {"color": "#522d80", "handle": "agogPorphyry", "mood": "offline"}, "illuminatedWax": {"color": "#ffff00", "handle": "illuminatedWax", "mood": "offline"}, "gamblingGenocider": {"color": "#00ff00", "handle": "gamblingGenocider", "mood": "offline"}, "elegantDiversion": {"color": "#12b40d", "handle": "elegantDiversion", "mood": "offline"}, "testOut": {"color": "#c760cc", "handle": "testOut", "mood": "offline"}, "superGhost": {"color": "#800564", "handle": "superGhost", "mood": "offline"}, "tentacleTherapist": {"color": "#cc66ff", "handle": "tentacleTherapist", "mood": "offline"}, "captainCaveman": {"color": "#7c414e", "handle": "captainCaveman", "mood": "offline"}, "cuttlefishCuller": {"color": "#77003c", "handle": "cuttlefishCuller", "mood": "offline"}, "mechanicalSpectacle": {"color": "#0000ff", "handle": "mechanicalSpectacle", "mood": "offline"}, "remoteBloodbath": {"color": "#c70000", "handle": "remoteBloodbath", "mood": "offline"}, "rageInducer": {"color": "#00ffff", "handle": "rageInducer", "mood": "offline"}, "gallowsCalibrator": {"color": "#008282", "handle": "gallowsCalibrator", "mood": "offline"}, "greenZephyr": {"color": "#00ca40", "handle": "greenZephyr", "mood": "offline"}, "schlagzeugGator": {"color": "#61821f", "handle": "schlagzeugGator", "mood": "offline"}, "gardenGnostic": {"color": "#00ff00", "handle": "gardenGnostic", "mood": "offline"}, "unknownTraveler": {"color": "#006666", "handle": "unknownTraveler", "mood": "offline"}, "marineAquist": {"color": "#00caca", "handle": "marineAquist", "mood": "offline"}} \ No newline at end of file +{"macruralAlchemist": {"color": "#700000", "handle": "macruralAlchemist", "mood": "offline"}, "fireSwallow": {"color": "#80bb9a", "handle": "fireSwallow", "mood": "offline"}, "aquaMarinist": {"color": "#00caca", "handle": "aquaMarinist", "mood": "offline"}, "nitroZealist": {"color": "#ff3737", "handle": "nitroZealist", "mood": "offline"}, "mechanicalSpectacle": {"color": "#000000", "handle": "mechanicalSpectacle", "mood": "offline"}, "caffeinatedAnalyst": {"color": "#aa0000", "handle": "caffeinatedAnalyst", "mood": "offline"}, "iw": {"color": "#ff0000", "handle": "iw", "mood": "offline"}, "pesterClient394": {"color": "#ff3737", "handle": "pesterClient394", "mood": "offline"}, "absoluteTranquility": {"color": "#000033", "handle": "absoluteTranquility", "mood": "offline"}, "centaursTesticle": {"color": "#000056", "handle": "centaursTesticle", "mood": "offline"}, "agogPorphyry": {"color": "#522d80", "handle": "agogPorphyry", "mood": "offline"}, "radicalApologist": {"color": "#ffaa00", "handle": "radicalApologist", "mood": "offline"}, "arachnidsGrip": {"color": "#005682", "handle": "arachnidsGrip", "mood": "offline"}, "illuminatedWax": {"color": "#ffff00", "handle": "illuminatedWax", "mood": "offline"}, "gamblingGenocider": {"color": "#00ff00", "handle": "gamblingGenocider", "mood": "offline"}, "elegantDiversion": {"color": "#12b40d", "handle": "elegantDiversion", "mood": "offline"}, "madLurker": {"color": "#000000", "handle": "madLurker", "mood": "offline"}, "testOut": {"color": "#c760cc", "handle": "testOut", "mood": "offline"}, "DocScratch": {"color": "#ffffff", "handle": "DocScratch", "mood": "offline"}, "recalcitrantDisaster": {"color": "#8b0068", "handle": "recalcitrantDisaster", "mood": "offline"}, "superGhost": {"color": "#800564", "handle": "superGhost", "mood": "offline"}, "tentacleTherapist": {"color": "#cc66ff", "handle": "tentacleTherapist", "mood": "offline"}, "aquaticMarinist": {"color": "#00caca", "handle": "aquaticMarinist", "mood": "offline"}, "captainCaveman": {"color": "#7c414e", "handle": "captainCaveman", "mood": "offline"}, "cuttlefishCuller": {"color": "#77003c", "handle": "cuttlefishCuller", "mood": "offline"}, "masterG": {"color": "#77003c", "handle": "masterG", "mood": "offline"}, "plasmaModerator": {"color": "#5685cc", "handle": "plasmaModerator", "mood": "offline"}, "remoteBloodbath": {"color": "#c70000", "handle": "remoteBloodbath", "mood": "offline"}, "rageInducer": {"color": "#00ffff", "handle": "rageInducer", "mood": "offline"}, "gallowsCalibrator": {"color": "#008282", "handle": "gallowsCalibrator", "mood": "offline"}, "greenZephyr": {"color": "#00ca40", "handle": "greenZephyr", "mood": "offline"}, "lawdEngrish": {"color": "#00ff00", "handle": "lawdEngrish", "mood": "offline"}, "adiosToreador": {"color": "#aa5500", "handle": "adiosToreador", "mood": "offline"}, "schlagzeugGator": {"color": "#61821f", "handle": "schlagzeugGator", "mood": "offline"}, "metaliAggressive": {"color": "#9289d5", "handle": "metaliAggressive", "mood": "offline"}, "magmaExploiter": {"color": "#d90000", "handle": "magmaExploiter", "mood": "offline"}, "gardenGnostic": {"color": "#00ff00", "handle": "gardenGnostic", "mood": "offline"}, "unknownTraveler": {"color": "#006666", "handle": "unknownTraveler", "mood": "offline"}, "utilitarianTurnabout": {"color": "#dd0000", "handle": "utilitarianTurnabout", "mood": "offline"}, "marineAquist": {"color": "#00caca", "handle": "marineAquist", "mood": "offline"}} \ No newline at end of file diff --git a/memos.py b/memos.py index a9062b9..f154149 100644 --- a/memos.py +++ b/memos.py @@ -196,6 +196,7 @@ class MemoTabWindow(PesterTabWindow): def updateMood(self): pass + _ctag_begin = re.compile(r'') class MemoText(PesterText): @@ -257,8 +258,9 @@ class MemoText(PesterText): window.chatlog.log(parent.channel, convertTags(msg, "bbcode")) - def changeTheme(self): - pass + def changeTheme(self, theme): + self.setStyleSheet(theme["memos/textarea/style"]) + class MemoInput(PesterInput): def __init__(self, theme, parent=None): @@ -348,6 +350,7 @@ class PesterMemo(PesterConvo): systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"]) self.textArea.append(convertTags(p.memoopenmsg(systemColor, self.time.getTime(), timeGrammar, self.mainwindow.theme["convo/text/openmemo"], self.channel))) + self.op = False self.newmessage = False def title(self): @@ -428,6 +431,8 @@ class PesterMemo(PesterConvo): if handle[0] == '@': op = True handle = handle[1:] + if handle == self.mainwindow.profile().handle: + self.op = True item = QtGui.QListWidgetItem(handle) if handle == self.mainwindow.profile().handle: color = self.mainwindow.profile().color @@ -512,17 +517,19 @@ class PesterMemo(PesterConvo): @QtCore.pyqtSlot(QtCore.QString, QtCore.QString, QtCore.QString) def userPresentChange(self, handle, channel, update): - if channel != self.channel: + if (update in ["join","left"]) and channel != self.channel: return chums = self.userlist.findItems(handle, QtCore.Qt.MatchFlags(0)) h = unicode(handle) c = unicode(channel) systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"]) # print exit - if update == "quit" or update == "left": + if update == "quit" or update == "left" or update == "oldnick": for c in chums: chum = PesterProfile(h) self.userlist.takeItem(self.userlist.row(c)) + if not self.times.has_key(h): + return while self.times[h].getTime() is not None: t = self.times[h] grammar = t.getGrammar() @@ -533,6 +540,8 @@ class PesterMemo(PesterConvo): time = self.time.getTime() serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server") self.messageSent.emit(serverText, self.title()) + elif update == "newnick": + self.addUser(h) def resetSlider(self, time): self.timeinput.setText(delta2txt(time)) diff --git a/memos.pyc b/memos.pyc index 9e525be..b04b9dc 100644 Binary files a/memos.pyc and b/memos.pyc differ diff --git a/pesterchum.py b/pesterchum.py index eebf8a4..402f8d8 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -1033,7 +1033,7 @@ class PesterWindow(MovingWindow): def userPresentUpdate(self, handle, channel, update): c = unicode(channel) n = unicode(handle) - if update == "quit": + if update == "quit" or update == "oldnick": for c in self.namesdb.keys(): try: i = self.namesdb[c].index(n) @@ -1050,6 +1050,14 @@ class PesterWindow(MovingWindow): pass except KeyError: self.namesdb[c] = [] + elif update == "newnick": + for c in self.namesdb.keys(): + try: + i = self.namesdb[c].index(n) + except ValueError: + self.namesdb[c].append(n) + except KeyError: + self.namesdb[c] = [n] elif update == "join": try: i = self.namesdb[c].index(n) diff --git a/profiles/ghostDunk.js b/profiles/ghostDunk.js index 338c689..43ce8df 100644 --- a/profiles/ghostDunk.js +++ b/profiles/ghostDunk.js @@ -1 +1 @@ -{"color": "#ff00ff", "theme": "pesterchum", "quirks": [], "handle": "ghostDunk"} \ No newline at end of file +{"color": "#ff00ff", "theme": "trollian", "quirks": [], "handle": "ghostDunk"} \ No newline at end of file diff --git a/themes/pesterchum/convobg.png b/themes/pesterchum/convobg.png new file mode 100644 index 0000000..7907669 Binary files /dev/null and b/themes/pesterchum/convobg.png differ diff --git a/themes/pesterchum/memo.png b/themes/pesterchum/memo.png index f4eaa2e..92fd30a 100644 Binary files a/themes/pesterchum/memo.png and b/themes/pesterchum/memo.png differ diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index c78287d..2bcb8ab 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -183,20 +183,20 @@ ] }, "convo": - {"style": "background: #fdb302; border:2px solid yellow; font-family: 'Courier'", - "margins": {"top": 0, "bottom": 0, "left": 0, "right": 0 }, - "size": [295, 191], - "chumlabel": { "style": "background: rgb(196, 138, 0); color: white; border:0px;", + {"style": "background-color: #fdb302; background-image:url($path/convobg.png); background-repeat: no-repeat; border:2px solid yellow; font-family: 'Courier'", + "margins": {"top": 0, "bottom": 6, "left": 0, "right": 0 }, + "size": [400, 250], + "chumlabel": { "style": "background: rgb(196, 138, 0); color: white; border:0px; font-size: 12px;", "align": { "h": "center", "v": "center" }, - "minheight": 30, - "maxheight": 50, + "minheight": 26, + "maxheight": 26, "text" : ":: $handle ::" }, "textarea": { - "style": "background: white; font:bold; border:2px solid #c48a00;text-align:center;" + "style": "background: white; font:bold; border:2px solid #c48a00;text-align:center; margin-top:21px; margin-right:10px; margin-left:10px; font-size: 12px;" }, "input": { - "style": "background: white; border:2px solid #c48a00;margin-top:5px;" + "style": "background: white; border:2px solid #c48a00;margin-top:3px; margin-right:10px; margin-left:10px; font-size: 12px;" }, "tabs": { "style": "", diff --git a/themes/pesterchum7/gbg.png b/themes/pesterchum7/gbg.png new file mode 100644 index 0000000..6e5b6a4 Binary files /dev/null and b/themes/pesterchum7/gbg.png differ diff --git a/themes/trollian/blocked.png b/themes/trollian/blocked.png index 7acb9f2..ba92a9d 100644 Binary files a/themes/trollian/blocked.png and b/themes/trollian/blocked.png differ diff --git a/themes/trollian/memo.png b/themes/trollian/memo.png index c5edf5f..30b9631 100644 Binary files a/themes/trollian/memo.png and b/themes/trollian/memo.png differ diff --git a/themes/trollian/style.js b/themes/trollian/style.js index a0f9b24..6ba418e 100644 --- a/themes/trollian/style.js +++ b/themes/trollian/style.js @@ -1,5 +1,5 @@ {"main": - {"style": "background-image:url($path/tnbg.png);background-color:rgba(255,255,255,0);", + {"style": "background-image:url($path/tnbg2.png);background-color:rgba(255,255,255,0);", "size": [650, 450], "icon": "$path/trayicon.png", "newmsgicon": "$path/trayicon2.png", @@ -276,18 +276,18 @@ "label": { "text": "$channel", "style": "background: rgb(255, 38, 18); color: white; padding: 2px; border:1px solid #c2c2c2;", "align": { "h": "center", "v": "center" }, - "minheight": 30, - "maxheight": 50 + "minheight": 18, + "maxheight": 18 }, "textarea": { "style": "background: white; border:2px solid #c2c2c2; font-size: 12px; margin-top: 4px;" }, "input": { - "style": "background: white;margin-top:5px; border:1px solid #c2c2c2; margin-right: 54px; font-size: 12px;" + "style": "background: white;margin-top:5px; border:1px solid #c2c2c2; font-size: 12px;" }, - "margins": {"top": 0, "bottom": 0, "left": 0, "right": 0 }, - "userlist": { "width": 150, - "style": "font-size: 12px; background: white; border:2px solid #c2c2c2; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200);" + "margins": {"top": 22, "bottom": 10, "left": 9, "right": 4 }, + "userlist": { "width": 100, + "style": "font-size: 12px; background: white; margin-top: 4px; margin-left: 5px; border:2px solid #c2c2c2; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200);" }, "time": { "text": { "width": 75, "style": "color:white;font:bold" diff --git a/themes/trollian/tnbg2.png b/themes/trollian/tnbg2.png index 4ea9d2a..e546baa 100644 Binary files a/themes/trollian/tnbg2.png and b/themes/trollian/tnbg2.png differ diff --git a/tmp/new pc themes.zip b/tmp/new pc themes.zip new file mode 100644 index 0000000..8f5b70d Binary files /dev/null and b/tmp/new pc themes.zip differ diff --git a/tmp/pesterchum/abouticon.png b/tmp/pesterchum/abouticon.png new file mode 100644 index 0000000..02fa887 Binary files /dev/null and b/tmp/pesterchum/abouticon.png differ diff --git a/tmp/pesterchum/acceptant.gif b/tmp/pesterchum/acceptant.gif new file mode 100644 index 0000000..f549f70 Binary files /dev/null and b/tmp/pesterchum/acceptant.gif differ diff --git a/tmp/pesterchum/alarm.wav b/tmp/pesterchum/alarm.wav new file mode 100644 index 0000000..910abdc Binary files /dev/null and b/tmp/pesterchum/alarm.wav differ diff --git a/tmp/pesterchum/amazed.gif b/tmp/pesterchum/amazed.gif new file mode 100644 index 0000000..9c2f1e6 Binary files /dev/null and b/tmp/pesterchum/amazed.gif differ diff --git a/tmp/pesterchum/bemused.gif b/tmp/pesterchum/bemused.gif new file mode 100644 index 0000000..15a9813 Binary files /dev/null and b/tmp/pesterchum/bemused.gif differ diff --git a/tmp/pesterchum/blocked.gif b/tmp/pesterchum/blocked.gif new file mode 100644 index 0000000..5031b07 Binary files /dev/null and b/tmp/pesterchum/blocked.gif differ diff --git a/tmp/pesterchum/chummy.gif b/tmp/pesterchum/chummy.gif new file mode 100644 index 0000000..26c9ad3 Binary files /dev/null and b/tmp/pesterchum/chummy.gif differ diff --git a/tmp/pesterchum/convobg.png b/tmp/pesterchum/convobg.png new file mode 100644 index 0000000..7907669 Binary files /dev/null and b/tmp/pesterchum/convobg.png differ diff --git a/tmp/pesterchum/detestful.gif b/tmp/pesterchum/detestful.gif new file mode 100644 index 0000000..c050d31 Binary files /dev/null and b/tmp/pesterchum/detestful.gif differ diff --git a/tmp/pesterchum/devious.gif b/tmp/pesterchum/devious.gif new file mode 100644 index 0000000..06ba8be Binary files /dev/null and b/tmp/pesterchum/devious.gif differ diff --git a/tmp/pesterchum/discontent.gif b/tmp/pesterchum/discontent.gif new file mode 100644 index 0000000..addcf54 Binary files /dev/null and b/tmp/pesterchum/discontent.gif differ diff --git a/tmp/pesterchum/distraught.gif b/tmp/pesterchum/distraught.gif new file mode 100644 index 0000000..0103ac5 Binary files /dev/null and b/tmp/pesterchum/distraught.gif differ diff --git a/tmp/pesterchum/ecstatic.gif b/tmp/pesterchum/ecstatic.gif new file mode 100644 index 0000000..dc3ee61 Binary files /dev/null and b/tmp/pesterchum/ecstatic.gif differ diff --git a/tmp/pesterchum/h.gif b/tmp/pesterchum/h.gif new file mode 100644 index 0000000..184514e Binary files /dev/null and b/tmp/pesterchum/h.gif differ diff --git a/tmp/pesterchum/insolent.gif b/tmp/pesterchum/insolent.gif new file mode 100644 index 0000000..d642481 Binary files /dev/null and b/tmp/pesterchum/insolent.gif differ diff --git a/tmp/pesterchum/leftarrow.png b/tmp/pesterchum/leftarrow.png new file mode 100644 index 0000000..4caf00b Binary files /dev/null and b/tmp/pesterchum/leftarrow.png differ diff --git a/tmp/pesterchum/m.gif b/tmp/pesterchum/m.gif new file mode 100644 index 0000000..3f6c396 Binary files /dev/null and b/tmp/pesterchum/m.gif differ diff --git a/tmp/pesterchum/manipulative.gif b/tmp/pesterchum/manipulative.gif new file mode 100644 index 0000000..642d988 Binary files /dev/null and b/tmp/pesterchum/manipulative.gif differ diff --git a/tmp/pesterchum/memo.png b/tmp/pesterchum/memo.png new file mode 100644 index 0000000..92fd30a Binary files /dev/null and b/tmp/pesterchum/memo.png differ diff --git a/tmp/pesterchum/mirthful.gif b/tmp/pesterchum/mirthful.gif new file mode 100644 index 0000000..cbf895c Binary files /dev/null and b/tmp/pesterchum/mirthful.gif differ diff --git a/tmp/pesterchum/moodcheck1.gif b/tmp/pesterchum/moodcheck1.gif new file mode 100644 index 0000000..0804f90 Binary files /dev/null and b/tmp/pesterchum/moodcheck1.gif differ diff --git a/tmp/pesterchum/moodcheck2.gif b/tmp/pesterchum/moodcheck2.gif new file mode 100644 index 0000000..d646f21 Binary files /dev/null and b/tmp/pesterchum/moodcheck2.gif differ diff --git a/tmp/pesterchum/moodcheck3.gif b/tmp/pesterchum/moodcheck3.gif new file mode 100644 index 0000000..f88321b Binary files /dev/null and b/tmp/pesterchum/moodcheck3.gif differ diff --git a/tmp/pesterchum/moodcheck4.gif b/tmp/pesterchum/moodcheck4.gif new file mode 100644 index 0000000..4cea74f Binary files /dev/null and b/tmp/pesterchum/moodcheck4.gif differ diff --git a/tmp/pesterchum/moodcheck5.gif b/tmp/pesterchum/moodcheck5.gif new file mode 100644 index 0000000..40ba9a1 Binary files /dev/null and b/tmp/pesterchum/moodcheck5.gif differ diff --git a/tmp/pesterchum/mystified.gif b/tmp/pesterchum/mystified.gif new file mode 100644 index 0000000..56341d6 Binary files /dev/null and b/tmp/pesterchum/mystified.gif differ diff --git a/tmp/pesterchum/offline.gif b/tmp/pesterchum/offline.gif new file mode 100644 index 0000000..e3c6b53 Binary files /dev/null and b/tmp/pesterchum/offline.gif differ diff --git a/tmp/pesterchum/pcbg.png b/tmp/pesterchum/pcbg.png new file mode 100644 index 0000000..688eab7 Binary files /dev/null and b/tmp/pesterchum/pcbg.png differ diff --git a/tmp/pesterchum/perky.gif b/tmp/pesterchum/perky.gif new file mode 100644 index 0000000..1d19661 Binary files /dev/null and b/tmp/pesterchum/perky.gif differ diff --git a/tmp/pesterchum/pleasant.gif b/tmp/pesterchum/pleasant.gif new file mode 100644 index 0000000..3233ff4 Binary files /dev/null and b/tmp/pesterchum/pleasant.gif differ diff --git a/tmp/pesterchum/pranky.gif b/tmp/pesterchum/pranky.gif new file mode 100644 index 0000000..e46e45e Binary files /dev/null and b/tmp/pesterchum/pranky.gif differ diff --git a/tmp/pesterchum/rancorous.gif b/tmp/pesterchum/rancorous.gif new file mode 100644 index 0000000..a826c75 Binary files /dev/null and b/tmp/pesterchum/rancorous.gif differ diff --git a/tmp/pesterchum/relaxed.gif b/tmp/pesterchum/relaxed.gif new file mode 100644 index 0000000..55a31a0 Binary files /dev/null and b/tmp/pesterchum/relaxed.gif differ diff --git a/tmp/pesterchum/rightarrow.png b/tmp/pesterchum/rightarrow.png new file mode 100644 index 0000000..30a8b70 Binary files /dev/null and b/tmp/pesterchum/rightarrow.png differ diff --git a/tmp/pesterchum/sleek.gif b/tmp/pesterchum/sleek.gif new file mode 100644 index 0000000..5573aa5 Binary files /dev/null and b/tmp/pesterchum/sleek.gif differ diff --git a/tmp/pesterchum/smooth.gif b/tmp/pesterchum/smooth.gif new file mode 100644 index 0000000..a261759 Binary files /dev/null and b/tmp/pesterchum/smooth.gif differ diff --git a/tmp/pesterchum/style.js b/tmp/pesterchum/style.js new file mode 100644 index 0000000..7a097e3 --- /dev/null +++ b/tmp/pesterchum/style.js @@ -0,0 +1,255 @@ +{"main": + {"style": "background-image:url($path/pcbg.png); background-repeat: no-repeat;", + "size": [232, 380], + "icon": "$path/trayicon.png", + "newmsgicon": "$path/trayicon2.png", + "windowtitle": "PESTERCHUM", + "close": { "image": "$path/x.gif", + "loc": [210, 2]}, + "minimize": { "image": "$path/m.gif", + "loc": [194, 8]}, + "menubar": { "style": "font-family: 'Courier'; font:bold; font-size: 12px;" }, + "menu" : { "style": "font-family: 'Courier'; font: bold; font-size: 12px; background-color: #fdb302;border:2px solid #ffff00", + "menuitem": "margin-right:10px;", + "selected": "background-color: #ffff00", + "loc": [10,0] + }, + "sounds": { "alertsound": "$path/alarm.wav" }, + "menus": {"client": {"_name": "CLIENT", + "options": "OPTIONS", + "memos": "MEMOS", + "userlist": "USERLIST", + "exit": "EXIT"}, + "profile": {"_name": "PROFILE", + "switch": "SWITCH", + "color": "COLOR", + "theme": "THEME", + "block": "TROLLSLUM", + "quirks": "QUIRKS"}, + "rclickchumlist": {"pester": "PESTER", + "removechum": "REMOVE CHUM", + "blockchum": "BLOCK", + "addchum": "ADD CHUM", + "unblockchum": "UNBLOCK" + } + }, + "chums": { "style": "border:2px solid yellow; background-color: black;color: white;font: bold;font-family: 'Courier';selection-background-color:#646464; ", + "loc": [12, 117], + "size": [209, 82], + "userlistcolor": "white", + "moods": { + +"chummy": { "icon": "$path/chummy.gif", "color": "white" }, + +"rancorous": { "icon": "$path/rancorous.gif", "color": "red" }, + +"offline": { "icon": "$path/offline.gif", "color": "#646464"}, + + +"pleasant": { "icon": "$path/pleasant.gif", "color": "white" }, + +"distraught": { "icon": "$path/distraught.gif", "color": "white" }, + +"unruly": { "icon": "$path/unruly.gif", "color": "white" }, + + +"smooth": { "icon": "$path/smooth.gif", "color": "white" }, + + +"ecstatic": { "icon": "$path/ecstatic.gif", "color": "red" }, + +"relaxed": { "icon": "$path/relaxed.gif", "color": "red" }, + +"discontent": { "icon": "$path/discontent.gif", "color": "red" }, + +"devious": { "icon": "$path/devious.gif", "color": "red" }, + +"sleek": { "icon": "$path/sleek.gif", "color": "red" }, + +"detestful": { "icon": "$path/detestful.gif", "color": "red" }, + +"mirthful": { "icon": "$path/mirthful.gif", "color": "red" }, + +"manipulative": { "icon": "$path/manipulative.gif", "color": "red" }, + +"vigorous": { "icon": "$path/vigorous.gif", "color": "red" }, + +"perky": { "icon": "$path/perky.gif", "color": "red" }, + +"acceptant": { "icon": "$path/acceptant.gif", "color": "red" }, + +"protective": { "icon": "$path/protective.gif", "color": "#00ff00" }, + +"blocked": { "icon": "$path/blocked.gif", "color": "black" } + + } + }, + "trollslum": { + "style": "background: #fdb302; border:2px solid yellow; font-family: 'Courier'", + "size": [195, 200], + "label": { "text": "TROLLSLUM", + "style": "color: rgba(0, 0, 0, 100%) ;font:bold; font-family: 'Courier';border:0px;" }, + "chumroll": {"style": "border:2px solid yellow; background-color: black;color: white;font: bold;font-family: 'Courier';selection-background-color:#646464; " } + }, + "mychumhandle": { "label": { "text": "CHUMHANDLE:", + "loc": [19,232], + "style": "color: rgba(255, 255, 0, 0%) ;font:bold; font-family: 'Courier';" }, + "handle": { "style": "background: black; padding: 3px; color:white; font-family:'Courier'; font:bold; text-align:left;", + "loc": [14,246], + "size": [190, 21] }, + "colorswatch": { "loc": [196,246], + "size": [23,21], + "text": "" } + }, + "defaultwindow": { "style": "background: #fdb302; font-family:'Courier';font:bold;selection-background-color:#919191; " + }, + "addchum": { "style": "background: rgba(255, 255, 0, 0%); border:2px solid #c48a00; font: bold; color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [12,202], + "size": [71, 22], + "text": "" + }, + "pester": { "style": "background: rgba(255, 255, 0, 0%); border:2px solid #c48a00; font: bold; color: rgba(255, 255, 0, 0%); font-family:'Courier';", + "loc": [150,202], + "size": [71, 22], + "text": "" + }, + "block": { "style": "background: rgba(255, 255, 0, 0%); border:2px solid #c48a00; font: bold; color: rgba(255, 255, 0, 0%); font-family:'Courier';", + "loc": [1500,202], + "size": [0, 0], + "text": "" + }, + "defaultmood": 0, + "moodlabel": { "style": "", + "loc": [20, 430], + "text": "MOODS" + }, + "moods": [ + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck1.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [12, 288], + "size": [104, 22], + "text": "CHUMMY", + "icon": "$path/chummy.gif", + "mood": 0 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck2.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [12, 308], + "size": [104, 22], + "text": "PALSY", + "icon": "$path/chummy.gif", + "mood": 3 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck3.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [12, 328], + "size": [104, 22], + "text": "CHIPPER", + "icon": "$path/chummy.gif", + "mood": 4 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck2.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [117, 288], + "size": [104, 22], + "text": "BULLY", + "icon": "$path/chummy.gif", + "mood": 5 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck2.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [117, 308], + "size": [104, 22], + "text": "PEPPY", + "icon": "$path/chummy.gif", + "mood": 6 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck4.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [117, 328], + "size": [104, 22], + "text": "RANCOROUS", + "icon": "$path/rancorous.gif", + "mood": 1 + }, + { "style": "text-align:left; border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier'", + "selected": "text-align:left; background-image:url($path/moodcheck5.gif); border:2px solid #c48a00; padding: 5px;color: rgba(0, 0, 0, 0%); font-family:'Courier';", + "loc": [12, 348], + "size": [209, 22], + "text": "ABSCOND", + "icon": "", + "mood": 2 + } + ] + }, + "convo": + {"style": "background-color: #fdb302; background-image:url($path/convobg.png); background-repeat: no-repeat; border:2px solid yellow; font-family: 'Courier'", + "margins": {"top": 0, "bottom": 6, "left": 0, "right": 0 }, + "size": [400, 250], + "chumlabel": { "style": "background: rgb(196, 138, 0); color: white; border:0px; font-size: 12px;", + "align": { "h": "center", "v": "center" }, + "minheight": 26, + "maxheight": 26, + "text" : ":: $handle ::" + }, + "textarea": { + "style": "background: white; font:bold; border:2px solid #c48a00;text-align:center; margin-top:21px; margin-right:10px; margin-left:10px; font-size: 12px;" + }, + "input": { + "style": "background: white; border:2px solid #c48a00;margin-top:3px; margin-right:10px; margin-left:10px; font-size: 12px;" + }, + "tabs": { + "style": "", + "selectedstyle": "", + "newmsgcolor": "#fdb302", + "tabstyle": 0 + }, + "text": { + "beganpester": "began pestering", + "ceasepester": "ceased pestering", + "blocked": "blocked", + "unblocked": "unblocked", + "openmemo": "opened memo on board", + "joinmemo": "responded to memo", + "closememo": "ceased responding to memo" + }, + "systemMsgColor": "#646464" + }, + "memos": + {"memoicon": "$path/memo.png", + "style": "background-color: #fdb302; background-image:url($path/convobg.png); background-repeat: no-repeat; border:2px solid yellow; font-family: 'Courier'; font: bold; selection-background-color:#919191; ", + "size": [450,300], + "tabs": { + "style": "", + "selectedstyle": "", + "newmsgcolor": "#fdb302", + "tabstyle": 0 + }, + "label": { "text": "Bulletin Board: $channel", + "style": "background: rgb(196, 138, 0); color: white; border:0px; font-size: 12px;", + "align": { "h": "center", "v": "center" }, + "minheight": 26, + "maxheight": 26 + }, + "input": { "style": "background: white; border:2px solid #c48a00;margin-top:5px; font-size: 12px; margin-left:10px;" }, + "textarea": { "style": "background: white; font:bold; border:2px solid #c48a00;text-align:center; font-size: 12px; margin-top: 21px; margin-left:10px;" }, + "margins": {"top": 0, "bottom": 6, "left": 0, "right": 0 }, + "userlist": { "width": 150, + "style": "border:2px solid #c48a00; background: white;font: bold;font-family: 'Courier';selection-background-color:#646464; font-size: 12px; margin-left:10px; margin-right:10px; margin-top: 21px;" + }, + "time": { "text": { "width": 75, + "style": " border: 2px solid yellow; background: white; font-size: 12px; margin-top: 5px; margin-right: 5px; margin-left: 5px;" + }, + "slider": { "style": "border: 0px;", + "groove": "", + "handle": "" + }, + "buttons": { "style": "color: black; font: bold; border: 2px solid #c48a00; font: bold; font-size: 12px; background: yellow; margin-top: 5px; margin-right: 5px; margin-left: 5px; padding: 2px; width: 50px;" }, + "arrows": { "left": "$path/leftarrow.png", + "right": "$path/rightarrow.png", + "style": " border:0px; margin-top: 5px; margin-right:10px;" + } + }, + "systemMsgColor": "#646464" + } +} \ No newline at end of file diff --git a/tmp/pesterchum/trayicon.gif b/tmp/pesterchum/trayicon.gif new file mode 100644 index 0000000..926ccc7 Binary files /dev/null and b/tmp/pesterchum/trayicon.gif differ diff --git a/tmp/pesterchum/trayicon.png b/tmp/pesterchum/trayicon.png new file mode 100644 index 0000000..817bf4b Binary files /dev/null and b/tmp/pesterchum/trayicon.png differ diff --git a/tmp/pesterchum/trayicon2.png b/tmp/pesterchum/trayicon2.png new file mode 100644 index 0000000..7b78586 Binary files /dev/null and b/tmp/pesterchum/trayicon2.png differ diff --git a/tmp/pesterchum/vigorous.gif b/tmp/pesterchum/vigorous.gif new file mode 100644 index 0000000..2408814 Binary files /dev/null and b/tmp/pesterchum/vigorous.gif differ diff --git a/tmp/pesterchum/x.gif b/tmp/pesterchum/x.gif new file mode 100644 index 0000000..6f29624 Binary files /dev/null and b/tmp/pesterchum/x.gif differ diff --git a/tmp/trollian/abouticon.png b/tmp/trollian/abouticon.png new file mode 100644 index 0000000..e3feb2c Binary files /dev/null and b/tmp/trollian/abouticon.png differ diff --git a/tmp/trollian/acceptant.png b/tmp/trollian/acceptant.png new file mode 100644 index 0000000..fdc482b Binary files /dev/null and b/tmp/trollian/acceptant.png differ diff --git a/tmp/trollian/alarm.wav b/tmp/trollian/alarm.wav new file mode 100644 index 0000000..910abdc Binary files /dev/null and b/tmp/trollian/alarm.wav differ diff --git a/tmp/trollian/alarm2.wav b/tmp/trollian/alarm2.wav new file mode 100644 index 0000000..5ae54fa Binary files /dev/null and b/tmp/trollian/alarm2.wav differ diff --git a/tmp/trollian/aquaicon.png b/tmp/trollian/aquaicon.png new file mode 100644 index 0000000..77c0357 Binary files /dev/null and b/tmp/trollian/aquaicon.png differ diff --git a/tmp/trollian/blocked.png b/tmp/trollian/blocked.png new file mode 100644 index 0000000..ba92a9d Binary files /dev/null and b/tmp/trollian/blocked.png differ diff --git a/tmp/trollian/canonchums.txt b/tmp/trollian/canonchums.txt new file mode 100644 index 0000000..38b497c --- /dev/null +++ b/tmp/trollian/canonchums.txt @@ -0,0 +1 @@ +["ectoBiologist", "tentacleTherapist", "turntechGodhead", "gardenGnostic", "carcinoGeneticist", "terminallyCapricious", "cuttlefishCuller", "apocalypseArisen", "arachnidsGrip", "gallowsCalibrator", "arsenicCatnip", "adiosToreador", "caligulasAquarium", "centaursTesticle", "grimAuxiliatrix", "twinArmageddons"] \ No newline at end of file diff --git a/tmp/trollian/chumlabelbg.png b/tmp/trollian/chumlabelbg.png new file mode 100644 index 0000000..1d12780 Binary files /dev/null and b/tmp/trollian/chumlabelbg.png differ diff --git a/tmp/trollian/chummy.png b/tmp/trollian/chummy.png new file mode 100644 index 0000000..2903e50 Binary files /dev/null and b/tmp/trollian/chummy.png differ diff --git a/tmp/trollian/close.png b/tmp/trollian/close.png new file mode 100644 index 0000000..f8974d0 Binary files /dev/null and b/tmp/trollian/close.png differ diff --git a/tmp/trollian/detestful.png b/tmp/trollian/detestful.png new file mode 100644 index 0000000..9681d6e Binary files /dev/null and b/tmp/trollian/detestful.png differ diff --git a/tmp/trollian/devious.png b/tmp/trollian/devious.png new file mode 100644 index 0000000..a8f7ad9 Binary files /dev/null and b/tmp/trollian/devious.png differ diff --git a/tmp/trollian/discontent.png b/tmp/trollian/discontent.png new file mode 100644 index 0000000..e4c9792 Binary files /dev/null and b/tmp/trollian/discontent.png differ diff --git a/tmp/trollian/distraught.png b/tmp/trollian/distraught.png new file mode 100644 index 0000000..458ea85 Binary files /dev/null and b/tmp/trollian/distraught.png differ diff --git a/tmp/trollian/ecstatic.png b/tmp/trollian/ecstatic.png new file mode 100644 index 0000000..4996fd7 Binary files /dev/null and b/tmp/trollian/ecstatic.png differ diff --git a/tmp/trollian/go.png b/tmp/trollian/go.png new file mode 100644 index 0000000..603ae88 Binary files /dev/null and b/tmp/trollian/go.png differ diff --git a/tmp/trollian/h.gif b/tmp/trollian/h.gif new file mode 100644 index 0000000..b62246b Binary files /dev/null and b/tmp/trollian/h.gif differ diff --git a/tmp/trollian/leftarrow.png b/tmp/trollian/leftarrow.png new file mode 100644 index 0000000..3a2103d Binary files /dev/null and b/tmp/trollian/leftarrow.png differ diff --git a/tmp/trollian/m.gif b/tmp/trollian/m.gif new file mode 100644 index 0000000..b40729b Binary files /dev/null and b/tmp/trollian/m.gif differ diff --git a/tmp/trollian/manipulative.png b/tmp/trollian/manipulative.png new file mode 100644 index 0000000..9fc9118 Binary files /dev/null and b/tmp/trollian/manipulative.png differ diff --git a/tmp/trollian/memo.png b/tmp/trollian/memo.png new file mode 100644 index 0000000..30b9631 Binary files /dev/null and b/tmp/trollian/memo.png differ diff --git a/tmp/trollian/mirthful.png b/tmp/trollian/mirthful.png new file mode 100644 index 0000000..ee731a4 Binary files /dev/null and b/tmp/trollian/mirthful.png differ diff --git a/tmp/trollian/moodcheck1.png b/tmp/trollian/moodcheck1.png new file mode 100644 index 0000000..121b5d9 Binary files /dev/null and b/tmp/trollian/moodcheck1.png differ diff --git a/tmp/trollian/moodcheck10.png b/tmp/trollian/moodcheck10.png new file mode 100644 index 0000000..381b192 Binary files /dev/null and b/tmp/trollian/moodcheck10.png differ diff --git a/tmp/trollian/moodcheck11.png b/tmp/trollian/moodcheck11.png new file mode 100644 index 0000000..acf46b9 Binary files /dev/null and b/tmp/trollian/moodcheck11.png differ diff --git a/tmp/trollian/moodcheck12.png b/tmp/trollian/moodcheck12.png new file mode 100644 index 0000000..8b19362 Binary files /dev/null and b/tmp/trollian/moodcheck12.png differ diff --git a/tmp/trollian/moodcheck2.png b/tmp/trollian/moodcheck2.png new file mode 100644 index 0000000..eba1b5e Binary files /dev/null and b/tmp/trollian/moodcheck2.png differ diff --git a/tmp/trollian/moodcheck3.png b/tmp/trollian/moodcheck3.png new file mode 100644 index 0000000..a9fec2e Binary files /dev/null and b/tmp/trollian/moodcheck3.png differ diff --git a/tmp/trollian/moodcheck4.png b/tmp/trollian/moodcheck4.png new file mode 100644 index 0000000..02acef5 Binary files /dev/null and b/tmp/trollian/moodcheck4.png differ diff --git a/tmp/trollian/moodcheck5.png b/tmp/trollian/moodcheck5.png new file mode 100644 index 0000000..d5855bc Binary files /dev/null and b/tmp/trollian/moodcheck5.png differ diff --git a/tmp/trollian/moodcheck6.png b/tmp/trollian/moodcheck6.png new file mode 100644 index 0000000..eacc11f Binary files /dev/null and b/tmp/trollian/moodcheck6.png differ diff --git a/tmp/trollian/moodcheck7.png b/tmp/trollian/moodcheck7.png new file mode 100644 index 0000000..53275b8 Binary files /dev/null and b/tmp/trollian/moodcheck7.png differ diff --git a/tmp/trollian/moodcheck8.png b/tmp/trollian/moodcheck8.png new file mode 100644 index 0000000..b014b2a Binary files /dev/null and b/tmp/trollian/moodcheck8.png differ diff --git a/tmp/trollian/moodcheck9.png b/tmp/trollian/moodcheck9.png new file mode 100644 index 0000000..97cab63 Binary files /dev/null and b/tmp/trollian/moodcheck9.png differ diff --git a/tmp/trollian/moodicon.psd b/tmp/trollian/moodicon.psd new file mode 100644 index 0000000..f79e0aa Binary files /dev/null and b/tmp/trollian/moodicon.psd differ diff --git a/tmp/trollian/moods.txt b/tmp/trollian/moods.txt new file mode 100644 index 0000000..1c87873 --- /dev/null +++ b/tmp/trollian/moods.txt @@ -0,0 +1,35 @@ +chummy jade 0 + +pleasant rose 3 + +pranky john 5 + +smooth dave 6 + +rancorous karkat 1 + +ecstatic feferi 7 + +relaxed kanaya 8 + +discontent tavros 9 + +devious terezi 10 + +sleek sollux 11 + +detestful eridan 12 + +mirthful gamzee 13 + +manipulative vriska 14 + +vigorous equius 15 + +perky nepeta 16 + +acceptant aradia 17 + +protective doc scratch 18 + +offline 2 \ No newline at end of file diff --git a/tmp/trollian/offline.png b/tmp/trollian/offline.png new file mode 100644 index 0000000..aaa4b92 Binary files /dev/null and b/tmp/trollian/offline.png differ diff --git a/tmp/trollian/perky.png b/tmp/trollian/perky.png new file mode 100644 index 0000000..252377d Binary files /dev/null and b/tmp/trollian/perky.png differ diff --git a/tmp/trollian/pleasant.png b/tmp/trollian/pleasant.png new file mode 100644 index 0000000..8512ca0 Binary files /dev/null and b/tmp/trollian/pleasant.png differ diff --git a/tmp/trollian/pranky.png b/tmp/trollian/pranky.png new file mode 100644 index 0000000..4b5284b Binary files /dev/null and b/tmp/trollian/pranky.png differ diff --git a/tmp/trollian/protective.png b/tmp/trollian/protective.png new file mode 100644 index 0000000..aedba54 Binary files /dev/null and b/tmp/trollian/protective.png differ diff --git a/tmp/trollian/rancorous.png b/tmp/trollian/rancorous.png new file mode 100644 index 0000000..beb09d7 Binary files /dev/null and b/tmp/trollian/rancorous.png differ diff --git a/tmp/trollian/relaxed.png b/tmp/trollian/relaxed.png new file mode 100644 index 0000000..08f11a0 Binary files /dev/null and b/tmp/trollian/relaxed.png differ diff --git a/tmp/trollian/rightarrow.png b/tmp/trollian/rightarrow.png new file mode 100644 index 0000000..d1055f7 Binary files /dev/null and b/tmp/trollian/rightarrow.png differ diff --git a/tmp/trollian/sleek.png b/tmp/trollian/sleek.png new file mode 100644 index 0000000..7c8f4d9 Binary files /dev/null and b/tmp/trollian/sleek.png differ diff --git a/tmp/trollian/smooth.png b/tmp/trollian/smooth.png new file mode 100644 index 0000000..2fc7991 Binary files /dev/null and b/tmp/trollian/smooth.png differ diff --git a/tmp/trollian/style.js b/tmp/trollian/style.js new file mode 100644 index 0000000..ed9af97 --- /dev/null +++ b/tmp/trollian/style.js @@ -0,0 +1,307 @@ +{"main": + {"style": "background-image:url($path/tnbg2.png);background-color:rgba(0,0,0,0); background-repeat: no-repeat;", + "size": [650, 450], + "icon": "$path/trayicon.png", + "newmsgicon": "$path/trayicon2.png", + "windowtitle": "TROLLIAN", + "close": { "image": "$path/x.gif", + "loc": [635, 2]}, + "minimize": { "image": "$path/m.gif", + "loc": [618, 4]}, + "menubar": { "style": "font-family: 'Arial'; font-size: 11px; color: rgba(0,0,0,0);" }, + "menu" : { "style": "font-family: 'Arial'; font-size: 11px; background-color: #c2c2c2; border:1px solid #545454;", + "selected": "background-color: #545454", + "menuitem": "margin-right:14px;", + "loc": [14,90] + }, + "sounds": { "alertsound": "$path/alarm.wav" }, + "menus": {"client": {"_name": "Trollian", + "options": "Options", + "memos": "Memos", + "userlist": "Fresh Targets", + "exit": "Abscond"}, + "profile": {"_name": "View", + "switch": "Trolltag", + "theme": "Theme", + "color": "Hemospectrum", + "block": "Chumpdump", + "quirks": "Annoying"}, + "rclickchumlist": {"pester": "Troll", + "removechum": "Trash", + "blockchum": "Block", + "addchum": "Add Chump", + "unblockchum": "Mercy"} + }, + "chums": { "style": "font-size: 12px; background: white; border:2px solid #c2c2c2; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200); ", + "loc": [475, 89], + "size": [175, 361], + "userlistcolor": "black", + "moods": { + + "chummy": { "icon": "$path/chummy.png", "color": "#63ea00" }, + + "rancorous": { "icon": "$path/rancorous.png", "color": "#7f7f7f" }, + + "offline": { "icon": "$path/offline.png", "color": "black"}, + + + "pleasant": { "icon": "$path/pleasant.png", "color": "#d69df8" }, + + "distraught": { "icon": "$path/distraught.png", "color": "#706eba" }, + + "unruly": { "icon": "$path/unruly.png", "color": "blue" }, + + + "smooth": { "icon": "$path/smooth.png", "color": "red" }, + + + "ecstatic": { "icon": "$path/ecstatic.png", "color": "#99004d" }, + + "relaxed": { "icon": "$path/relaxed.png", "color": "#078446" }, + + "discontent": { "icon": "$path/discontent.png", "color": "#a75403" }, + + "devious": { "icon": "$path/devious.png", "color": "#008282" }, + + "sleek": { "icon": "$path/sleek.png", "color": "#a1a100" }, + + "detestful": { "icon": "$path/detestful.png", "color": "#6a006a" }, + + "mirthful": { "icon": "$path/mirthful.png", "color": "#450077" }, + + "manipulative": { "icon": "$path/manipulative.png", "color": "#004182" }, + + "vigorous": { "icon": "$path/vigorous.png", "color": "#0021cb" }, + + "perky": { "icon": "$path/perky.png", "color": "#406600" }, + + "acceptant": { "icon": "$path/acceptant.png", "color": "#a10000" }, + + "protective": { "icon": "$path/protective.png", "color": "white" }, + + "blocked": { "icon": "$path/blocked.png", "color": "black" } + + } + }, + "trollslum": { + "style": "background: rgb(190, 19, 4); font-family: 'Arial'", + "size": [175, 461], + "label": { "text": "Chumpdump", + "style": "color: rgba(0, 0, 0, 100%) ;font:bold; font-family: 'Arial';border: 0px;" }, + "chumroll": {"style": "border: 0px; background-color: white; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200); " } + }, + "mychumhandle": { "label": { "text": "", + "loc": [0,0], + "style": "color:rgba(0,0,0,0);" }, + "handle": { "style": "background: rgba(0,0,0,0); color:rgba(0,0,0,0);", + "loc": [0,0], + "size": [0,0] }, + "colorswatch": { "loc": [0,0], + "size": [0,0], + "text": "" } + }, + "defaultwindow": { "style": "background: #c2c2c2; font-family:'Arial';font:bold;selection-background-color:#545454; " + }, + "addchum": { "style": "background: rgba(0,0,0,0); border:0px; color: rgba(0,0,0,0);", + "loc": [475, 67], + "size": [175, 18], + "text": "" + }, + "pester": { "style": "background: rgba(0,0,0,0); border:0px; color: rgba(0,0,0,0);", + "loc": [0,0], + "size": [0, 0], + "text": "" + }, + "block": { "style": "background: rgba(0,0,0,0); border:0px; color: rgba(0,0,0,0);", + "loc": [1500,202], + "size": [71, 22], + "text": "" + }, + "defaultmood": 7, + "moodlabel": { "style": "", + "loc": [0, 0], + "text": "" + }, + "moods": [ + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck1.png); border:0px;", + "loc": [25, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 17 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck2.png); border:0px;", + "loc": [60, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 9 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck3.png); border:0px;", + "loc": [95, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 11 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck4.png); border:0px;", + "loc": [130, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 1 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck5.png); border:0px;", + "loc": [165, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 16 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck6.png); border:0px;", + "loc": [200, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 8 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck7.png); border:0px;", + "loc": [235, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 10 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck8.png); border:0px;", + "loc": [270, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 14 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck9.png); border:0px;", + "loc": [305, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 15 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck10.png); border:0px;", + "loc": [340, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 13 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck11.png); border:0px;", + "loc": [375, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 12 + }, + { "style": "border:0px;", + "selected": "background-image:url($path/moodcheck12.png); border:0px;", + "loc": [410, 141], + "size": [20, 270], + "text": "", + "icon": "", + "mood": 7 + }, + + { "style": "border:0px;color: rgba(0, 0, 0, 0%);", + "selected": "border:0px; color: rgba(0, 0, 0, 0%);", + "loc": [12, 117], + "size": [435, 18], + "text": "", + "icon": "", + "mood": 2 + } + ] + }, + "convo": + {"style": "background: rgb(190, 19, 4); font-family: 'Arial';", + "margins": {"top": 22, "bottom": 9, "left": 10, "right": 4 }, + "size": [400, 250], + "chumlabel": { "style": "background: rgb(255, 38, 18); color: white; padding: 2px; border:1px solid #c2c2c2;", + "align": { "h": "left", "v": "center" }, + "minheight": 18, + "maxheight": 18, + "text" : "trolling: $handle" + }, + "textarea": { + "style": "background: white; border:2px solid #c2c2c2; font-size: 12px; margin-top: 4px;" + }, + "input": { + "style": "background: white;margin-top:5px; border:1px solid #c2c2c2; margin-right: 54px; font-size: 12px; height: 19px;" + }, + "tabs": { + "style": "", + "selectedstyle": "", + "newmsgcolor": "red", + "tabstyle": 0 + }, + "text": { + "beganpester": "began trolling", + "ceasepester": "gave up trolling", + "blocked": "blocked", + "unblocked": "mercifully forgave", + "openmemo": "opened memo on board", + "joinmemo": "responded to memo", + "closememo": "ceased responding to memo" + }, + "systemMsgColor": "#646464" + }, + "memos": + {"memoicon": "$path/memo.png", + "style": "background: rgb(190, 19, 4); font-family: 'Arial';", + "size": [450,300], + "tabs": { + "style": "", + "selectedstyle": "", + "newmsgcolor": "red", + "tabstyle": 0 + }, + "label": { "text": "Bulletin Board: $channel", + "style": "background-image:url($path/chumlabelbg.png);background-color:rgb(255,38,18); background-repeat: no-repeat; color: white; padding: 2px; border:1px solid #c2c2c2;", + "align": { "h": "left", "v": "center" }, + "minheight": 18, + "maxheight": 18 + }, + "textarea": { + "style": "background: white; border:2px solid #c2c2c2; font-size: 12px; margin-top: 4px;" + }, + "input": { + "style": "background: white;margin-top:5px; border:1px solid #c2c2c2; font-size: 12px; height: 19px; margin-bottom: 5px; " + }, + "margins": {"top": 22, "bottom": 10, "left": 9, "right": 4 }, + "userlist": { "width": 125, + "style": "font-size: 12px; background: white; margin-top: 4px; margin-left: 5px; margin-bottom: 5px; border:2px solid #c2c2c2; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200);" + }, + "time": { "text": { "width": 75, + "style": "color: black; font:bold; border:1px solid #c2c2c2; background: white; height: 19px;" + }, + "slider": { "style": " border:1px solid #c2c2c2;", + "groove": "border-image:url($path/timeslideraqua.png);", + "handle": "image:url($path/aquaicon.png);" + }, + "buttons": { "style": "border:1px solid #a68168; height: 17px; width: 50px; color: #cd8f9d; font-family: 'Arial'; background: rgb(190, 19, 4); margin-left: 2px;" }, + "arrows": { "left": "$path/leftarrow.png", + "right": "$path/rightarrow.png", + "style": "width: 19px; height: 19px; border:0px; margin-left: 2px;" + } + }, + "systemMsgColor": "#646464" + } +} \ No newline at end of file diff --git a/tmp/trollian/timeslider.png b/tmp/trollian/timeslider.png new file mode 100644 index 0000000..b004b93 Binary files /dev/null and b/tmp/trollian/timeslider.png differ diff --git a/tmp/trollian/timeslideraqua.png b/tmp/trollian/timeslideraqua.png new file mode 100644 index 0000000..ac2118a Binary files /dev/null and b/tmp/trollian/timeslideraqua.png differ diff --git a/tmp/trollian/tnbg.png b/tmp/trollian/tnbg.png new file mode 100644 index 0000000..1c409a5 Binary files /dev/null and b/tmp/trollian/tnbg.png differ diff --git a/tmp/trollian/tnbg2.png b/tmp/trollian/tnbg2.png new file mode 100644 index 0000000..e546baa Binary files /dev/null and b/tmp/trollian/tnbg2.png differ diff --git a/tmp/trollian/tnbg3.png b/tmp/trollian/tnbg3.png new file mode 100644 index 0000000..4ea9d2a Binary files /dev/null and b/tmp/trollian/tnbg3.png differ diff --git a/tmp/trollian/trayicon.png b/tmp/trollian/trayicon.png new file mode 100644 index 0000000..31f7d29 Binary files /dev/null and b/tmp/trollian/trayicon.png differ diff --git a/tmp/trollian/trayicon2.png b/tmp/trollian/trayicon2.png new file mode 100644 index 0000000..84d1156 Binary files /dev/null and b/tmp/trollian/trayicon2.png differ diff --git a/tmp/trollian/trollian.psd b/tmp/trollian/trollian.psd new file mode 100644 index 0000000..255f683 Binary files /dev/null and b/tmp/trollian/trollian.psd differ diff --git a/tmp/trollian/unruly.png b/tmp/trollian/unruly.png new file mode 100644 index 0000000..4b5284b Binary files /dev/null and b/tmp/trollian/unruly.png differ diff --git a/tmp/trollian/vigorous.png b/tmp/trollian/vigorous.png new file mode 100644 index 0000000..715dbfd Binary files /dev/null and b/tmp/trollian/vigorous.png differ diff --git a/tmp/trollian/x.gif b/tmp/trollian/x.gif new file mode 100644 index 0000000..80f14b6 Binary files /dev/null and b/tmp/trollian/x.gif differ