diff --git a/TODO b/TODO index 7722240..58c66cf 100644 --- a/TODO +++ b/TODO @@ -1,9 +1,4 @@ Features: -* Handle user signoffs/signons -* Handle nick changes -* theme elements define, implement -* default user -* Moods * Add chum * REMOVE chum * Sounds @@ -12,10 +7,13 @@ Features: * menubar should pass on mouse move * Quirks -- package +* theme elements define, implement +* User signon? * Logging * Block list * User list/add from list * User commands/stop user from sending commands accidentally +-- release alpha * System tray stuff * Chat rooms -- release beta diff --git a/oyoyo/__init__.pyc b/oyoyo/__init__.pyc index 28e3e80..be26c04 100644 Binary files a/oyoyo/__init__.pyc and b/oyoyo/__init__.pyc differ diff --git a/oyoyo/client.pyc b/oyoyo/client.pyc index ad7d9f7..08d3b01 100644 Binary files a/oyoyo/client.pyc and b/oyoyo/client.pyc differ diff --git a/oyoyo/cmdhandler.pyc b/oyoyo/cmdhandler.pyc index d97b3d1..e9def19 100644 Binary files a/oyoyo/cmdhandler.pyc and b/oyoyo/cmdhandler.pyc differ diff --git a/oyoyo/helpers.pyc b/oyoyo/helpers.pyc index 89ddc32..c0234d2 100644 Binary files a/oyoyo/helpers.pyc and b/oyoyo/helpers.pyc differ diff --git a/oyoyo/ircevents.pyc b/oyoyo/ircevents.pyc index c83999f..1f1ccd6 100644 Binary files a/oyoyo/ircevents.pyc and b/oyoyo/ircevents.pyc differ diff --git a/oyoyo/parse.pyc b/oyoyo/parse.pyc index 9095b24..e67f2ea 100644 Binary files a/oyoyo/parse.pyc and b/oyoyo/parse.pyc differ diff --git a/pesterchum.py b/pesterchum.py index a7b71d0..01cbc85 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -13,7 +13,9 @@ from PyQt4 import QtGui, QtCore logging.basicConfig(level=logging.INFO) class Mood(object): - moods = ["chummy", "rancorous", "offline"] + moods = ["chummy", "rancorous", "offline", "pleasant", "distraught", + "unruly", "smooth", "ecstatic", "relaxed", "discontent", + "devious", "sleek", "detestful"] def __init__(self, mood): if type(mood) is int: self.mood = mood @@ -124,16 +126,19 @@ class userProfile(object): "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() + self.theme = pesterTheme(self.userprofile["theme"]) self.chat = PesterProfile(self.userprofile["handle"], QtGui.QColor(self.userprofile["color"]), - Mood(0)) - self.theme = pesterTheme(self.userprofile["theme"]) + 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 @@ -240,6 +245,12 @@ class PesterChooseProfile(QtGui.QDialog): else: self.profileBox = None + self.defaultcheck = QtGui.QCheckBox(self) + self.defaultlabel = QtGui.QLabel("Set This Profile As Default", self) + layout_2 = QtGui.QHBoxLayout() + layout_2.addWidget(self.defaultlabel) + layout_2.addWidget(self.defaultcheck) + self.ok = QtGui.QPushButton("OK", self) self.ok.setDefault(True) self.connect(self.ok, QtCore.SIGNAL('clicked()'), @@ -261,6 +272,7 @@ class PesterChooseProfile(QtGui.QDialog): layout_0.addWidget(profileLabel) layout_0.addWidget(self.profileBox) layout_0.addLayout(layout_ok) + layout_0.addLayout(layout_2) self.errorMsg = QtGui.QLabel(self) self.errorMsg.setStyleSheet("color:red;") layout_0.addWidget(self.errorMsg) @@ -387,6 +399,59 @@ class chumArea(QtGui.QListWidget): for c in chums: c.changeTheme(theme) +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 + oldbutton = self.buttons[oldmood.value()] + newbutton = self.buttons[m] + oldbutton.setSelected(False) + 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 = QtGui.QIcon(options["icon"]) + QtGui.QPushButton.__init__(self, icon, options["text"], parent) + 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) @@ -528,19 +593,19 @@ class PesterText(QtGui.QTextEdit): parent = self.parent() parent.setChumOpen(True) window = parent.mainwindow - me = window.profile + me = window.profile() msg = chum.beganpestermsg(me) self.append(msg) elif msg == "PESTERCHUM:CEASE": parent = self.parent() parent.setChumOpen(False) window = parent.mainwindow - me = window.profile + me = window.profile() msg = chum.ceasedpestermsg(me) self.append(msg) else: - if not self.parent().chumopen and chum is not self.parent().mainwindow.profile: - me = self.parent().mainwindow.profile + if not self.parent().chumopen and chum is not self.parent().mainwindow.profile(): + me = self.parent().mainwindow.profile() beginmsg = chum.beganpestermsg(me) self.parent().setChumOpen(True) self.append(beginmsg) @@ -591,10 +656,14 @@ class PesterConvo(QtGui.QFrame): if parent: parent.addChat(self) if initiated: - msg = self.mainwindow.profile.beganpestermsg(self.chum) + msg = self.mainwindow.profile().beganpestermsg(self.chum) self.textArea.append(msg) def updateMood(self, mood): + if mood.name() == "offline": + msg = self.mainwindow.profile().ceasepestermsg(self.chum) + self.textArea.append(msg) + self.chumopen = False if self.parent(): self.parent().updateMood(self.chum.handle, mood) else: @@ -604,7 +673,7 @@ class PesterConvo(QtGui.QFrame): self.chum.color = color def addMessage(self, text, me=True): if me: - chum = self.mainwindow.profile + chum = self.mainwindow.profile() else: chum = self.chum self.textArea.addMessage(text, chum) @@ -652,11 +721,9 @@ class PesterWindow(MovingWindow): self.config = userConfig() if self.config.defaultprofile(): self.userprofile = userProfile(self.config.defaultprofile()) - self.profile = self.userprofile.chat self.theme = self.userprofile.getTheme() else: self.userprofile = userProfile(PesterProfile("pesterClient%d" % (random.randint(100,999)), QtGui.QColor("black"), Mood(0))) - self.profile = self.userprofile.chat self.theme = self.userprofile.getTheme() self.changeProfile() @@ -705,9 +772,13 @@ class PesterWindow(MovingWindow): self.connect(self.chumList, QtCore.SIGNAL('itemDoubleClicked(QListWidgetItem *)'), self, QtCore.SLOT('newConversationWindow(QListWidgetItem *)')) + self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in self.theme["main/moods"]]) + self.convos = {} self.tabconvo = None self.optionmenu = None + def profile(self): + return self.userprofile.chat def mainSS(self): self.setStyleSheet("QFrame#main { "+self.theme["main/style"]+" }") def menuBarSS(self): @@ -792,6 +863,10 @@ class PesterWindow(MovingWindow): self.miniButton.move(*self.theme["main/minimize/loc"]) # chum area self.chumList.changeTheme(theme) + # moods + self.moods.removeButtons() + self.moods = PesterMoodHandler(self, *[PesterMoodButton(self, **d) for d in self.theme["main/moods"]]) + self.moods.showButtons() # do open windows if self.tabconvo: self.tabconvo.changeTheme(theme) @@ -811,7 +886,7 @@ class PesterWindow(MovingWindow): def tabsClosed(self): del self.tabconvo self.tabconvo = None - + @QtCore.pyqtSlot(QtCore.QString, Mood) def updateMoodSlot(self, handle, mood): h = str(handle) @@ -889,16 +964,21 @@ class PesterWindow(MovingWindow): if self.chooseprofile.profileBox and \ self.chooseprofile.profileBox.currentIndex() > 0: handle = unicode(self.chooseprofile.profileBox.currentText()) + if handle == self.profile().handle: + return self.userprofile = userProfile(handle) - self.profile = self.userprofile.chat self.changeTheme(self.userprofile.getTheme()) else: - profile = PesterProfile(unicode(self.chooseprofile.chumHandle.text()), - self.chooseprofile.chumcolor, - Mood(0)) + handle = unicode(self.chooseprofile.chumHandle.text()) + if handle == self.profile().handle: + return + profile = PesterProfile(handle, + self.chooseprofile.chumcolor) self.userprofile = userProfile.newUserProfile(profile) - self.profile = self.userprofile.chat + # is default? + if self.chooseprofile.defaultcheck.isChecked(): + self.config.set("defaultprofile", self.userprofile.chat.handle) # this may have to be fixed self.closeConversations() self.profileChanged.emit() @@ -935,13 +1015,14 @@ class PesterWindow(MovingWindow): convoClosed = QtCore.pyqtSignal(QtCore.QString) profileChanged = QtCore.pyqtSignal() moodRequest = QtCore.pyqtSignal(PesterProfile) + moodUpdated = QtCore.pyqtSignal() class PesterIRC(QtCore.QObject): def __init__(self, window): QtCore.QObject.__init__(self) self.mainwindow = window def IRCConnect(self): - self.cli = IRCClient(PesterHandler, host="irc.tymoon.eu", port=6667, nick=self.mainwindow.profile.handle, blocking=True) + self.cli = IRCClient(PesterHandler, host="irc.tymoon.eu", port=6667, nick=self.mainwindow.profile().handle, blocking=True) self.cli.command_handler.parent = self self.cli.command_handler.mainwindow = self.mainwindow self.conn = self.cli.connect() @@ -960,16 +1041,20 @@ class PesterIRC(QtCore.QObject): h = str(handle) if initiated: helpers.msg(self.cli, h, "PESTERCHUM:BEGIN") - helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile.colorcmd())) + helpers.msg(self.cli, h, "COLOR >%s" % (self.mainwindow.profile().colorcmd())) @QtCore.pyqtSlot(QtCore.QString) def endConvo(self, handle): h = str(handle) helpers.msg(self.cli, h, "PESTERCHUM:CEASE") @QtCore.pyqtSlot() def updateProfile(self): - me = self.mainwindow.profile + me = self.mainwindow.profile() handle = me.handle helpers.nick(self.cli, handle) + self.updateMood() + @QtCore.pyqtSlot() + def updateMood(self): + me = self.mainwindow.profile() helpers.msg(self.cli, "#pesterchum", "MOOD >%d" % (me.mood.value())) def updateIRC(self): self.conn.next() @@ -995,8 +1080,8 @@ class PesterHandler(DefaultCommandHandler): mood = Mood(0) self.parent.moodUpdated.emit(handle, mood) elif msg[0:7] == "GETMOOD": - mychumhandle = self.mainwindow.profile.handle - mymood = self.mainwindow.profile.mood.value() + mychumhandle = self.mainwindow.profile().handle + mymood = self.mainwindow.profile().mood.value() if msg.find(mychumhandle, 8) != -1: helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood)) @@ -1004,7 +1089,7 @@ class PesterHandler(DefaultCommandHandler): else: # private message # silently ignore messages to yourself. - if handle == self.mainwindow.profile.handle: + if handle == self.mainwindow.profile().handle: return if msg[0:7] == "COLOR >": colors = msg[7:].split(",") @@ -1020,8 +1105,8 @@ class PesterHandler(DefaultCommandHandler): def welcome(self, server, nick, msg): helpers.join(self.client, "#pesterchum") - mychumhandle = self.mainwindow.profile.handle - mymood = self.mainwindow.profile.mood.value() + mychumhandle = self.mainwindow.profile().handle + mymood = self.mainwindow.profile().mood.value() helpers.msg(self.client, "#pesterchum", "MOOD >%d" % (mymood)) chums = self.mainwindow.chumList.chums @@ -1030,11 +1115,20 @@ class PesterHandler(DefaultCommandHandler): def nicknameinuse(self, server, cmd, nick, msg): helpers.nick(self.client, "pesterClient%d" % (random.randint(100,999))) self.parent.nickCollision.emit(nick) + def quit(self, nick, reason): + handle = nick[0:nick.find("!")] + self.parent.moodUpdated.emit(handle, Mood("offline")) + def nick(self, oldnick, newnick): + oldhandle = oldnick[0:oldnick.find("!")] + newchum = PesterProfile(newnick) + self.parent.moodUpdated.emit(oldhandle, Mood("offline")) + self.getMood(newchum) + def getMood(self, *chums): chumglub = "GETMOOD " for c in chums: chandle = c.handle - if len(chumglub+chandle) >= 510: + if len(chumglub+chandle) >= 350: helpers.msg(self.client, "#pesterchum", chumglub) chumglub = "GETMOOD " chumglub += chandle @@ -1079,6 +1173,10 @@ def main(): QtCore.SIGNAL('moodRequest(PyQt_PyObject)'), irc, QtCore.SLOT('getMood(PyQt_PyObject)')) + irc.connect(widget, + QtCore.SIGNAL('moodUpdated()'), + irc, + QtCore.SLOT('updateMood()')) irc.connect(irc, QtCore.SIGNAL('moodUpdated(QString, PyQt_PyObject)'), widget, diff --git a/profiles/superGhost.js b/profiles/superGhost.js index e45bde0..f0ddd8a 100644 --- a/profiles/superGhost.js +++ b/profiles/superGhost.js @@ -1 +1 @@ -{"color": "#00aaff", "theme": "trollian", "quirks": [], "handle": "superGhost"} \ No newline at end of file +{"color": "#00aaff", "theme": "pesterchum", "quirks": [], "handle": "superGhost"} \ No newline at end of file diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index a73fe10..e0e2946 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -12,20 +12,96 @@ }, "chums": { "style": "background-color: black;color: white;font: bold;font-family: 'Courier New';selection-background-color:#919191; ", "loc": [20, 65], - "size": [265, 400], + "size": [265, 350], "moods": { "chummy": { "icon": "$path/chummy.gif", "color": "white" }, "offline": { "icon": "$path/offline.gif", "color": "#919191"}, "rancorous": { "icon": "$path/rancorous.gif", - "color": "red" } + "color": "red" }, + "detestful": { "icon": "$path/detestful.gif", + "color": "red" }, + "devious": { "icon": "$path/devious.gif", + "color": "white" }, + "discontent": { "icon": "$path/discontent.gif", + "color": "white" }, + "distraught": { "icon": "$path/distraught.gif", + "color": "white" }, + "ecstatic": { "icon": "$path/estatic.gif", + "color": "white" }, + "pleasant": { "icon": "$path/pleasant.gif", + "color": "white" }, + "relaxed": { "icon": "$path/relaxed.gif", + "color": "white" }, + "sleek": { "icon": "$path/sleek.gif", + "color": "white" }, + "smooth": { "icon": "$path/smooth.gif", + "color": "white" }, + "unruly": { "icon": "$path/unruly.gif", + "color": "white" } } }, "defaultwindow": { "style": "background: #fdb302; font-family:'Courier New';font:bold;selection-background-color:#919191; " }, "labels": { "mychumhandle": "MYCHUMHANDLE" }, - "elements": [ - { "style": "" } + "defaultmood": 0, + "moods": [ + { "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 470], + "size": [133, 30], + "text": "CHUMMY", + "icon": "$path/chummy.gif", + "mood": 0 + }, + { "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color: #919191", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 497], + "size": [133, 30], + "text": "PLEASANT", + "icon": "$path/pleasant.gif", + "mood": 3 + }, + { "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 524], + "size": [133, 30], + "text": "DISTRAUGHT", + "icon": "$path/distraught.gif", + "mood": 4 + }, + { "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 470], + "size": [133, 30], + "text": "UNRULY", + "icon": "$path/unruly.gif", + "mood": 5 + }, + { "style": "text-align:left; background: white; border:3px solid black; padding: 5px;color:#919191;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 497], + "size": [133, 30], + "text": "SMOOTH", + "icon": "$path/smooth.gif", + "mood": 6 + }, + { "style": "text-align:left; background: red; border:3px solid black; padding: 5px;", + "selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 524], + "size": [133, 30], + "text": "RANCOROUS", + "icon": "$path/rancorous.gif", + "mood": 1 + }, + { "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;", + "selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 551], + "size": [263, 30], + "text": "ABSCOND", + "icon": "$path/offline.gif", + "mood": 2 + } ] }, "convo": diff --git a/themes/trollian/style.js b/themes/trollian/style.js index 671883c..e989340 100644 --- a/themes/trollian/style.js +++ b/themes/trollian/style.js @@ -1,31 +1,107 @@ {"main": {"style": "background-image:url($path/tnbg2.png);", "size": [300, 620], - "icon": "$path/trayicon3.gif", + "icon": "$path/trayicon3.png", "close": { "image": "$path/x.gif", - "loc": [255, 0]}, + "loc": [275, 0]}, "minimize": { "image": "$path/m.gif", - "loc": [225, 0]}, + "loc": [255, 0]}, "menubar": { "style": "font-family: 'Courier New'; font-weight: bold; font-size: 12px;" }, "menu" : { "style": "font-family: 'Courier New'; font-weight: bold; font-size: 12px; background-color: #e5000f; border:2px solid #ff0000", "selected": "background-color: #ff0000" }, - "chums": { "style": "background-color: white;color: black;font: bold;font-family: 'Courier New';selection-background-color:#ffb6b6; ", + "chums": { "style": "background-color: black;color: white;font: bold;font-family: 'Courier New';selection-background-color:#ffb6b6; ", "loc": [20, 65], - "size": [265, 450], + "size": [266, 350], "moods": { "chummy": { "icon": "$path/chummy.gif", - "color": "black" }, + "color": "white" }, "offline": { "icon": "$path/offline.gif", - "color": "#dbdbdb"}, + "color": "#919191"}, "rancorous": { "icon": "$path/rancorous.gif", - "color": "red" } + "color": "red" }, + "detestful": { "icon": "$path/detestful.gif", + "color": "red" }, + "devious": { "icon": "$path/devious.gif", + "color": "white" }, + "discontent": { "icon": "$path/discontent.gif", + "color": "white" }, + "distraught": { "icon": "$path/distraught.gif", + "color": "white" }, + "ecstatic": { "icon": "$path/estatic.gif", + "color": "white" }, + "pleasant": { "icon": "$path/pleasant.gif", + "color": "white" }, + "relaxed": { "icon": "$path/relaxed.gif", + "color": "white" }, + "sleek": { "icon": "$path/sleek.gif", + "color": "white" }, + "smooth": { "icon": "$path/smooth.gif", + "color": "white" }, + "unruly": { "icon": "$path/unruly.gif", + "color": "white" } } }, "defaultwindow": { "style": "background: #e5000f; font-family:'Courier New';font:bold;selection-background-color:#ffb6b6; " }, "labels": { "mychumhandle": "MYTROLLTAG" }, - "elements": [ - { "style": "" } + "defaultmood": 7, + "moods": [ + { "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 470], + "size": [133, 30], + "text": "ECSTATIC", + "icon": "$path/estatic.gif", + "mood": 7 + }, + { "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color: #dbdbdb", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 497], + "size": [133, 30], + "text": "RELAXED", + "icon": "$path/relaxed.gif", + "mood": 8 + }, + { "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 524], + "size": [133, 30], + "text": "DISCONTENT", + "icon": "$path/discontent.gif", + "mood": 9 + }, + { "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 470], + "size": [133, 30], + "text": "DEVIOUS", + "icon": "$path/devious.gif", + "mood": 10 + }, + { "style": "text-align:left; background: black; border:3px solid black; padding: 5px;color:#dbdbdb;", + "selected": "text-align:left; background: white; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 497], + "size": [133, 30], + "text": "SLEEK", + "icon": "$path/sleek.gif", + "mood": 11 + }, + { "style": "text-align:left; background: red; border:3px solid black; padding: 5px;", + "selected": "text-align:left; background: red; border:3px solid black; padding: 5px;font: bold;", + "loc": [150, 524], + "size": [133, 30], + "text": "DETESTFUL", + "icon": "$path/detestful.gif", + "mood": 12 + }, + { "style": "text-align:center; background: #919191; border:3px solid black; padding: 5px;", + "selected": "text-align:center; background: #919191; border:3px solid black; padding: 5px;font: bold;", + "loc": [20, 551], + "size": [263, 30], + "text": "ABSCOND", + "icon": "$path/offline.gif", + "mood": 2 + } ] }, "convo":