Skip to content

Commit

Permalink
Add a function to select matching commands
Browse files Browse the repository at this point in the history
Refactored from tk-flame. Will be used for #31592. Added a comment to
register_panel to indicate that it should be couple with
register_command.

Closes #212
  • Loading branch information
JesseEmond authored and JesseEmond committed Nov 3, 2015
1 parent 59f990a commit 1556ffb
Showing 1 changed file with 71 additions and 8 deletions.
79 changes: 71 additions & 8 deletions python/tank/platform/engine.py
Original file line number Diff line number Diff line change
Expand Up @@ -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').
Expand Down Expand Up @@ -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}

Expand Down Expand Up @@ -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

Expand Down

0 comments on commit 1556ffb

Please sign in to comment.