diff --git a/TODO.mkdn b/TODO.mkdn index 088dc56..ed61864 100644 --- a/TODO.mkdn +++ b/TODO.mkdn @@ -10,13 +10,14 @@ Features * Spy mode * Turn @ and # links on/off? * "Someone has friended you" notifier -* Show true bans? +* Show true bans? COMPRESS QUIT MESSAGES ON BAN * Colour saving boxes things? * Whowas for last seen online? * Tab completion of two letter names * When 'banned' make impossible to connect using timestamp banned under * Fully working Toasts * Auto download/install updates via Windows installer +* Turn memo notifications on/off from right-click menu on memos (Idea: lostGash) Bugs ---- diff --git a/menus.py b/menus.py index 84a62a5..a13c953 100644 --- a/menus.py +++ b/menus.py @@ -1169,6 +1169,25 @@ class PesterOptions(QtGui.QDialog): if self.config.blink() & self.config.MBLINK: self.memoBlink.setChecked(True) + self.notifycheck = QtGui.QCheckBox("Toast Notifications", self) + if self.config.notify(): + self.notifycheck.setChecked(True) + self.connect(self.notifycheck, QtCore.SIGNAL('stateChanged(int)'), + self, QtCore.SLOT('notifyChange(int)')) + self.notifyOptions = QtGui.QComboBox(self) + types = self.parent().tm.avaliableTypes() + cur = self.parent().tm.currentType() + self.notifyOptions.addItems(types) + for (i,t) in enumerate(types): + if t == cur: + self.notifyOptions.setCurrentIndex(i) + break + self.notifyTypeLabel = QtGui.QLabel("Type", self) + layout_type = QtGui.QHBoxLayout() + layout_type.addWidget(self.notifyTypeLabel) + layout_type.addWidget(self.notifyOptions) + self.notifyChange(self.notifycheck.checkState()) + if parent.advanced: self.modechange = QtGui.QLineEdit(self) layout_change = QtGui.QHBoxLayout() @@ -1226,6 +1245,13 @@ class PesterOptions(QtGui.QDialog): layout_interface.addLayout(layout_close) layout_interface.addWidget(self.pesterBlink) layout_interface.addWidget(self.memoBlink) + layout_interface.addSpacing(16) + layout_interface.addWidget(QtGui.QLabel("NOT FULLY COMPLETE YET:")) + layout_interface.addWidget(self.notifycheck) + layout_indent = QtGui.QVBoxLayout() + layout_indent.addLayout(layout_type) + layout_indent.setContentsMargins(22,0,0,0) + layout_interface.addLayout(layout_indent) self.pages.addWidget(widget) # Sound @@ -1303,6 +1329,16 @@ class PesterOptions(QtGui.QDialog): # What is this, I don't even. qt, fuck page = -page - 2 self.pages.setCurrentIndex(page) + + @QtCore.pyqtSlot(int) + def notifyChange(self, state): + if state == 0: + self.notifyTypeLabel.setEnabled(False) + self.notifyOptions.setEnabled(False) + else: + self.notifyTypeLabel.setEnabled(True) + self.notifyOptions.setEnabled(True) + @QtCore.pyqtSlot(int) def soundChange(self, state): if state == 0: diff --git a/pesterchum.py b/pesterchum.py index a1e6e7f..e12db02 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -76,6 +76,7 @@ from bugreport import BugReporter from randomer import RandomHandler from updatecheck import MSPAChecker from toast import PesterToastMachine, PesterToast +from libs import pytwmn canon_handles = ["apocalypseArisen", "arsenicCatnip", "arachnidsGrip", "adiosToreador", \ "caligulasAquarium", "cuttlefishCuller", "carcinoGeneticist", "centaursTesticle", \ @@ -430,6 +431,10 @@ class userConfig(object): return self.config.get('mspa', False) def blink(self): return self.config.get('blink', self.PBLINK | self.MBLINK) + def notify(self): + return self.config.get('notify', True) + def notifyType(self): + return self.config.get('notifyType', "default") def addChum(self, chum): if chum.handle not in self.chums(): fp = open(self.filename) # what if we have two clients open?? @@ -1591,7 +1596,8 @@ class PesterWindow(MovingWindow): themeWarning.exec_() self.theme = pesterTheme("pesterchum") - self.tm = PesterToastMachine(self, lambda: self.theme["main/windowtitle"], "default", extras={'pester': PesterToast}) + self.tm = PesterToastMachine(self, lambda: self.theme["main/windowtitle"], on=self.config.notify(), + type=self.config.notifyType(), extras={'pester': PesterToast, 'twmn': pytwmn.Notification}) self.tm.run() t = self.tm.Toast(self.tm.appName, "!!---Started up ToastMachine---!!") t.show() @@ -2869,6 +2875,9 @@ class PesterWindow(MovingWindow): curblink = self.config.blink() if blinksetting != curblink: self.config.set('blink', blinksetting) + # toast notifications + self.tm.setEnabled(self.optionmenu.notifycheck.isChecked()) + self.tm.setCurrentType(str(self.optionmenu.notifyOptions.currentText())) # advanced ## user mode if self.advanced: diff --git a/toast.py b/toast.py index 1e342c4..71b2347 100644 --- a/toast.py +++ b/toast.py @@ -18,9 +18,8 @@ class DefaultToast(object): class ToastMachine(object): class __Toast__(object): - def __init__(self, parent, window, title, msg, time=3000, icon="", importance=0): - self.parent = parent - self.mainwindow = window + def __init__(self, machine, title, msg, time=3000, icon="", importance=0): + self.machine = machine self.title = title self.msg = msg self.time = time @@ -49,16 +48,20 @@ class ToastMachine(object): else: return self.importance def show(self): - # Use libnotify's queue if using libnotify - if self.parent.toasts and self.parent.type != "libnotify": - self.parent.toasts.append(self) - else: - self.realShow() + if self.machine.on: + # Use libnotify's queue if using libnotify + if self.machine.type == "libnotify" or self.machine.type == "twmn": + self.realShow() + elif self.machine.toasts: + self.machine.toasts.append(self) + else: + self.machine.toasts.append(self) + self.realShow() def realShow(self): t = None - for (k,v) in self.parent.types.iteritems(): - if self.parent.type == k: + for (k,v) in self.machine.types.iteritems(): + if self.machine.type == k: t = v(self.title, self.msg, self.icon) # Use libnotify's urgency setting if k == "libnotify": @@ -70,43 +73,65 @@ class ToastMachine(object): t.set_urgency(pynotify.URGENCY_LOW) break if not t: - if 'default' in self.parent.types: - if 'parent' in inspect.getargspec(self.parent.types['default']).args: - t = self.parent.types['default'](self.title, self.msg, self.icon, self.mainwindow) + if 'default' in self.machine.types: + if 'parent' in inspect.getargspec(self.machine.types['default']).args: + t = self.machine.types['default'](self.title, self.msg, self.icon, self.machine.parent) else: - t = self.parent.types['default'](self.title, self.msg, self.icon) + t = self.machine.types['default'](self.title, self.msg, self.icon) else: t = DefaultToast(self.title, self.msg, self.icon) t.show() print "SLEEPING" #time.sleep(self.time/1000) - if self in self.parent.toasts: - self.parent.toasts.remove(self) + if self in self.machine.toasts: + self.machine.toasts.remove(self) - def __init__(self, parent, name, type="default", types=({'default' : DefaultToast, - 'libnotify': pynotify.Notification} - if pynotify else - {'default' : DefaultToast}), - extras={}): - self.mainwindow = parent + def __init__(self, parent, name, on=True, type="default", + types=({'default' : DefaultToast, + 'libnotify': pynotify.Notification} + if pynotify else + {'default' : DefaultToast}), + extras={}): + self.parent = parent self.name = name + self.on = on types.update(extras) self.types = types - self.type = type + self.type = "default" self.quit = False - if type == "libnotify": - try: - if not pynotify or not pynotify.init("ToastMachine"): - raise Exception - except: - print "Problem initilizing pynotify" - self.type = type = "default" + self.setCurrentType(type) self.toasts = [] def Toast(self, title, msg, icon=""): - return self.__Toast__(self, self.mainwindow, title, msg, time=0, icon=icon) + return self.__Toast__(self, title, msg, time=0, icon=icon) + + def setEnabled(self, on): + self.on = (on is True) + + def currentType(self): + return self.type + + def avaliableTypes(self): + return sorted(self.types.keys()) + + def setCurrentType(self, type): + if type in self.types: + if type == "libnotify": + if not pynotify or not pynotify.init("ToastMachine"): + print "Problem initilizing pynotify" + return + #self.type = type = "default" + elif type == "twmn": + from libs import pytwmn + try: + pytwmn.init() + except pytwmn.ERROR,e: + print "Problem initilizing pytwmn: " + str(e) + return + #self.type = type = "default" + self.type = type def appName(self): if inspect.ismethod(self.name) or inspect.isfunction(self.name): @@ -134,7 +159,7 @@ class ToastMachine(object): def run(self): while not self.quit: - if self.toasts: + if self.on and self.toasts: self.showNext() @@ -174,21 +199,39 @@ class PesterToast(QtGui.QFrame, DefaultToast): #~ themeWarning.exec_() class PesterToastMachine(ToastMachine, QtCore.QObject): - def __init__(self, parent, name, type="default", + def __init__(self, parent, name, on=True, type="default", types=({'default' : DefaultToast, 'libnotify' : pynotify.Notification} if pynotify else {'default' : DefaultToast}), extras={}): - ToastMachine.__init__(self, parent, name, type, types, extras) + ToastMachine.__init__(self, parent, name, on, type, types, extras) QtCore.QObject.__init__(self, parent) + def setEnabled(self, on): + oldon = self.on + ToastMachine.setEnabled(self, on) + if oldon != self.on: + self.parent.config.set('notify', self.on) + if self.on: + self.timer.start() + else: + self.timer.stop() + + def setCurrentType(self, type): + oldtype = self.type + ToastMachine.setCurrentType(self, type) + if oldtype != self.type: + self.parent.config.set('notifyType', self.type) + @QtCore.pyqtSlot() def showNext(self): ToastMachine.showNext(self) def run(self): self.timer = QtCore.QTimer(self) + self.timer.setInterval(1000) self.connect(self.timer, QtCore.SIGNAL('timeout()'), self, QtCore.SLOT('showNext()')) - #self.timer.start(1000) + if self.on: + pass#self.timer.start()