Added option to mute and enable highlights/beeps on a PER-MEMO/CHUM basis. It's in the right-click menu, near the OOC toggle.
This commit is contained in:
parent
3a48cf204b
commit
75e99db77e
5 changed files with 125 additions and 22 deletions
|
@ -87,6 +87,9 @@ Bugs
|
||||||
* Log folder/file names are not case-sensitive, so they break on non-Windows systems
|
* Log folder/file names are not case-sensitive, so they break on non-Windows systems
|
||||||
* Capitalized /me's don't render (should forcibly lowercase them)
|
* Capitalized /me's don't render (should forcibly lowercase them)
|
||||||
|
|
||||||
|
* Volume control doesn't work without pygame
|
||||||
|
* Sound on Linux doesn't work without pygame
|
||||||
|
|
||||||
Windows Bugs
|
Windows Bugs
|
||||||
------------
|
------------
|
||||||
* XP SP2: sometimes mouse clicks dont register? must be some kinda crash
|
* XP SP2: sometimes mouse clicks dont register? must be some kinda crash
|
||||||
|
|
91
convo.py
91
convo.py
|
@ -133,6 +133,7 @@ class PesterTabWindow(QtGui.QFrame):
|
||||||
i = self.tabIndices[handle]
|
i = self.tabIndices[handle]
|
||||||
self.tabs.setTabTextColor(i, QtGui.QColor(self.mainwindow.theme["%s/tabs/newmsgcolor" % (self.type)]))
|
self.tabs.setTabTextColor(i, QtGui.QColor(self.mainwindow.theme["%s/tabs/newmsgcolor" % (self.type)]))
|
||||||
convo = self.convos[handle]
|
convo = self.convos[handle]
|
||||||
|
# Create a function for the icon to use
|
||||||
def func():
|
def func():
|
||||||
convo.showChat()
|
convo.showChat()
|
||||||
self.mainwindow.waitingMessages.addMessage(handle, func)
|
self.mainwindow.waitingMessages.addMessage(handle, func)
|
||||||
|
@ -557,8 +558,34 @@ class PesterConvo(QtGui.QFrame):
|
||||||
self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
|
self.connect(self.logchum, QtCore.SIGNAL('triggered()'),
|
||||||
self, QtCore.SLOT('openChumLogs()'))
|
self, QtCore.SLOT('openChumLogs()'))
|
||||||
|
|
||||||
|
# For this, we'll want to use setChecked to toggle these so they match
|
||||||
|
# the user's setting. Alternately (better), use a tristate checkbox, so
|
||||||
|
# that they start semi-checked?
|
||||||
|
# Easiest solution: Implement a 'Mute' option that overrides all
|
||||||
|
# notifications for that window, save for mentions.
|
||||||
|
# TODO: Look into setting up theme support here.
|
||||||
|
self._beepToggle = QtGui.QAction("Beep on Message", self)
|
||||||
|
self._beepToggle.setCheckable(True)
|
||||||
|
self.connect(self._beepToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleBeep(bool)'))
|
||||||
|
|
||||||
|
self._flashToggle = QtGui.QAction("Flash on Message", self)
|
||||||
|
self._flashToggle.setCheckable(True)
|
||||||
|
self.connect(self._flashToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleFlash(bool)'))
|
||||||
|
|
||||||
|
self._muteToggle = QtGui.QAction("Mute Notifications", self)
|
||||||
|
self._muteToggle.setCheckable(True)
|
||||||
|
self.connect(self._muteToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleMute(bool)'))
|
||||||
|
|
||||||
self.optionsMenu.addAction(self.quirksOff)
|
self.optionsMenu.addAction(self.quirksOff)
|
||||||
self.optionsMenu.addAction(self.oocToggle)
|
self.optionsMenu.addAction(self.oocToggle)
|
||||||
|
|
||||||
|
self.optionsMenu.addAction(self._beepToggle)
|
||||||
|
self.optionsMenu.addAction(self._flashToggle)
|
||||||
|
self.optionsMenu.addAction(self._muteToggle)
|
||||||
|
|
||||||
self.optionsMenu.addAction(self.logchum)
|
self.optionsMenu.addAction(self.logchum)
|
||||||
self.optionsMenu.addAction(self.addChumAction)
|
self.optionsMenu.addAction(self.addChumAction)
|
||||||
self.optionsMenu.addAction(self.blockAction)
|
self.optionsMenu.addAction(self.blockAction)
|
||||||
|
@ -568,6 +595,10 @@ class PesterConvo(QtGui.QFrame):
|
||||||
self.applyquirks = True
|
self.applyquirks = True
|
||||||
self.ooc = False
|
self.ooc = False
|
||||||
|
|
||||||
|
self.always_beep = False
|
||||||
|
self.always_flash = False
|
||||||
|
self.notifications_muted = False
|
||||||
|
|
||||||
if parent:
|
if parent:
|
||||||
parent.addChat(self)
|
parent.addChat(self)
|
||||||
if initiated:
|
if initiated:
|
||||||
|
@ -637,30 +668,52 @@ class PesterConvo(QtGui.QFrame):
|
||||||
|
|
||||||
def notifyNewMessage(self):
|
def notifyNewMessage(self):
|
||||||
# first see if this conversation HASS the focus
|
# first see if this conversation HASS the focus
|
||||||
|
title = self.title()
|
||||||
|
parent = self.parent()
|
||||||
|
memoblink = pesterblink = self.mainwindow.config.blink()
|
||||||
|
memoblink &= self.mainwindow.config.MBLINK
|
||||||
|
pesterblink &= self.mainwindow.config.PBLINK
|
||||||
|
print "{!s}.notifications_muted: {!s}".format(self,
|
||||||
|
self.notifications_muted)
|
||||||
|
mutednots = self.notifications_muted
|
||||||
|
mtsrc = self
|
||||||
|
if parent:
|
||||||
|
try:
|
||||||
|
mutednots = parent.notifications_muted
|
||||||
|
mtsrc = parent
|
||||||
|
except:
|
||||||
|
pass
|
||||||
if not (self.hasFocus() or self.textArea.hasFocus() or
|
if not (self.hasFocus() or self.textArea.hasFocus() or
|
||||||
self.textInput.hasFocus() or
|
self.textInput.hasFocus() or
|
||||||
(self.parent() and self.parent().convoHasFocus(self.title()))):
|
(parent and parent.convoHasFocus(title))):
|
||||||
# ok if it has a tabconvo parent, send that the notify.
|
# ok if it has a tabconvo parent, send that the notify.
|
||||||
if self.parent():
|
if parent:
|
||||||
self.parent().notifyNewMessage(self.title())
|
print "{!s}.notifications_muted: {!s}".format(mtsrc,
|
||||||
if type(self.parent()).__name__ == "PesterTabWindow":
|
mutednots)
|
||||||
if self.mainwindow.config.blink() & self.mainwindow.config.PBLINK:
|
if not mutednots:
|
||||||
self.mainwindow.gainAttention.emit(self.parent())
|
# Stop the icon from highlighting
|
||||||
elif type(self.parent()).__name__ == "MemoTabWindow":
|
parent.notifyNewMessage(title)
|
||||||
if self.mainwindow.config.blink() & self.mainwindow.config.MBLINK:
|
if type(parent).__name__ == "PesterTabWindow":
|
||||||
self.mainwindow.gainAttention.emit(self.parent())
|
if self.always_flash or pesterblink:
|
||||||
|
self.mainwindow.gainAttention.emit(parent)
|
||||||
|
elif type(parent).__name__ == "MemoTabWindow":
|
||||||
|
if self.always_flash or memoblink:
|
||||||
|
self.mainwindow.gainAttention.emit(parent)
|
||||||
# if not change the window title and update system tray
|
# if not change the window title and update system tray
|
||||||
else:
|
else:
|
||||||
self.newmessage = True
|
self.newmessage = True
|
||||||
self.setWindowTitle(self.title()+"*")
|
self.setWindowTitle(title + "*")
|
||||||
|
# karxi: The order of execution here is a bit unclear...I'm not
|
||||||
|
# entirely sure how much of this directly affects what we see.
|
||||||
def func():
|
def func():
|
||||||
self.showChat()
|
self.showChat()
|
||||||
self.mainwindow.waitingMessages.addMessage(self.title(), func)
|
self.mainwindow.waitingMessages.addMessage(title, func)
|
||||||
|
if not self.notifications_muted:
|
||||||
if type(self).__name__ == "PesterConvo":
|
if type(self).__name__ == "PesterConvo":
|
||||||
if self.mainwindow.config.blink() & self.mainwindow.config.PBLINK:
|
if self.always_flash or pesterblink:
|
||||||
self.mainwindow.gainAttention.emit(self)
|
self.mainwindow.gainAttention.emit(self)
|
||||||
elif type(self).__name__ == "PesterMemo":
|
elif type(self).__name__ == "PesterMemo":
|
||||||
if self.mainwindow.config.blink() & self.mainwindow.config.MBLINK:
|
if self.always_flash or memoblink:
|
||||||
self.mainwindow.gainAttention.emit(self)
|
self.mainwindow.gainAttention.emit(self)
|
||||||
|
|
||||||
def clearNewMessage(self):
|
def clearNewMessage(self):
|
||||||
|
@ -759,6 +812,18 @@ class PesterConvo(QtGui.QFrame):
|
||||||
self.mainwindow.chumList.pesterlogviewer.raise_()
|
self.mainwindow.chumList.pesterlogviewer.raise_()
|
||||||
self.mainwindow.chumList.pesterlogviewer.activateWindow()
|
self.mainwindow.chumList.pesterlogviewer.activateWindow()
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(bool)
|
||||||
|
def toggleBeep(self, toggled):
|
||||||
|
self.always_beep = toggled
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(bool)
|
||||||
|
def toggleFlash(self, toggled):
|
||||||
|
self.always_flash = toggled
|
||||||
|
|
||||||
|
@QtCore.pyqtSlot(bool)
|
||||||
|
def toggleMute(self, toggled):
|
||||||
|
self.notifications_muted = toggled
|
||||||
|
|
||||||
messageSent = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
|
messageSent = QtCore.pyqtSignal(QtCore.QString, QtCore.QString)
|
||||||
windowClosed = QtCore.pyqtSignal(QtCore.QString)
|
windowClosed = QtCore.pyqtSignal(QtCore.QString)
|
||||||
|
|
||||||
|
|
25
memos.py
25
memos.py
|
@ -407,8 +407,29 @@ class PesterMemo(PesterConvo):
|
||||||
self.invitechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
|
self.invitechum = QtGui.QAction(self.mainwindow.theme["main/menus/rclickchumlist/invitechum"], self)
|
||||||
self.connect(self.invitechum, QtCore.SIGNAL('triggered()'),
|
self.connect(self.invitechum, QtCore.SIGNAL('triggered()'),
|
||||||
self, QtCore.SLOT('inviteChums()'))
|
self, QtCore.SLOT('inviteChums()'))
|
||||||
|
|
||||||
|
self._beepToggle = QtGui.QAction("Beep on Message", self)
|
||||||
|
self._beepToggle.setCheckable(True)
|
||||||
|
self.connect(self._beepToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleBeep(bool)'))
|
||||||
|
|
||||||
|
self._flashToggle = QtGui.QAction("Flash on Message", self)
|
||||||
|
self._flashToggle.setCheckable(True)
|
||||||
|
self.connect(self._flashToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleFlash(bool)'))
|
||||||
|
|
||||||
|
self._muteToggle = QtGui.QAction("Mute Notifications", self)
|
||||||
|
self._muteToggle.setCheckable(True)
|
||||||
|
self.connect(self._muteToggle, QtCore.SIGNAL('toggled(bool)'),
|
||||||
|
self, QtCore.SLOT('toggleMute(bool)'))
|
||||||
|
|
||||||
self.optionsMenu.addAction(self.quirksOff)
|
self.optionsMenu.addAction(self.quirksOff)
|
||||||
self.optionsMenu.addAction(self.oocToggle)
|
self.optionsMenu.addAction(self.oocToggle)
|
||||||
|
|
||||||
|
self.optionsMenu.addAction(self._beepToggle)
|
||||||
|
self.optionsMenu.addAction(self._flashToggle)
|
||||||
|
self.optionsMenu.addAction(self._muteToggle)
|
||||||
|
|
||||||
self.optionsMenu.addAction(self.logchum)
|
self.optionsMenu.addAction(self.logchum)
|
||||||
self.optionsMenu.addAction(self.invitechum)
|
self.optionsMenu.addAction(self.invitechum)
|
||||||
|
|
||||||
|
@ -508,6 +529,10 @@ class PesterMemo(PesterConvo):
|
||||||
self.applyquirks = True
|
self.applyquirks = True
|
||||||
self.ooc = False
|
self.ooc = False
|
||||||
|
|
||||||
|
self.always_beep = False
|
||||||
|
self.always_flash = False
|
||||||
|
self.notifications_muted = False
|
||||||
|
|
||||||
@QtCore.pyqtSlot()
|
@QtCore.pyqtSlot()
|
||||||
def toggleUserlist(self):
|
def toggleUserlist(self):
|
||||||
if self.userlist.isHidden():
|
if self.userlist.isHidden():
|
||||||
|
|
|
@ -719,6 +719,7 @@ def kxhandleInput(ctx, text=None, flavor=None):
|
||||||
print repr(msg)
|
print repr(msg)
|
||||||
except Exception as err:
|
except Exception as err:
|
||||||
print "(Couldn't print processed message: {!s})".format(err)
|
print "(Couldn't print processed message: {!s})".format(err)
|
||||||
|
|
||||||
# karxi: We have a list...but I'm not sure if we ever get anything else, so
|
# karxi: We have a list...but I'm not sure if we ever get anything else, so
|
||||||
# best to play it safe. I may remove this during later refactoring.
|
# best to play it safe. I may remove this during later refactoring.
|
||||||
if isinstance(msg, list):
|
if isinstance(msg, list):
|
||||||
|
@ -734,6 +735,12 @@ def kxhandleInput(ctx, text=None, flavor=None):
|
||||||
# Quirks have been applied. Lex the messages (finally).
|
# Quirks have been applied. Lex the messages (finally).
|
||||||
msg = kxlexMsg(msg)
|
msg = kxlexMsg(msg)
|
||||||
|
|
||||||
|
# Debug output.
|
||||||
|
try:
|
||||||
|
print repr(msg)
|
||||||
|
except Exception as err:
|
||||||
|
print "(Couldn't print lexed message: {!s})".format(err)
|
||||||
|
|
||||||
# Remove coloring if this is a /me!
|
# Remove coloring if this is a /me!
|
||||||
if is_action:
|
if is_action:
|
||||||
# Filter out formatting specifiers (just ctags, at the moment).
|
# Filter out formatting specifiers (just ctags, at the moment).
|
||||||
|
|
|
@ -1350,6 +1350,7 @@ class PesterWindow(MovingWindow):
|
||||||
def newMemoMsg(self, chan, handle, msg):
|
def newMemoMsg(self, chan, handle, msg):
|
||||||
if not self.memos.has_key(chan):
|
if not self.memos.has_key(chan):
|
||||||
# silently ignore in case we forgot to /part
|
# silently ignore in case we forgot to /part
|
||||||
|
# TODO: This is really bad practice. Fix it later.
|
||||||
return
|
return
|
||||||
memo = self.memos[chan]
|
memo = self.memos[chan]
|
||||||
msg = unicode(msg)
|
msg = unicode(msg)
|
||||||
|
@ -1358,7 +1359,7 @@ class PesterWindow(MovingWindow):
|
||||||
newtime = timedelta(0)
|
newtime = timedelta(0)
|
||||||
time = TimeTracker(newtime)
|
time = TimeTracker(newtime)
|
||||||
memo.times[handle] = time
|
memo.times[handle] = time
|
||||||
if msg[0:3] != "/me" and msg[0:13] != "PESTERCHUM:ME":
|
if not (msg.startswith("/me") or msg.startswith("PESTERCHUM:ME")):
|
||||||
msg = addTimeInitial(msg, memo.times[handle].getGrammar())
|
msg = addTimeInitial(msg, memo.times[handle].getGrammar())
|
||||||
if handle == "ChanServ":
|
if handle == "ChanServ":
|
||||||
systemColor = QtGui.QColor(self.theme["memos/systemMsgColor"])
|
systemColor = QtGui.QColor(self.theme["memos/systemMsgColor"])
|
||||||
|
@ -1383,9 +1384,11 @@ class PesterWindow(MovingWindow):
|
||||||
if mentioned:
|
if mentioned:
|
||||||
self.namesound.play()
|
self.namesound.play()
|
||||||
return
|
return
|
||||||
|
if not memo.notifications_muted:
|
||||||
if self.honk and re.search(r"\bhonk\b", convertTags(msg, "text"), re.I):
|
if self.honk and re.search(r"\bhonk\b", convertTags(msg, "text"), re.I):
|
||||||
|
# TODO: I've got my eye on you, Gamzee.
|
||||||
self.honksound.play()
|
self.honksound.play()
|
||||||
elif self.config.memoPing():
|
elif self.config.memoPing() or memo.always_beep:
|
||||||
self.memosound.play()
|
self.memosound.play()
|
||||||
|
|
||||||
def changeColor(self, handle, color):
|
def changeColor(self, handle, color):
|
||||||
|
|
Loading…
Reference in a new issue