Files
gtav-src/tools_ng/techart/dcc/motionbuilder2014/python/RS/Utils/Wing.py
T
2025-09-29 00:52:08 +02:00

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)