-
Notifications
You must be signed in to change notification settings - Fork 14
Expand file tree
/
Copy pathaction.py
More file actions
208 lines (153 loc) · 5.55 KB
/
Copy pathaction.py
File metadata and controls
208 lines (153 loc) · 5.55 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
import os
from .vendor.Qt import QtWidgets
class Action(QtWidgets.QAction):
"""Custom Action widget"""
def __init__(self, parent=None):
QtWidgets.QAction.__init__(self, parent)
self._root = None
self._tags = list()
self._command = None
self._sourcetype = None
self._iconfile = None
self._label = None
self._COMMAND = """import imp
f, filepath, descr = imp.find_module('{module_name}', ['{dirname}'])
module = imp.load_module('{module_name}', f, filepath, descr)
module.{module_name}()"""
@property
def root(self):
return self._root
@root.setter
def root(self, value):
self._root = value
@property
def tags(self):
return self._tags
@tags.setter
def tags(self, value):
self._tags = value
@property
def command(self):
return self._command
@command.setter
def command(self, value):
"""
Store the command in the QAction
Args:
value (str): the full command which will be executed when clicked
Return:
None
"""
self._command = value
@property
def sourcetype(self):
return self._sourcetype
@sourcetype.setter
def sourcetype(self, value):
"""
Set the command type to get the correct execution of the command given
Args:
value (str): the name of the command type
Returns:
None
"""
self._sourcetype = value
@property
def iconfile(self):
return self._iconfile
@iconfile.setter
def iconfile(self, value):
"""Store the path to the image file which needs to be displayed
Args:
value (str): the path to the image
Returns:
None
"""
self._iconfile = value
@property
def label(self):
return self._label
@label.setter
def label(self, value):
"""
Set the abbreviation which will be used as overlay text in the shelf
Args:
value (str): an abbreviation of the name
Returns:
None
"""
self._label = value
def run_command(self):
"""
Run the command of the instance or copy the command to the active shelf
based on the current modifiers.
If callbacks have been registered with fouind modifier integer the
function will trigger all callbacks. When a callback function returns a
non zero integer it will not execute the action's command
"""
# get the current application and its linked keyboard modifiers
app = QtWidgets.QApplication.instance()
modifiers = app.keyboardModifiers()
# If the menu has a callback registered for the current modifier
# we run the callback instead of the action itself.
registered = self._root.registered_callbacks
callbacks = registered.get(int(modifiers), [])
for callback in callbacks:
signal = callback(self)
if signal != 0:
# Exit function on non-zero return code
return
exec(self.process_command())
def process_command(self):
"""
Check if the command is a file which needs to be launched and if it
has a relative path, if so return the full path by expanding
environment variables. Wrap any mel command in a executable string
for Python and return the string if the source type is
Add your own source type and required process to ensure callback
is stored correctly.
An example of a process is the sourcetype is MEL
(Maya Embedded Language) as Python cannot run it on its own so it
needs to be wrapped in a string in which we explicitly import mel and
run it as a mel.eval. The string is then parsed to python as
exec("command").
Returns:
str: a clean command which can be used
"""
if self._sourcetype == "python":
return self._command
if self._sourcetype == "mel":
# Escape single quotes
conversion = self._command.replace("'", "\\'")
return "import maya; maya.mel.eval('{}')".format(conversion)
if self._sourcetype == "file":
if os.path.isabs(self._command):
filepath = self._command
else:
filepath = os.path.normpath(os.path.expandvars(self._command))
return self._wrap_filepath(filepath)
def has_tag(self, tag):
"""Check whether the tag matches with the action's tags.
A partial match will also return True, for example tag `a` will match
correctly with the `ape` tag on the Action.
Args:
tag (str): The tag
Returns
bool: Whether the action is tagged with given tag
"""
for tagitem in self.tags:
if tag not in tagitem:
continue
return True
return False
def _wrap_filepath(self, file_path):
"""Create a wrapped string for the python command
Args:
file_path (str): the filepath of a script
Returns:
str: the wrapped command
"""
dirname = os.path.dirname(r"{}".format(file_path))
dirpath = dirname.replace("\\", "/")
module_name = os.path.splitext(os.path.basename(file_path))[0]
return self._COMMAND.format(module_name=module_name, dirname=dirpath)