199 lines
7.3 KiB
Python
Executable File
199 lines
7.3 KiB
Python
Executable File
"""
|
|
Module for getting information from, setting up and connecting to WingIDE
|
|
"""
|
|
import os
|
|
import sys
|
|
import _winreg
|
|
import shutil
|
|
import filecmp
|
|
import ConfigParser
|
|
import logging
|
|
|
|
import pyfbsdk as mobu
|
|
|
|
from RS import Config
|
|
from RS import Perforce
|
|
from RS import Globals
|
|
|
|
logging.getLogger(__name__)
|
|
|
|
|
|
def SetupDefaultWingIDEPreferences(prefsFile):
|
|
"""
|
|
Sets up the default Wing IDE preferences
|
|
|
|
Arguments:
|
|
prefsFile (string): path to file that has WingIde's preferences
|
|
|
|
Return:
|
|
tuple (boolean, string): The first value is True or False, depending if the command completed successfully
|
|
and the second is a string containing an error message if an error was encountered.
|
|
"""
|
|
|
|
errorMessage = "The {} does not exist".format(prefsFile)
|
|
|
|
if os.path.isfile(prefsFile):# and os.path.getsize(prefsFile):
|
|
# Wrapping in a try catch because sometimes preferences file can become corrupt
|
|
try:
|
|
config = ConfigParser.ConfigParser()
|
|
config.read(prefsFile)
|
|
|
|
# Turn on passive listen so that we can accept debug connections.
|
|
config.set('user-preferences', 'debug.passive-listen', True)
|
|
|
|
# Setup our keymapping to the remote script execution.
|
|
try:
|
|
keymapOverrideDict = eval(config.get('user-preferences', 'gui.keymap-override'))
|
|
|
|
except ConfigParser.NoOptionError:
|
|
keymapOverrideDict = {'Ctrl-E': 'ExecuteActiveScript'}
|
|
|
|
config.set('user-preferences', 'gui.keymap-override', keymapOverrideDict)
|
|
|
|
# Custom keys already exist. See if our custom script is in there already.
|
|
customActionExists = [True
|
|
for command in keymapOverrideDict.itervalues()
|
|
if command == 'ExecuteActiveScript']
|
|
|
|
# Command doesn't exist, so add it.
|
|
if not customActionExists:
|
|
keymapOverrideDict['Ctrl-E'] = 'ExecuteActiveScript'
|
|
config.set('user-preferences', 'gui.keymap-override', keymapOverrideDict)
|
|
|
|
# Write out the preferences.
|
|
with open(prefsFile, 'w') as prefFile:
|
|
config.write(prefFile)
|
|
|
|
errorMessage = ''
|
|
|
|
except Exception, error:
|
|
logging.warning("Wing IDE Error - {}".format(error))
|
|
errorMessage = ('Wing IDE preferences file seems to be corrupt. '
|
|
'You will need to load Wing\nopen up preferences, '
|
|
'toggle a setting and apply to fix the preferences file.')
|
|
|
|
return bool(errorMessage), errorMessage
|
|
|
|
|
|
def GetWingDirectory():
|
|
"""
|
|
Gets the location where WingIde is installed
|
|
|
|
Return:
|
|
tuple(string, string): The first value is the path , depending if the command completed successfully
|
|
and the second is a string containing an error message if an error was encountered.
|
|
"""
|
|
reg = _winreg.ConnectRegistry(None, _winreg.HKEY_LOCAL_MACHINE)
|
|
wingHome = ""
|
|
errorMessage = ""
|
|
if "wildwest" in __file__.lower() or Config.User.Type in ("Tools", "Programmer"):
|
|
logging.warning('Could not find an installation path for Wing IDE!')
|
|
key = None
|
|
# Check for Wing 5 first.
|
|
for wingVersion in ("5.0", "4.1"):
|
|
|
|
try:
|
|
key = _winreg.OpenKey(reg, r'SOFTWARE\Wow6432Node\ARCHAEOPTERYX\WINGIDE\{}\INSTALL'.format(wingVersion), 0,
|
|
_winreg.KEY_ALL_ACCESS)
|
|
logging.info("Wing IDE Version {} detected".format(wingVersion))
|
|
except:
|
|
continue
|
|
|
|
wingHome = _winreg.QueryValueEx(key, 'WINGHOME')[0]
|
|
_winreg.CloseKey(key)
|
|
|
|
_, errorMessage = SetupDefaultWingIDEPreferences(os.path.join(os.environ['USERPROFILE'],
|
|
'AppData', 'Roaming', 'Wing IDE {}'.format(wingVersion[0]),
|
|
'preferences'))
|
|
if not key:
|
|
logging.warning('Wing Ide Error - preferences file not found')
|
|
return wingHome, errorMessage
|
|
|
|
|
|
def SetupWingIDE():
|
|
"""
|
|
Copies the RunFromWing.py file to Wing IDE's scripts directory, so that it can be bound to a hot key.
|
|
|
|
Return:
|
|
tuple (boolean, string): The first value is True or False, depending if the command completed successfully
|
|
and the second is a string containing an error message if an error was encountered.
|
|
"""
|
|
wingHome, errorMessage = GetWingDirectory()
|
|
|
|
if wingHome:
|
|
defaultRunFromWingScript = os.path.join(wingHome, 'scripts', 'RunFromWing.py')
|
|
rockstarRunFromWingScript = os.path.join(Config.Script.Path.Root, 'etc', 'RunFromWing.py')
|
|
|
|
fileState = Perforce.GetFileState(rockstarRunFromWingScript)
|
|
|
|
if fileState:
|
|
|
|
# Is our script the file up-to-date
|
|
isLatest = Perforce.IsLatest(fileState)
|
|
# Does wing script exist locally
|
|
exists = os.path.isfile(defaultRunFromWingScript)
|
|
# Compare the our script against the Wing IDE script
|
|
isSame = exists and filecmp.cmp(rockstarRunFromWingScript, defaultRunFromWingScript)
|
|
|
|
# Sync latest version of the script
|
|
Perforce.Sync(rockstarRunFromWingScript)
|
|
|
|
# override the script in Wing with ours from the Python directory if our script was out of date, the wing
|
|
# ide script does not exist or the wing ide script does not match our script.
|
|
if not all((isLatest, exists, isSame)):
|
|
shutil.copyfile(rockstarRunFromWingScript, defaultRunFromWingScript)
|
|
|
|
return bool(wingHome), errorMessage
|
|
|
|
|
|
def ConnectToWing(show=False):
|
|
""" Connect to Wing IDE for debugging python scripts """
|
|
try:
|
|
import wingdbstub
|
|
wingdbstub.Ensure()
|
|
return True
|
|
except Exception, error:
|
|
logging.warning("Wing IDE Error - {}".format(error))
|
|
return False
|
|
|
|
|
|
def OnWatchRunRemoteScriptFileChanged():
|
|
"""
|
|
When the Remote Watch File is updated, execute the contents of the file as a python script in Motion Builder.
|
|
"""
|
|
with open(Globals.WingRemoteWatchFile, 'r') as remoteFile:
|
|
line = remoteFile.readline()
|
|
|
|
silent = "-silent" in line
|
|
script = line.startswith('-script')
|
|
reload = line.startswith('-reload')
|
|
|
|
if script or reload:
|
|
|
|
# Attempt to make Wing IDE connection.
|
|
if '-ignoreWing' not in line:
|
|
try:
|
|
import wingdbstub
|
|
wingdbstub.Ensure()
|
|
|
|
except:
|
|
print 'Could not connect to Wing IDE!'
|
|
|
|
arg, executable = line.split(';')
|
|
|
|
if not silent:
|
|
# Force the MotionBuilder Python editor to open.
|
|
mobu.FBPopNormalTool('Python Editor')
|
|
|
|
print ('Executing script: ', 'Running module: ')[reload], executable
|
|
|
|
if script:
|
|
Globals.Application.ExecuteScript(executable)
|
|
|
|
else:
|
|
if executable not in sys.modules:
|
|
__import__(executable, globals(), locals(), [], -1)
|
|
|
|
else:
|
|
module = sys.modules[ executable ]
|
|
reload(module) |