Beispiel #1
0
    def __init__(self, *args, **kwargs):
        '''Initialise widget.'''
        super(ThumbnailDropZone, self).__init__(*args, **kwargs)

        self.setObjectName('ftrack-connect-pipeline-thumbnail-drop-zone')

        layout = QtWidgets.QHBoxLayout()
        layout.addSpacing(0)
        layout.setContentsMargins(0, 0, 0, 0)
        self.setLayout(layout)

        self.setAcceptDrops(True)
        self.setProperty('ftrackDropZone', True)

        self._filePath = None
        self._imageWidth = 200
        self._imageHeight = 50

        self.thumbnail_button = QtWidgets.QPushButton('Import')
        self.setDropZoneText()
        layout.addWidget(self.thumbnail_button, 10)

        # TODO: Add theme support.
        removeIcon = QtGui.QIcon(QtGui.QPixmap(':/ftrack/image/light/trash'))
        self.removeButton = QtWidgets.QPushButton()
        self.removeButton.setVisible(False)
        self.removeButton.setFlat(True)
        self.removeButton.setIcon(removeIcon)
        self.removeButton.clicked.connect(self.removeThumbnail)

        layout.addWidget(self.removeButton, 0)
        self.thumbnail_button.clicked.connect(self.on_button_clicked)
    def __init__(self, *args, **kwargs):
        '''Instantiate the entity selector widget.'''
        super(EntitySelector, self).__init__(*args, **kwargs)
        self._entity = None

        # Create widget used to select an entity.
        selectionWidget = QtWidgets.QFrame()
        selectionWidget.setLayout(QtWidgets.QHBoxLayout())
        selectionWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.insertWidget(0, selectionWidget)

        self.entityBrowser = _entity_browser.EntityBrowser(parent=self)
        self.entityBrowser.setMinimumSize(600, 400)
        self.entityBrowser.selectionChanged.connect(
            self._onEntityBrowserSelectionChanged)

        self.entityBrowseButton = QtWidgets.QPushButton('Browse')

        # TODO: Once the link is available through the API change this to a
        # combo with assigned tasks.
        self.assignedContextSelector = QtWidgets.QLineEdit()
        self.assignedContextSelector.setReadOnly(True)

        selectionWidget.layout().addWidget(self.assignedContextSelector)
        selectionWidget.layout().addWidget(self.entityBrowseButton)

        # Create widget used to present current selection.
        presentationWidget = QtWidgets.QFrame()
        presentationWidget.setLayout(QtWidgets.QHBoxLayout())
        presentationWidget.layout().setContentsMargins(0, 0, 0, 0)
        self.insertWidget(1, presentationWidget)

        self.entityPath = _entity_path.EntityPath()
        presentationWidget.layout().addWidget(self.entityPath)

        self.discardEntityButton = QtWidgets.QPushButton()
        removeIcon = QtGui.QIcon(QtGui.QPixmap(':/ftrack/image/light/remove'))
        self.discardEntityButton.setIconSize(QtCore.QSize(20, 20))
        self.discardEntityButton.setIcon(removeIcon)
        self.discardEntityButton.setFixedWidth(20)
        self.discardEntityButton.clicked.connect(
            self._onDiscardEntityButtonClicked)

        presentationWidget.layout().addWidget(self.discardEntityButton)

        self.entityChanged.connect(self.entityPath.setEntity)
        self.entityChanged.connect(self._updateIndex)
        self.entityBrowseButton.clicked.connect(
            self._onEntityBrowseButtonClicked)
Beispiel #3
0
    def __init__(self, parent=None):
        '''Initialise widget with *parent*'''
        super(Notification, self).__init__(parent=parent)

        self._context = defaultdict(list)

        layout = QtWidgets.QVBoxLayout()

        toolbar = QtWidgets.QHBoxLayout()

        self.setLayout(layout)

        reloadIcon = QtGui.QIcon(QtGui.QPixmap(':/ftrack/image/dark/reload'))

        self.reloadButton = QtWidgets.QPushButton(reloadIcon, '')
        self.reloadButton.clicked.connect(self.reload)

        toolbar.addWidget(QtWidgets.QWidget(), stretch=1)
        toolbar.addWidget(self.reloadButton, stretch=0)

        layout.addLayout(toolbar)

        self._list = NotificationList(self)
        self._list.setObjectName('notification-list')
        layout.addWidget(self._list, stretch=1)

        self.overlay = ftrack_connect.ui.widget.overlay.BusyOverlay(
            self, message='Loading')

        self.overlay.hide()

        self.loadStarted.connect(self._onLoadStarted)
        self.loadEnded.connect(self._onLoadEnded)
Beispiel #4
0
    def refresh(self):
        '''Refresh content.'''
        layout = self._list_instances_layout

        general_options = self.publish_asset.get_options()
        if general_options:
            settings_widget = self.settings_provider(
                label=None,
                options=general_options,
                store=self.general_options_store)
            self._list_items_settings_layout.insertWidget(0, settings_widget)

        items = self.publish_asset.get_publish_items()

        self.list_items_view = ListItemsWidget(items)
        self.list_items_view.itemChanged.connect(self.on_selection_changed)

        scene_select_button = QtWidgets.QPushButton('Scene selection')

        scene_select_button.clicked.connect(self._on_sync_scene_selection)
        layout.addWidget(scene_select_button)

        layout.addWidget(self.list_items_view, stretch=0)

        for item in items:
            if item.get('value') is True:
                self.add_instance_settings(item)

        self.list_items_view.setFocus()
Beispiel #5
0
    def __init__(self, currentEntity, parent=None):
        '''Initialise with the *currentEntity* and *parent* widget.'''
        super(ContextSelector, self).__init__(parent=parent)
        self.setObjectName('context-selector-widget')
        self._entity = currentEntity
        self.entityBrowser = EntityBrowser()
        self.entityBrowser.setMinimumWidth(600)
        self.entityPath = EntityPath()

        self.entityBrowseButton = QtWidgets.QPushButton('Change')
        self.entityBrowseButton.setFixedWidth(110)
        self.entityBrowseButton.setFixedHeight(35)

        layout = QtWidgets.QHBoxLayout()
        layout.setContentsMargins(10, 0, 10, 0)
        self.setMinimumHeight(50)
        self.setLayout(layout)

        layout.addWidget(self.entityPath)
        layout.addWidget(self.entityBrowseButton)

        self.entityBrowseButton.clicked.connect(
            self._onEntityBrowseButtonClicked
        )
        self.entityChanged.connect(self.entityPath.setEntity)
        self.entityBrowser.selectionChanged.connect(
            self._onEntityBrowserSelectionChanged
        )
        self.setEntity(self._entity)
    def __init__(self, *args, **kwargs):
        '''Initialise DataDropZone widget.'''
        super(DataDropZone, self).__init__(*args, **kwargs)

        self.log = logging.getLogger(__name__ + '.' + self.__class__.__name__)
        self.setAcceptDrops(True)
        self.setObjectName('ftrack-connect-publisher-browse-button')
        self.setProperty('ftrackDropZone', True)

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        bottomCenterAlignment = QtCore.Qt.AlignBottom | QtCore.Qt.AlignHCenter
        topCenterAlignment = QtCore.Qt.AlignTop | QtCore.Qt.AlignHCenter

        self._label = QtWidgets.QLabel('Drop files here or')
        layout.addWidget(self._label, alignment=bottomCenterAlignment)

        self._browseButton = QtWidgets.QPushButton('Browse')
        self._browseButton.setToolTip('Browse for file(s).')
        layout.addWidget(self._browseButton, alignment=topCenterAlignment)

        self._setupConnections()

        homeFolder = os.path.expanduser('~')
        if os.path.isdir(homeFolder):
            self._currentLocation = homeFolder
Beispiel #7
0
    def __init__(self, parent=None):
        '''Initiate chat widget with *chatHub*.'''
        super(Chat, self).__init__(parent)

        self.setLayout(QtWidgets.QVBoxLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().setSpacing(0)
        self.setObjectName('chat-widget')

        self._chatFeed = Feed(parent)
        self.layout().addWidget(self._chatFeed, stretch=1)

        self._messageArea = ChatTextEdit(self)
        self._messageArea.setMinimumHeight(30)
        self._messageArea.setMaximumHeight(75)
        self._messageArea.returnPressed.connect(self.onReturnPressed)
        self.layout().addWidget(self._messageArea, stretch=0)

        self._sendMessageButton = QtWidgets.QPushButton('Submit')
        self.layout().addWidget(self._sendMessageButton, stretch=0)

        self._sendMessageButton.clicked.connect(self.onReturnPressed)

        self.busyOverlay = ftrack_connect.ui.widget.overlay.BusyOverlay(
            self, message='Loading')
        self.hideOverlay()
Beispiel #8
0
    def create_overlay_widgets(self, congrat_text, success_text):
        '''Create overlay widgets to report publish result.'''

        self.activeWidget = QtWidgets.QWidget()
        self.activeWidget.setLayout(QtWidgets.QVBoxLayout())
        self.layout().addWidget(self.activeWidget)
        main_layout = self.activeWidget.layout()

        icon = QtGui.QPixmap(':ftrack/image/default/ftrackLogoLabelNew')
        icon = icon.scaled(QtCore.QSize(85, 85), QtCore.Qt.KeepAspectRatio,
                           QtCore.Qt.SmoothTransformation)

        self.ftrack_icon = QtWidgets.QLabel()
        self.ftrack_icon.setPixmap(icon)

        main_layout.addStretch(1)
        main_layout.insertWidget(1,
                                 self.ftrack_icon,
                                 alignment=QtCore.Qt.AlignCenter)

        congrat_label = QtWidgets.QLabel(congrat_text)
        congrat_label.setAlignment(QtCore.Qt.AlignCenter)

        success_label = QtWidgets.QLabel(success_text)
        success_label.setAlignment(QtCore.Qt.AlignCenter)

        main_layout.addWidget(congrat_label)
        main_layout.addWidget(success_label)
        main_layout.addStretch(1)

        buttons_layout = QtWidgets.QHBoxLayout()

        main_layout.addLayout(buttons_layout)

        self.details_button = QtWidgets.QPushButton('Details')
        buttons_layout.addWidget(self.details_button)
        self.details_button.clicked.connect(self.on_show_details)

        if self.details_window_callback is None:
            self.details_button.setDisabled(True)

        self.open_in_ftrack = QtWidgets.QPushButton('Open in ftrack')
        buttons_layout.addWidget(self.open_in_ftrack)
        self.open_in_ftrack.clicked.connect(self.on_open_in_ftrack)

        if self.asset_version is None:
            self.open_in_ftrack.setDisabled(True)
Beispiel #9
0
 def __init__(self, parent, message=''):
     super(PublisherBlockingOverlay, self).__init__(parent, message=message)
     self.confirmButton = QtWidgets.QPushButton('Ok')
     self.contentLayout.insertWidget(3,
                                     self.confirmButton,
                                     alignment=QtCore.Qt.AlignCenter,
                                     stretch=0)
     self.confirmButton.hide()
     self.confirmButton.clicked.connect(self.hide)
     self.content.setMinimumWidth(350)
Beispiel #10
0
    def __init__(
        self, parent,
        icon=':ftrack/image/default/ftrackLogoColor'
    ):
        super(AboutDialog, self).__init__(parent)

        layout = QtWidgets.QVBoxLayout()
        layout.setContentsMargins(20, 20, 20, 20)
        layout.setSizeConstraint(QtWidgets.QLayout.SetFixedSize)
        self.setLayout(layout)

        self.icon = QtWidgets.QLabel()
        pixmap = QtGui.QPixmap(icon)
        self.icon.setPixmap(
            pixmap.scaledToHeight(36, mode=QtCore.Qt.SmoothTransformation)
        )
        self.icon.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.icon)

        self.messageLabel = QtWidgets.QLabel()
        self.messageLabel.setWordWrap(True)
        self.messageLabel.setAlignment(QtCore.Qt.AlignLeft)
        layout.addWidget(self.messageLabel)

        layout.addSpacing(25)

        self.debugButton = QtWidgets.QPushButton('More info')
        self.debugButton.clicked.connect(self._onDebugButtonClicked)

        layout.addWidget(self.debugButton)

        self.loggingButton = QtWidgets.QPushButton('Open log directory')
        self.loggingButton.clicked.connect(self._onLoggingButtonClicked)

        layout.addWidget(self.loggingButton)

        self.debugTextEdit = QtWidgets.QTextEdit()
        self.debugTextEdit.setReadOnly(True)
        self.debugTextEdit.setFontPointSize(10)
        self.debugTextEdit.hide()
        layout.addWidget(self.debugTextEdit)
Beispiel #11
0
    def __init__(self, parent, message='Processing'):
        '''Initialise with *parent* and busy *message*.'''
        super(CancelOverlay, self).__init__(parent, message=message)

        self.contentLayout.addSpacing(10)

        loginButton = QtWidgets.QPushButton(text='Cancel')
        loginButton.clicked.connect(self.hide)

        self.contentLayout.addWidget(
            loginButton, alignment=QtCore.Qt.AlignCenter
        )
Beispiel #12
0
    def __init__(self, title=None, description=None, data=None, parent=None):
        '''Initialise time log.

        *title* should be the title entry to display for the time log whilst
        *description* can provide an optional longer description.

        *data* is optional data that can be stored for future reference (for
        example a link to an ftrack task that the time log represents).

        *parent* should be the optional parent of this widget.

        '''
        super(TimeLog, self).__init__(parent=parent)
        self.setObjectName('time-log')
        self._data = None

        layout = QtWidgets.QHBoxLayout()
        self.setLayout(layout)

        self.labelLayout = QtWidgets.QVBoxLayout()
        layout.addLayout(self.labelLayout, stretch=1)

        self.titleLabel = ftrack_connect.ui.widget.label.Label()
        self.titleLabel.setProperty('title', True)
        self.labelLayout.addWidget(self.titleLabel)

        self.descriptionLabel = ftrack_connect.ui.widget.label.Label()
        self.labelLayout.addWidget(self.descriptionLabel)

        # TODO: Add theme support.
        playIcon = QtGui.QIcon(
            QtGui.QPixmap(':/ftrack/image/light/play')
        )

        self.playButton = QtWidgets.QPushButton(playIcon, '')
        self.playButton.setFlat(True)
        self.playButton.clicked.connect(self._onPlayButtonClicked)
        layout.addWidget(self.playButton)

        self.setSizePolicy(
            QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed
        )

        # Set initial values.
        self.setValue({
            'title': title,
            'description': description,
            'data': data
        })
Beispiel #13
0
    def __init__(self, *args, **kwargs):
        '''Instantiate the time tracker.'''
        super(TimeTracker, self).__init__(*args, **kwargs)
        self.setObjectName('timeTracker')

        self._activeEntity = None

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        self.activeLabel = QtWidgets.QLabel('Currently running')
        self.activeLabel.setProperty('title', True)
        layout.addWidget(self.activeLabel)

        self._timerEnabled = False
        self.timer = ftrack_connect.ui.widget.timer.Timer()
        layout.addWidget(self.timer)

        self.timerPlaceholder = TimerOverlay(self.timer)

        # TODO: Add theme support.
        reloadIcon = QtGui.QIcon(QtGui.QPixmap(':/ftrack/image/light/reload'))

        assignedTimeLogUpdateButton = QtWidgets.QPushButton(reloadIcon, '')
        assignedTimeLogUpdateButton.setFlat(True)
        assignedTimeLogUpdateButton.setToolTip('Refresh list')
        assignedTimeLogUpdateButton.clicked.connect(self._updateAssignedList)

        self.assignedTimeLogList = _TimeLogList(
            title='Assigned', headerWidgets=[assignedTimeLogUpdateButton])
        layout.addWidget(self.assignedTimeLogList, stretch=1)

        # Connect events.
        self.timer.stopped.connect(self._onCommitTime)
        self.timer.timeEdited.connect(self._onCommitTime)

        self.assignedTimeLogList.itemSelected.connect(self._onSelectTimeLog)

        self.blockingOverlay = TimeTrackerBlockingOverlay(
            self, 'Time tracker is currently disabled during beta.')
        self.blockingOverlay.show()

        self._updateAssignedList()
    def __init__(self, results):
        '''Instantiate and show results.'''
        super(Dialog, self).__init__()
        self.setObjectName('ftrack-result-dialog')
        self.setMinimumSize(1080, 720)
        main_layout = QtWidgets.QVBoxLayout(self)
        self.setLayout(main_layout)

        filter_layout = QtWidgets.QHBoxLayout()
        filter_label = QtWidgets.QLabel('Filter log')
        self.filter_field = QtWidgets.QLineEdit()
        self.filter_field.setObjectName('ftrack-log-filter-field')
        self.filter_field.textChanged.connect(self.on_search)

        filter_layout.addWidget(filter_label)
        filter_layout.addWidget(self.filter_field)
        main_layout.addLayout(filter_layout)

        log_list = QtWidgets.QTableView()
        log_list.verticalHeader().hide()

        log_list.setObjectName('ftrack-log-view')
        log_list.setAlternatingRowColors(True)
        log_list.setSelectionBehavior(QtWidgets.QAbstractItemView.SelectRows)
        log_list.horizontalHeader().setStretchLastSection(True)
        log_items = self._parse_results(results)

        log_model = ftrack_connect_pipeline.ui.model.log_table.LogTableModel(
            self, log_items)
        self.log_sort_model = ftrack_connect_pipeline.ui.model.log_table.FilterProxyModel(
        )
        self.log_sort_model.setDynamicSortFilter(True)
        self.log_sort_model.setSourceModel(log_model)
        log_list.setModel(self.log_sort_model)

        main_layout.addWidget(log_list)

        open_log_folder_button = QtWidgets.QPushButton('Open log directory')
        open_log_folder_button.clicked.connect(self._on_logging_button_clicked)
        main_layout.addWidget(open_log_folder_button)
    def __init__(self, currentEntity, parent=None):
        '''Initialise with the *currentEntity* and *parent* widget.'''
        super(ContextSelector, self).__init__(parent=parent)
        self._entity = currentEntity
        self.entityBrowser = entityBrowser.EntityBrowser()
        self.entityBrowser.setMinimumWidth(600)
        self.entityPath = entityPath.EntityPath()
        self.entityBrowseButton = QtWidgets.QPushButton('Browse')
        applyTheme(self.entityBrowser, 'integration')
        layout = QtWidgets.QHBoxLayout()
        layout.setContentsMargins(0, 0, 0, 0)

        self.setLayout(layout)

        layout.addWidget(self.entityPath)
        layout.addWidget(self.entityBrowseButton)

        self.entityBrowseButton.clicked.connect(
            self._onEntityBrowseButtonClicked)
        self.entityChanged.connect(self.entityPath.setEntity)
        self.entityBrowser.selectionChanged.connect(
            self._onEntityBrowserSelectionChanged)
    def build(self):
        '''Build widgets and layout.'''
        self.setLayout(QtWidgets.QVBoxLayout())
        self.layout().setContentsMargins(0, 0, 0, 0)

        self.optionsLayout = QtWidgets.QHBoxLayout()
        self.assetTypeSelector = QtWidgets.QComboBox()
        self.optionsLayout.addWidget(self.assetTypeSelector)

        self.refreshButton = QtWidgets.QPushButton(self.tr('Refresh'))
        self.optionsLayout.addWidget(self.refreshButton)
        self.optionsLayout.addStretch(1)

        self.layout().addLayout(self.optionsLayout)

        self.assetTable = QtWidgets.QTableWidget()
        self.assetTable.setEditTriggers(
            QtWidgets.QAbstractItemView.NoEditTriggers)
        self.assetTable.setSelectionMode(
            QtWidgets.QAbstractItemView.SingleSelection)
        self.assetTable.setSelectionBehavior(
            QtWidgets.QAbstractItemView.SelectRows)

        self.assetTable.setColumnCount(len(self.assetTableColumns))
        self.assetTable.setRowCount(0)
        self.assetTable.verticalHeader().hide()

        self.assetTable.setHorizontalHeaderLabels(self.assetTableColumns)

        horizontalHeader = self.assetTable.horizontalHeader()
        horizontalHeader.setResizeMode(QtWidgets.QHeaderView.Fixed)

        self.assetTable.horizontalHeader().setDefaultSectionSize(100)
        self.assetTable.setColumnWidth(1, 63)
        self.assetTable.horizontalHeader().setResizeMode(
            0, QtWidgets.QHeaderView.Stretch)

        self.layout().addWidget(self.assetTable)
Beispiel #17
0
    def _construct(self):
        '''Construct widget.'''
        self.setLayout(QtWidgets.QVBoxLayout())

        self.headerLayout = QtWidgets.QHBoxLayout()

        self.navigationBar = QtWidgets.QTabBar()
        self.navigationBar.setExpanding(False)
        self.navigationBar.setDrawBase(False)
        self.headerLayout.addWidget(self.navigationBar, stretch=1)

        self.navigateUpButton = QtWidgets.QToolButton()
        self.navigateUpButton.setObjectName('entity-browser-up-button')
        self.navigateUpButton.setIcon(
            QtGui.QIcon(':ftrack/image/light/upArrow')
        )
        self.navigateUpButton.setToolTip('Navigate up a level.')
        self.headerLayout.addWidget(self.navigateUpButton)

        self.reloadButton = QtWidgets.QToolButton()
        self.reloadButton.setObjectName('entity-browser-reload-button')

        self.reloadButton.setIcon(
            QtGui.QIcon(':ftrack/image/light/reload')
        )
        self.reloadButton.setToolTip('Reload listing from server.')
        self.headerLayout.addWidget(self.reloadButton)

        self.layout().addLayout(self.headerLayout)

        self.contentSplitter = QtWidgets.QSplitter()

        self.bookmarksList = QtWidgets.QListView()
        self.contentSplitter.addWidget(self.bookmarksList)

        self.view = QtWidgets.QTableView()
        self.view.setSelectionBehavior(self.view.SelectRows)
        self.view.setSelectionMode(self.view.SingleSelection)
        self.view.verticalHeader().hide()

        self.contentSplitter.addWidget(self.view)

        proxy = ftrack_connect_pipeline.ui.model.entity_tree.EntityTreeProxyModel(self)
        model = ftrack_connect_pipeline.ui.model.entity_tree.EntityTreeModel(
            root=ftrack_connect_pipeline.ui.model.entity_tree.ItemFactory(
                self._session, self._root
            ),
            parent=self
        )
        proxy.setSourceModel(model)
        proxy.setDynamicSortFilter(True)

        self.view.setModel(proxy)
        self.view.setSortingEnabled(True)

        self.contentSplitter.setStretchFactor(1, 1)
        self.layout().addWidget(self.contentSplitter)

        self.footerLayout = QtWidgets.QHBoxLayout()
        self.footerLayout.addStretch(1)

        self.cancelButton = QtWidgets.QPushButton('Cancel')
        self.footerLayout.addWidget(self.cancelButton)

        self.acceptButton = QtWidgets.QPushButton('Choose')
        self.footerLayout.addWidget(self.acceptButton)

        self.layout().addLayout(self.footerLayout)

        self.overlay = ftrack_connect_pipeline.ui.widget.overlay.BusyOverlay(
            self.view, message='Loading'
        )
Beispiel #18
0
    def refreshAssetManager(self):
        '''Refresh assets in asset manager.'''
        assets = self.connector.getAssets()

        self.ui.AssertManagerTableWidget.setSortingEnabled(False)
        self.ui.AssertManagerTableWidget.setRowCount(0)

        self.ui.AssertManagerTableWidget.setRowCount(len(assets))

        component_ids = []

        for component_id, _ in assets:
            if component_id:
                component_ids.append(component_id)

        if component_ids:
            query_string = (
                'select name, version.asset.type.short, version.asset.name, '
                'version.asset.type.name, version.asset.versions.version, '
                'version.id, version.version, version.asset.versions, '
                'version.date, version.comment, version.asset.name, version, '
                'version_id, version.user.first_name, version.user.last_name '
                'from Component where id in ({0})'.format(
                    ','.join(component_ids)))
            components = self.connector.session.query(query_string).all()

            asset_ids = set()
            for component in components:
                asset_ids.add(component['version']['asset']['id'])

            if asset_ids:
                # Because of bug in 3.3.X backend we need to divide the query. The
                # memory cache will allow using entities without caring about this.
                preload_string = (
                    'select components.name from AssetVersion where '
                    'asset_id in ({0})').format(', '.join(list(asset_ids)))
                self.connector.session.query(preload_string).all()

            component_map = dict(
                (component['id'], component) for component in components)
        else:
            component_map = {}

        for i in range(len(assets)):
            if assets[i][0]:
                component = component_map[assets[i][0]]
                asset_version = component['version']
                componentNameStr = component['name']
                assetVersionNr = asset_version['version']
                asset = asset_version['asset']

                asset_versions_with_same_component_name = []
                for related_version in asset['versions']:
                    for other_component in related_version['components']:
                        if other_component['name'] == componentNameStr:
                            asset_versions_with_same_component_name.append(
                                related_version)

                asset_versions_with_same_component_name = sorted(
                    asset_versions_with_same_component_name,
                    key=lambda x: x['version'])
                latest_version_number = (
                    asset_versions_with_same_component_name[-1]['version'])

                versionIndicatorButton = QtWidgets.QPushButton('')
                if assetVersionNr == latest_version_number:
                    versionIndicatorButton.setStyleSheet('''
                        QPushButton {
                            background-color: #1CBC90;
                            border: none;
                        }
                    ''')
                    self.connector.setNodeColor(applicationObject=assets[i][1],
                                                latest=True)
                else:
                    versionIndicatorButton.setStyleSheet('''
                        QPushButton {
                            background-color: #E36316;
                            border: none;
                        }
                    ''')
                    self.connector.setNodeColor(applicationObject=assets[i][1],
                                                latest=False)
                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 0, versionIndicatorButton)

                componentName = QtWidgets.QTableWidgetItem(componentNameStr)
                self.ui.AssertManagerTableWidget.setItem(i, 1, componentName)

                componentId = QtWidgets.QTableWidgetItem(component['id'])
                self.ui.AssertManagerTableWidget.setItem(i, 2, componentId)

                assetType = QtWidgets.QTableWidgetItem(asset['type']['short'])
                self.ui.AssertManagerTableWidget.setItem(i, 3, assetType)

                assetTypeLong = QtWidgets.QTableWidgetItem(
                    asset['type']['name'])
                self.ui.AssertManagerTableWidget.setItem(i, 4, assetTypeLong)

                versionNumberComboBox = QtWidgets.QComboBox()
                for version in reversed(
                        asset_versions_with_same_component_name):
                    versionNumberComboBox.addItem(str(version['version']))

                conName = self.connector.getConnectorName()
                if conName in self.notVersionable:
                    if componentNameStr in self.notVersionable[conName]:
                        versionNumberComboBox.setEnabled(False)

                result = versionNumberComboBox.findText(str(assetVersionNr))
                versionNumberComboBox.setCurrentIndex(result)

                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 5, versionNumberComboBox)

                versionNumberComboBox.currentIndexChanged.connect(
                    self.changeVersion)

                latestVersionNumberWidget = QtWidgets.QTableWidgetItem(
                    str(latest_version_number))
                self.ui.AssertManagerTableWidget.setItem(
                    i, 6, latestVersionNumberWidget)

                assetName = QtWidgets.QTableWidgetItem(asset['name'])
                assetName.setToolTip(asset['name'])
                self.ui.AssertManagerTableWidget.setItem(i, 7, assetName)

                assetNameInScene = QtWidgets.QTableWidgetItem(assets[i][1])
                assetNameInScene.setToolTip(assets[i][1])
                self.ui.AssertManagerTableWidget.setItem(
                    i, 8, assetNameInScene)

                selectButton = QtWidgets.QPushButton('S')
                selectButton.setToolTip('Select asset in scene')
                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 9, selectButton)
                selectButton.clicked.connect(self.signalMapperSelect.map)

                self.signalMapperSelect.setMapping(selectButton, assets[i][1])

                replaceButton = QtWidgets.QPushButton('R')
                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 10, replaceButton)

                removeButton = QtWidgets.QPushButton()
                removeButton.setToolTip('Remove asset from scene')
                icon = QtGui.QIcon()
                icon.addPixmap(
                    QtGui.QPixmap(':ftrack/image/integration/trash'),
                    QtGui.QIcon.Normal, QtGui.QIcon.Off)
                removeButton.setIcon(icon)
                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 11, removeButton)
                removeButton.clicked.connect(self.signalMapperRemove.map)
                self.signalMapperRemove.setMapping(removeButton, assets[i][1])

                assetId = QtWidgets.QTableWidgetItem(str(asset['id']))
                self.ui.AssertManagerTableWidget.setItem(i, 12, assetId)

                assetVersionId = QtWidgets.QTableWidgetItem(
                    str(asset_version['id']))
                self.ui.AssertManagerTableWidget.setItem(i, 13, assetVersionId)

                currentVersionFallback = QtWidgets.QTableWidgetItem(
                    str(assetVersionNr))
                self.ui.AssertManagerTableWidget.setItem(
                    i, 14, currentVersionFallback)

                commentButton = QtWidgets.QPushButton()
                commentButton.setText('')
                icon = QtGui.QIcon()
                icon.addPixmap(
                    QtGui.QPixmap(':ftrack/image/integration/comment'),
                    QtGui.QIcon.Normal, QtGui.QIcon.Off)
                commentButton.setIcon(icon)

                fullUserName = (asset_version['user']['first_name'] + ' ' +
                                asset_version['user']['last_name'])
                pubDate = str(asset_version['date'])
                comment = asset_version['comment']
                tooltipText = '\n'.join([fullUserName, pubDate, comment])

                commentButton.setToolTip(tooltipText)
                self.ui.AssertManagerTableWidget.setCellWidget(
                    i, 15, commentButton)

                commentButton.clicked.connect(self.signalMapperComment.map)

                self.signalMapperComment.setMapping(commentButton,
                                                    str(asset_version['id']))

                commentButton.setEnabled(has_webwidgets)

        self.ui.AssertManagerTableWidget.setHorizontalHeaderLabels(
            self.columnHeaders)
    def onActionButtonClicked(self, row):
        '''Handle transfer request.'''
        column = self.columns.index
        actionItem = self.cellWidget(row, column('Action'))

        # TODO: Make more robust test.
        if actionItem.text() == 'Import':
            self.importComponentSignal.emit(row)

        elif actionItem.text() == 'Transfer':
            locationItem = self.cellWidget(row, column('Location'))
            locationItem.setEnabled(False)
            location = locationItem.itemData(locationItem.currentIndex())

            componentItem = self.item(row, column('Component'))
            component_id = componentItem.data(self.COMPONENT_ROLE)
            ftrack_component = self.session.get('Component', component_id)

            # Unfortunately, this will destroy the push button, so have to
            # recreate it afterwards. If Qt adds a takeCellWidget this can be
            # improved.
            transferProgressItem = QtWidgets.QProgressBar()
            transferProgressItem.setTextVisible(False)
            self.setCellWidget(row, self.columns.index('Action'),
                               transferProgressItem)

            transferProgressItem.setRange(0, 0)

            try:
                worker = Worker(
                    self.transfer,
                    [ftrack_component, None, location],
                    parent=self
                )
                worker.start()

                while worker.isRunning():
                    app = QtWidgets.QApplication.instance()
                    app.processEvents()

                if worker.error:
                    raise worker.error[1], None, worker.error[2]

            except Exception as error:
                traceback.print_exc()
                QtWidgets.QMessageBox.critical(
                    None,
                    'Transfer Failed',
                    'Could not transfer to location!'
                    '\n{0}'.format(error)
                )

            finally:
                transferProgressItem.setMaximum(1)
                transferProgressItem.reset()
                locationItem.setEnabled(True)

                # Have to recreate action button
                actionItem = QtWidgets.QPushButton()
                self.setCellWidget(row, column('Action'), actionItem)

                actionItem.clicked.connect(self.actionSignalMapper.map)
                self.actionSignalMapper.setMapping(actionItem, row)

                self.onLocationSelected(row)
    def setAssetVersion(self, assetVersionId):
        '''Update list of components for asset version with *assetVersionId*.'''
        self.clear()

        query = (
            'select id, asset, asset.type, asset.type.short, components'
            ' from AssetVersion where id is "{0}"'.format(assetVersionId)
        )
        asset_version = self.session.query(query).one()

        self.assetType = asset_version['asset']['type']['short']

        asset_version_components = asset_version['components']

        connectorName = self.connector.getConnectorName()
        # Temporary alias
        column = self.columns.index

        for component in asset_version_components:
            componentName = component['name']

            if (
                connectorName == 'nuke' and 'proxy' in componentName
            ):
                pass
            else:
                rowCount = self.rowCount()
                self.insertRow(rowCount)

                componentItem = QtWidgets.QTableWidgetItem(componentName)
                componentItem.setData(self.COMPONENT_ROLE, component['id'])

                self.setItem(
                    rowCount, column('Component'), componentItem
                )

                pathItem = QtWidgets.QTableWidgetItem('')
                self.setItem(rowCount, column('Path'), pathItem)

                availabilityItem = QtWidgets.QTableWidgetItem('')
                self.setItem(
                    rowCount, column('Availability'), availabilityItem
                )

                actionItem = QtWidgets.QPushButton()
                self.setCellWidget(rowCount, column('Action'), actionItem)

                actionItem.clicked.connect(self.actionSignalMapper.map)
                self.actionSignalMapper.setMapping(actionItem, rowCount)

                locationItem = QtWidgets.QComboBox()
                self.setCellWidget(rowCount, column('Location'), locationItem)

                # Map version widget to row number to enable simple lookup
                locationItem.currentIndexChanged[int].connect(
                    self.locationSignalMapper.map
                )
                self.locationSignalMapper.setMapping(
                    locationItem, rowCount
                )

                available_locations = []
                for location in self.locations:
                    accessor = location.accessor
                    # Don't show inaccessible locations
                    if accessor is symbol.NOT_SET:
                        continue
                    name = location['name']
                    location_id = location['id']
                    locationItem.addItem(name, location_id)
                    available_locations.append(location)

                picked_location = self.session.pick_location(component)

                try:
                    location_index = available_locations.index(picked_location)
                except ValueError:
                    location_index = 0

                locationItem.setCurrentIndex(location_index)
Beispiel #21
0
    def __init__(self,
                 label,
                 description,
                 publish_asset,
                 session,
                 settings_provider=None,
                 parent=None):
        '''Display instances that can be published.'''
        super(Workflow, self).__init__()
        self.setObjectName('ftrack-workflow-widget')
        self.session = session
        self._label_text = label
        self.publish_asset = publish_asset

        plugin = ftrack_connect_pipeline.get_plugin()
        plugin_information = plugin.get_plugin_information()
        event_metadata = {
            'workflow_label': self._label_text,
        }
        if isinstance(plugin_information, dict):
            event_metadata.update(plugin_information)

        send_usage('USED-FTRACK-CONNECT-PIPELINE-PUBLISH', event_metadata)

        self.publish_asset.prepare_publish()

        self.item_options_store = {}
        self.general_options_store = {}

        self.settings_provider = settings_provider
        if self.settings_provider is None:
            self.settings_provider = BaseSettingsProvider()

        self.settings_map = {}
        list_instances_widget = QtWidgets.QFrame()
        list_instances_widget.setObjectName('ftrack-instances-widget')

        self._list_instances_layout = QtWidgets.QVBoxLayout()

        list_instances_widget.setLayout(self._list_instances_layout)
        self._list_instances_layout.setContentsMargins(5, 5, 5, 5)

        list_instance_settings_widget = QtWidgets.QFrame()
        list_instance_settings_widget.setObjectName(
            'ftrack-instances-settings-widget')

        self._list_items_settings_layout = QtWidgets.QVBoxLayout()
        self._list_items_settings_layout.addStretch(1)
        list_instance_settings_widget.setLayout(
            self._list_items_settings_layout)
        self._list_items_settings_layout.setContentsMargins(5, 5, 5, 5)

        configuration_layout = QtWidgets.QHBoxLayout()
        configuration_layout.addWidget(list_instances_widget, stretch=1)
        configuration_layout.addWidget(list_instance_settings_widget,
                                       stretch=1)
        configuration = QtWidgets.QFrame()
        configuration.setObjectName('ftrack-configuration-widget')
        configuration.setLayout(configuration_layout)
        configuration_layout.setContentsMargins(0, 0, 0, 0)

        information_layout = QtWidgets.QHBoxLayout()
        information_layout.addWidget(
            QtWidgets.QLabel('<h3>{0}</h3>'.format(self._label_text)))
        information_layout.addWidget(QtWidgets.QLabel(
            '<i>{0}</i>'.format(description)),
                                     stretch=1)
        information = QtWidgets.QFrame()
        information.setObjectName('ftrack-information-widget')
        information.setLayout(information_layout)
        information_layout.setContentsMargins(0, 0, 0, 0)

        publish_button = QtWidgets.QPushButton('Publish')
        publish_button.clicked.connect(self.on_publish_clicked)

        main_layout = QtWidgets.QVBoxLayout(self)
        self.setLayout(main_layout)
        self.layout().setContentsMargins(0, 0, 0, 0)

        scroll = QtWidgets.QScrollArea(self)

        scroll.setWidgetResizable(True)
        scroll.setLineWidth(0)
        scroll.setFrameShape(QtWidgets.QFrame.NoFrame)
        scroll.setHorizontalScrollBarPolicy(QtCore.Qt.ScrollBarAlwaysOff)

        scroll.setWidget(configuration)

        self._list_instances_layout.addWidget(information)

        main_layout.addWidget(scroll, stretch=1)
        self._list_items_settings_layout.addWidget(publish_button)

        self._publish_overlay = BusyOverlay(self,
                                            message='Publishing Assets...')
        self._publish_overlay.setStyleSheet(OVERLAY_DARK_STYLE)
        self._publish_overlay.setVisible(False)

        self.result_win = PublishResult(self.session, self)
        self.result_win.setStyleSheet(OVERLAY_DARK_STYLE)
        self.result_win.setVisible(False)

        self.refresh()
Beispiel #22
0
    def __init__(self, session, parent):
        '''Instantiate with *session*.'''
        super(CreateAssetTypeOverlay, self).__init__(parent=parent)
        self.session = session

        self.main_layout = QtWidgets.QVBoxLayout()
        self.setLayout(self.main_layout)

        icon = QtGui.QPixmap(':ftrack/image/default/ftrackLogoColor')
        icon = icon.scaled(QtCore.QSize(85, 85), QtCore.Qt.KeepAspectRatio,
                           QtCore.Qt.SmoothTransformation)
        self.ftrack_icon = QtWidgets.QLabel()
        self.ftrack_icon.setPixmap(icon)

        self.main_layout.addStretch(1)
        self.main_layout.insertWidget(1,
                                      self.ftrack_icon,
                                      alignment=QtCore.Qt.AlignCenter)
        self.main_layout.addStretch(1)
        self.main_layout.setContentsMargins(20, 20, 20, 20)

        # create asset type widget
        self.create_asset_widget = QtWidgets.QFrame()
        self.create_asset_widget.setVisible(False)

        create_asset_layout = QtWidgets.QVBoxLayout()
        create_asset_layout.setContentsMargins(20, 20, 20, 20)
        create_asset_layout.addStretch(1)
        buttons_layout = QtWidgets.QHBoxLayout()
        self.create_asset_widget.setLayout(create_asset_layout)

        self.create_asset_label_top = QtWidgets.QLabel()

        self.create_asset_label_bottom = QtWidgets.QLabel(
            '<h4>Do you want to create one ?</h4>')

        create_asset_layout.insertWidget(1,
                                         self.create_asset_label_top,
                                         alignment=QtCore.Qt.AlignCenter)
        create_asset_layout.insertWidget(2,
                                         self.create_asset_label_bottom,
                                         alignment=QtCore.Qt.AlignCenter)
        self.create_asset_button = QtWidgets.QPushButton('Create')
        self.cancel_asset_button = QtWidgets.QPushButton('Cancel')
        create_asset_layout.addLayout(buttons_layout)
        buttons_layout.addWidget(self.create_asset_button)
        buttons_layout.addWidget(self.cancel_asset_button)

        # result create asset type
        self.create_asset_widget_result = QtWidgets.QFrame()
        self.create_asset_widget_result.setVisible(False)

        create_asset_layout_result = QtWidgets.QVBoxLayout()
        create_asset_layout_result.setContentsMargins(20, 20, 20, 20)
        create_asset_layout_result.addStretch(1)

        self.create_asset_widget_result.setLayout(create_asset_layout_result)
        self.create_asset_label_result = QtWidgets.QLabel()
        self.continue_button = QtWidgets.QPushButton('Continue')

        create_asset_layout_result.insertWidget(
            1, self.create_asset_label_result, alignment=QtCore.Qt.AlignCenter)

        create_asset_layout_result.insertWidget(
            2, self.continue_button, alignment=QtCore.Qt.AlignCenter)

        # error on create asset
        self.create_asset_widget_error = QtWidgets.QFrame()
        self.create_asset_widget_error.setVisible(False)

        create_asset_layout_error = QtWidgets.QVBoxLayout()
        create_asset_layout_error.setContentsMargins(20, 20, 20, 20)
        create_asset_layout_error.addStretch(1)

        self.create_asset_widget_error.setLayout(create_asset_layout_error)
        self.create_asset_label_error = QtWidgets.QLabel()
        self.close_button = QtWidgets.QPushButton('Close')

        create_asset_layout_error.insertWidget(1,
                                               self.create_asset_label_error,
                                               alignment=QtCore.Qt.AlignCenter)

        create_asset_layout_error.insertWidget(2,
                                               self.close_button,
                                               alignment=QtCore.Qt.AlignCenter)

        # parent all.
        self.main_layout.addWidget(self.create_asset_widget)
        self.main_layout.addWidget(self.create_asset_widget_result)
        self.main_layout.addWidget(self.create_asset_widget_error)

        self.main_layout.addStretch(1)

        # signals
        self.create_asset_button.clicked.connect(self.on_create_asset)
        self.continue_button.clicked.connect(self.on_continue)
        self.close_button.clicked.connect(self.on_fail)
        self.cancel_asset_button.clicked.connect(self.on_fail)
    def __init__(self, parent=None, connector=None):
        '''Instantiate widget with *connector*.'''
        if not connector:
            raise ValueError(
                'Please provide a connector object for {0}'.format(
                    self.__class__.__name__))

        super(FtrackImportAssetDialog, self).__init__(parent=parent)
        applyTheme(self, 'integration')

        #---------------------------------------------------------------------------#
        # Add for proper hou colors
        try:
            import hou
            self.stylesheet = '%s; background-color: #3a3a3a; color: #FFFFFF;' % hou.qt.styleSheet(
            )
            self.setStyleSheet(self.stylesheet)
        except:
            pass
#---------------------------------------------------------------------------#

        self.connector = connector
        self.currentEntity = ftrack.Task(
            os.getenv('FTRACK_TASKID', os.getenv('FTRACK_SHOTID')))

        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                           QtWidgets.QSizePolicy.Expanding)

        self.setMinimumWidth(600)

        self.mainLayout = QtWidgets.QVBoxLayout(self)
        self.setLayout(self.mainLayout)

        self.mainLayout.setContentsMargins(0, 0, 0, 0)
        self.mainLayout.setSpacing(0)

        self.scrollArea = QtWidgets.QScrollArea(self)
        self.mainLayout.addWidget(self.scrollArea)

        self.scrollArea.setWidgetResizable(True)
        self.scrollArea.setObjectName("scrollArea")
        self.scrollArea.setLineWidth(0)
        self.scrollArea.setFrameShape(QtWidgets.QFrame.NoFrame)
        self.scrollArea.setHorizontalScrollBarPolicy(
            QtCore.Qt.ScrollBarAlwaysOff)

        self.mainWidget = QtWidgets.QWidget(self)
        self.scrollArea.setWidget(self.mainWidget)

        self.verticalLayout = QtWidgets.QVBoxLayout()
        self.mainWidget.setLayout(self.verticalLayout)

        self.headerWidget = header.Header(getpass.getuser(), self)
        self.verticalLayout.addWidget(self.headerWidget, stretch=0)

        self.browseTasksWidget = ContextSelector(
            currentEntity=self.currentEntity, parent=self)

        self.verticalLayout.addWidget(self.browseTasksWidget, stretch=0)

        self.listAssetsTableWidget = ListAssetsTableWidget(self)

        self.verticalLayout.addWidget(self.listAssetsTableWidget, stretch=4)

        # Horizontal line
        self.divider = QtWidgets.QFrame()
        self.divider.setFrameShape(QtWidgets.QFrame.HLine)
        self.divider.setFrameShadow(QtWidgets.QFrame.Sunken)
        self.divider.setLineWidth(2)

        self.verticalLayout.addWidget(self.divider)

        self.assetVersionDetailsWidget = AssetVersionDetailsWidget(
            self, connector=self.connector)

        self.verticalLayout.addWidget(self.assetVersionDetailsWidget,
                                      stretch=0)

        self.componentTableWidget = ComponentTableWidget(
            self, connector=self.connector)

        self.verticalLayout.addWidget(self.componentTableWidget, stretch=3)

        self.horizontalLayout = QtWidgets.QHBoxLayout()
        self.verticalLayout.addLayout(self.horizontalLayout)

        self.importAllButton = QtWidgets.QPushButton("Import All")
        self.importAllButton.setFixedWidth(120)
        self.importAllButton.setObjectName('ftrack-import-btn')

        self.importSelectedButton = QtWidgets.QPushButton("Import Selected")
        self.importSelectedButton.setFixedWidth(120)
        self.importAllButton.setObjectName('ftrack-import-btn')

        self.horizontalLayout.addWidget(self.importSelectedButton)
        self.horizontalLayout.addWidget(self.importAllButton)

        self.horizontalLayout.setAlignment(QtCore.Qt.AlignRight)

        self.importOptionsWidget = ImportOptionsWidget(
            parent=self, connector=self.connector)

        self.verticalLayout.addWidget(self.importOptionsWidget, stretch=0)

        self.messageLabel = QtWidgets.QLabel(self)
        self.messageLabel.setText(' \n ')
        self.verticalLayout.addWidget(self.messageLabel, stretch=0)

        self.setObjectName('ftrackImportAsset')
        self.setWindowTitle("ftrackImportAsset")

        panelComInstance = PanelComInstance.instance()
        panelComInstance.addSwitchedShotListener(self.reset_context_browser)

        self.browseTasksWidget.entityChanged.connect(self.clickedIdSignal)

        self.importAllButton.clicked.connect(self.importAllComponents)
        self.importSelectedButton.clicked.connect(
            self.importSelectedComponents)
        self.listAssetsTableWidget.assetVersionSelectedSignal[str].connect(
            self.clickedAssetVSignal)
        self.listAssetsTableWidget.assetTypeSelectedSignal[str].connect(
            self.importOptionsWidget.setStackedWidget)
        self.importSignal.connect(panelComInstance.refreshListeners)

        self.componentTableWidget.importComponentSignal.connect(
            self.onImportComponent)

        self.browseTasksWidget.reset()
Beispiel #24
0
    def __init__(self, title=None, description=None, time=0, parent=None):
        '''Initialise timer.

        *title* should be the title entry to display for the time log whilst
        *description* can provide an optional longer description.

        *time* should be the initial value to set elapsed time to.

        *parent* should be the optional parent of this widget.

        '''
        super(Timer, self).__init__(parent=parent)
        self.setObjectName('timer')

        self._state = self.STOPPED
        self._timer = None
        self._tick = None
        self._tickInterval = 50
        self._elapsed = 0

        layout = QtWidgets.QHBoxLayout()
        self.setLayout(layout)

        self.labelLayout = QtWidgets.QVBoxLayout()
        layout.addLayout(self.labelLayout, stretch=1)

        self.titleLabel = ftrack_connect.ui.widget.label.Label()
        self.titleLabel.setProperty('title', True)
        self.labelLayout.addWidget(self.titleLabel)

        self.descriptionLabel = ftrack_connect.ui.widget.label.Label()
        self.labelLayout.addWidget(self.descriptionLabel)

        self.timeField = ftrack_connect.ui.widget.line_edit.LineEdit()
        self.timeField.setObjectName('timeField')
        self.timeField.setAlignment(QtCore.Qt.AlignCenter)
        layout.addWidget(self.timeField)

        self.toggleButton = QtWidgets.QPushButton('Start')
        self.toggleButton.setObjectName('primary')
        self.toggleButton.setProperty('mode', 'start')

        layout.addWidget(self.toggleButton)

        self.setSizePolicy(QtWidgets.QSizePolicy.Expanding,
                           QtWidgets.QSizePolicy.Fixed)

        # Install event filter at application level in order to manage focus
        # behaviour correctly.
        application = QtCore.QCoreApplication.instance()
        application.installEventFilter(self)

        # Connect events.
        self.toggleButton.clicked.connect(self.toggle)

        # Set initial values.
        self.setValue({
            'title': title,
            'description': description,
            'time': time
        })
    def populateUI(self, widget, exportTemplate):
        if exportTemplate:

            self._exportTemplate = exportTemplate

            properties = self._preset.properties()

            layout = QtWidgets.QFormLayout()

            self._readList = QtWidgets.QListView()
            self._writeList = QtWidgets.QListView()

            self._readList.setMinimumHeight(50)
            self._writeList.setMinimumHeight(50)
            self._readList.resize(200, 50)
            self._writeList.resize(200, 50)

            self._readModel = QtWidgets.QStandardItemModel()
            self._writeModel = QtWidgets.QStandardItemModel()

            # Default to the empty item unless the preset has a value set.
            for model, presetValue in ((self._readModel,
                                        properties["readPaths"]),
                                       (self._writeModel,
                                        properties["writePaths"])):
                for path, preset in exportTemplate.flatten():

                    if model is self._writeModel:
                        if not hasattr(preset._parentType, 'nukeWriteNode'):
                            continue

                    item = QtWidgets.QStandardItem(path)
                    item.setFlags(QtCore.Qt.ItemIsUserCheckable
                                  | QtCore.Qt.ItemIsEnabled)

                    item.setData(QtCore.Qt.Unchecked, QtCore.Qt.CheckStateRole)
                    if path in presetValue:
                        item.setData(QtCore.Qt.Checked,
                                     QtCore.Qt.CheckStateRole)

                    model.appendRow(item)

            self._readList.setModel(self._readModel)
            self._writeList.setModel(self._writeModel)

            readNodeListToolTip = """Select multiple entries within the shot template to be used as inputs for the read nodes (i.e. symlink, transcode.. etc).\n No selection will mean that read nodes are created in the nuke script pointing directly at the source media.\n"""
            writeNodeListToolTip = """Add one or more "Nuke Write Node" tasks to your export structure to define the path and codec settings for the nuke script.\nIf no write paths are selected, no write node will be added to the nuke script."""

            self._readList.setToolTip(readNodeListToolTip)
            self._writeList.setToolTip(writeNodeListToolTip)
            self._readModel.dataChanged.connect(self.readPresetChanged)

            publishScriptTip = """When enabled, if there is a known shot in the asset that matches the shot in Hiero, the Nuke script will be published there."""
            key, value, label = "publishScript", True, FnAssetAPI.l(
                "{publish} Script")
            uiProperty = UIPropertyFactory.create(
                type(value),
                key=key,
                value=value,
                dictionary=self._preset._properties,
                label=label,
                tooltip=publishScriptTip)
            self._uiProperties.append(uiProperty)
            layout.addRow(uiProperty._label + ":", uiProperty)

            ## @todo Think of a better name
            useAssetsTip = """If enabled, any Clips that point to managed Assets will reference the Asset, rather than their files."""
            key, value, label = "useAssets", True, "Use Assets"
            uiProperty = UIPropertyFactory.create(
                type(value),
                key=key,
                value=value,
                dictionary=self._preset._properties,
                label=label,
                tooltip=useAssetsTip)
            self._uiProperties.append(uiProperty)
            layout.addRow(uiProperty._label + ":", uiProperty)

            layout.addRow("Read Nodes:", self._readList)
            self._writeModel.dataChanged.connect(self.writePresetChanged)
            layout.addRow("Write Nodes:", self._writeList)

            retimeToolTip = """Sets the retime method used if retimes are enabled.\n-Motion - Motion Estimation.\n-Blend - Frame Blending.\n-Frame - Nearest Frame"""
            key, value = "method", ("None", "Motion", "Frame", "Blend")
            uiProperty = UIPropertyFactory.create(
                type(value),
                key=key,
                value=value,
                dictionary=self._preset._properties,
                label="Retime Method",
                tooltip=retimeToolTip)
            self._uiProperties.append(uiProperty)
            layout.addRow(uiProperty._label + ":", uiProperty)

            collateTracksToolTip = """Enable this to include other shots which overlap the sequence time of each shot within the script. Cannot be enabled when Read Node overrides are set."""

            key, value, label = "collateTracks", False, "Collate Shot Timings"
            uiProperty = UIPropertyFactory.create(
                type(value),
                key=key,
                value=value,
                dictionary=self._preset.properties(),
                label=label + ":",
                tooltip=collateTracksToolTip)
            layout.addRow(label + ":", uiProperty)
            self._uiProperties.append(uiProperty)
            self._collateTimeProperty = uiProperty

            collateShotNameToolTip = """Enable this to include other shots which have the same name in the Nuke script. Cannot be enabled when Read Node overrides are set."""
            key, value, label = "collateShotNames", False, "Collate Shot Name"
            uiProperty = UIPropertyFactory.create(
                type(value),
                key=key,
                value=value,
                dictionary=self._preset.properties(),
                label=label + ":",
                tooltip=collateShotNameToolTip)
            layout.addRow(label + ":", uiProperty)
            self._collateNameProperty = uiProperty
            self._uiProperties.append(uiProperty)
            self.readPresetChanged(None, None)

            additionalNodesToolTip = """When enabled, allows custom Nuke nodes to be added into Nuke Scripts.\n Click Edit to add nodes on a per Shot, Track or Sequence basis.\n Additional Nodes can also optionally be filtered by Tag."""

            additionalNodesLayout = QtWidgets.QHBoxLayout()
            additionalNodesCheckbox = QtWidgets.QCheckBox()
            additionalNodesCheckbox.setToolTip(additionalNodesToolTip)
            additionalNodesCheckbox.stateChanged.connect(
                self._additionalNodesEnableClicked)
            if self._preset.properties()["additionalNodesEnabled"]:
                additionalNodesCheckbox.setCheckState(QtCore.Qt.Checked)
            additionalNodesButton = QtWidgets.QPushButton("Edit")
            additionalNodesButton.setToolTip(additionalNodesToolTip)
            additionalNodesButton.clicked.connect(
                self._additionalNodesEditClicked)
            additionalNodesLayout.addWidget(additionalNodesCheckbox)
            additionalNodesLayout.addWidget(additionalNodesButton)
            layout.addRow("Additional Nodes:", additionalNodesLayout)

            widget.setLayout(layout)
Beispiel #26
0
    def __init__(self, session, error_data, missing_assets_types,
                 duplicated_components):
        '''Return a validator widget for the given *error_data* and *missing_assets_types*.'''
        super(FtrackSettingsValidator, self).__init__()

        self.setWindowTitle('Validation error')
        self._session = session

        self.logger = logging.getLogger(__name__ + '.' +
                                        self.__class__.__name__)

        ftrack_icon = QtGui.QIcon(':/ftrack/image/default/ftrackLogoLight')
        self.setWindowIcon(ftrack_icon)

        layout = QtWidgets.QVBoxLayout()
        self.setLayout(layout)

        box = QtWidgets.QGroupBox(
            'An error occured in the current schema configuration.')

        self.layout().addWidget(box)

        box_layout = QtWidgets.QVBoxLayout()
        box.setLayout(box_layout)

        form_layout = TaskUIFormLayout()
        box_layout.addLayout(form_layout)
        if duplicated_components:

            form_layout.addDivider(
                '{} Duplicated components name have been found'.format(
                    len(duplicated_components)))

            for component_name, task in duplicated_components:

                ui_property = UIPropertyFactory.create(
                    type(component_name),
                    key='component_name',
                    value=component_name,
                    dictionary=task._preset.properties()['ftrack'],
                    label='Component ' + ':',
                    tooltip='Duplicated component name')
                ui_property.update(True)
                form_layout.addRow('Duplicated component' + ':', ui_property)

                if component_name != task.component_name():
                    component_index = duplicated_components.index(
                        (task.component_name(), task))
                    duplicated_components.pop(component_index)

        for processor, values in error_data.items():
            form_layout.addDivider('Wrong {0} presets'.format(
                processor.__class__.__name__))

            for attribute, valid_values in values.items():
                valid_values.insert(0, '- select a value -')
                key, value, label = attribute, valid_values, ' '.join(
                    attribute.split('_'))
                tooltip = 'Set {0} value'.format(attribute)

                ui_property = UIPropertyFactory.create(
                    type(value),
                    key=key,
                    value=value,
                    dictionary=processor._preset.properties()['ftrack'],
                    label=label + ':',
                    tooltip=tooltip)
                form_layout.addRow(label + ':', ui_property)
                ui_property.update(True)

        if missing_assets_types:
            form_layout.addDivider('Missing asset types')

            for missing_asset in missing_assets_types:
                create_asset_button = QtWidgets.QPushButton(
                    missing_asset.capitalize())
                create_asset_button.clicked.connect(self.create_missing_asset)
                form_layout.addRow('Create asset: ', create_asset_button)

        buttons = QtWidgets.QDialogButtonBox()
        buttons.setOrientation(QtCore.Qt.Horizontal)
        buttons.addButton('Cancel', QtWidgets.QDialogButtonBox.RejectRole)
        buttons.addButton('Accept', QtWidgets.QDialogButtonBox.AcceptRole)
        buttons.accepted.connect(self.accept)
        buttons.rejected.connect(self.reject)
        self.layout().addWidget(buttons)
Beispiel #27
0
    def setupUi(self, ExportOptions):
        ExportOptions.setObjectName("ExportOptions")
        ExportOptions.resize(339, 266)
        sizePolicy = QtWidgets.QSizePolicy(QtWidgets.QSizePolicy.Preferred,
                                           QtWidgets.QSizePolicy.Preferred)
        sizePolicy.setHorizontalStretch(0)
        sizePolicy.setVerticalStretch(0)
        sizePolicy.setHeightForWidth(
            ExportOptions.sizePolicy().hasHeightForWidth())
        ExportOptions.setSizePolicy(sizePolicy)
        self.verticalLayout = QtWidgets.QVBoxLayout(ExportOptions)
        self.verticalLayout.setSpacing(3)
        self.verticalLayout.setContentsMargins(0, 0, 0, 0)
        self.verticalLayout.setObjectName("verticalLayout")
        self.optionsPlaceHolderLayout = QtWidgets.QHBoxLayout()
        self.optionsPlaceHolderLayout.setObjectName("optionsPlaceHolderLayout")
        self.verticalLayout.addLayout(self.optionsPlaceHolderLayout)
        self.label_4 = QtWidgets.QLabel(ExportOptions)
        self.label_4.setObjectName("label_4")
        self.verticalLayout.addWidget(self.label_4)
        self.gridLayout_4 = QtWidgets.QGridLayout()
        self.gridLayout_4.setObjectName("gridLayout_4")
        self.thumbnailLineEdit = QtWidgets.QLineEdit(ExportOptions)
        self.thumbnailLineEdit.setObjectName("thumbnailLineEdit")
        self.gridLayout_4.addWidget(self.thumbnailLineEdit, 2, 0, 1, 1)
        self.pushButton = QtWidgets.QPushButton(ExportOptions)
        self.pushButton.setObjectName("pushButton")
        self.gridLayout_4.addWidget(self.pushButton, 2, 1, 1, 1)
        self.screenshotButton = QtWidgets.QPushButton(ExportOptions)
        self.screenshotButton.setObjectName("screenshotButton")
        self.gridLayout_4.addWidget(self.screenshotButton, 2, 2, 1, 1)
        self.verticalLayout.addLayout(self.gridLayout_4)
        self.label_5 = QtWidgets.QLabel(ExportOptions)
        self.label_5.setObjectName("label_5")
        self.verticalLayout.addWidget(self.label_5)
        self.commentTextEdit = QtWidgets.QPlainTextEdit(ExportOptions)
        self.commentTextEdit.setMaximumSize(QtCore.QSize(16777215, 80))
        self.commentTextEdit.setObjectName("commentTextEdit")
        self.verticalLayout.addWidget(self.commentTextEdit)
        self.publishButton = QtWidgets.QPushButton(ExportOptions)
        self.publishButton.setObjectName("publishButton")
        self.verticalLayout.addWidget(self.publishButton)
        self.progressBar = QtWidgets.QProgressBar(ExportOptions)
        self.progressBar.setProperty("value", 24)
        self.progressBar.setObjectName("progressBar")
        self.verticalLayout.addWidget(self.progressBar)
        self.publishMessageLabel = QtWidgets.QLabel(ExportOptions)
        self.publishMessageLabel.setText("")
        self.publishMessageLabel.setObjectName("publishMessageLabel")
        self.verticalLayout.addWidget(self.publishMessageLabel)
        spacerItem = QtWidgets.QSpacerItem(20, 40,
                                           QtWidgets.QSizePolicy.Minimum,
                                           QtWidgets.QSizePolicy.Expanding)
        self.verticalLayout.addItem(spacerItem)

        self.retranslateUi(ExportOptions)

        QtCore.QObject.connect(self.pushButton, QtCore.SIGNAL("clicked()"),
                               ExportOptions.setThumbnailFilename)
        QtCore.QObject.connect(self.screenshotButton,
                               QtCore.SIGNAL("clicked()"),
                               ExportOptions.takeScreenshot)
        QtCore.QMetaObject.connectSlotsByName(ExportOptions)
Beispiel #28
0
    def create_validate_failed_overlay_widgets(self, label, failed_validators):
        '''Create overlay widgets to report validation failures.'''
        congrat_text = '<h2>Validation Failed!</h2>'
        success_text = 'Your <b>{0}</b> failed to validate.'.format(label)

        self.activeWidget = QtWidgets.QWidget()
        self.activeWidget.setLayout(QtWidgets.QVBoxLayout())
        self.layout().addWidget(self.activeWidget)
        main_layout = self.activeWidget.layout()

        main_layout.addStretch(1)

        congrat_label = QtWidgets.QLabel(congrat_text)
        congrat_label.setAlignment(QtCore.Qt.AlignCenter)

        success_label = QtWidgets.QLabel(success_text)
        success_label.setAlignment(QtCore.Qt.AlignCenter)

        main_layout.addWidget(congrat_label)
        main_layout.addWidget(success_label)

        validators_table_container = QtWidgets.QWidget()
        table_layout = QtWidgets.QVBoxLayout()
        table_layout.setContentsMargins(15, 10, 15, 10)
        validators_table_container.setLayout(table_layout)

        validators_table = QtWidgets.QTableWidget()
        validators_table.setSelectionBehavior(
            QtWidgets.QAbstractItemView.SelectionBehavior.SelectRows)
        validators_table.setSelectionMode(QtWidgets.QTableWidget.NoSelection)

        validators_table.setColumnCount(2)
        validators_table.setHorizontalHeaderLabels(['Validation', 'Error'])
        validators_table.horizontalHeader().setResizeMode(
            0, QtWidgets.QHeaderView.ResizeToContents)
        validators_table.horizontalHeader().setSectionResizeMode(
            QtWidgets.QHeaderView.Stretch)
        validators_table.horizontalHeader().setVisible(True)

        validators_table.setRowCount(len(failed_validators))
        validators_table.verticalHeader().setVisible(False)

        icon = QtGui.QIcon(':ftrack/image/dark/remove')
        font = QtGui.QFont()
        font.setBold(True)

        for row, validator in enumerate(failed_validators):
            item = QtWidgets.QTableWidgetItem(icon, validator[0])
            item.setFont(font)
            validators_table.setItem(row, 0, item)

            error_msg = validator[1]

            # Remove quotes from error message, if present.
            if ((error_msg[0] == error_msg[-1]) and error_msg.startswith(
                ("'", '"'))):
                error_msg = error_msg[1:-1]

            item = QtWidgets.QTableWidgetItem(error_msg)
            validators_table.setItem(row, 1, item)

        table_layout.addWidget(validators_table)
        main_layout.addWidget(validators_table_container)

        main_layout.addStretch(1)
        label = QtWidgets.QLabel('See details for more information.')
        label.setAlignment(QtCore.Qt.AlignCenter)
        main_layout.addWidget(label)

        buttons_layout = QtWidgets.QHBoxLayout()
        main_layout.addLayout(buttons_layout)

        self.details_button = QtWidgets.QPushButton('Details')
        buttons_layout.addWidget(self.details_button)
        self.details_button.clicked.connect(self.on_show_details)

        self.close_button = QtWidgets.QPushButton('Close')
        buttons_layout.addWidget(self.close_button)
        self.close_button.clicked.connect(self.close_window_callback)

        if self.details_window_callback is None:
            self.details_button.setDisabled(True)
Beispiel #29
0
    def __init__(self, session):
        '''Instantiate the configure scenario widget.'''
        super(ConfigureScenario, self).__init__()

        # Check if user has permissions to configure scenario.
        # TODO: Update this with an actual permission check once available in
        # the API.
        try:
            session.query('Setting where name is "storage_scenario" and '
                          'group is "STORAGE"').one()
            can_configure_scenario = True
        except ftrack_api.exception.NoResultFoundError:
            can_configure_scenario = False

        layout = QtWidgets.QVBoxLayout()
        layout.addSpacing(0)
        layout.setContentsMargins(50, 0, 50, 0)
        self.setLayout(layout)

        layout.addSpacing(100)

        svg_renderer = QtSvg.QSvgRenderer(':ftrack/image/default/cloud-done')
        image = QtWidgets.QImage(50, 50, QtWidgets.QImage.Format_ARGB32)

        # Set the ARGB to 0 to prevent rendering artifacts.
        image.fill(0x00000000)

        svg_renderer.render(QtGui.QPainter(image))

        icon = QtWidgets.QLabel()
        icon.setPixmap(QtGui.QPixmap.fromImage(image))
        icon.setAlignment(QtCore.Qt.AlignCenter)
        icon.setObjectName('icon-label')
        layout.addWidget(icon)

        layout.addSpacing(50)

        label = QtWidgets.QLabel()
        label.setObjectName('regular-label')
        text = ('Hi there, Connect needs to be configured so that ftrack can '
                'store and track your files for you.')

        if can_configure_scenario is False:
            text += (
                '<br><br> You do not have the required permission, please ask '
                'someone with access to system settings in ftrack to '
                'configure it before you proceed.')

        label.setText(text)
        label.setContentsMargins(0, 0, 0, 0)
        label.setAlignment(QtCore.Qt.AlignCenter)
        label.setWordWrap(True)

        # Min height is required due to issue when word wrap is True and window
        # being resized which cases text to dissapear.
        label.setMinimumHeight(120)

        label.setMinimumWidth(300)
        layout.addWidget(label, alignment=QtCore.Qt.AlignCenter)

        layout.addSpacing(20)

        configure_button = QtWidgets.QPushButton(text='Configure now')
        configure_button.setObjectName('primary')
        configure_button.clicked.connect(self._configure_storage_scenario)
        configure_button.setMinimumHeight(40)
        configure_button.setMaximumWidth(125)

        dismiss_button = QtWidgets.QPushButton(text='Do it later')
        dismiss_button.clicked.connect(self._complete_configuration)
        dismiss_button.setMinimumHeight(40)
        dismiss_button.setMaximumWidth(125)

        hbox = QtWidgets.QHBoxLayout()
        hbox.addWidget(dismiss_button)
        if can_configure_scenario:
            hbox.addSpacing(10)
            hbox.addWidget(configure_button)
        layout.addLayout(hbox)

        layout.addSpacing(20)

        label = QtWidgets.QLabel()
        label.setObjectName('lead-label')
        label.setText(
            'If you decide to do this later, some of the functionality in '
            'ftrack connect and applications started from connect may not '
            'work as expected until configured.')
        label.setAlignment(QtCore.Qt.AlignCenter)
        label.setWordWrap(True)

        # Min height is required due to issue when word wrap is True and window
        # being resized which cases text to dissapear.
        label.setMinimumHeight(100)

        label.setMinimumWidth(300)
        layout.addWidget(label, alignment=QtCore.Qt.AlignCenter)

        layout.addStretch(1)

        label = QtWidgets.QLabel()
        label.setObjectName('green-link')
        label.setText(
            '<a style="color: #1CBC90;" '
            'href="{0}/doc/using/managing_versions/storage_scenario.html"> '
            'Learn more about storage scenarios.'.format(session.server_url))
        label.setAlignment(QtCore.Qt.AlignCenter)
        label.setOpenExternalLinks(True)
        layout.addWidget(label, alignment=QtCore.Qt.AlignCenter)
        layout.addSpacing(20)

        self._subscriber_identifier = session.event_hub.subscribe(
            'topic=ftrack.storage-scenario.configure-done',
            self._complete_configuration)
        self._session = session
Beispiel #30
0
    def __init__(self, *args, **kwargs):
        '''Instantiate the login widget.'''
        super(Login, self).__init__(*args, **kwargs)

        layout = QtWidgets.QVBoxLayout()
        layout.addSpacing(100)
        layout.setContentsMargins(50, 0, 50, 0)
        layout.setSpacing(15)
        self.setLayout(layout)

        label = QtWidgets.QLabel()
        label.setText('Sign in')
        label.setObjectName('login-label')
        layout.addWidget(label, alignment=QtCore.Qt.AlignCenter)

        self.server = QtWidgets.QLineEdit()
        self.server.setPlaceholderText('Site name or custom domain URL')
        layout.addWidget(self.server)

        self.username = QtWidgets.QLineEdit()
        self.username.setPlaceholderText('User name')
        self.username.hide()
        layout.addWidget(self.username)

        self.apiKey = QtWidgets.QLineEdit()
        self.apiKey.setPlaceholderText('API key')
        self.apiKey.hide()
        layout.addWidget(self.apiKey)

        loginButton = QtWidgets.QPushButton(text='SIGN IN')
        loginButton.setObjectName('primary')
        loginButton.clicked.connect(self.handleLogin)
        loginButton.setMinimumHeight(35)
        layout.addWidget(loginButton)

        label = QtWidgets.QLabel()
        label.setObjectName('lead-label')
        label.setContentsMargins(0, 0, 0, 0)
        label.setText(
            'Your site name is your ftrackapp.com web address '
            '(e.g https://sitename.ftrackapp.com OR your custom domain URL).')
        label.setAlignment(QtCore.Qt.AlignCenter)
        label.setWordWrap(True)

        # Min height is required due to issue when word wrap is True and window
        # being resized which cases text to dissapear.
        label.setMinimumHeight(50)

        label.setMinimumWidth(300)
        layout.addWidget(label, alignment=QtCore.Qt.AlignCenter)

        self.errorLabel = QtWidgets.QLabel()
        self.errorLabel.setWordWrap(True)
        layout.addWidget(self.errorLabel)
        self.loginError.connect(self.on_set_error)

        layout.addStretch(1)

        self.toggle_api_label = label = ClickableLabel()
        self.toggle_api_label.setObjectName('lead-label')
        self.toggle_api_label.setText(
            'Trouble signing in? '
            '<a href="#" style="color: #1CBC90;">Sign in with username and API key</a>'
        )
        self.toggle_api_label.clicked.connect(self._toggle_credentials)
        layout.addWidget(self.toggle_api_label,
                         alignment=QtCore.Qt.AlignCenter)
        layout.addSpacing(20)