diff --git a/.gitignore b/.gitignore index 4cf8dd1..0ccc61f 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,2 @@ -logs/* \ No newline at end of file +logs/* +build/* \ No newline at end of file diff --git a/TODO b/TODO index f3e1ae1..44efa4f 100644 --- a/TODO +++ b/TODO @@ -1,46 +1,33 @@ Features: -* dropped messages when chatting -* X closes to tray -* color text is not being translated to server? +* comment history (up button) +* page up/down scrolling +* System tray menu +* troll colors +* ctrl-tab should prefer new convos +* Idling +* More complex quirks: random, spelling, by-sound +* change profile only once we have confirmation from server * convo backgrounds -- make them more like http://www.mspaintadventures.com/storyfiles/hs2/02546_2.gif -* make other ppl ops -* turn off sound option!! * help button on quirks menu? * help menu -- about and forum +* dropped messages when chatting ? -- release alpha * scroll bar style? * User commands/stop user from sending commands accidentally * shared buddy lists - changes to the buddy list should refresh it? multiple clients share buddy list??? -* System tray menu * new sound on CEASE and BEGIN? -* comment history (up button) -* page up/down scrolling -* get rid of border on chat window? -* Idling -* ctrl-tab should prefer new convos -* More complex quirks: random, spelling, by-sound -* Implement TC options * chumList not scaling -- QListView + delegate? * spell check? * Help menu -* change profile only once we have confirmation from server -- release beta * log viewer * pick your own icon * time codes -* theme elements define, implement * Theme checking * don't clear new message when clicking away from tab? * Spy mode * Animated * put code into separate files * hide offline chums -* chum list groups - - - --- MEMOS: -list has "CREATE" CACNCEL JOIN buttons -no "--" for sys mesg - +* chum list groups \ No newline at end of file diff --git a/convo.py b/convo.py index aa541a7..9bfbbe2 100644 --- a/convo.py +++ b/convo.py @@ -343,6 +343,7 @@ class PesterConvo(QtGui.QFrame): self.textArea.append(convertTags(msg)) self.mainwindow.chatlog.log(self.title(), convertTags(msg, "bbcode")) self.newmessage = False + self.history = [] def title(self): return self.chum.handle @@ -448,21 +449,21 @@ class PesterConvo(QtGui.QFrame): @QtCore.pyqtSlot() def sentMessage(self): - text = self.textInput.text() + text = unicode(self.textInput.text()) if text == "": return # deal with quirks here if self.applyquirks: - qtext = self.mainwindow.userprofile.quirks.apply(unicode(text)) - text = QtCore.QString(qtext) - self.textInput.setText("") + qtext = self.mainwindow.userprofile.quirks.apply(text) + text = qtext self.addMessage(text, True) # if ceased, rebegin if hasattr(self, 'chumopen') and not self.chumopen: self.mainwindow.newConvoStarted.emit(QtCore.QString(self.title()), True) # convert color tags - text = convertTags(unicode(text), "ctag") + text = convertTags(text, "ctag") self.messageSent.emit(text, self.title()) + self.textInput.setText("") @QtCore.pyqtSlot() def addThisChum(self): diff --git a/convo.pyc b/convo.pyc index f1930fc..e375bcf 100644 Binary files a/convo.pyc and b/convo.pyc differ diff --git a/irc.py b/irc.py index 70b7b6d..93f7a49 100644 --- a/irc.py +++ b/irc.py @@ -229,6 +229,8 @@ class PesterHandler(DefaultCommandHandler): self.parent.userPresentUpdate.emit(handle, channel, "join") if channel == "#pesterchum": self.parent.moodUpdated.emit(handle, Mood("chummy")) + def mode(self, op, channel, mode, handle=""): + self.parent.userPresentUpdate.emit(handle, channel, mode) def nick(self, oldnick, newnick): oldhandle = oldnick[0:oldnick.find("!")] newchum = PesterProfile(newnick, chumdb=self.mainwindow.chumdb) diff --git a/irc.pyc b/irc.pyc index 3bc3deb..e4a65a5 100644 Binary files a/irc.pyc and b/irc.pyc differ diff --git a/logs/chums.js b/logs/chums.js index 4c68cba..48e3171 100644 --- a/logs/chums.js +++ b/logs/chums.js @@ -1 +1 @@ -{"macruralAlchemist": {"color": "#700000", "handle": "macruralAlchemist", "mood": "offline"}, "lyricalKeraunoscopic": {"color": "#00c000", "handle": "lyricalKeraunoscopic", "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"}, "greyscalePacifist": {"color": "#7f7f7f", "handle": "greyscalePacifist", "mood": "offline"}, "caffeinatedAnalyst": {"color": "#aa0000", "handle": "caffeinatedAnalyst", "mood": "offline"}, "iw": {"color": "#ff0000", "handle": "iw", "mood": "offline"}, "insipidTranscient": {"color": "#104e68", "handle": "insipidTranscient", "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"}, "DocScratch": {"color": "#ffffff", "handle": "DocScratch", "mood": "offline"}, "apocalypseArisen": {"color": "#a10000", "handle": "apocalypseArisen", "mood": "offline"}, "radicalApologist": {"color": "#ffaa00", "handle": "radicalApologist", "mood": "offline"}, "microMachines": {"color": "#aa00ff", "handle": "microMachines", "mood": "offline"}, "arachnidsGrip": {"color": "#005682", "handle": "arachnidsGrip", "mood": "offline"}, "illuminatedWax": {"color": "#ffff00", "handle": "illuminatedWax", "mood": "offline"}, "tentacleTherapist": {"color": "#cc66ff", "handle": "tentacleTherapist", "mood": "offline"}, "gamblingGenocider": {"color": "#00ff00", "handle": "gamblingGenocider", "mood": "offline"}, "elegantDiversion": {"color": "#14b40a", "handle": "elegantDiversion", "mood": "offline"}, "madLurker": {"color": "#000000", "handle": "madLurker", "mood": "offline"}, "testOut": {"color": "#c760cc", "handle": "testOut", "mood": "offline"}, "androidTechnician": {"color": "#0000ff", "handle": "androidTechnician", "mood": "offline"}, "recalcitrantDisaster": {"color": "#8b0068", "handle": "recalcitrantDisaster", "mood": "offline"}, "superGhost": {"color": "#800564", "handle": "superGhost", "mood": "offline"}, "arsenicCatnip": {"color": "#006400", "handle": "arsenicCatnip", "mood": "offline"}, "aquaticMarinist": {"color": "#00caca", "handle": "aquaticMarinist", "mood": "offline"}, "captainCaveman": {"color": "#7c414e", "handle": "captainCaveman", "mood": "offline"}, "cuttlefishCuller": {"color": "#77003c", "handle": "cuttlefishCuller", "mood": "offline"}, "carcinoGeneticist": {"color": "#999999", "handle": "carcinoGeneticist", "mood": "offline"}, "masterG": {"color": "#77003c", "handle": "masterG", "mood": "offline"}, "plasmaModerator": {"color": "#5685cc", "handle": "plasmaModerator", "mood": "offline"}, "carcinoGenetecist": {"color": "#7f7f7f", "handle": "carcinoGenetecist", "mood": "offline"}, "remoteBloodbath": {"color": "#c70000", "handle": "remoteBloodbath", "mood": "offline"}, "moirailBunp": {"color": "#6a3d0f", "handle": "moirailBunp", "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"}, "maxiumumFatness": {"color": "#3366ff", "handle": "maxiumumFatness", "mood": "offline"}, "schlagzeugGator": {"color": "#61821f", "handle": "schlagzeugGator", "mood": "offline"}, "metaliAggressive": {"color": "#9289d5", "handle": "metaliAggressive", "mood": "offline"}, "midnightSparrow": {"color": "#ff55ff", "handle": "midnightSparrow", "mood": "offline"}, "magmaExploiter": {"color": "#d90000", "handle": "magmaExploiter", "mood": "offline"}, "zealousScarecrow": {"color": "#00c882", "handle": "zealousScarecrow", "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 +{"macruralAlchemist": {"color": "#700000", "handle": "macruralAlchemist", "mood": "offline"}, "lyricalKeraunoscopic": {"color": "#00c000", "handle": "lyricalKeraunoscopic", "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"}, "greyscalePacifist": {"color": "#7f7f7f", "handle": "greyscalePacifist", "mood": "offline"}, "caffeinatedAnalyst": {"color": "#aa0000", "handle": "caffeinatedAnalyst", "mood": "offline"}, "iw": {"color": "#ff0000", "handle": "iw", "mood": "offline"}, "insipidTranscient": {"color": "#104e68", "handle": "insipidTranscient", "mood": "offline"}, "pesterClient394": {"color": "#ff3737", "handle": "pesterClient394", "mood": "offline"}, "absoluteTranquility": {"color": "#000033", "handle": "absoluteTranquility", "mood": "offline"}, "centaursTesticle": {"color": "#000056", "handle": "centaursTesticle", "mood": "offline"}, "quintessentialArbalest": {"color": "#999999", "handle": "quintessentialArbalest", "mood": "offline"}, "agogPorphyry": {"color": "#522d80", "handle": "agogPorphyry", "mood": "offline"}, "DocScratch": {"color": "#ffffff", "handle": "DocScratch", "mood": "offline"}, "anguillaNuntia": {"color": "#ff007f", "handle": "anguillaNuntia", "mood": "offline"}, "aceIsm": {"color": "#ffcc66", "handle": "aceIsm", "mood": "offline"}, "apocalypseArisen": {"color": "#a10000", "handle": "apocalypseArisen", "mood": "offline"}, "radicalApologist": {"color": "#ffaa00", "handle": "radicalApologist", "mood": "offline"}, "microMachines": {"color": "#aa00ff", "handle": "microMachines", "mood": "offline"}, "uroborosUnbound": {"color": "#00416a", "handle": "uroborosUnbound", "mood": "offline"}, "arachnidsGrip": {"color": "#005682", "handle": "arachnidsGrip", "mood": "offline"}, "percipientPedestrian": {"color": "#00ffff", "handle": "percipientPedestrian", "mood": "offline"}, "tentacleTherapist": {"color": "#cc66ff", "handle": "tentacleTherapist", "mood": "offline"}, "gamblingGenocider": {"color": "#00ff00", "handle": "gamblingGenocider", "mood": "offline"}, "elegantDiversion": {"color": "#14b40a", "handle": "elegantDiversion", "mood": "offline"}, "moirailBunp": {"color": "#6a3d0f", "handle": "moirailBunp", "mood": "offline"}, "madLurker": {"color": "#000000", "handle": "madLurker", "mood": "offline"}, "testOut": {"color": "#c760cc", "handle": "testOut", "mood": "offline"}, "pesterClient3022": {"color": "#336600", "handle": "pesterClient3022", "mood": "offline"}, "hellerificJefferson": {"color": "#3300ff", "handle": "hellerificJefferson", "mood": "offline"}, "androidTechnician": {"color": "#0000ff", "handle": "androidTechnician", "mood": "offline"}, "recalcitrantDisaster": {"color": "#8b0068", "handle": "recalcitrantDisaster", "mood": "offline"}, "superGhost": {"color": "#800564", "handle": "superGhost", "mood": "offline"}, "arsenicCatnip": {"color": "#006400", "handle": "arsenicCatnip", "mood": "offline"}, "kaleidoscopicMind": {"color": "#ff6666", "handle": "kaleidoscopicMind", "mood": "offline"}, "aquaticMarinist": {"color": "#00caca", "handle": "aquaticMarinist", "mood": "offline"}, "captainCaveman": {"color": "#7c414e", "handle": "captainCaveman", "mood": "offline"}, "cuttlefishCuller": {"color": "#77003c", "handle": "cuttlefishCuller", "mood": "offline"}, "carcinoGeneticist": {"color": "#999999", "handle": "carcinoGeneticist", "mood": "offline"}, "masterG": {"color": "#77003c", "handle": "masterG", "mood": "offline"}, "plasmaModerator": {"color": "#5685cc", "handle": "plasmaModerator", "mood": "offline"}, "carcinoGenetecist": {"color": "#7f7f7f", "handle": "carcinoGenetecist", "mood": "offline"}, "remoteBloodbath": {"color": "#c70000", "handle": "remoteBloodbath", "mood": "offline"}, "oilslickOrchid": {"color": "#743f7e", "handle": "oilslickOrchid", "mood": "offline"}, "acapellaWaterfall": {"color": "#000099", "handle": "acapellaWaterfall", "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"}, "maxiumumFatness": {"color": "#3366ff", "handle": "maxiumumFatness", "mood": "offline"}, "schlagzeugGator": {"color": "#61821f", "handle": "schlagzeugGator", "mood": "offline"}, "metaliAggressive": {"color": "#9289d5", "handle": "metaliAggressive", "mood": "offline"}, "midnightSparrow": {"color": "#ff55ff", "handle": "midnightSparrow", "mood": "offline"}, "magmaExploiter": {"color": "#d90000", "handle": "magmaExploiter", "mood": "offline"}, "zealousScarecrow": {"color": "#00c882", "handle": "zealousScarecrow", "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 e417e77..7ca4036 100644 --- a/memos.py +++ b/memos.py @@ -243,6 +243,9 @@ class MemoText(PesterText): if chum is not me: if parent.times.has_key(chum.handle): time = parent.times[chum.handle] + if not time.getTime(): + # MY WAY OR THE HIGHWAY + time.addTime(timedelta(0)) else: # new chum! time current newtime = timedelta(0) @@ -309,8 +312,11 @@ class PesterMemo(PesterConvo): self.banuserAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/banuser"], self) self.connect(self.banuserAction, QtCore.SIGNAL('triggered()'), self, QtCore.SLOT('banSelectedUser()')) + self.opAction = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/opuser"], self) + self.connect(self.opAction, QtCore.SIGNAL('triggered()'), + self, QtCore.SLOT('opSelectedUser()')) self.userlist.optionsMenu.addAction(self.addchumAction) - # ban list added if we are op + # ban & op list added if we are op self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self) self.timeinput = TimeInput(self.timeslider, self) @@ -424,10 +430,12 @@ class PesterMemo(PesterConvo): self.channelLabel.setMaximumHeight(theme["memos/label/maxheight"]) self.channelLabel.setMinimumHeight(theme["memos/label/minheight"]) + self.userlist.optionsMenu.setStyleSheet(theme["main/defaultwindow/style"]) self.userlist.setStyleSheet(theme["memos/userlist/style"]) self.userlist.setFixedWidth(theme["memos/userlist/width"]) self.addchumAction.setText(theme["main/menus/rclickchumlist/addchum"]) self.banuserAction.setText(theme["main/menus/rclickchumlist/banuser"]) + self.opAction.setText(theme["main/menus/rclickchumlist/opuser"]) self.timeinput.setFixedWidth(theme["memos/time/text/width"]) self.timeinput.setStyleSheet(theme["memos/time/text/style"]) @@ -454,6 +462,10 @@ class PesterMemo(PesterConvo): margins = theme["memos/margins"] self.layout.setContentsMargins(margins["left"], margins["top"], margins["right"], margins["bottom"]) + for item in [self.userlist.row(i) for i in range(0,self.userlist.count())]: + if item.op: + icon = PesterIcon(self.mainwindow.theme["memos/op/icon"]) + item.setIcon(icon) def addUser(self, handle): chumdb = self.mainwindow.chumdb @@ -463,6 +475,7 @@ class PesterMemo(PesterConvo): op = True handle = handle[1:] if handle == self.mainwindow.profile().handle: + self.userlist.optionsMenu.addAction(self.opAction) self.userlist.optionsMenu.addAction(self.banuserAction) self.op = True item = QtGui.QListWidgetItem(handle) @@ -471,6 +484,10 @@ class PesterMemo(PesterConvo): else: color = chumdb.getColor(handle, defaultcolor) item.setTextColor(color) + item.op = op + if op: + icon = PesterIcon(self.mainwindow.theme["memos/op/icon"]) + item.setIcon(icon) self.userlist.addItem(item) def timeUpdate(self, handle, cmd): @@ -561,7 +578,8 @@ class PesterMemo(PesterConvo): oldnick = l[0] newnick = l[1] h = oldnick - if (update in ["join","left", "kick"]) and channel != self.channel: + if (update in ["join","left", "kick", "+o"]) \ + and channel != self.channel: return chums = self.userlist.findItems(h, QtCore.Qt.MatchFlags(0)) systemColor = QtGui.QColor(self.mainwindow.theme["memos/systemMsgColor"]) @@ -639,6 +657,14 @@ class PesterMemo(PesterConvo): time = self.time.getTime() serverText = "PESTERCHUM:TIME>"+delta2txt(time, "server") self.messageSent.emit(serverText, self.title()) + elif update == "+o": + chums = self.userlist.findItems(h, QtCore.Qt.MatchFlags(0)) + for c in chums: + icon = PesterIcon(self.mainwindow.theme["memos/op/icon"]) + c.setIcon(icon) + if unicode(c.text()) == self.mainwindow.profile().handle: + self.userlist.optionsMenu.addAction(self.opAction) + self.userlist.optionsMenu.addAction(self.banuserAction) @QtCore.pyqtSlot() def addChumSlot(self): @@ -652,6 +678,12 @@ class PesterMemo(PesterConvo): return currentHandle = unicode(self.userlist.currentItem().text()) self.mainwindow.kickUser.emit(currentHandle, self.channel) + @QtCore.pyqtSlot() + def opSelectedUser(self): + if not self.userlist.currentItem(): + return + currentHandle = unicode(self.userlist.currentItem().text()) + self.mainwindow.setChannelMode.emit(self.channel, "+o", currentHandle) def resetSlider(self, time, send=True): self.timeinput.setText(delta2txt(time)) self.timeinput.setSlider() diff --git a/memos.pyc b/memos.pyc index 0ba617b..1b0b798 100644 Binary files a/memos.pyc and b/memos.pyc differ diff --git a/menus.py b/menus.py index 25ab2c4..765babd 100644 --- a/menus.py +++ b/menus.py @@ -280,14 +280,13 @@ class PesterOptions(QtGui.QDialog): self.theme = theme self.setStyleSheet(self.theme["main/defaultwindow/style"]) - self.tabcheck = QtGui.QCheckBox(self) + self.tabcheck = QtGui.QCheckBox("Tabbed Conversations", self) if self.config.tabs(): self.tabcheck.setChecked(True) - self.tablabel = QtGui.QLabel("Tabbed Conversations", self) - layout_1 = QtGui.QHBoxLayout() - layout_1.addWidget(self.tablabel) - layout_1.addWidget(self.tabcheck) - + + self.soundcheck = QtGui.QCheckBox("Sounds On", self) + if self.config.soundOn(): + self.soundcheck.setChecked(True) self.ok = QtGui.QPushButton("OK", self) self.ok.setDefault(True) self.connect(self.ok, QtCore.SIGNAL('clicked()'), @@ -300,7 +299,8 @@ class PesterOptions(QtGui.QDialog): layout_2.addWidget(self.ok) layout_0 = QtGui.QVBoxLayout() - layout_0.addLayout(layout_1) + layout_0.addWidget(self.tabcheck) + layout_0.addWidget(self.soundcheck) layout_0.addLayout(layout_2) self.setLayout(layout_0) @@ -410,7 +410,7 @@ class PesterMemoList(QtGui.QDialog): self.orjoinlabel = QtGui.QLabel("OR MAKE A NEW MEMO:") self.newmemo = QtGui.QLineEdit(channel, self) - self.secretChannel = QtGui.QCheckBox("HIDDEN?", self) + self.secretChannel = QtGui.QCheckBox("HIDDEN CHANNEL?", self) self.timelabel = QtGui.QLabel("TIMEFRAME:") self.timeslider = TimeSlider(QtCore.Qt.Horizontal, self) diff --git a/menus.pyc b/menus.pyc index a149307..7cad1d7 100644 Binary files a/menus.pyc and b/menus.pyc differ diff --git a/parsetools.py b/parsetools.py index b52f567..abacaa1 100644 --- a/parsetools.py +++ b/parsetools.py @@ -43,6 +43,9 @@ def convertTags(string, format="html"): string = _urlre.sub(urlrep, string) if format == "html": string = _memore.sub(r" \1", string) + string = string.replace(" :trollcool:", " " % ("themes/pesterchum/trollcool.gif")) # ugh hardcoded, gross i know. but its just 1 smiley + elif format == "bbcode": + string = string.replace(" :trollcool:", " [img]http://www.mspaintadventures.com/storyfiles/hs2/scraps/trollcool.gif[/img]") return string def escapeBrackets(string): diff --git a/parsetools.pyc b/parsetools.pyc index a872cfc..bb5bc72 100644 Binary files a/parsetools.pyc and b/parsetools.pyc differ diff --git a/pesterchum.ico b/pesterchum.ico new file mode 100644 index 0000000..5b8fa1c Binary files /dev/null and b/pesterchum.ico differ diff --git a/pesterchum.js b/pesterchum.js index 3f6e37c..23ae945 100644 --- a/pesterchum.js +++ b/pesterchum.js @@ -1 +1 @@ -{"tabs": false, "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"], "defaultprofile": "testProfile", "block": []} \ No newline at end of file +{"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"], "defaultprofile": "testProfile", "block": []} \ No newline at end of file diff --git a/pesterchum.py b/pesterchum.py index 4b236a1..cebee54 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -6,6 +6,7 @@ from datetime import * from string import Template import random import json +import codecs import re import socket from PyQt4 import QtGui, QtCore @@ -61,7 +62,7 @@ class PesterLog(object): 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') + fp = codecs.open("logs/%s/%s/%s.%s" % (self.handle, handle, handle, time), encoding='utf-8', mode='a') self.convos[handle] = fp self.convos[handle].write(msg+"\n") self.convos[handle].flush() @@ -115,11 +116,18 @@ class pesterTheme(dict): theme = json.load(fp, object_hook=self.pathHook) self.update(theme) fp.close() + defaultfp = open("themes/pesterchum/style.js") # set default + defaultTheme = json.load(defaultfp, object_hook=self.pathHook) + self.defaultTheme = defaultTheme + defaultfp.close() def __getitem__(self, key): keys = key.split("/") v = dict.__getitem__(self, keys.pop(0)) for k in keys: - v = v[k] + try: + v = v[k] + except KeyError: + v = self.defaultTheme[k] return v def pathHook(self, d): for (k, v) in d.iteritems(): @@ -184,6 +192,10 @@ class userConfig(object): l = self.getBlocklist() l.pop(l.index(handle)) self.set('block', l) + def soundOn(self): + if not self.config.has_key('soundon'): + self.set('soundon', True) + return self.config['soundon'] def set(self, item, setting): self.config[item] = setting try: @@ -671,7 +683,7 @@ class PesterWindow(MovingWindow): self.closeButton = WMButton(PesterIcon(self.theme["main/close/image"]), self) self.connect(self.closeButton, QtCore.SIGNAL('clicked()'), - self, QtCore.SLOT('close()')) + self, QtCore.SLOT('closeToTray()')) self.miniButton = WMButton(PesterIcon(self.theme["main/minimize/image"]), self) self.connect(self.miniButton, QtCore.SIGNAL('clicked()'), self, QtCore.SLOT('showMinimized()')) @@ -746,6 +758,10 @@ class PesterWindow(MovingWindow): palette.setBrush(QtGui.QPalette.Window, QtGui.QBrush(self.backgroundImage)) self.setPalette(palette) + @QtCore.pyqtSlot() + def closeToTray(self): + self.hide() + self.closeToTraySignal.emit() def closeEvent(self, event): self.closeConversations() if hasattr(self, 'trollslum') and self.trollslum: @@ -770,7 +786,8 @@ class PesterWindow(MovingWindow): convo = self.convos[handle] convo.addMessage(msg, False) # play sound here - self.alarm.play() + if self.config.soundOn(): + self.alarm.play() def newMemoMsg(self, chan, handle, msg): if not self.memos.has_key(chan): # silently ignore in case we forgot to /part @@ -1001,9 +1018,11 @@ class PesterWindow(MovingWindow): if len(self.waitingMessages) == 0: if self.isMinimized(): self.showNormal() + elif self.isHidden(): + self.show() else: if self.isActiveWindow(): - self.showMinimized() + self.hide() else: self.raise_() self.activateWindow() @@ -1346,6 +1365,9 @@ class PesterWindow(MovingWindow): self.memos = newmemos # save options self.config.set("tabs", tabsetting) + # sound + soundsetting = self.optionmenu.soundcheck.isChecked() + self.config.set("soundon", soundsetting) self.optionmenu = None @QtCore.pyqtSlot() @@ -1467,6 +1489,7 @@ class PesterWindow(MovingWindow): # show context menu i guess pass + closeToTraySignal = QtCore.pyqtSignal() newConvoStarted = QtCore.pyqtSignal(QtCore.QString, bool, name="newConvoStarted") sendMessage = QtCore.pyqtSignal(QtCore.QString, QtCore.QString) convoClosed = QtCore.pyqtSignal(QtCore.QString) @@ -1542,6 +1565,10 @@ class MainProgram(QtCore.QObject): QtCore.SIGNAL('trayIconSignal(int)'), self.trayicon, QtCore.SLOT('changeTrayIcon(int)')) + self.trayicon.connect(self.widget, + QtCore.SIGNAL('closeToTraySignal()'), + self.trayicon, + QtCore.SLOT('show()')) self.irc = PesterIRC(self.widget) self.connectWidgets(self.irc, self.widget) diff --git a/setup.py b/setup.py index 3454796..b2de052 100644 --- a/setup.py +++ b/setup.py @@ -19,14 +19,14 @@ setup( )]) if sys.platform == "win32": os.rename("build/exe.win32-2.6", "build/pesterchum") + shutil.copytree("imageformats", "build/pesterchum/imageformats") + shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcm90.dll", "build/pesterchum") + shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcp90.dll", "build/pesterchum") + shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcr90.dll", "build/pesterchum") + shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375.manifest", + "build/pesterchum") shutil.copytree("themes", "build/pesterchum/themes") -shutil.copytree("imageformats", "build/pesterchum/imageformats") shutil.copy("pesterchum.js", "build/pesterchum/") -shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcm90.dll", "build/pesterchum") -shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcp90.dll", "build/pesterchum") -shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/msvcr90.dll", "build/pesterchum") -shutil.copy("C:/Dev/Py26MSdlls-9.0.21022.8/msvc/x86_Microsoft.VC90.CRT_1fc8b3b9a1e18e3b_9.0.21022.8_x-ww_d08d0375.manifest", - "build/pesterchum") os.mkdir("build/pesterchum/profiles") os.mkdir("build/pesterchum/logs") diff --git a/themes/pesterchum/op.gif b/themes/pesterchum/op.gif new file mode 100644 index 0000000..25e8ffb Binary files /dev/null and b/themes/pesterchum/op.gif differ diff --git a/themes/pesterchum/style.js b/themes/pesterchum/style.js index 171bd6c..589e99f 100644 --- a/themes/pesterchum/style.js +++ b/themes/pesterchum/style.js @@ -34,6 +34,7 @@ "addchum": "ADD CHUM", "unblockchum": "UNBLOCK", "banuser": "BAN USER", + "opuser": "MAKE OP", "quirksoff": "QUIRKS OFF" } }, @@ -84,7 +85,7 @@ "protective": { "icon": "$path/protective.gif", "color": "#00ff00" }, -"blocked": { "icon": "$path/blocked.gif", "color": "black" } + "blocked": { "icon": "$path/blocked.gif", "color": "black" } } }, @@ -259,6 +260,7 @@ "style": " border:0px; margin-top: 5px; margin-right:10px;" } }, - "systemMsgColor": "#646464" + "systemMsgColor": "#646464", + "op": { "icon": "$path/op.gif" } } } \ No newline at end of file diff --git a/themes/pesterchum/trollcool.gif b/themes/pesterchum/trollcool.gif new file mode 100644 index 0000000..25e8ffb Binary files /dev/null and b/themes/pesterchum/trollcool.gif differ diff --git a/themes/trollian/op.gif b/themes/trollian/op.gif new file mode 100644 index 0000000..25e8ffb Binary files /dev/null and b/themes/trollian/op.gif differ diff --git a/themes/trollian/style.js b/themes/trollian/style.js index 6315787..024b86d 100644 --- a/themes/trollian/style.js +++ b/themes/trollian/style.js @@ -34,6 +34,7 @@ "addchum": "Add Chump", "unblockchum": "Mercy", "banuser": "Ban", + "opuser": "Promote", "quirksoff": "Quirks Off" } }, "chums": { "style": "font-size: 12px; background: white; border:2px solid #c2c2c2; padding: 5px; font-family: 'Arial';selection-background-color:rgb(200,200,200); ", @@ -309,6 +310,7 @@ "style": "width: 19px; height: 19px; border:0px; margin-left: 2px;" } }, - "systemMsgColor": "#646464" + "systemMsgColor": "#646464", + "op": { "icon": "$path/op.gif" } } } \ No newline at end of file