/pxr/usdImaging/usdviewq/layerStackContextMenu.py

https://github.com/PixarAnimationStudios/USD · Python · 219 lines · 126 code · 43 blank · 50 comment · 26 complexity · c49f2a386a094f56f7cdbbbf4a245401 MD5 · raw file

  1. #
  2. # Copyright 2016 Pixar
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "Apache License")
  5. # with the following modification; you may not use this file except in
  6. # compliance with the Apache License and the following modification to it:
  7. # Section 6. Trademarks. is deleted and replaced with:
  8. #
  9. # 6. Trademarks. This License does not grant permission to use the trade
  10. # names, trademarks, service marks, or product names of the Licensor
  11. # and its affiliates, except as required to comply with Section 4(c) of
  12. # the License and to reproduce the content of the NOTICE file.
  13. #
  14. # You may obtain a copy of the Apache License at
  15. #
  16. # http://www.apache.org/licenses/LICENSE-2.0
  17. #
  18. # Unless required by applicable law or agreed to in writing, software
  19. # distributed under the Apache License with the above modification is
  20. # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
  21. # KIND, either express or implied. See the Apache License for the specific
  22. # language governing permissions and limitations under the Apache License.
  23. #
  24. from .qt import QtCore, QtGui, QtWidgets
  25. from .usdviewContextMenuItem import UsdviewContextMenuItem
  26. import os, subprocess, sys
  27. from pxr import Ar
  28. #
  29. # Specialized context menu for running commands in the layer stack view.
  30. #
  31. class LayerStackContextMenu(QtWidgets.QMenu):
  32. def __init__(self, parent, item):
  33. QtWidgets.QMenu.__init__(self, parent)
  34. self._menuItems = _GetContextMenuItems(item)
  35. for menuItem in self._menuItems:
  36. if menuItem.isValid():
  37. # create menu actions
  38. action = self.addAction(menuItem.GetText(), menuItem.RunCommand)
  39. # set enabled
  40. if not menuItem.IsEnabled():
  41. action.setEnabled(False)
  42. def _GetContextMenuItems(item):
  43. return [OpenLayerMenuItem(item),
  44. UsdviewLayerMenuItem(item),
  45. CopyLayerPathMenuItem(item),
  46. CopyLayerIdentifierMenuItem(item),
  47. CopyPathMenuItem(item)]
  48. #
  49. # The base class for layer stack context menu items.
  50. #
  51. class LayerStackContextMenuItem(UsdviewContextMenuItem):
  52. def __init__(self, item):
  53. self._item = item
  54. def IsEnabled(self):
  55. return True
  56. def GetText(self):
  57. return ""
  58. def RunCommand(self):
  59. pass
  60. #
  61. # Opens the layer using usdedit.
  62. #
  63. class OpenLayerMenuItem(LayerStackContextMenuItem):
  64. # XXX: Note that this logic is duplicated from usddiff
  65. # see bug 150247 for centralizing this API.
  66. def _FindUsdEdit(self):
  67. import platform
  68. from distutils.spawn import find_executable
  69. usdedit = find_executable('usdedit')
  70. if not usdedit:
  71. usdedit = find_executable('usdedit', path=os.path.abspath(os.path.dirname(sys.argv[0])))
  72. if not usdedit and (platform.system() == 'Windows'):
  73. for path in os.environ['PATH'].split(os.pathsep):
  74. base = os.path.join(path, 'usdedit')
  75. for ext in ['.cmd', '']:
  76. if os.access(base + ext, os.X_OK):
  77. usdedit = base + ext
  78. return usdedit
  79. def GetText(self):
  80. from .common import PrettyFormatSize
  81. fileSize = 0
  82. if (hasattr(self._item, "layerPath")
  83. and os.path.isfile(getattr(self._item, "layerPath"))):
  84. fileSize = os.path.getsize(getattr(self._item, "layerPath"))
  85. if fileSize:
  86. return "Open Layer In Editor (%s)" % PrettyFormatSize(fileSize)
  87. else:
  88. return "Open Layer In Editor"
  89. def IsEnabled(self):
  90. return hasattr(self._item, "layerPath")
  91. def RunCommand(self):
  92. if not self._item:
  93. return
  94. # Get layer path from item
  95. layerPath = getattr(self._item, "layerPath")
  96. if not layerPath:
  97. print("Error: Could not find layer file.")
  98. return
  99. if Ar.IsPackageRelativePath(layerPath):
  100. layerName = os.path.basename(
  101. Ar.SplitPackageRelativePathInner(layerPath)[1])
  102. else:
  103. layerName = os.path.basename(layerPath)
  104. layerName += ".tmp"
  105. usdeditExe = self._FindUsdEdit()
  106. if not usdeditExe:
  107. print("Warning: Could not find 'usdedit', expected it to be in PATH.")
  108. return
  109. print("Opening file: %s" % layerPath)
  110. command = [usdeditExe,'-n',layerPath,'-p',layerName]
  111. subprocess.Popen(command, close_fds=True)
  112. #
  113. # Opens the layer using usdview.
  114. #
  115. class UsdviewLayerMenuItem(LayerStackContextMenuItem):
  116. def GetText(self):
  117. return "Open Layer In usdview"
  118. def IsEnabled(self):
  119. return hasattr(self._item, "layerPath")
  120. def RunCommand(self):
  121. if not self._item:
  122. return
  123. # Get layer path from item
  124. layerPath = getattr(self._item, "layerPath")
  125. if not layerPath:
  126. return
  127. print("Spawning usdview %s" % layerPath)
  128. os.system("usdview %s &" % layerPath)
  129. #
  130. # Copy the layer path to clipboard
  131. #
  132. class CopyLayerPathMenuItem(LayerStackContextMenuItem):
  133. def GetText(self):
  134. return "Copy Layer Path"
  135. def RunCommand(self):
  136. if not self._item:
  137. return
  138. layerPath = getattr(self._item, "layerPath")
  139. if not layerPath:
  140. return
  141. cb = QtWidgets.QApplication.clipboard()
  142. cb.setText(layerPath, QtGui.QClipboard.Selection )
  143. cb.setText(layerPath, QtGui.QClipboard.Clipboard )
  144. #
  145. # Copy the layer identifier to clipboard
  146. #
  147. class CopyLayerIdentifierMenuItem(LayerStackContextMenuItem):
  148. def GetText(self):
  149. return "Copy Layer Identifier"
  150. def RunCommand(self):
  151. if not self._item:
  152. return
  153. identifier = getattr(self._item, "identifier")
  154. if not identifier:
  155. return
  156. cb = QtWidgets.QApplication.clipboard()
  157. cb.setText(identifier, QtGui.QClipboard.Selection )
  158. cb.setText(identifier, QtGui.QClipboard.Clipboard )
  159. #
  160. # Copy the prim path to clipboard, if there is one
  161. #
  162. class CopyPathMenuItem(LayerStackContextMenuItem):
  163. def GetText(self):
  164. return "Copy Object Path"
  165. def RunCommand(self):
  166. if not self._item:
  167. return
  168. path = getattr(self._item, "path")
  169. if not path:
  170. return
  171. path = str(path)
  172. cb = QtWidgets.QApplication.clipboard()
  173. cb.setText(path, QtGui.QClipboard.Selection )
  174. cb.setText(path, QtGui.QClipboard.Clipboard )
  175. def IsEnabled(self):
  176. return hasattr(self._item, "path")