diff --git a/pesterchum.py b/pesterchum.py index aeb666b..64c1277 100644 --- a/pesterchum.py +++ b/pesterchum.py @@ -79,6 +79,7 @@ from logviewer import PesterLogUserSelect, PesterLogViewer from bugreport import BugReporter from randomer import RandomHandler from updatecheck import MSPAChecker +from toast import PesterToastMachine, PesterToast canon_handles = ["apocalypseArisen", "arsenicCatnip", "arachnidsGrip", "adiosToreador", \ "caligulasAquarium", "cuttlefishCuller", "carcinoGeneticist", "centaursTesticle", \ @@ -1508,6 +1509,11 @@ class PesterWindow(MovingWindow): themeWarning.exec_() self.theme = pesterTheme("pesterchum") + self.tm = PesterToastMachine(self, lambda: self.theme["main/windowtitle"], "default", extras={'pester': PesterToast}) + self.tm.run() + t = self.tm.Toast(self.tm.appName, "!!---Started up ToastMachine---!!") + t.show() + self.chatlog = PesterLog(self.profile().handle, self) self.move(100, 100) diff --git a/toast.py b/toast.py new file mode 100644 index 0000000..98d739c --- /dev/null +++ b/toast.py @@ -0,0 +1,191 @@ +import inspect +import threading +import time +from PyQt4 import QtGui, QtCore + +try: + import pynotify + pynote = True +except: + pynote = False + +class DefaultToast(object): + def __init__(self, title, msg, icon): + self.title = title + self.msg = msg + self.icon = icon + def show(self): + print self.title, self.msg, self.icon + +class ToastMachine(object): + class __Toast__(object): + def __init__(self, parent, window, title, msg, time=3000, icon="", importance=0): + self.parent = parent + self.mainwindow = window + self.title = title + self.msg = msg + self.time = time + self.icon = icon + self.importance = importance + if inspect.ismethod(self.title) or inspect.isfunction(self.title): + self.title = self.title() + + def titleM(self, title=None): + if title: + self.title = title + if inspect.ismethod(self.title) or inspect.isfunction(self.title): + self.title = self.title() + else: return self.title + def msgM(self, msg=None): + if msg: self.msg = msg + else: return self.msg + def timeM(self, time=None): + if time: self.time = time + else: return self.time + def iconM(self, icon=None): + if icon: self.icon = icon + else: return self.icon + def importanceM(self, importance=None): + if importance != None: self.importance = importance + 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() + + def realShow(self): + t = None + for (k,v) in self.parent.types.iteritems(): + if self.parent.type == k: + t = v(self.title, self.msg, self.icon) + # Use libnotify's urgency setting + if k == "libnotify": + if self.importance < 0: + t.set_urgency(pynotify.URGENCY_CRITICAL) + elif self.importance == 0: + t.set_urgency(pynotify.URGENCY_NORMAL) + elif self.importance > 0: + 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) + else: + t = self.parent.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) + + def __init__(self, parent, name, type="default", types={'default' : DefaultToast, + 'libnotify': pynotify.Notification}, + extras={}): + self.mainwindow = parent + self.name = name + types.update(extras) + self.types = types + self.type = type + self.quit = False + + if type == "libnotify": + try: + if not pynote or not pynotify.init("ToastMachine"): + raise Exception + except: + print "Problem initilizing pynotify" + self.type = type = "default" + + self.toasts = [] + + def Toast(self, title, msg, icon=""): + return self.__Toast__(self, self.mainwindow, title, msg, time=0, icon=icon) + + def appName(self): + if inspect.ismethod(self.name) or inspect.isfunction(self.name): + return self.name() + else: + return self.name + + def showNext(self): + high = filter(lambda x: x.importance < 0, self.toasts) + normal = filter(lambda x: x.importance == 0, self.toasts) + low = filter(lambda x: x.importance > 0, self.toasts) + + if high: + high.sort(key=lambda x: x.importance) + high[0].realShow() + elif normal: + normal[0].realShow() + elif low: + low.sort(key=lambda x: x.importance) + low[0].realShow() + + def showAll(self): + while self.toasts: + self.showNext() + + def run(self): + while not self.quit: + if self.toasts: + self.showNext() + + +class PesterToast(QtGui.QFrame, DefaultToast): + def __init__(self, title, msg, icon, parent=None): + QtGui.QFrame.__init__(self, parent, + (QtCore.Qt.CustomizeWindowHint | + QtCore.Qt.FramelessWindowHint)) + #self.setAttribute(QtCore.Qt.WA_QuitOnClose, False) + #self.setAttribute(QtCore.Qt.WA_TranslucentBackground, True) + #self.setAttribute(QtCore.Qt.WA_NoSystemBackground, True) + self.setObjectName("toast") + self.setWindowTitle("toast") + #self.setFocusPolicy(QtCore.Qt.ClickFocus) + + self.title = QtGui.QLabel(title, self) + self.msg = QtGui.QLabel(msg, self) + + self.btn = QtGui.QPushButton("Push Me", self) + self.connect(self.btn, QtCore.SIGNAL('clicked()'), + self, QtCore.SLOT('close()')) + + layout_0 = QtGui.QVBoxLayout() + layout_0.addWidget(self.title) + layout_0.addWidget(self.btn) + layout_0.addWidget(self.msg) + + self.setLayout(layout_0) + + print self.isWindow() + + def show(self): + QtGui.QFrame.setVisible(self, True) + print "SHOWING" + #~ themeWarning = QtGui.QMessageBox(self) + #~ themeWarning.setText("ASDFASD") + #~ themeWarning.exec_() + +class PesterToastMachine(ToastMachine, QtCore.QObject): + def __init__(self, parent, name, type="default", + types={'default' : DefaultToast, + 'libnotify': pynotify.Notification}, + extras={}): + ToastMachine.__init__(self, parent, name, type, types, extras) + QtCore.QObject.__init__(self, parent) + + @QtCore.pyqtSlot() + def showNext(self): + ToastMachine.showNext(self) + + def run(self): + self.timer = QtCore.QTimer(self) + self.connect(self.timer, QtCore.SIGNAL('timeout()'), + self, QtCore.SLOT('showNext()')) + #self.timer.start(1000)