commit/StationPlaylist: josephsl: SPL Engine (4.0-dev/5.0-dev): Complete rewrite of SAM and SPL Encoder Support.

  • From: commits-noreply@xxxxxxxxxxxxx
  • To: nvda-addons-commits@xxxxxxxxxxxxx
  • Date: Sun, 16 Nov 2014 23:40:01 -0000

1 new commit in StationPlaylist:

https://bitbucket.org/nvdaaddonteam/stationplaylist/commits/38e040d84991/
Changeset:   38e040d84991
Branch:      splengine
User:        josephsl
Date:        2014-11-16 23:39:10+00:00
Summary:     SPL Engine (4.0-dev/5.0-dev): Complete rewrite of SAM and SPL 
Encoder Support.

As the encoders are run as DLL's under SPL Engine (splengine.exe), moved 
encoder support routines from global plugin to the new app module.
As this is a highly experimental feature, this may or may not make it into 
add-on 4.0 (it'll befinitely be included next year in 5.0-dev).

Affected #:  2 files

diff --git a/addon/appModules/splengine.py b/addon/appModules/splengine.py
new file mode 100755
index 0000000..8f3f582
--- /dev/null
+++ b/addon/appModules/splengine.py
@@ -0,0 +1,287 @@
+# Station Playlist Encoder Engine
+# Author: Joseph Lee
+# Copyright 2013-2014, released under GPL.
+
+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 appModuleHandler
+import api
+import ui
+import speech
+import braille
+import globalVars
+import review
+import textInfos
+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 SAM encoder window.
+
+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.connecting: return
+               encoderType = self.isEncoderWindow(obj)
+               streamLabel = None
+               if encoderType == "SAM":
+                       try:
+                               streamLabel = SAMStreamLabels[obj.name]
+                       except KeyError:
+                               streamLabel = None
+               elif encoderType == "SPL":
+                       try:
+                               streamLabel = 
SPLStreamLabels[str(obj.parent.children.index(obj)+1)]
+                       except KeyError:
+                               streamLabel = None
+               # Speak the stream label if it exists.
+               if streamLabel is not None:
+                       speech.speakMessage(streamLabel)
+                       if encoderType == "SAM": brailleStreamLabel = 
str(obj.name) + ": " + streamLabel
+                       elif encoderType == "SPL":
+                               brailleStreamLabel = 
str(obj.parent.children.index(obj)+1) + ": " + streamLabel
+                       braille.handler.message(brailleStreamLabel)
+               nextHandler()
+
+
+       # Few things to check
+       focusToStudio = False
+       playAfterConnecting = False
+
+       def isEncoderWindow(self, obj):
+               fg = api.getForegroundObject()
+               if obj.windowClassName == "TListView" and fg.windowClassName == 
"TfoSCEncoders":
+                       return "SAM"
+               elif obj.windowClassName == "SysListView32" and "splengine" in 
obj.appModule.appName:
+                       return "SPL"
+               return None
+
+       # Routines for each encoder
+       # Mostly connection monitoring
+
+       def connect_sam(self, encoderWindow, 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_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) # Play 
status tones every second.
+                       #info = review.getScreenPosition(self)[0]
+                       #info.expand(textInfos.UNIT_LINE)
+                       #if "Error" in info.text:
+                       if "Error" in encoderWindow.description:
+                               # Announce the description of the error.
+                               
ui.message(encoderWindow.description[encoderWindow.description.find("Status")+8:])
+                               break
+                       #elif "Encoding" in info.text or "Encoded" in info.text:
+                       elif "Encoding" in encoderWindow.description or 
"Encoded" in encoderWindow.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
+
+       # Only needed in SPL Encoder to prevent focus announcement.
+       connecting = 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 = True
+               connectButton = api.getForegroundObject().children[2]
+               if connectButton.name == "Disconnect": 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)
+                       attempt += 1
+                       if attempt%250 == 0: tones.beep(500, 50)
+                       #info = review.getScreenPosition(self)[0]
+                       #info.expand(textInfos.UNIT_LINE)
+                       #if not info.text.endswith("Disconnected"): 
ui.message(info.text)
+                       #if info.text.endswith("Connected"):
+                       if "Unable to connect" in encoderWindow.name:
+                               break
+                       if encoderWindow.children[1].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 encoderWindow.children[1].name != "Connected":
+                       self.connecting = False
+                       ui.message(encoderWindow.children[1].name)
+
+       # Encoder scripts
+
+       def script_connect(self, gesture):
+               focus = api.getFocusObject()
+               encoder = self.isEncoderWindow(focus)
+               if encoder is None:
+                       return
+               elif encoder == "SAM":
+                       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):
+               if not self.focusToStudio:
+                       self.focusToStudio = True
+                       #elf.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
+                       # 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
+                       # 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):
+               encoder = api.getFocusObject()
+               encoderType = self.isEncoderWindow(encoder)
+               if not encoderType:
+                       return
+               else:
+                       curStreamLabel = titleText = ""
+                       if encoderType == "SAM":
+                               try:
+                                       curStreamLabel = 
SAMStreamLabels[encoder.name]
+                               except KeyError:
+                                       curStreamLabel = ""
+                               titleText = encoder.name
+                       elif encoderType == "SPL":
+                               childPos = 
str(encoder.parent.children.index(encoder)+1)
+                               if childPos in SPLStreamLabels:
+                                       curStreamLabel = 
SPLStreamLabels[childPos]
+                               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.parent.children.index(encoder)+1)] = dlg.GetValue()
+                                       else:
+                                               if encoderType == "SAM": del 
SAMStreamLabels[encoder.name]
+                                               elif encoderType == "SPL":
+                                                       del 
SPLStreamLabels[str(encoder.parent.children.index(encoder)+1)]
+                       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 bccd4d1..154d717 100644
--- a/addon/globalPlugins/SPLStudioUtils.py
+++ b/addon/globalPlugins/SPLStudioUtils.py
@@ -1,27 +1,14 @@
 # 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, along with support for Sam Encoder.
+# Adds a few utility features such as switching focus to the SPL Studio window 
and some global scripts.
 
-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
 import ui
-import speech
-import braille
-import globalVars
-import review
-import textInfos
-from NVDAObjects.IAccessible import IAccessible
 import winUser
 import tones
-import gui
-import wx
 import addonHandler
 addonHandler.initTranslation()
 
@@ -40,7 +27,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 = windll.user32 # user32.dll.
+user32 = winUser.user32 # user32.dll.
 SPLWin = 0 # A handle to studio window.
 SPLMSG = winUser.WM_USER
 
@@ -55,17 +42,6 @@ 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
-
 # 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():
@@ -82,33 +58,7 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
        scriptCategory = _("Station Playlist Studio")
 
 
-       # 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).
+       #Global layer environment (see the app module for more information).
        SPLController = False # Control SPL from anywhere.
 
        def getScript(self, gesture):
@@ -253,228 +203,3 @@ class GlobalPlugin(globalPluginHandler.GlobalPlugin):
                #"kb:nvda+shift+`":"focusToSPLWindow",
                #"kb:nvda+`":"SPLControllerPrefix"
        }
-
-       # Support for Sam Encoder
-       # Sam encoder is a Winamp plug-in, so we can use overlay class.
-       def chooseNVDAObjectOverlayClasses(self, obj, clsList):
-               fg = api.getForegroundObject()
-               if obj.windowClassName == "TListView" and fg.windowClassName == 
"TfoSCEncoders":
-                       clsList.insert(0, self.SAMEncoderWindow)
-               elif obj.windowClassName == "SysListView32" and "splengine" in 
obj.appModule.appName:
-                       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) # 
Play status tones every second.
-                               #info = review.getScreenPosition(self)[0]
-                               #info.expand(textInfos.UNIT_LINE)
-                               #if "Error" in info.text:
-                               if "Error" in self.description:
-                                       # Announce the description of the error.
-                                       
ui.message(self.description[self.description.find("Status")+8:])
-                                       break
-                               #elif "Encoding" in info.text or "Encoded" in 
info.text:
-                               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)
-                               attempt += 1
-                               if attempt%250 == 0: tones.beep(500, 50)
-                               #info = review.getScreenPosition(self)[0]
-                               #info.expand(textInfos.UNIT_LINE)
-                               #if not info.text.endswith("Disconnected"): 
ui.message(info.text)
-                               #if info.text.endswith("Connected"):
-                               if "Unable to connect" in self.name:
-                                       break
-                               if self.name.endswith("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:

  • » commit/StationPlaylist: josephsl: SPL Engine (4.0-dev/5.0-dev): Complete rewrite of SAM and SPL Encoder Support. - commits-noreply