commit/StationPlaylist: 2 new changesets

  • From: commits-noreply@xxxxxxxxxxxxx
  • To: nvda-addons-commits@xxxxxxxxxxxxx
  • Date: Sat, 22 Nov 2014 03:45:48 -0000

2 new commits in StationPlaylist:

https://bitbucket.org/nvdaaddonteam/stationplaylist/commits/3ceab6a052e3/
Changeset:   3ceab6a052e3
Branch:      legacy
User:        josephsl
Date:        2014-11-21 17:51:07+00:00
Summary:     Merge SPL Controller routines from master

Affected #:  1 file

diff --git a/addon/globalPlugins/SPLStudioUtils.py 
b/addon/globalPlugins/SPLStudioUtils.py
index b7f4515..384fdda 100644
--- a/addon/globalPlugins/SPLStudioUtils.py
+++ b/addon/globalPlugins/SPLStudioUtils.py
@@ -20,6 +20,7 @@ import winUser
 import tones
 import gui
 import wx
+import nvwave
 import addonHandler
 addonHandler.initTranslation()
 
@@ -53,6 +54,10 @@ SPLLibraryScanCount = 32
 SPL_TrackPlaybackStatus = 104
 SPLCurTrackPlaybackTime = 105
 
+# On/off toggle wave files.
+onFile = os.path.join(os.path.dirname(__file__), "..", "appModules", 
"SPL_on.wav")
+offFile = os.path.join(os.path.dirname(__file__), "..", "appModules", 
"SPL_off.wav")
+
 # Needed in SAM Encoder support:
 SAMFocusToStudio = {} # A dictionary to record whether to switch to SPL Studio 
for this encoder.
 SAMPlayAfterConnecting = {}
@@ -77,7 +82,6 @@ def labelWriteAttempt():
                        
labelStore.write("{streamName}={streamLabel}\n".format(streamName = label, 
streamLabel = SAMStreamLabels[label]))
                labelStore.close()
 
-
 # Try to see if SPL foreground object can be fetched. This is used for 
switching to SPL Studio window from anywhere and to switch to Studio window 
from SAM encoder window.
 
 def fetchSPLForegroundWindow():
@@ -188,10 +192,16 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
 
        def script_micOn(self, gesture):
                winUser.sendMessage(SPLWin,SPLMSG,1,SPLMic)
+               nvwave.playWaveFile(onFile)
+               self.finish()
+
+       def script_micNoFade(self, gesture):
+               winUser.sendMessage(SPLWin,SPLMSG,2,SPLMic)
                self.finish()
 
        def script_micOff(self, gesture):
                winUser.sendMessage(SPLWin,SPLMSG,0,SPLMic)
+               nvwave.playWaveFile(offFile)
                self.finish()
 
        def script_lineInOn(self, gesture):
@@ -241,6 +251,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                "kb:shift+a":"automateOff",
                "kb:m":"micOn",
                "kb:shift+m":"micOff",
+               "kb:n":"micNoFade",
                "kb:l":"lineInOn",
                "kb:shift+l":"lineInOff",
                "kb:shift+r":"libraryScanProgress",


https://bitbucket.org/nvdaaddonteam/stationplaylist/commits/ca656526d9e3/
Changeset:   ca656526d9e3
Branch:      master
User:        josephsl
Date:        2014-11-22 02:36:25+00:00
Summary:     SPL Engine: revert chnages to encoder support which was causing 
stream labeler to fail (a showstopper).
Along with spl engine reversal, added various enhancements derived from spl 
engine experiment such as better thread safety.

Affected #:  2 files

diff --git a/addon/appModules/splengine.py b/addon/appModules/splengine.py
deleted file mode 100755
index fcda357..0000000
--- a/addon/appModules/splengine.py
+++ /dev/null
@@ -1,344 +0,0 @@
-# Station Playlist Audio Engine
-# Author: Joseph Lee
-# Copyright 2014, released under GPL.
-# Mainly used for encoder window support.
-
-# SPL Audio Engine (splengine.exe) is a container for audio processing DLL's 
including encoders.
-# Each encoder is a DLL. As NVDA is unable to assign app modules based on 
DLL's, a workaround was implemented to support each encoder.
-# The app module provides scripts to be used in encoder windows, while each 
"encoder window" provides it's own protocol for various scripts.
-# Here "encoder window" really is a disguised overlay class check routine.
-
-import threading
-import os
-import time
-from configobj import ConfigObj
-import appModuleHandler
-import api
-import ui
-import speech
-import braille
-import controlTypes
-import globalVars
-import winUser
-import tones
-import gui
-import wx
-import addonHandler
-addonHandler.initTranslation()
-
-# SPL Studio uses WM messages to send and receive data, similar to Winamp (see 
NVDA sources/appModules/winamp.py for more information).
-user32 = winUser.user32 # user32.dll.
-SPLWin = 0 # A handle to studio window.
-SPLMSG = winUser.WM_USER
-
-# Needed in encoder connection support
-SPLPlay = 12
-
-# Needed in SAM and SPL Encoder support:
-SAMFocusToStudio = {} # A dictionary to record whether to switch to SPL Studio 
for this encoder.
-SPLFocusToStudio = {}
-SAMPlayAfterConnecting = {}
-SPLPlayAfterConnecting = {}
-SAMStreamLabels= {} # A dictionary to store custom labels for each stream.
-SPLStreamLabels= {} # Same as above but optimized for SPL encoders (Studio 
5.00 and later).
-
-# Stream labels
-labels = ConfigObj(os.path.join(globalVars.appArgs.configPath, 
"splStreamLabels.ini"))
-try:
-       SAMStreamLabels = dict(labels["SAMEncoders"])
-except KeyError:
-       SAMStreamLabels = {}
-try:
-       SPLStreamLabels = dict(labels["SPLEncoders"])
-except KeyError:
-       SPLStreamLabels = {}
-
-
-# Try to see if SPL foreground object can be fetched. This is used for 
switching to SPL Studio window from anywhere and to switch to Studio window 
from encoder windows.
-
-def fetchSPLForegroundWindow():
-       # Turns out NVDA core does have a method to fetch desktop objects, so 
use this to find SPL window from among its children.
-       dt = api.getDesktopObject()
-       for fg in dt.children:
-               if "splstudio" in fg.appModule.appModuleName: return fg
-       return None
-
-
-class AppModule(appModuleHandler.AppModule):
-
-       # Translators: Script category for Station Playlist commands in input 
gestures dialog.
-       scriptCategory = _("Station Playlist Studio")
-
-
-       def terminate(self):
-               global labels, SAMStreamLabels, SPLStreamLabels
-               labels["SAMEncoders"] = SAMStreamLabels
-               labels["SPLEncoders"] = SPLStreamLabels
-               labels.write()
-
-       # Announce stream labels
-       def event_gainFocus(self, obj, nextHandler):
-               if self.isEncoderWindow(obj) == "SPL" and self.connecting_SPL: 
return
-               streamLabel = self._get_streamLabel(obj)
-               if streamLabel is not None:
-                       speech.speakMessage(streamLabel)
-                       brailleStreamLabel = ": 
".join([str(obj.IAccessibleChildID), streamLabel])
-                       braille.handler.message(brailleStreamLabel)
-               nextHandler()
-
-
-       # Few setup routines for scripts.
-
-       def isEncoderWindow(self, obj, fg=None):
-               # The foreground variable is intended for debugging purposes 
and should not be set from outside the Python Console.
-               if not fg: fg = api.getForegroundObject()
-               if obj.role == controlTypes.ROLE_LISTITEM:
-                       if obj.windowClassName == "TListView" and 
fg.windowClassName == "TfoSCEncoders":
-                               return "SAM"
-                       elif obj.windowClassName == "SysListView32" and 
fg.windowClassName == "#32770":
-                               return "SPL"
-               return None
-
-       def _get_streamLabel(self, encoder, fg=None):
-               streamLabel = None
-               encoderType = self.isEncoderWindow(encoder, fg=fg)
-               if encoderType == "SAM":
-                       try:
-                               streamLabel = SAMStreamLabels[encoder.name]
-                       except KeyError:
-                               pass
-               elif encoderType == "SPL":
-                       try:
-                               streamLabel = 
SPLStreamLabels[str(encoder.firstChild.rowNumber)]
-                       except KeyError:
-                               pass
-               return streamLabel
-
-       # Routines for each encoder
-       # Mostly connection monitoring
-
-       # A variable that acts as a mutex.
-       connecting_SAM = False
-
-       def connect_sam(self, encoderWindow, gesture):
-               gesture.send()
-               self.connecting_SAM = True
-               # Translators: Presented when SAM Encoder is trying to connect 
to a streaming server.
-               ui.message(_("Connecting..."))
-               # Oi, status thread, can you keep an eye on the connection 
status for me?
-               statusThread = 
threading.Thread(target=self.reportConnectionStatus_sam, args=(encoderWindow,))
-               statusThread.name = "Connection Status Reporter"
-               statusThread.start()
-
-       def reportConnectionStatus_sam(self, encoderWindow):
-               # Keep an eye on the stream's description field until connected 
or error occurs.
-               # In order to not block NVDA commands, this will be done using 
a different thread.
-               SPLWin = user32.FindWindowA("SPLStudio", None)
-               toneCounter = 0
-               while True:
-                       time.sleep(0.001)
-                       toneCounter+=1
-                       if toneCounter%250 == 0:
-                               tones.beep(500, 50)
-                               if toneCounter >= 750 and "Idle" in 
encoderWindow.description:
-                                       self.connecting_SAM = False
-                                       tones.beep(250, 250)
-                                       return
-                       if "Error" in encoderWindow.description:
-                               # Announce the description of the error.
-                               
ui.message(encoderWindow.description[encoderWindow.description.find("Status")+8:])
-                               break
-                       elif "Encoding" in encoderWindow.description or 
"Encoded" in encoderWindow.description:
-                               # We're on air, so exit.
-                               tones.beep(1000, 150)
-                               break
-               self.connecting_SAM = False
-               try:
-                       focusToStudio = SAMFocusToStudio[encoderWindow.name]
-               except KeyError:
-                       focusToStudio = False
-               try:
-                       playAfterConnecting = 
SAMPlayAfterConnecting[encoderWindow.name]
-               except KeyError:
-                       playAfterConnecting = False
-               if focusToStudio:
-                       fetchSPLForegroundWindow().setFocus()
-               if playAfterConnecting:
-                       winUser.sendMessage(SPLWin, SPLMSG, 0, SPLPlay)
-
-       # Only needed in SPL Encoder to prevent focus announcement.
-       connecting_SPL = False
-
-       def connect_spl(self, encoderWindow):
-               # Same as SAM's connection routine, but this time, keep an eye 
on self.name and a different connection flag.
-               self.connecting_SPL = True
-               connectButton = api.getForegroundObject().children[2]
-               if connectButton.name == "Disconnect":
-                       self.connecting_SPL = False
-                       return
-               ui.message(_("Connecting..."))
-               # Juggle the focus around.
-               connectButton.doAction()
-               encoderWindow.setFocus()
-               # Same as SAM encoders.
-               statusThread = 
threading.Thread(target=self.reportConnectionStatus_spl, args=(encoderWindow,))
-               statusThread.name = "Connection Status Reporter"
-               statusThread.start()
-
-       def reportConnectionStatus_spl(self, encoderWindow):
-               # Same routine as SAM encoder: use a thread to prevent blocking 
NVDA commands.
-               SPLWin = user32.FindWindowA("SPLStudio", None)
-               attempt = 0
-               while True:
-                       time.sleep(0.001)
-                       try:
-                               statChild = encoderWindow.children[1]
-                       except IndexError:
-                               return # Don't leave zombie objects around.
-                       attempt += 1
-                       if attempt%250 == 0:
-                               tones.beep(500, 50)
-                               if attempt>= 500 and statChild.name == 
"Disconnected":
-                                       self.connecting_SPL = False
-                                       tones.beep(250, 250)
-                                       return
-                       if "Unable to connect" in statChild.name or "Failed" in 
statChild.name:
-                               ui.message(statChild.name)
-                               break
-                       if statChild.name == "Connected":
-                               # We're on air, so exit.
-                               tones.beep(1000, 150)
-                               break
-               self.connecting_SPL = False
-               try:
-                       focusToStudio = 
SPLFocusToStudio[str(encoderWindow.firstChild.rowNumber)]
-               except KeyError:
-                       focusToStudio = False
-               try:
-                       playAfterConnecting = 
SPLPlayAfterConnecting[str(encoderWindow.firstChild.rowNumber)]
-               except KeyError:
-                       playAfterConnecting = False
-               if focusToStudio:
-                       fetchSPLForegroundWindow().setFocus()
-               if playAfterConnecting:
-                       winUser.sendMessage(SPLWin, SPLMSG, 0, SPLPlay)
-
-
-       # Encoder scripts
-
-       def script_connect(self, gesture):
-               focus = api.getFocusObject()
-               encoder = self.isEncoderWindow(focus)
-               if encoder is None:
-                       return
-               elif encoder == "SAM":
-                       if self.connecting_SAM: return
-                       else: self.connect_sam(focus, gesture)
-               else:
-                       self.connect_spl(focus)
-
-       def script_disconnect(self, gesture):
-               gesture.send()
-               if self.isEncoderWindow(api.getFocusObject()) == "SAM":
-                       # Translators: Presented when SAM Encoder is 
disconnecting from a streaming server.
-                       ui.message(_("Disconnecting..."))
-
-       def script_toggleFocusToStudio(self, gesture):
-               focus = api.getFocusObject()
-               encoder = self.isEncoderWindow(focus)
-               if not encoder:
-                       return
-               if encoder == "SAM":
-                       try:
-                               focusToStudio = SAMFocusToStudio[focus.name]
-                       except KeyError:
-                               focusToStudio = False
-               elif encoder == "SPL":
-                       try:
-                               focusToStudio = 
SPLFocusToStudio[str(focus.firstChild.rowNumber)]
-                       except KeyError:
-                               focusToStudio = False
-               if not focusToStudio:
-                       focusToStudio = True
-                       # Translators: Presented when toggling the setting to 
switch to Studio when connected to a streaming server.
-                       ui.message(_("Switch to Studio after connecting"))
-               else:
-                       focusToStudio = False
-                       # Translators: Presented when toggling the setting to 
switch to Studio when connected to a streaming server.
-                       ui.message(_("Do not switch to Studio after 
connecting"))
-               if encoder == "SAM":
-                       SAMFocusToStudio[focus.name] = focusToStudio
-               elif encoder == "SPL":
-                       SPLFocusToStudio[str(focus.firstChild.rowNumber)] = 
focusToStudio
-       # Translators: Input help mode message in SAM Encoder window.
-       script_toggleFocusToStudio.__doc__=_("Toggles whether NVDA will switch 
to Studio when connected to a streaming server.")
-
-       def script_togglePlay(self, gesture):
-               focus = api.getFocusObject()
-               encoder = self.isEncoderWindow(focus)
-               if not encoder:
-                       return
-               if encoder == "SAM":
-                       try:
-                               playAfterConnecting = 
SAMPlayAfterConnecting[focus.name]
-                       except KeyError:
-                               playAfterConnecting = False
-               elif encoder == "SPL":
-                       try:
-                               playAfterConnecting = 
SPLPlayAfterConnecting[str(focus.firstChild.rowNumber)]
-                       except KeyError:
-                               playAfterConnecting = False
-               if not playAfterConnecting:
-                       playAfterConnecting = True
-                       # Translators: Presented when toggling the setting to 
play selected song when connected to a streaming server.
-                       ui.message(_("Play first track after connecting"))
-               else:
-                       playAfterConnecting = False
-                       # Translators: Presented when toggling the setting to 
switch to Studio when connected to a streaming server.
-                       ui.message(_("Do not play first track after 
connecting"))
-               if encoder == "SAM":
-                       SAMPlayAfterConnecting[focus.name] = playAfterConnecting
-               elif encoder == "SPL":
-                       SPLPlayAfterConnecting[str(focus.firstChild.rowNumber)] 
= playAfterConnecting
-       # Translators: Input help mode message in SAM Encoder window.
-       script_togglePlay.__doc__=_("Toggles whether Studio will play the first 
song when connected to a streaming server.")
-
-       def script_streamLabeler(self, gesture):
-               encoder = api.getFocusObject()
-               encoderType = self.isEncoderWindow(encoder)
-               if not encoderType:
-                       return
-               else:
-                       curStreamLabel = self._get_streamLabel(encoder)
-                       if encoderType == "SAM":
-                               titleText = encoder.name
-                       elif encoderType == "SPL":
-                               titleText = encoder.firstChild.name
-                       # Translators: The title of the stream labeler dialog 
(example: stream labeler for 1).
-                       streamTitle = _("Stream labeler for 
{streamEntry}").format(streamEntry = titleText)
-                       # Translators: The text of the stream labeler dialog.
-                       streamText = _("Enter the label for this stream")
-                       dlg = wx.TextEntryDialog(gui.mainFrame,
-                       streamText, streamTitle, defaultValue=curStreamLabel)
-                       def callback(result):
-                               if result == wx.ID_OK:
-                                       if dlg.GetValue() != "":
-                                               if encoderType == "SAM": 
SAMStreamLabels[encoder.name] = dlg.GetValue()
-                                               elif encoderType == "SPL":
-                                                       
SPLStreamLabels[str(encoder.firstChild.rowNumber)] = dlg.GetValue()
-                                       else:
-                                               if encoderType == "SAM": del 
SAMStreamLabels[encoder.name]
-                                               elif encoderType == "SPL":
-                                                       del 
SPLStreamLabels[str(encoder.firstChild.rowNumber)]
-                       gui.runScriptModalDialog(dlg, callback)
-       # Translators: Input help mode message in SAM Encoder window.
-       script_streamLabeler.__doc__=_("Opens a dialog to label the selected 
encoder.")
-
-       __gestures={
-               "kb:f9":"connect",
-               "kb:f10":"disconnect",
-               "kb:f11":"toggleFocusToStudio",
-               "kb:shift+f11":"togglePlay",
-               "kb:f12":"streamLabeler"
-       }
-

diff --git a/addon/globalPlugins/SPLStudioUtils.py 
b/addon/globalPlugins/SPLStudioUtils.py
index a693069..e9e1bcc 100644
--- a/addon/globalPlugins/SPLStudioUtils.py
+++ b/addon/globalPlugins/SPLStudioUtils.py
@@ -1,16 +1,27 @@
 # Station Playlist Utilities
 # Author: Joseph Lee
 # Copyright 2013-2014, released under GPL.
-# Adds a few utility features such as switching focus to the SPL Studio window 
and some global scripts.
+# Adds a few utility features such as switching focus to the SPL Studio window 
and some global scripts, along with support for Encoders.
 
+from ctypes import windll
 from functools import wraps
+import threading
 import os
+import time
+from configobj import ConfigObj # Configuration management; configspec will be 
used to store app module and global plugin settings in one ini file.
 import globalPluginHandler
 import api
+from controlTypes import ROLE_LISTITEM
 import ui
+import speech
+import braille
+import globalVars
+from NVDAObjects.IAccessible import IAccessible
 import winUser
 import tones
 import nvwave
+import gui
+import wx
 import addonHandler
 addonHandler.initTranslation()
 
@@ -29,7 +40,7 @@ def finally_(func, final):
        return wrap(final)
 
 # SPL Studio uses WM messages to send and receive data, similar to Winamp (see 
NVDA sources/appModules/winamp.py for more information).
-user32 = winUser.user32 # user32.dll.
+user32 = windll.user32 # user32.dll.
 SPLWin = 0 # A handle to studio window.
 SPLMSG = winUser.WM_USER
 
@@ -44,6 +55,17 @@ SPLLibraryScanCount = 32
 SPL_TrackPlaybackStatus = 104
 SPLCurTrackPlaybackTime = 105
 
+# Needed in SAM and SPL Encoder support:
+SAMFocusToStudio = {} # A dictionary to record whether to switch to SPL Studio 
for this encoder.
+SPLFocusToStudio = {}
+SAMPlayAfterConnecting = {}
+SPLPlayAfterConnecting = {}
+SAMStreamLabels= {} # A dictionary to store custom labels for each stream.
+SPLStreamLabels= {} # Same as above but optimized for SPL encoders (Studio 
5.00 and later).
+
+# Configuration management.
+Config = None
+
 # On/off toggle wave files.
 onFile = os.path.join(os.path.dirname(__file__), "..", "appModules", 
"SPL_on.wav")
 offFile = os.path.join(os.path.dirname(__file__), "..", "appModules", 
"SPL_off.wav")
@@ -64,7 +86,33 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
        scriptCategory = _("Station Playlist Studio")
 
 
-       #Global layer environment (see the app module for more information).
+       # Do some initialization, such as stream labels for SAM encoders.
+       def __init__(self):
+               super(globalPluginHandler.GlobalPlugin, self).__init__()
+               # Load stream labels (and possibly other future goodies) from a 
file-based database.
+               global config, SAMStreamLabels, SPLStreamLabels
+               #if 
os.path.isfile(os.path.join(config.getUserDefaultConfigPath(), 
"splStreamLabels.ini")):
+               config = ConfigObj(os.path.join(globalVars.appArgs.configPath, 
"splStreamLabels.ini"))
+               #else:
+                       #config = 
ConfigObj(os.path.join(config.getUserDefaultConfigPath(), 
"splStreamLabels.ini"), create_empty=True)
+               # Read stream labels.
+               try:
+                       SAMStreamLabels = dict(config["SAMEncoders"])
+               except KeyError:
+                       SAMStreamLabels = {}
+               try:
+                       SPLStreamLabels = dict(config["SPLEncoders"])
+               except KeyError:
+                       SPLStreamLabels = {}
+
+       # Save configuration file.
+       def terminate(self):
+               global config
+               config["SAMEncoders"] = SAMStreamLabels
+               config["SPLEncoders"] = SPLStreamLabels
+               config.write()
+
+                       #Global layer environment (see the app module for more 
information).
        SPLController = False # Control SPL from anywhere.
 
        def getScript(self, gesture):
@@ -145,15 +193,15 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                nvwave.playWaveFile(onFile)
                self.finish()
 
-       def script_micNoFade(self, gesture):
-               winUser.sendMessage(SPLWin,SPLMSG,2,SPLMic)
-               self.finish()
-
        def script_micOff(self, gesture):
                winUser.sendMessage(SPLWin,SPLMSG,0,SPLMic)
                nvwave.playWaveFile(offFile)
                self.finish()
 
+       def script_micNoFade(self, gesture):
+               winUser.sendMessage(SPLWin,SPLMSG,2,SPLMic)
+               self.finish()
+
        def script_lineInOn(self, gesture):
                winUser.sendMessage(SPLWin,SPLMSG,1,SPLLineIn)
                self.finish()
@@ -216,3 +264,236 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                #"kb:nvda+shift+`":"focusToSPLWindow",
                #"kb:nvda+`":"SPLControllerPrefix"
        }
+
+       # Support for Encoders
+
+       def chooseNVDAObjectOverlayClasses(self, obj, clsList):
+               fg = api.getForegroundObject()
+               if obj.appModule.appName in ["splengine", "splstreamer"]:
+                       if obj.windowClassName == "TListView" and 
fg.windowClassName == "TfoSCEncoders":
+                               clsList.insert(0, self.SAMEncoderWindow)
+                       elif obj.windowClassName == "SysListView32" and 
fg.windowClassName == "#32770":
+                               if obj.role == ROLE_LISTITEM:
+                                       clsList.insert(0, self.SPLEncoderWindow)
+
+       class SAMEncoderWindow(IAccessible):
+               # Support for Sam Encoder window.
+
+               # Few useful variables for encoder list:
+               focusToStudio = False # If true, Studio will gain focus after 
encoder connects.
+               playAfterConnecting = False # When connected, the first track 
will be played.
+               encoderType = "SAM"
+
+
+               def reportConnectionStatus(self):
+                       # Keep an eye on the stream's description field until 
connected or error occurs.
+                       # In order to not block NVDA commands, this will be 
done using a different thread.
+                       SPLWin = user32.FindWindowA("SPLStudio", None)
+                       toneCounter = 0
+                       while True:
+                               time.sleep(0.001)
+                               toneCounter+=1
+                               if toneCounter%250 == 0:
+                                       tones.beep(500, 50)
+                                       if toneCounter >= 750 and "Idle" in 
self.description:
+                                               tones.beep(250, 250)
+                                               return
+                               if "Error" in self.description:
+                                       # Announce the description of the error.
+                                       
ui.message(self.description[self.description.find("Status")+8:])
+                                       break
+                               elif "Encoding" in self.description or 
"Encoded" in self.description:
+                                       # We're on air, so exit.
+                                       if self.focusToStudio:
+                                               
fetchSPLForegroundWindow().setFocus()
+                                       tones.beep(1000, 150)
+                                       if self.playAfterConnecting:
+                                               winUser.sendMessage(SPLWin, 
SPLMSG, 0, SPLPlay)
+                                       break
+
+               def script_connect(self, gesture):
+                       gesture.send()
+                       # Translators: Presented when SAM Encoder is trying to 
connect to a streaming server.
+                       ui.message(_("Connecting..."))
+                       # Oi, status thread, can you keep an eye on the 
connection status for me?
+                       statusThread = 
threading.Thread(target=self.reportConnectionStatus)
+                       statusThread.name = "Connection Status Reporter"
+                       statusThread.start()
+
+               def script_disconnect(self, gesture):
+                       gesture.send()
+                       # Translators: Presented when SAM Encoder is 
disconnecting from a streaming server.
+                       ui.message(_("Disconnecting..."))
+
+               def script_toggleFocusToStudio(self, gesture):
+                       if not self.focusToStudio:
+                               self.focusToStudio = True
+                               if self.encoderType == "SAM":
+                                       SAMFocusToStudio[self.name] = True
+                               elif self.encoderType == "SPL":
+                                       
SPLFocusToStudio[str(self.IAccessibleChildID)] = True
+                               # Translators: Presented when toggling the 
setting to switch to Studio when connected to a streaming server.
+                               ui.message(_("Switch to Studio after 
connecting"))
+                       else:
+                               self.focusToStudio = False
+                               if self.encoderType == "SAM":
+                                       SAMFocusToStudio[self.name] = False
+                               elif self.encoderType == "SPL":
+                                       
SPLFocusToStudio[str(self.IAccessibleChildID)] = False
+                               # Translators: Presented when toggling the 
setting to switch to Studio when connected to a streaming server.
+                               ui.message(_("Do not switch to Studio after 
connecting"))
+               # Translators: Input help mode message in SAM Encoder window.
+               script_toggleFocusToStudio.__doc__=_("Toggles whether NVDA will 
switch to Studio when connected to a streaming server.")
+
+               def script_togglePlay(self, gesture):
+                       if not self.playAfterConnecting:
+                               self.playAfterConnecting = True
+                               if self.encoderType == "SAM":
+                                       SAMPlayAfterConnecting[self.name] = True
+                               elif self.encoderType == "SPL":
+                                       
SPLPlayAfterConnecting[str(self.IAccessibleChildID)] = True
+                               # Translators: Presented when toggling the 
setting to play selected song when connected to a streaming server.
+                               ui.message(_("Play first track after 
connecting"))
+                       else:
+                               self.playAfterConnecting = False
+                               if self.encoderType == "SAM":
+                                       SAMPlayAfterConnecting[self.name] = 
False
+                               elif self.encoderType == "SPL":
+                                       
SPLPlayAfterConnecting[str(self.IAccessibleChildID)] = False
+                               # Translators: Presented when toggling the 
setting to switch to Studio when connected to a streaming server.
+                               ui.message(_("Do not play first track after 
connecting"))
+               # Translators: Input help mode message in SAM Encoder window.
+               script_togglePlay.__doc__=_("Toggles whether Studio will play 
the first song when connected to a streaming server.")
+
+               def script_streamLabeler(self, gesture):
+                       curStreamLabel = ""
+                       if self.encoderType == "SAM" and self.name in 
SAMStreamLabels:
+                               curStreamLabel = SAMStreamLabels[self.name]
+                       elif self.encoderType == "SPL" and 
str(self.IAccessibleChildID) in SPLStreamLabels:
+                               curStreamLabel = 
SPLStreamLabels[str(self.IAccessibleChildID)]
+                       # Translators: The title of the stream labeler dialog 
(example: stream labeler for 1).
+                       streamTitle = _("Stream labeler for 
{streamEntry}").format(streamEntry = self.name)
+                       # Translators: The text of the stream labeler dialog.
+                       streamText = _("Enter the label for this stream")
+                       dlg = wx.TextEntryDialog(gui.mainFrame,
+                       streamText, streamTitle, defaultValue=curStreamLabel)
+                       def callback(result):
+                               if result == wx.ID_OK:
+                                       if dlg.GetValue() != "":
+                                               if self.encoderType == "SAM": 
SAMStreamLabels[self.name] = dlg.GetValue()
+                                               elif self.encoderType == "SPL": 
SPLStreamLabels[str(self.IAccessibleChildID)] = dlg.GetValue()
+                                       else:
+                                               if self.encoderType == "SAM": 
del SAMStreamLabels[self.name]
+                                               elif self.encoderType == "SPL": 
del SPLStreamLabels[(self.IAccessibleChildID)]
+                       gui.runScriptModalDialog(dlg, callback)
+               # Translators: Input help mode message in SAM Encoder window.
+               script_streamLabeler.__doc__=_("Opens a dialog to label the 
selected encoder.")
+
+
+               def initOverlayClass(self):
+                       # Can I switch to Studio when connected to a streaming 
server?
+                       try:
+                               self.focusToStudio = SAMFocusToStudio[self.name]
+                       except KeyError:
+                               pass
+
+               def event_gainFocus(self):
+                       try:
+                               streamLabel = SAMStreamLabels[self.name]
+                       except KeyError:
+                               streamLabel = None
+                       # Speak the stream label if it exists.
+                       if streamLabel is not None: 
speech.speakMessage(streamLabel)
+                       super(type(self), self).reportFocus()
+                       # Braille the stream label if present.
+                       if streamLabel is not None:
+                               brailleStreamLabel = self.name + ": " + 
streamLabel
+                               braille.handler.message(brailleStreamLabel)
+
+
+               __gestures={
+                       "kb:f9":"connect",
+                       "kb:f10":"disconnect",
+                       "kb:f11":"toggleFocusToStudio",
+                       "kb:shift+f11":"togglePlay",
+                       "kb:f12":"streamLabeler"
+               }
+
+       class SPLEncoderWindow(SAMEncoderWindow):
+               # Support for SPL Encoder window.
+
+               # A few more subclass flags.
+               encoderType = "SPL"
+
+               def reportConnectionStatus(self):
+                       # Same routine as SAM encoder: use a thread to prevent 
blocking NVDA commands.
+                       SPLWin = user32.FindWindowA("SPLStudio", None)
+                       attempt = 0
+                       while True:
+                               time.sleep(0.001)
+                               try:
+                                       statChild = self.children[1]
+                               except IndexError:
+                                       return # Don't leave zombie objects 
around.
+                               attempt += 1
+                               if attempt%250 == 0:
+                                       tones.beep(500, 50)
+                                       if attempt>= 500 and statChild.name == 
"Disconnected":
+                                               tones.beep(250, 250)
+                                               return
+                               if "Unable to connect" in statChild.name or 
"Failed" in statChild.name:
+                                       ui.message(statChild.name)
+                                       break
+                               if statChild.name == "Connected":
+                                       # We're on air, so exit.
+                                       if self.focusToStudio:
+                                               
fetchSPLForegroundWindow().setFocus()
+                                       tones.beep(1000, 150)
+                                       if self.playAfterConnecting:
+                                               winUser.sendMessage(SPLWin, 
SPLMSG, 0, SPLPlay)
+                                       break
+                       #if not self.name.endswith("Connected"): 
ui.message(self.name[self.name.find("Transfer")+15:])
+
+               def script_connect(self, gesture):
+                       # Same as SAM's connection routine, but this time, keep 
an eye on self.name and a different connection flag.
+                       connectButton = api.getForegroundObject().children[2]
+                       if connectButton.name == "Disconnect": return
+                       ui.message(_("Connecting..."))
+                       # Juggle the focus around.
+                       connectButton.doAction()
+                       self.setFocus()
+                       # Same as SAM encoders.
+                       statusThread = 
threading.Thread(target=self.reportConnectionStatus)
+                       statusThread.name = "Connection Status Reporter"
+                       statusThread.start()
+               script_connect.__doc__=_("Connects to a streaming server.")
+
+
+               def initOverlayClass(self):
+                       # Can I switch to Studio when connected to a streaming 
server?
+                       try:
+                               self.focusToStudio = 
SPLFocusToStudio[str(self.IAccessibleChildID)]
+                       except KeyError:
+                               pass
+
+               def event_gainFocus(self):
+                       try:
+                               streamLabel = 
SPLStreamLabels[str(self.IAccessibleChildID)]
+                       except KeyError:
+                               streamLabel = None
+                       # Speak the stream label if it exists.
+                       if streamLabel is not None: 
speech.speakMessage(streamLabel)
+                       super(type(self), self).reportFocus()
+                       # Braille the stream label if present.
+                       if streamLabel is not None:
+                               brailleStreamLabel = 
str(self.IAccessibleChildID) + ": " + streamLabel
+                               braille.handler.message(brailleStreamLabel)
+
+
+
+               __gestures={
+                       "kb:f9":"connect",
+                       "kb:f10":None
+               }
+
+

Repository URL: https://bitbucket.org/nvdaaddonteam/stationplaylist/

--

This is a commit notification from bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.

Other related posts: