-
Notifications
You must be signed in to change notification settings - Fork 5
Include context switching during regular File->Open operation #17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 3 commits
4d5bd2a
795b3c9
3d4e5f9
d981fad
2d2cbb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,5 +8,190 @@ | |
| # agreement to the Shotgun Pipeline Toolkit Source Code License. All rights | ||
| # not expressly granted therein are reserved by Shotgun Software Inc. | ||
|
|
||
| import sgtk #@UnresolvedImport | ||
| import os | ||
| from traceback import format_exc | ||
|
|
||
| from .menu_generation import MenuGenerator | ||
| from .maxscript import MaxScript | ||
| from .warning_dialog import WarningDialog | ||
|
|
||
| import MaxPlus, pymxs #@UnresolvedImport | ||
|
|
||
| logger = sgtk.LogManager.get_logger(__name__) | ||
|
|
||
| g_tank_callbacks_registered = False | ||
|
|
||
| def PostOpenProcess(*args, **kwargs): | ||
| """ | ||
| Callback that fires every time a script is loaded. | ||
| """ | ||
| try: | ||
| logger.debug("SGTK Callback: script loaded") | ||
| # If we have opened a file then we should check if automatic | ||
| # context switching is enabled and change if possible | ||
| engine = sgtk.platform.current_engine() | ||
| file_name = _session_path() | ||
| logger.debug("Currently running engine: %s" % (engine,)) | ||
| logger.debug("File name to load: '%s'" % (file_name,)) | ||
|
|
||
| #if we already have a context and it matches the path, dont do anything else | ||
| curr_ctx = None | ||
| if engine: | ||
| curr_ctx = engine.context | ||
| new_ctx = engine.sgtk.context_from_path(file_name, curr_ctx) | ||
| if curr_ctx==new_ctx: | ||
| logger.debug("Shotgun reports context is already correct, not attempting to reset") | ||
| return | ||
|
|
||
| if file_name and engine is not None: | ||
| logger.debug("Will attempt to execute tank_from_path('%s')" % (file_name,)) | ||
| try: | ||
| # todo: do we need to create a new tk object, instead should we just | ||
| # check that the context gets created correctly? | ||
| tk = sgtk.sgtk_from_path(file_name) | ||
| logger.debug("Instance '%s'is associated with '%s'" % (tk, file_name)) | ||
| except sgtk.TankError as e: | ||
| error=format_exc().replace('\n', '<br />') | ||
| errorMessage="No tk instance associated with '%s':<br /><br /> %s<br /><br />%s" % (file_name, e, error) | ||
| friendlyMessage='<b>Could not determine a Shotgun Entitiy for '+os.path.basename(file_name)+",</b><br />" | ||
| friendlyMessage+='Please ensure you are in a Shotgun-aware instance of 3dsMax with the correct project and try again.' | ||
| logger.debug(errorMessage) | ||
| engine.show_modal('Error Initializing Shotgun', | ||
| engine, | ||
| WarningDialog, | ||
| message=friendlyMessage, | ||
| details=errorMessage) | ||
|
|
||
| #TODO: replace with command that just remove tools requiring specific context (ie Publish) | ||
| #but leave tools that can direct a user back to the correct context (ie Workfiles) | ||
| engine._remove_shotgun_menu() | ||
| return | ||
|
|
||
| # try to get current ctx and inherit its values if possible | ||
| curr_ctx = None | ||
| if sgtk.platform.current_engine(): | ||
| curr_ctx = sgtk.platform.current_engine().context | ||
|
|
||
| logger.debug("") | ||
| new_ctx = tk.context_from_path(file_name, curr_ctx) | ||
| logger.debug("Current context: %r" % (curr_ctx,)) | ||
| logger.debug("New context: %r" % (new_ctx,)) | ||
| # Now switch to the context appropriate for the file | ||
| engine.change_context(new_ctx) | ||
|
|
||
| elif file_name and engine is None: | ||
|
|
||
| #NOTE that this is untested, as I was unable to determine when this sitatuation would be true | ||
|
|
||
| # we have no engine, this maybe because the integration disabled itself, | ||
| # due to a non Toolkit file being opened, prior to this new file. We must | ||
| # create a sgtk instance from the script path. | ||
| logger.debug("3dsmax file is already loaded but no tk engine running.") | ||
| logger.debug("Will attempt to execute tank_from_path('%s')" % (file_name,)) | ||
| try: | ||
| tk = sgtk.sgtk_from_path(file_name) | ||
| logger.debug("Instance '%s'is associated with '%s'" % (tk, file_name)) | ||
| except sgtk.TankError as e: | ||
| error=format_exc().replace('\n', '<br />') | ||
| errorMessage="No tk instance associated with '%s':<br /><br /> %s<br /><br />%s" % (file_name, e, error) | ||
| friendlyMessage='<b>Could not determine a Shotgun Entitiy for '+os.path.basename(file_name)+",</b><br />" | ||
| friendlyMessage+='Please ensure you are in a Shotgun-aware instance of 3dsMax with the correct project and try again.' | ||
| logger.debug(errorMessage) | ||
| engine.show_modal('Error Initializing Shotgun', | ||
| engine, | ||
| WarningDialog, | ||
| message=friendlyMessage, | ||
| details=errorMessage) | ||
|
|
||
| engine._remove_shotgun_menu() | ||
| return | ||
|
|
||
| new_ctx = tk.context_from_path(file_name) | ||
| logger.debug("New context: %r" % (new_ctx,)) | ||
| # Now switch to the context appropriate for the file | ||
| engine.change_context(new_ctx) | ||
|
|
||
| except Exception: | ||
| error=format_exc() | ||
| logger.exception("An exception was raised during addOnScriptLoad callback.") | ||
| friendlyMessage='An unknown error occured attempting to initialize the Shotgun engine.' | ||
| logger.debug(error) | ||
| engine.show_modal('Error Initializing Shotgun', | ||
| engine, | ||
| WarningDialog, | ||
| message=friendlyMessage, | ||
| details=error) | ||
| return | ||
|
|
||
| def tank_ensure_callbacks_registered(engine=None): | ||
| """ | ||
| Make sure that we have callbacks tracking context state changes. | ||
| The OnScriptLoad callback really only comes into play when you're opening a file or creating a new script, when | ||
| there is no current script open in your Nuke session. If there is a script currently open then this will spawn a | ||
| new Nuke instance and the callback won't be called. | ||
| """ | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| global g_tank_callbacks_registered | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| logger.debug("Setting up 3dsMax Context Switching callbacks") | ||
|
|
||
| # we'll assume context switching is allowed for now | ||
| #if engine.get_setting("automatic_context_switch"): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| if not g_tank_callbacks_registered: | ||
| logger.debug("SGTK Registering onLoad callback") | ||
| MaxPlus.NotificationManager.Register(MaxPlus.NotificationCodes.FilePostOpen, PostOpenProcess) | ||
| g_tank_callbacks_registered = True | ||
| #else: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| # we have an engine but the automatic context switching has been disabled, we should ensure the callbacks | ||
| # are removed. | ||
| # if g_tank_callbacks_registered: | ||
| #remove here | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| # g_tank_callbacks_registered = False | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| def _session_path(): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
| """ | ||
| Return the path to the current session | ||
| :return: | ||
| """ | ||
| if pymxs.runtime.maxFilePath and pymxs.runtime.maxFileName: | ||
| return os.path.join(pymxs.runtime.maxFilePath, pymxs.runtime.maxFileName) | ||
| else: | ||
| return None | ||
|
|
||
| def __engine_refresh(new_context): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
| """ | ||
| Checks if the 3dsmax engine should be created or just have the context changed. | ||
| If an engine is already started then we just need to change context, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
| else we need to start the engine. | ||
| """ | ||
|
|
||
| engine_name = 'tk-3dsmax' | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| curr_engine = sgtk.platform.current_engine() | ||
| if curr_engine: | ||
| # If we already have an engine, we can just tell it to change contexts | ||
| curr_engine.change_context(new_context) | ||
| else: | ||
| # try to create new engine | ||
| try: | ||
| logger.debug( | ||
| "Starting new engine: %s, %s, %s" % ( | ||
| engine_name, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
| new_context.sgtk, | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. trailing whitespace |
||
| new_context | ||
| ) | ||
| ) | ||
| sgtk.platform.start_engine(engine_name, new_context.sgtk, new_context) | ||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| except sgtk.TankEngineInitError as e: | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. local variable 'e' is assigned to but never used |
||
| # context was not sufficient! - disable tank! | ||
| logger.exception("Engine could not be started.") | ||
| #TODO: replace with command that just remove tools requiring specific context (ie Publish) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| #but leave tools that can direct a user back to the correct context (ie Workfiles) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| #engine._remove_shotgun_menu() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line at end of file |
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,32 @@ | ||
| ''' | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Black would make changes. |
||
|
|
||
| simple dialog to raise warnings to user | ||
|
|
||
| ''' | ||
|
|
||
| from sgtk.platform.qt import QtGui, QtCore #@UnresolvedImport | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. inline comment should start with '# ' |
||
|
|
||
| #if we have an engine, we can simply use this class | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| class WarningDialog(QtGui.QWidget): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| def __init__(self, message, details=None, *args, **kwargs): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| super(WarningDialog, self).__init__(*args, **kwargs) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| self.setObjectName("SGTK_WARNING_DIALOG") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
|
||
| self._label = QtGui.QLabel("<h3>"+message+"</h3>") | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| self._label.setTextFormat(QtCore.Qt.RichText) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| self._text = QtGui.QTextEdit() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| self._text.setReadOnly(True) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| #self._text.setLineWrapMode(QtGui.QTextEdit.NoWrap) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| self._text.setText(str(details)) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
|
||
| self._layout = QtGui.QVBoxLayout(self) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| self._layout.addWidget(self._label) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
| self._layout.addWidget(self._text) | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| #if we don't have an engine, we'll need to do some of the legwork ourselves | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. block comment should start with '# ' |
||
| def showWarningDialog(message, details=None): | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. expected 2 blank lines, found 1 |
||
|
|
||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. blank line contains whitespace |
||
| parent=QtGui.QApplication.activeWindow() | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. indentation contains tabs |
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
expected 2 blank lines, found 1