def __init__(self, componentName=None, resourceIdentifier=None, parent=None): '''Initialise widget with initial component *value* and *parent*.''' super(Component, self).__init__(parent=parent) self.setLayout(QtWidgets.QVBoxLayout()) self.componentNameEdit = ftrack_connect.ui.widget.line_edit.LineEdit() self.componentNameEdit.setPlaceholderText('Enter component name') self.componentNameEdit.textChanged.connect(self.nameChanged) self.layout().addWidget(self.componentNameEdit) # TODO: Add theme support. removeIcon = QtGui.QIcon( QtGui.QPixmap(':/ftrack/image/light/trash') ) self.removeAction = QtWidgets.QAction( QtGui.QIcon(removeIcon), 'Remove', self.componentNameEdit ) self.removeAction.setStatusTip('Remove component.') self.componentNameEdit.addAction( self.removeAction ) self.resourceInformation = ftrack_connect.ui.widget.label.Label() self.layout().addWidget(self.resourceInformation) # Set initial values. self.setId(str(uuid.uuid4())) self.setComponentName(componentName) self.setResourceIdentifier(resourceIdentifier)
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)
def __init__(self, *args, **kwargs): '''Initialise widget.''' super(ThumbnailDropZone, self).__init__(*args, **kwargs) self.setObjectName('ftrack-connect-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.imageLabel = QtWidgets.QLabel() self.setDropZoneText() layout.addWidget(self.imageLabel, alignment=QtCore.Qt.AlignLeft) # 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, alignment=QtCore.Qt.AlignRight)
def __init__(self, *args, **kwargs): super(AdvancedHieroItemSpreadsheet, self).__init__(*args, **kwargs) self._columnTitle = 'Status' self._disabledText = '' self._enabledText = '' self._textCallback = None self._enabledIcon = QtGui.QIcon("icons:status/TagFinal.png") self._disabledIcon = QtGui.QIcon("icons:status/TagOmitted.png") self._iconCallback = None self._disabledCallback = None self._disableItems = True self._statusIndex = -1 self._iconIndex = -1
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)
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 })
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 _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' )
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)
def icon(self): '''Return icon.''' return QtGui.QIcon(':/ftrack/image/default/ftrackLogoGreyDark')
def icon(self): '''Return icon.''' return QtGui.QIcon(':/ftrack/image/light/project')
def icon(self): '''Return icon.''' icon = self.entity.get('object_type', {}).get('icon', 'default') return QtGui.QIcon(':/ftrack/image/light/object_type/{0}'.format(icon))
def __init__(self, *args, **kwargs): '''Initialise the main application window.''' theme = kwargs.pop('theme', 'light') super(Application, self).__init__(*args, **kwargs) self.logger = logging.getLogger( __name__ + '.' + self.__class__.__name__ ) self.defaultPluginDirectory = appdirs.user_data_dir( 'ftrack-connect-plugins', 'ftrack' ) self.pluginHookPaths = set() self.pluginHookPaths.update( self._gatherPluginHooks( self.defaultPluginDirectory ) ) if 'FTRACK_CONNECT_PLUGIN_PATH' in os.environ: for connectPluginPath in ( os.environ['FTRACK_CONNECT_PLUGIN_PATH'].split(os.pathsep) ): self.pluginHookPaths.update( self._gatherPluginHooks( connectPluginPath ) ) self.logger.info( u'Connect plugin hooks directories: {0}'.format( ', '.join(self.pluginHookPaths) ) ) # Register widget for error handling. self.uncaughtError = _uncaught_error.UncaughtError( parent=self ) if not QtWidgets.QSystemTrayIcon.isSystemTrayAvailable(): raise ftrack_connect.error.ConnectError( 'No system tray located.' ) self.logoIcon = QtGui.QIcon( QtGui.QPixmap(':/ftrack/image/default/ftrackLogoColor') ) self._login_server_thread = None self._theme = None self.setTheme(theme) self.plugins = {} self._initialiseTray() self.setObjectName('ftrack-connect-window') self.setWindowTitle('ftrack connect') self.resize(450, 700) self.move(50, 50) self.setWindowIcon(self.logoIcon) self._login_overlay = None self.loginWidget = _login.Login() self.loginSignal.connect(self.loginWithCredentials) self.login()
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)
def _buildClipsTree(self, shotItems, parentEntity, sharedParentEntity, context): tickIcon = QtGui.QIcon("icons:TagGood.png") crossIcon = QtGui.QIcon("icons:status/TagBad.png") blockIcon = QtGui.QIcon("icons:status/TagOnHold.png") addIcon = QtGui.QIcon("icons:Add.png") l = FnAssetAPI.l shotParentTreeItem = GroupingTreeItem() shotParentTreeItem.setSizeHint(0, QtCore.QSize(300, 22)) shotParentTreeItem.setSizeHint(1, QtCore.QSize(120, 22)) shotParentTreeItem.setSizeHint(4, QtCore.QSize(120, 22)) shotParentTreeItem.setEntity(parentEntity, context) boldFont = shotParentTreeItem.font(0) boldFont.setBold(True) italicFont = shotParentTreeItem.font(0) italicFont.setItalic(True) shotParentTreeItem.setFont(0, boldFont) newShots, existingShots, unused = cmdUtils.shot.analyzeHieroShotItems( shotItems, parentEntity, context, checkForConflicts=False) clips, sharedClips = cmdUtils.shot.analyzeHeiroShotItemClips( shotItems, asItems=False) ignorePublished = self.__options.get('ignorePublishedClips', True) publishShared = self.__options.get('publishSharedClips', False) customName = '' if self.__options.get('clipsUseCustomName', False): customName = self.__options.get('customClipName', '') processsedSharedClips = set() allSharedClips = [] for s in shotItems: shotTreeItem = GroupingTreeItem() shotTreeItem.setItem(s) shotTreeItem.setText(1, l("{shot}")) status = "" shotDisabled = False if s in newShots: status = l("Unable to find matching {shot}") shotDisabled = True shotTreeItem.setIcon(2, blockIcon) shotTreeItem.setText(3, status) clips = cmdUtils.shot.clipsFromHieroShotTrackItem(s) for c in clips: clipItem = items.HieroClipItem(c) clipIsAssetised = bool(clipItem.getEntity()) clipTreeItem = ClipTreeItem() clipTreeItem.setItem(clipItem) status = l("{publish}") disabled = False icon = addIcon if clipIsAssetised: if ignorePublished: status = l("Already {published}") disabled = True icon = tickIcon else: status = l("{publish} New Version") clipTreeItem.setText(3, status) clipTreeItem.setDisabled(disabled) clipTreeItem.setIcon(2, icon) clipTreeItem.setText(1, "Clip") if c in sharedClips: clipTreeItem.setText(1, "Shared Clip") if c not in processsedSharedClips: if publishShared: if not clipIsAssetised or (clipIsAssetised and not ignorePublished): if not shotDisabled: allSharedClips.append(clipTreeItem) processsedSharedClips.add(c) placeholderTreeItem = ClipTreeItem() placeholderTreeItem.setItem(clipItem) placeholderTreeItem.setText(1, "Shared Clip") placeholderTreeItem.setFont(0, italicFont) if not clipTreeItem.isDisabled(): if publishShared: if sharedParentEntity: msg = l("{publish} to '%s'") % sharedParentEntity.getName(context) icon = tickIcon else: msg = "No Shared Clip destination chosen" icon = blockIcon placeholderTreeItem.setText(3, msg) else: placeholderTreeItem.setText(3, l("Shared Clip {publish} disabled")) icon = crossIcon else: placeholderTreeItem.setText(3, clipTreeItem.text(3)) placeholderTreeItem.setIcon(2, icon) if shotDisabled: placeholderTreeItem.setText(3, '') placeholderTreeItem.setIcon(2, QtGui.QIcon()) placeholderTreeItem.setDisabled(True) shotTreeItem.addChild(placeholderTreeItem) else: if shotDisabled: clipTreeItem.setText(3, '') clipTreeItem.setIcon(2, QtGui.QIcon()) clipTreeItem.setDisabled(True) if customName and len(clips)==1: origName = clipTreeItem.text(0) clipTreeItem.setText(4, origName) clipTreeItem.setText(0, customName) shotTreeItem.addChild(clipTreeItem) if shotDisabled: shotTreeItem.setDisabled(True) shotTreeItem.stopExpand = shotDisabled shotParentTreeItem.addChild(shotTreeItem) # We need to figure out if our sharedParentEntity is either the same # as parentEntity, or one of its (for now, immediate) children. sharedInTree = False sharedParentTreeItem = None if sharedParentEntity: if parentEntity.reference == sharedParentEntity.reference: sharedParentTreeItem = shotParentTreeItem sharedInTree = True else: for i in range(shotParentTreeItem.childCount()): treeItem = shotParentTreeItem.child(i) shotEntity = treeItem.entity if shotEntity and shotEntity.reference == sharedParentEntity.reference: sharedParentTreeItem = treeItem sharedInTree = True break if sharedParentEntity and not sharedParentTreeItem: sharedParentTreeItem = GroupingTreeItem() sharedParentTreeItem.setFont(0, boldFont) sharedParentTreeItem.setEntity(sharedParentEntity, context) if allSharedClips and sharedParentTreeItem: sharedParentTreeItem.insertChildren(0, allSharedClips) treeItems = [] treeItems.append(shotParentTreeItem) if sharedParentTreeItem and not sharedInTree: treeItems.append(sharedParentTreeItem) return treeItems
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)