def state(self, value): """ set the current state of the window """ # if state isn't changing do not do anything if self.__state == value: return # update tracker variable self.__state = value if self.__state == self.STATE_PINNED: self._set_window_mask() self.__move_to_systray() if not is_windows(): # Setting this on Windows doesn't actually alter the visual look when docked, # however switching to and back from pinned mode results in a # old style desktop window frame being used. So we just don't set the FramelessWindowHint # on Windows. # It feels like this fix doesn't get to the bottom of the true issue here though. self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) osutils.make_app_background() elif self.__state == self.STATE_WINDOWED: self._set_window_mask() if not is_windows(): self.setWindowFlags(self.windowFlags() & ~QtCore.Qt.FramelessWindowHint) self.show() self.raise_() osutils.make_app_foreground() else: raise ValueError("Unknown value for state: %s" % value) self.systray_state_changed.emit(self.__state)
def _find_software(self): """ Find executables in the Registry for Windows :returns: List of :class:`SoftwareVersion` instances """ sw_versions = [] if is_windows(): # Determine a list of paths to search for VRED executables based # on the windows registry install_paths_dicts = _get_installation_paths_from_windows_registry( self.logger) for install_paths in install_paths_dicts: executable_version = self._map_version_year( install_paths["version"]) executable_path = install_paths["path"] launcher_name = install_paths["_name"] icon_file = self._icon_from_executable(launcher_name) # Create The actual SoftwareVersions sw_versions.append( SoftwareVersion( executable_version, launcher_name, executable_path, icon_file, )) return sw_versions
def _launch_viewer(self, path): """ Launches an image viewer based on config settings. We assume that the path to the image is just passed as a param to the viewer. This seems to be standard for most apps. """ try: app_path = None if util.is_linux(): app_path = self.get_setting("viewer_path_linux") cmd = '%s "%s" &' % (app_path, path) elif util.is_macos(): app_path = self.get_setting("viewer_path_mac") cmd = 'open -n "%s" --args "%s"' % (app_path, path) elif util.is_windows(): app_path = self.get_setting("viewer_path_windows") cmd = 'start /B "Maya" "%s" "%s"' % (app_path, path) if not app_path: raise KeyError() except KeyError: raise Exception("Platform '%s' is not supported." % sys.platform) self.log_debug("Executing launch command '%s'" % cmd) exit_code = os.system(cmd) if exit_code != 0: self.log_error( "Failed to launch Viewer! This is most likely because the path " "to the viewer executable is not set to a correct value. The " "current value is '%s' - please double check that this path " "is valid and update as needed in this app's configuration. " "If you have any questions, don't hesitate to contact support " "on [email protected]." % app_path )
def get_adobe_cep_dir(): # the CEP install directory is OS-specific if util.is_windows(): app_data = os.getenv("APPDATA") elif util.is_macos(): app_data = os.path.expanduser("~/Library/Application Support") else: raise Exception("This engine only runs on OSX & Windows.") # the adobe CEP install directory. This is where the extension is stored. return os.path.join(app_data, "Adobe", "CEP", "extensions")
def get_dialog_parent(self): """ Get the QWidget parent for all dialogs created through show_dialog & show_modal. """ # determine the parent widget to use: if is_windows(): # for windows, we create a proxy window parented to the # main application window that we can then set as the owner # for all Toolkit dialogs return self.get_proxy_window() return self._engine.get_parent_window()
def __init__(self, parent=None): QtGui.QMainWindow.__init__(self, parent) if sys.platform == "darwin": self.setAttribute(QtCore.Qt.WA_MacNoShadow) self.filter = self.ApplicationEventFilter(self) QtGui.QApplication.instance().installEventFilter(self.filter) if not is_windows(): # Setting this on Windows doesn't actually alter the visual look when docked, # however switching to and back from pinned mode results in a # old style desktop window frame being used. So we just don't set the FramelessWindowHint # on Windows. # It feels like this fix doesn't get to the bottom of the true issue here though. self.setWindowFlags(self.windowFlags() | QtCore.Qt.FramelessWindowHint) self.__state = None # pinned or windowed self.__anchor_side = None # which side the anchor is currently pinned on self.__content_layout = ( None # layout whose margin will be set to contain the anchor ) self.__mouse_down_pos = None # track position when dragging self.__mouse_down_global = None # track global position when dragging # setup the anchor self.__bottom_anchor = QtGui.QPixmap(":/tk-desktop/anchor_arrow.png") self.__top_anchor = self.__bottom_anchor.transformed( QtGui.QTransform(1, 0, 0, -1, 0, 0)) self.__right_anchor = self.__bottom_anchor.transformed( QtGui.QTransform(0, 1, 1, 0, 0, 0)) self.__left_anchor = self.__bottom_anchor.transformed( QtGui.QTransform(0, 1, -1, 0, 0, 0)) # radius for rounded corners self.__corner_radius = 4 # widgets that will trigger the drag to move behavior self.__drag_widgets = [] # create the system tray icon self.systray = ShotgunSystemTrayIcon(self) self.systray.show() # hook up handler for when the systray is clicked self.systray.clicked.connect(self.systray_clicked)
def launch(self, path): self.log_debug("Launching default system viewer for file %s" % path) # run the app if util.is_linux(): cmd = 'xdg-open "%s"' % path elif util.is_macos(): cmd = 'open "%s"' % path elif util.is_windows(): cmd = 'cmd.exe /C start "file" "%s"' % path else: raise Exception("Platform '%s' is not supported." % sys.platform) self.log_debug("Executing command '%s'" % cmd) exit_code = os.system(cmd) if exit_code != 0: self.log_error("Failed to launch '%s'!" % cmd)
def _get_published_file_path(published_file): """ Return the path on disk for the given published file. :param published_file: The PublishedFile entity """ if published_file is None: return None path = published_file.get("path", None) if path is None: return "" # Return the local path right away, if we have it if path.get("local_path", None) is not None: return path["local_path"] # This published file came from a zero config publish, it will # have a file URL rather than a local path. path_on_disk = path.get("url", None) if path_on_disk is not None: # We might have something like a %20, which needs to be # unquoted into a space, as an example. if "%" in path_on_disk: path_on_disk = urllib.parse.unquote(path_on_disk) # If this came from a file url via a zero-config style publish # then we'll need to remove that from the head in order to end # up with the local disk path to the file. # # On Windows, we will have a path like file:///E:/path/to/file.jpg # and we need to ditch all three of the slashes at the head. On # other operating systems it will just be file:///path/to/file.jpg # and we will want to keep the leading slash. if util.is_windows(): pattern = r"^file:///" else: pattern = r"^file://" path_on_disk = re.sub(pattern, "", path_on_disk) return path_on_disk
def _jump_to_fs(self): """ Jump from a context to the filesystem. """ # launch one window for each location on disk paths = self._engine.context.filesystem_locations for disk_location in paths: if is_linux(): cmd = 'xdg-open "%s"' % disk_location elif is_macos(): cmd = 'open "%s"' % disk_location elif is_windows(): cmd = 'cmd.exe /C start "Folder" "%s"' % disk_location else: raise Exception("Platform is not supported.") self._engine.logger.debug("Jump to filesystem command: {}".format(cmd)) exit_code = os.system(cmd) if exit_code != 0: self._engine.logger.error("Failed to launch '%s'!", cmd)
import sys try: from . import tk_framework_adobe from . import tk_framework_adobe_utils except ImportError: pass from .tk_framework_adobe import adobe_bridge from sgtk import util if util.is_windows(): from .tk_framework_adobe_utils import win_32_api
def launch_publish(self, entity_type, entity_ids): published_file_entity_type = sgtk.util.get_published_file_entity_type(self.sgtk) if entity_type not in [published_file_entity_type, "Version"]: raise Exception( "Sorry, this app only works with entities of type %s or Version." % published_file_entity_type ) if len(entity_ids) != 1: raise Exception("Action only accepts a single item.") if entity_type == "Version": # entity is a version so try to get the id # of the published file it is linked to: if published_file_entity_type == "PublishedFile": v = self.shotgun.find_one( "Version", [["id", "is", entity_ids[0]]], ["published_files"] ) if not v.get("published_files"): self.log_error( "Sorry, this can only be used on Versions with an associated Published File." ) return publish_id = v["published_files"][0]["id"] else: # == "TankPublishedFile": v = self.shotgun.find_one( "Version", [["id", "is", entity_ids[0]]], ["tank_published_file"] ) if not v.get("tank_published_file"): self.log_error( "Sorry, this can only be used on Versions with an associated Published File." ) return publish_id = v["tank_published_file"]["id"] else: publish_id = entity_ids[0] # first get the path to the file on the local platform d = self.shotgun.find_one( published_file_entity_type, [["id", "is", publish_id]], ["path", "task", "entity"], ) path_on_disk = d.get("path").get("local_path") # If this PublishedFile came from a zero config publish, it will # have a file URL rather than a local path. if path_on_disk is None: path_on_disk = d.get("path").get("url") if path_on_disk is not None: # We might have something like a %20, which needs to be # unquoted into a space, as an example. if "%" in path_on_disk: path_on_disk = urllib.parse.unquote(path_on_disk) # If this came from a file url via a zero-config style publish # then we'll need to remove that from the head in order to end # up with the local disk path to the file. # # On Windows, we will have a path like file:///E:/path/to/file.jpg # and we need to ditch all three of the slashes at the head. On # other operating systems it will just be file:///path/to/file.jpg # and we will want to keep the leading slash. if util.is_windows(): pattern = r"^file:///" else: pattern = r"^file://" path_on_disk = re.sub(pattern, "", path_on_disk) else: self.log_error( "Unable to determine the path on disk for entity id=%s." % publish_id ) # first check if we should pass this to the viewer # hopefully this will cover most image sequence types # any image sequence types not passed to the viewer # will fail later when we check if the file exists on disk for x in self.get_setting("viewer_extensions", {}): if path_on_disk.endswith(".%s" % x): self._launch_viewer(path_on_disk) return # check that it exists if not os.path.exists(path_on_disk): self.log_error( "The file associated with this publish, " "%s, cannot be found on disk!" % path_on_disk ) return # now get the context - try to be as inclusive as possible here: # start with the task, if that doesn't work, fall back onto the path # this is because some paths don't include all the metadata that # is contained inside the publish record (e.g typically not the task) if d.get("task"): ctx = self.sgtk.context_from_entity("Task", d.get("task").get("id")) else: ctx = self.sgtk.context_from_path(path_on_disk) # call out to the hook try: launched = self.execute_hook( "hook_launch_publish", path=path_on_disk, context=ctx, associated_entity=d.get("entity"), ) except TankError as e: self.log_error( "Failed to launch an application for this published file: %s" % e ) return if not launched: # hook didn't know how to launch this # just use std associated file launch self.launch(path_on_disk)