5

When the user saves a file I want a check to happen prior to saving. If the check fails then it doesn't save. I got this working with mSceneMessage and kBeforeSaveCheck, but I don't know how to customize the pop-up message when it fails. Is this possible?

import maya.OpenMaya as om
import maya.cmds as cmds

def func(retCode, clientData):
    objExist = cmds.objExists('pSphere1')
    om.MScriptUtil.setBool(retCode, (not objExist) ) # Cancel save if there's pSphere1 in the scene

cb_id = om.MSceneMessage.addCheckCallback(om.MSceneMessage.kBeforeSaveCheck, func)

Right now it displays

File operation cancelled by user supplied callback.

Green Cell
  • 4,677
  • 2
  • 18
  • 49
  • According to the documentation, it is not possible to change the text of the pop-up message. After uncompyling `C:\Program Files\Autodesk\Maya2014\Python\Lib\site-packages\maya\OpenMaya.pyc`, I suspect that the actual code in charge for this pop-up is located in `_OpenMaya.pyd` (in the same folder) which is the equivalent of a windows DLL file (machine code, hard to RE) – DrHaze Jul 27 '15 at 14:07
  • Should this check occur everytime a user saves his file by any way? `Ctrl+s` ? `File -> Save Scene`? `cmds.file()`? – DrHaze Jul 27 '15 at 14:10
  • Thanks for checking this out! Could there be some alternative to suppress the message so I can spit out my own? – Green Cell Jul 27 '15 at 14:33
  • ^ Yes, it's mainly so I can enforce naming conventions to the file name. – Green Cell Jul 27 '15 at 14:34
  • Unfortunately, I'm afraid you won't be able to suppress this error message, I'll try finding an other way for this. – DrHaze Jul 27 '15 at 14:39
  • It's an annoying behavior, I'm surprised Autodesk didn't expose it in anyway. The only other thing I could think of is to create my own save functions then override the native ones. Not exactly the route I'd like to take though. – Green Cell Jul 28 '15 at 01:45

1 Answers1

5

I'm a bit slow to the question, but I needed something similar today so I figured I'd respond. I cannot decide if I would recommend this in the general case, but strictly speaking, it is possible to change a considerable number of static strings in the Maya interface using the displayString command. The easy part is, you know the string you are looking for

import maya.cmds as cmds

message = u"File operation cancelled by user supplied callback."

keys = cmds.displayString("_", q=True, keys=True)
for k in keys:
    value = cmds.displayString(k, q=True, value=True)
    if value == message:
        print("Found matching displayString: {}".format(k))

Running this on Maya 2015 finds over 30000 registered display strings and returns a single matching key: s_TfileIOStrings.rFileOpCancelledByUser. Seems promising to me.

Here's your initial code modified to change the display string:

import maya.OpenMaya as om
import maya.cmds as cmds


def func(retCode, clientData):
    """Cancel save if there is a pSphere1 in the scene"""

    objExist = cmds.objExists('pSphere1')

    string_key = "s_TfileIOStrings.rFileOpCancelledByUser"
    string_default = "File operation cancelled by user supplied callback."
    string_error = "There is a pSphere1 node in your scene"

    message = string_error if objExist else string_default
    cmds.displayString(string_key, replace=True, value=message)

    om.MScriptUtil.setBool(retCode, (not objExist))


cb_id = om.MSceneMessage.addCheckCallback(om.MSceneMessage.kBeforeSaveCheck, func)
systemexit
  • 551
  • 6
  • 11
  • This is awesome, I had no idea of `displayString`! I noticed that the pop up has no title, I wonder if there's a way to specify that too? Thanks for the great answer. – Green Cell Nov 01 '15 at 03:12
  • Thanks,it really help me a lot ! One more question? How can I change the icon image of the pop up message ? – Isaac Jan 17 '18 at 05:50
  • I don't have general access to Maya right now, but I doubt that the icon or really any aspect of the popup other than the display strings are accessible from an API. Were the title not blank, you probably could have looked it up and changed it with the same strategy. – systemexit Jan 22 '18 at 08:58
  • Does anyone know what the `om.MScriptUtil.setBool(retCode, (not objExist))` actually does? Because you can just `return False` to get the exact same behaviour! what is it needed for? – ewerybody May 09 '18 at 12:41
  • 1
    I think that's more appropriate to ask as a separate question. – systemexit May 09 '18 at 17:39