diff --git a/TODO b/TODO index 2562cdd..c668bcc 100644 --- a/TODO +++ b/TODO @@ -1,22 +1,19 @@ Features: * Tray doesn't disappear on windows after close -* Idling -* PESTERCHUM:BLOCKED -* new sound on CEASE and BEGIN? * scroll bar style? +* flashing?? * More complex quirks: random, spelling, by-sound -* change profile only once we have confirmation from server * convert hex tags ( or ) -* convo backgrounds -- make them more like http://www.mspaintadventures.com/storyfiles/hs2/02546_2.gif -* help button on quirks menu? * help menu -- about and forum -* dropped messages when chatting ? -- release alpha * shared buddy lists - changes to the buddy list should refresh it? multiple clients share buddy list??? * chumList not scaling -- QListView + delegate? * spell check? +* convo backgrounds -- make them more like http://www.mspaintadventures.com/storyfiles/hs2/02546_2.gif +* help button on quirks menu? -- release beta +* change profile only once we have confirmation from server * log viewer * pick your own icon * time codes diff --git a/convo.py b/convo.py index f91d105..51c99b4 100644 --- a/convo.py +++ b/convo.py @@ -1,5 +1,6 @@ from string import Template import re +from datetime import datetime, timedelta from PyQt4 import QtGui, QtCore from dataobjs import PesterProfile, Mood, PesterHistory @@ -223,6 +224,14 @@ class PesterText(QtGui.QTextEdit): msg = chum.pestermsg(me, systemColor, window.theme['convo/text/unblocked']) window.chatlog.log(chum.handle, convertTags(msg, "bbcode")) self.append(convertTags(msg)) + elif msg == "PESTERCHUM:BLOCKED": + msg = chum.pestermsg(me, systemColor, window.theme['convo/text/blockedmsg']) + window.chatlog.log(chum.handle, convertTags(msg, "bbcode")) + self.append(convertTags(msg)) + elif msg == "PESTERCHUM:IDLE": + msg = chum.idlemsg(systemColor, window.theme['convo/text/idle']) + window.chatlog.log(chum.handle, convertTags(msg, "bbcode")) + self.append(convertTags(msg)) elif msg[0:3] == "/me" or msg[0:13] == "PESTERCHUM:ME": if msg[0:3] == "/me": start = 3 @@ -248,6 +257,12 @@ class PesterText(QtGui.QTextEdit): if chum is me: window.chatlog.log(parent.chum.handle, convertTags(msg, "bbcode")) else: + if window.idle: + idlethreshhold = 60 + if (not hasattr(self, 'lastmsg')) or \ + datetime.now() - self.lastmsg > timedelta(0,60): + parent.messageSent.emit("PESTERCHUM:IDLE", parent.title()) + self.lastmsg = datetime.now() window.chatlog.log(chum.handle, convertTags(msg, "bbcode")) def changeTheme(self, theme): self.setStyleSheet(theme["convo/textarea/style"]) @@ -295,6 +310,7 @@ class PesterInput(QtGui.QLineEdit): self.setText(prev) elif event.key() in [QtCore.Qt.Key_PageUp, QtCore.Qt.Key_PageDown]: self.parent().textArea.keyPressEvent(event) + self.parent().mainwindow.idletime = 0 QtGui.QLineEdit.keyPressEvent(self, event) @@ -348,6 +364,10 @@ class PesterConvo(QtGui.QFrame): self.quirksOff.setCheckable(True) self.connect(self.quirksOff, QtCore.SIGNAL('toggled(bool)'), self, QtCore.SLOT('toggleQuirks(bool)')) + self.unblockchum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self) + self.connect(self.unblockchum, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('unblockChumSlot()')) + self.optionsMenu.addAction(self.quirksOff) self.optionsMenu.addAction(self.addChumAction) self.optionsMenu.addAction(self.blockAction) @@ -373,6 +393,7 @@ class PesterConvo(QtGui.QFrame): def updateMood(self, mood, unblocked=False, old=None): syscolor = QtGui.QColor(self.mainwindow.theme["convo/systemMsgColor"]) if mood.name() == "offline" and self.chumopen == True and not unblocked: + self.mainwindow.ceasesound.play() msg = self.chum.pestermsg(self.mainwindow.profile(), syscolor, self.mainwindow.theme["convo/text/ceasepester"]) self.textArea.append(convertTags(msg)) self.mainwindow.chatlog.log(self.title(), convertTags(msg, "bbcode")) @@ -386,14 +407,21 @@ class PesterConvo(QtGui.QFrame): else: if self.chum.blocked(self.mainwindow.config) and not unblocked: self.setWindowIcon(QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])) + self.optionsMenu.addAction(self.unblockchum) + self.optionsMenu.removeAction(self.blockAction) else: self.setWindowIcon(mood.icon(self.mainwindow.theme)) + self.optionsMenu.removeAction(self.unblockchum) + self.optionsMenu.addAction(self.blockAction) # print mood update? def updateBlocked(self): if self.parent(): self.parent().updateBlocked(self.title()) else: self.setWindowIcon(QtGui.QIcon(self.mainwindow.theme["main/chums/moods/blocked/icon"])) + self.optionsMenu.addAction(self.unblockchum) + self.optionsMenu.removeAction(self.blockAction) + def updateColor(self, color): self.chum.color = color def addMessage(self, text, me=True): @@ -468,6 +496,7 @@ class PesterConvo(QtGui.QFrame): self.quirksOff.setText(self.mainwindow.theme["main/menus/rclickchumlist/quirksoff"]) self.addChumAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/addchum"]) self.blockAction.setText(self.mainwindow.theme["main/menus/rclickchumlist/blockchum"]) + self.unblockchum.setText(self.mainwindow.theme["main/menus/rclickchumlist/unblockchum"], self) self.textArea.changeTheme(theme) self.textInput.changeTheme(theme) @@ -498,11 +527,13 @@ class PesterConvo(QtGui.QFrame): @QtCore.pyqtSlot() def blockThisChum(self): self.mainwindow.blockChum(self.chum.handle) + @QtCore.pyqtSlot() + def unblockChumSlot(self): + self.mainwindow.unblockChum(self.chum.handle) @QtCore.pyqtSlot(bool) def toggleQuirks(self, toggled): self.applyquirks = not toggled - messageSent = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) windowClosed = QtCore.pyqtSignal(QtCore.QString) diff --git a/convo.pyc b/convo.pyc index 69f939d..2c481a8 100644 Binary files a/convo.pyc and b/convo.pyc differ diff --git a/dataobjs.py b/dataobjs.py index 9ebb3d9..c51be52 100644 --- a/dataobjs.py +++ b/dataobjs.py @@ -140,6 +140,8 @@ class PesterProfile(object): return "-- %s [%s] %s %s [%s] at %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), verb, otherchum.handle, otherchum.colorhtml(), otherchum.initials(), datetime.now().strftime("%H:%M")) def moodmsg(self, mood, syscolor, theme): return "-- %s [%s] changed their mood to %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), mood.name().upper(), theme["main/chums/moods"][mood.name()]["icon"]) + def idlemsg(self, syscolor, verb): + return "-- %s [%s] %s --" % (syscolor.name(), self.handle, self.colorhtml(), self.initials(), verb) def memoclosemsg(self, syscolor, timeGrammar, verb): return "%s%s%s %s." % (syscolor.name(), self.colorhtml(), timeGrammar.pcf, self.initials(), timeGrammar.number, verb) def memoopenmsg(self, syscolor, td, timeGrammar, verb, channel): diff --git a/dataobjs.pyc b/dataobjs.pyc index 042338f..f807641 100644 Binary files a/dataobjs.pyc and b/dataobjs.pyc differ diff --git a/generic.pyc b/generic.pyc index cc9b4e2..033bd9a 100644 Binary files a/generic.pyc and b/generic.pyc differ diff --git a/irc.pyc b/irc.pyc index e4a65a5..62a8eb1 100644 Binary files a/irc.pyc and b/irc.pyc differ diff --git a/memos.pyc b/memos.pyc index 0dd44f5..aa9b72e 100644 Binary files a/memos.pyc and b/memos.pyc differ diff --git a/menus.pyc b/menus.pyc index 53c48cf..a4bfd9e 100644 Binary files a/menus.pyc and b/menus.pyc differ 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 9115adc..5ba5325 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 e5b17da..e5c82c4 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/parsetools.pyc b/parsetools.pyc index 15d589a..9e38294 100644 Binary files a/parsetools.pyc and b/parsetools.pyc differ diff --git a/pesterchum.js b/pesterchum.js index c2cec68..da823fc 100644 --- a/pesterchum.js +++ b/pesterchum.js @@ -1 +1 @@ -{"tabs": true, "soundon": true, "chums": ["marineAquist", "unknownTraveler", "tentacleTherapist", "macruralAlchemist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "adiosToreador", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "maxiumumFatness", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "acapellaWaterfall", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist", "ardentAbettor"], "defaultprofile": "ghostDunk", "block": []} \ No newline at end of file +{"tabs": true, "soundon": true, "chums": ["unknownTraveler", "tentacleTherapist", "vaginalEngineer", "mechanicalSpectacle", "carcinoGeneticist", "schlagzeugGator", "gamblingGenocider", "gardenGnostic", "superGhost", "centaursTesticle", "arachnidsGrip", "grimAuxiliatrix", "remoteBloodbath", "nitroZealist", "greenZephyr", "arsenicCatnip", "adiosToreador", "cuttlefishCuller", "rageInducer", "gallowsCalibrator", "caligulasAquarium", "terminallyCapricious", "illuminatedWax", "aquaMarinist", "maxiumumFatness", "elegantDiversion", "moirailBunp", "uroborosUnbound", "androidTechnician", "midnightSparrow", "apocalypseArisen", "anguillaNuntia", "oilslickOrchid", "confusedTransient", "pretentiousFantasia", "aquaticMarinist"], "defaultprofile": "ghostDunk", "block": []} \ No newline at end of file diff --git a/pesterchum.py b/pesterchum.py index f4d5312..4b2df4e 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -662,6 +662,7 @@ class PesterWindow(MovingWindow): self.importaction = QtGui.QAction(self.theme["main/menus/client/import"], self) self.connect(self.importaction, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('importExternalConfig()')) + self.menu = QtGui.QMenuBar(self) filemenu = self.menu.addMenu(self.theme["main/menus/client/_name"]) @@ -762,6 +763,15 @@ class PesterWindow(MovingWindow): self.waitingMessages = waitingMessageHolder(self) + self.idle = False + self.idlethreshold = 600 + self.idletimer = QtCore.QTimer(self) + self.idleposition = QtGui.QCursor.pos() + self.idletime = 0 + self.connect(self.idletimer, QtCore.SIGNAL('timeout()'), + self, QtCore.SLOT('checkIdle()')) + self.idletimer.start(1000) + if not self.config.defaultprofile(): self.changeProfile() self.loadingscreen = LoadingScreen(self) @@ -800,6 +810,7 @@ class PesterWindow(MovingWindow): def newMessage(self, handle, msg): if handle in self.config.getBlocklist(): #yeah suck on this + self.sendMessage.emit("PESTERCHUM:BLOCKED", handle) return if not self.convos.has_key(handle): if msg == "PESTERCHUM:CEASE": # ignore cease after we hang up @@ -817,7 +828,10 @@ class PesterWindow(MovingWindow): convo.addMessage(msg, False) # play sound here if self.config.soundOn(): - self.alarm.play() + if msg in ["PESTERCHUM:CEASE", "PESTERCHUM:BLOCK"]: + self.ceasesound.play() + else: + self.alarm.play() def newMemoMsg(self, chan, handle, msg): if not self.memos.has_key(chan): # silently ignore in case we forgot to /part @@ -1016,8 +1030,10 @@ class PesterWindow(MovingWindow): # sounds if not pygame.mixer: self.alarm = NoneSound() + self.ceasesound = NoneSound() else: self.alarm = pygame.mixer.Sound(theme["main/sounds/alertsound"]) + self.ceasesound = pygame.mixer.Sound(theme["main/sounds/ceasesound"]) def changeTheme(self, theme): self.theme = theme @@ -1247,6 +1263,32 @@ class PesterWindow(MovingWindow): self.moodRequest.emit(chum) self.unblockedChum.emit(handle) + @QtCore.pyqtSlot(bool) + def toggleIdle(self, idle): + if self.idle and not idle: + self.idle = False + elif idle and not self.idle: + self.idle = True + sysColor = QtGui.QColor(self.theme["convo/systemMsgColor"]) + verb = self.theme["convo/text/idle"] + for (h, convo) in self.convos.iteritems(): + msg = self.profile().idlemsg(sysColor, verb) + convo.textArea.append(convertTags(msg)) + self.chatlog.log(h, convertTags(msg, "bbcode")) + self.sendMessage.emit("PESTERCHUM:IDLE", h) + + @QtCore.pyqtSlot() + def checkIdle(self): + newpos = QtGui.QCursor.pos() + if newpos == self.idleposition: + self.idletime += 1 + else: + self.idletime = 0 + if self.idletime >= self.idlethreshold: + self.toggleIdle(True) + else: + self.toggleIdle(False) + self.idleposition = newpos @QtCore.pyqtSlot() def importExternalConfig(self): f = QtGui.QFileDialog.getOpenFileName(self) @@ -1695,7 +1737,6 @@ class MainProgram(QtCore.QObject): irc, QtCore.SLOT('setChannelMode(QString, QString, QString)')) - # IRC --> Main window irc.connect(irc, QtCore.SIGNAL('connected()'), widget, QtCore.SLOT('connected()')) @@ -1752,6 +1793,9 @@ class MainProgram(QtCore.QObject): def run(self): self.ircapp.start() + self.widget.loadingscreen = LoadingScreen(self.widget) + self.connect(self.widget.loadingscreen, QtCore.SIGNAL('rejected()'), + self.widget, QtCore.SLOT('close()')) status = self.widget.loadingscreen.exec_() if status == QtGui.QDialog.Rejected: sys.exit(0) diff --git a/themes/pesterchum/cease.wav b/themes/pesterchum/cease.wav new file mode 100644 index 0000000..4169e12 Binary files /dev/null and b/themes/pesterchum/cease.wav differ diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index 90f3029..7fe812d 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -15,12 +15,14 @@ "selected": "background-color: #ffff00", "loc": [10,0] }, - "sounds": { "alertsound": "$path/alarm.wav" }, + "sounds": { "alertsound": "$path/alarm.wav", + "ceasesound": "$path/cease.wav" }, "menus": {"client": {"_name": "CLIENT", "options": "OPTIONS", "memos": "MEMOS", "userlist": "USERLIST", "import": "IMPORT", + "idle": "IDLE", "exit": "EXIT"}, "profile": {"_name": "PROFILE", "switch": "SWITCH", @@ -220,10 +222,12 @@ "ceasepester": "ceased pestering", "blocked": "blocked", "unblocked": "unblocked", + "blockedmsg": "did not receive message from", "openmemo": "opened memo on board", "joinmemo": "responded to memo", "closememo": "ceased responding to memo", - "kickedmemo": "You have been banned from this memo!" + "kickedmemo": "You have been banned from this memo!", + "idle": "is now an idle chum!" }, "systemMsgColor": "#646464" }, diff --git a/themes/trollian/cease.wav b/themes/trollian/cease.wav new file mode 100644 index 0000000..4169e12 Binary files /dev/null and b/themes/trollian/cease.wav differ diff --git a/themes/trollian/style.js b/themes/trollian/style.js index 0affc98..c878188 100644 --- a/themes/trollian/style.js +++ b/themes/trollian/style.js @@ -21,6 +21,7 @@ "memos": "Memos", "userlist": "Fresh Targets", "import": "import U2;", + "idle":, "Idle", "exit": "Abscond"}, "profile": {"_name": "View", "switch": "Trolltag",