diff --git a/python/tank/platform/engine.py b/python/tank/platform/engine.py index fb6b833545..127f32e210 100644 --- a/python/tank/platform/engine.py +++ b/python/tank/platform/engine.py @@ -504,7 +504,8 @@ def register_command(self, name, callback, properties=None): def register_panel(self, callback, panel_name="main", properties=None): """ Similar to register_command, but instead of registering a menu item in the form of a - command, this method registers a UI panel. + command, this method registers a UI panel. A register_panel call should + be used in conjunction with a register_command call. Panels need to be registered if they should persist between DCC sessions (e.g. for example 'saved layouts'). @@ -538,17 +539,17 @@ def register_panel(self, callback, panel_name="main", properties=None): # similar to register_command, track which app this request came from properties["app"] = current_app - # now compose a unique id for this panel - # this is done based on the app instance name plus the given - # panel name. By using the instance name rather than the app name, - # we support the use case where more than one instance of an app exists - # within a config. + # now compose a unique id for this panel. + # This is done based on the app instance name plus the given panel name. + # By using the instance name rather than the app name, we support the + # use case where more than one instance of an app exists within a + # config. panel_id = "%s_%s" % (current_app.instance_name, panel_name) - # to ensure the string is safe to use in most engines, + # to ensure the string is safe to use in most engines, # sanitize to simple alpha-numeric form panel_id = re.sub("\W", "_", panel_id) panel_id = panel_id.lower() - + # add it to the list of registered panels self.__panels[panel_id] = {"callback": callback, "properties": properties} @@ -628,6 +629,68 @@ def threaded_work(val): # we don't have an invoker so just call the function: return func(*args, **kwargs) + def get_matching_commands(self, command_selectors): + """ + Finds all the commands that match the given selectors. + + Command selector structures are typically found in engine configurations + and are typically defined on the following form in yaml: + + menu_favourites: + - {app_instance: tk-multi-workfiles, name: Shotgun File Manager...} + - {app_instance: tk-multi-snapshot, name: Snapshot...} + - {app_instance: tk-multi-workfiles, name: Shotgun Save As...} + - {app_instance: tk-multi-publish, name: Publish...} + + Note that selectors that do not match a command will output a warning. + + :param command_selectors: A list of command selectors, with each + selector having the following structure: + { + name: command-name, + app_instance: instance-name + } + An empty name ('') will select all the + commands of the given instance-name. + + :returns: A list of tuples for all commands that match + the selectors. Each tuple has the format: + (instance-name, command-name, callback) + """ + # return a dictionary grouping all the commands by instance name + commands_by_instance = {} + for (name, value) in self.commands.iteritems(): + app_instance = value["properties"].get("app") + if app_instance is None: + continue + instance_name = app_instance.instance_name + commands_by_instance.setdefault(instance_name, []).append( + (name, value["callback"])) + + # go through the selectors and return any matching commands + ret_value = [] + for selector in command_selectors: + command_name = selector["name"] + instance_name = selector["app_instance"] + instance_commands = commands_by_instance.get(instance_name, []) + + # add the commands if the name of the settings is '' + # or the name matches + matching_commands = [(instance_name, name, callback) + for (name, callback) in instance_commands + if not command_name or (command_name == name)] + ret_value.extend(matching_commands) + + # give feedback if no commands were found + if not matching_commands: + self._engine.log_warning( + "The requested command '%s' from app instance '%s' could " + "not be matched.\nPlease make sure that you have the app " + "installed and that it has successfully initialized." % + (command_name, instance_name)) + + return ret_value + ########################################################################################## # logging interfaces