Esempio n. 1
0
    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)
Esempio n. 2
0
    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
Esempio n. 3
0
    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
            )
Esempio n. 4
0
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")
Esempio n. 5
0
    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()
Esempio n. 6
0
    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)
Esempio n. 7
0
    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
Esempio n. 9
0
    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)
Esempio n. 10
0
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
Esempio n. 11
0
    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)