def __init__(self, text, name, me=False, parent=None): '''Initialise widget with *text* and *name*.''' super(Message, self).__init__(parent) self.setLayout(QtWidgets.QVBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.layout().setSpacing(0) if me: name = 'You' self.sender = QtWidgets.QLabel(name) self.layout().addWidget(self.sender, stretch=0) self.text = QtWidgets.QLabel(text) self.text.setWordWrap(True) self.text.setObjectName('message-text') self.layout().addWidget(self.text, stretch=1) if me: self.sender.setStyleSheet(''' QLabel { color: #1CBC90; } ''') self.sender.setAlignment(QtCore.Qt.AlignRight) self.text.setAlignment(QtCore.Qt.AlignTop | QtCore.Qt.AlignRight) else: self.sender.setStyleSheet(''' QLabel { color: rgba(52, 152, 219, 255); } ''')
def __init__( self, parent, message='Processing', icon=':ftrack/image/default/ftrackLogoColor' ): '''Initialise with *parent*. *message* is the message to display on the overlay. ''' super(BlockingOverlay, self).__init__(parent) layout = QtWidgets.QVBoxLayout() layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) self.content = QtWidgets.QFrame() self.content.setObjectName('content') layout.addWidget( self.content, alignment=QtCore.Qt.AlignCenter ) self.contentLayout = QtWidgets.QVBoxLayout() self.contentLayout.setContentsMargins(0, 0, 0, 0) self.content.setLayout(self.contentLayout) self.icon = QtWidgets.QLabel() pixmap = QtGui.QPixmap(icon) self.icon.setPixmap( pixmap.scaledToHeight(36, mode=QtCore.Qt.SmoothTransformation) ) self.icon.setAlignment(QtCore.Qt.AlignCenter) self.contentLayout.addWidget(self.icon) self.messageLabel = QtWidgets.QLabel() self.messageLabel.setWordWrap(True) self.messageLabel.setAlignment(QtCore.Qt.AlignCenter) self.contentLayout.addWidget(self.messageLabel) self.setStyleSheet(''' BlockingOverlay { background-color: rgba(250, 250, 250, 200); border: none; } BlockingOverlay QFrame#content { padding: 0px; border: 80px solid transparent; background-color: transparent; border-image: url(:ftrack/image/default/boxShadow) 140 stretch; } BlockingOverlay QLabel { background: transparent; } ''') self.setMessage(message)
def __init__(self, session, all_section_text=None, overlay=None, parent=None): '''Initiate a actions view.''' super(Actions, self).__init__(parent) self.logger = logging.getLogger(__name__ + '.' + self.__class__.__name__) self._session = session self._action_label_text = all_section_text layout = QtWidgets.QVBoxLayout() self.setLayout(layout) self.layout().setContentsMargins(0, 0, 0, 0) self._currentUserId = None self._recentActions = [] self._actions = [] self._recentLabel = QtWidgets.QLabel('Recent') layout.addWidget(self._recentLabel) self._recentSection = ActionSection(self) # self._recentSection.setFixedHeight(100) self._recentSection.beforeActionLaunch.connect( self._onBeforeActionLaunched) self._recentSection.actionLaunched.connect(self._onActionLaunched) # layout.addWidget(self._recentSection) self._allLabel = QtWidgets.QLabel() self._allLabel.setAlignment(QtCore.Qt.AlignCenter) layout.addWidget(self._allLabel) self._allSection = ActionSection(self) self._allSection.beforeActionLaunch.connect( self._onBeforeActionLaunched) self._allSection.actionLaunched.connect(self._onActionLaunched) layout.addWidget(self._allSection) if overlay is None: self._overlay = overlay_.BusyOverlay(self, message='Launching...') else: self._overlay = overlay self._overlay.setStyleSheet(OVERLAY_DARK_STYLE) self._overlay.setVisible(False) self.recentActionsChanged.connect(self._updateRecentSection) self._loadActionsForContext([]) self._updateRecentActions()
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
def __init__(self, username, session, parent=None): '''Instantiate user name and logo widget using *username*.''' super(User, self).__init__(parent=parent) self.setObjectName('ftrack-userid-widget') self.main_layout = QtWidgets.QHBoxLayout() self.main_layout.setContentsMargins(0, 0, 0, 0) self.main_layout.setAlignment(QtCore.Qt.AlignRight) self.setLayout(self.main_layout) self.session = session self.label = QtWidgets.QLabel(self) self.image = thumbnail.User(self) self.image.setFixedSize(30, 30) self.main_layout.addWidget(self.label) self.main_layout.addWidget(self.image) self.username = username self.image.load(username) if username in NAME_CACHE: self.set_user_fullname() else: self.load_user_fullname()
def parseRow(self, rowElement, connectorName, mainLayout, assetTypeName): '''Parse xml *rowElement*.''' accepts = rowElement.attribute('accepts') acceptsSplit = accepts.split(',') if accepts == '' or connectorName in acceptsSplit: rowLayout = QtWidgets.QHBoxLayout() rowName = rowElement.attribute('name') rowEnabled = rowElement.attribute('enabled') optionLabel = QtWidgets.QLabel(rowName) optionLabel.setFixedWidth(160) rowLayout.addWidget(optionLabel) if rowEnabled == 'False': enabled = False optionLabel.setEnabled(False) else: enabled = True optionElements = rowElement.elementsByTagName('option') optionsCount = self.parseOptions(rowLayout, optionElements, assetTypeName, enabled) return rowLayout, optionsCount else: return None, 0
def __init__(self, parent=None, title=None, headerWidgets=None): '''Instantiate widget with optional *parent* and *title*. *headerWidgets* is an optional list of widgets to append to the header of the time log widget. ''' super(TimeLogList, self).__init__(widgetFactory=self._createWidget, widgetItem=lambda widget: widget.value(), parent=parent) self.setObjectName('time-log-list') self.list.setShowGrid(False) # Disable selection on internal list. self.list.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) headerLayout = QtWidgets.QHBoxLayout() self.titleLabel = QtWidgets.QLabel(title) self.titleLabel.setProperty('title', True) headerLayout.addWidget(self.titleLabel, stretch=1) # TODO: Refacor and make use of QToolBar and QAction. # Also consider adding 'addAction'/'removeAction'. if headerWidgets: for widget in headerWidgets: headerLayout.addWidget(widget, stretch=0) self.layout().insertLayout(0, headerLayout)
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 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)
def __init__(self, parent=None): '''Initiate a actions view.''' super(Actions, self).__init__(parent) self.logger = logging.getLogger(__name__ + '.' + self.__class__.__name__) self._session = ftrack_connect.session.get_session() layout = QtWidgets.QVBoxLayout() self.setLayout(layout) self._currentUserId = None self._recentActions = [] self._actions = [] self._entitySelector = entity_selector.EntitySelector() self._entitySelector.setFixedHeight(50) self._entitySelector.entityChanged.connect(self._onEntityChanged) layout.addWidget(QtWidgets.QLabel('Select action context')) layout.addWidget(self._entitySelector) self._recentLabel = QtWidgets.QLabel('Recent') layout.addWidget(self._recentLabel) self._recentSection = ActionSection(self) self._recentSection.setFixedHeight(100) self._recentSection.beforeActionLaunch.connect( self._onBeforeActionLaunched) self._recentSection.actionLaunched.connect(self._onActionLaunched) layout.addWidget(self._recentSection) self._allLabel = QtWidgets.QLabel('Discovering actions..') self._allLabel.setAlignment(QtCore.Qt.AlignCenter) layout.addWidget(self._allLabel) self._allSection = ActionSection(self) self._allSection.beforeActionLaunch.connect( self._onBeforeActionLaunched) self._allSection.actionLaunched.connect(self._onActionLaunched) layout.addWidget(self._allSection) self._overlay = overlay.BusyOverlay(self, message='Launching...') self._overlay.setVisible(False) self.recentActionsChanged.connect(self._updateRecentSection) self._loadActionsForContext([]) self._updateRecentActions()
def __init__(self, event=None, date=None, parent=None): '''Initialise widget with initial component *event* and *parent*.''' super(Notification, self).__init__(parent=parent) self.horizontalLayout = QtWidgets.QHBoxLayout() verticalLayout = QtWidgets.QVBoxLayout() self.setLayout(self.horizontalLayout) self.horizontalLayout.addLayout(verticalLayout, stretch=1) self.textLabel = QtWidgets.QLabel() verticalLayout.addWidget(self.textLabel) self.dateLabel = QtWidgets.QLabel() verticalLayout.addWidget(self.dateLabel) self.setDate(event['created_at']) self.setEvent(event)
def __init__(self, parent=None): '''Initialise widget with *parent*.''' super(ComponentsList, self).__init__(widgetFactory=self._createComponentWidget, widgetItem=lambda widget: widget.value(), parent=parent) self.list.setSelectionMode(QtWidgets.QAbstractItemView.NoSelection) self.list.setShowGrid(False) self.label = QtWidgets.QLabel('Components') self.layout().insertWidget(0, self.label)
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)
def __init__( self, name, userId, group=None, applications=None, parent=None ): '''Initialise widget with initial component *value* and *parent*.''' super(User, self).__init__(parent) if applications is None: applications = {} self._userId = userId self._applications = applications self._group = group self.setObjectName('user') self.setLayout(QtWidgets.QHBoxLayout()) self.thumbnail = ftrack_connect.ui.widget.thumbnail.User() self.thumbnail.setFixedWidth(30) self.thumbnail.setFixedHeight(30) self.thumbnail.load(userId) self.layout().addWidget(self.thumbnail) self.layout().setContentsMargins(0, 0, 0, 0) nameAndActivity = QtWidgets.QWidget() nameAndActivity.setLayout(QtWidgets.QVBoxLayout()) nameAndActivity.layout().setContentsMargins(0, 0, 0, 0) self.countLabel = QtWidgets.QLabel() self.countLabel.setObjectName('user-conversation-count') self.countLabel.hide() self.nameLabel = ftrack_connect.ui.widget.label.Label() self.nameLabel.setText(name) self.nameLabel.setObjectName('name') nameAndActivity.layout().addWidget(self.nameLabel) self.activityLabel = ftrack_connect.ui.widget.label.Label() self.activityLabel.setObjectName('user-activity') self.nameAndCountLayout = QtWidgets.QHBoxLayout() self.nameAndCountLayout.addWidget(self.nameLabel, stretch=1) self.nameAndCountLayout.addWidget(self.countLabel, stretch=0) self.nameAndCountLayout.addSpacing(5) nameAndActivity.layout().addLayout(self.nameAndCountLayout) nameAndActivity.layout().addWidget(self.activityLabel) self.layout().addWidget(nameAndActivity) self._refreshStyles() self._updateActivity()
def __init__(self, parent): '''Initialise.''' super(TimerOverlay, self).__init__(parent) layout = QtWidgets.QVBoxLayout() self.setLayout(layout) message = QtWidgets.QLabel('Select a task to activate timer.') message.setWordWrap(True) message.setAlignment(QtCore.Qt.AlignVCenter) layout.addWidget(message) # TODO: See if there is a way to stop Sass converting the rgba string # to the wrong value. self.setStyleSheet(''' #ftrack-connect-window TimerOverlay { background-color: rgba(255, 255, 255, 200); } ''')
def __init__( self, name, userId, applications, group=None, parent=None ): '''Initialise widget with initial component *value* and *parent*.''' super(UserExtended, self).__init__(parent=parent) self.applicationInfoWidget = QtWidgets.QLabel() self._userId = userId self._applications = applications self.setLayout(QtWidgets.QVBoxLayout()) self.user = User(name, userId, group=None, applications=applications) self.layout().addWidget(self.user) self.layout().addWidget(self.applicationInfoWidget, stretch=0) self.updateInformation(name, userId, applications)
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, parent=None): '''Instantiate message widget.''' super(MessageBox, self).__init__(parent=parent) self.setObjectName('ftrack-message-box') self.main_layout = QtWidgets.QHBoxLayout() self.main_layout.setContentsMargins(0, 0, 0, 0) self.main_layout.setSpacing(0) self.main_layout.setAlignment(QtCore.Qt.AlignTop) self.setLayout(self.main_layout) self.label = QtWidgets.QLabel(parent=self) self.label.resize(QtCore.QSize(900, 80)) self.label.setSizePolicy(QtWidgets.QSizePolicy.Expanding, QtWidgets.QSizePolicy.Fixed) self.label.hide() self.label.setObjectName('ftrack-header-message-info') self.main_layout.addWidget(self.label)
def __init__(self, start_frame, end_frame): '''Instantiate start and end frame field.''' super(StartEndFrameField, self).__init__() self.setLayout(QtWidgets.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.start_frame = QtWidgets.QDoubleSpinBox() self.start_frame.setValue(start_frame) self.start_frame.setMaximum(sys.maxint) self.start_frame.setDecimals(0) self.start_frame.valueChanged.connect(self.notify_changed) self.end_frame = QtWidgets.QDoubleSpinBox() self.end_frame.setValue(end_frame) self.end_frame.setMaximum(sys.maxint) self.end_frame.setDecimals(0) self.end_frame.valueChanged.connect(self.notify_changed) self.layout().addWidget(QtWidgets.QLabel('Frame Range')) self.layout().addWidget(self.start_frame) self.layout().addWidget(self.end_frame)
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 build(self): '''Build widgets and layout.''' self.setLayout(QtWidgets.QHBoxLayout()) self.layout().setContentsMargins(0, 0, 0, 0) self.thumbnailWidget = QtWidgets.QLabel() self.thumbnailWidget.setFrameStyle(QtWidgets.QFrame.StyledPanel) self.thumbnailWidget.setAlignment(QtCore.Qt.AlignCenter) self.thumbnailWidget.setFixedWidth(240) self.layout().addWidget(self.thumbnailWidget) self.propertyTableWidget = QtWidgets.QTableWidget() self.propertyTableWidget.setEditTriggers( QtWidgets.QAbstractItemView.NoEditTriggers) self.propertyTableWidget.setSelectionMode( QtWidgets.QAbstractItemView.NoSelection) self.propertyTableWidget.setRowCount(len(self.headers)) self.propertyTableWidget.setVerticalHeaderLabels(self.headers) self.propertyTableWidget.setColumnCount(1) horizontalHeader = self.propertyTableWidget.horizontalHeader() horizontalHeader.hide() horizontalHeader.setResizeMode(QtWidgets.QHeaderView.Stretch) verticalHeader = self.propertyTableWidget.verticalHeader() verticalHeader.setResizeMode(QtWidgets.QHeaderView.ResizeToContents) # Fix missing horizontal scrollbar when only single column self.propertyTableWidget.setHorizontalScrollMode( QtWidgets.QAbstractItemView.ScrollPerPixel) for index in range(len(self.headers)): self.propertyTableWidget.setItem(index, 0, QtWidgets.QTableWidgetItem('')) self.layout().addWidget(self.propertyTableWidget)
def __init__(self, username, parent=None): '''Instantiate user name and logo widget using *username*.''' super(User, self).__init__(parent=parent) self.setObjectName('ftrack-userid-widget') self.main_layout = QtWidgets.QHBoxLayout() self.main_layout.setContentsMargins(0, 0, 0, 0) self.main_layout.setAlignment(QtCore.Qt.AlignRight) self.setLayout(self.main_layout) self.label = QtWidgets.QLabel(self) self.image = thumbnail.User(self) self.image.setFixedSize(35, 35) self.main_layout.addWidget(self.label) self.main_layout.addWidget(self.image) self.image.load(username) if username not in NAME_CACHE: NAME_CACHE[username] = ftrack.User(username).getName().title() self.label.setText(NAME_CACHE[username])
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)
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
def __init__(self, actions, parent=None): '''Initialize action item with *actions* *actions* should be a list of action dictionaries with the same label. Each action may contain a the following: label To be displayed as text icon An URL to an image or one of the provided icons. variant A variant of the action. Will be shown in the menu shown for multiple actions, or as part of the label for a single action. description A optional description of the action to be shown on hover. Label, icon and description will be retrieved from the first action if multiple actions are specified. ''' super(ActionItem, self).__init__(parent=parent) self.logger = logging.getLogger(__name__ + '.' + self.__class__.__name__) self.setMouseTracking(True) self.setFixedSize(QtCore.QSize(80, 80)) layout = QtWidgets.QVBoxLayout() layout.setAlignment(QtCore.Qt.AlignCenter) layout.setSpacing(0) layout.setContentsMargins(0, 0, 0, 0) self.setLayout(layout) if not actions: raise ValueError('No actions specified') self._actions = actions self._label = actions[0].get('label', 'Untitled action') self._icon = actions[0].get('icon', None) self._description = actions[0].get('description', None) self._variants = [ u'{0} {1}'.format(action.get('label', 'Untitled action'), action.get('variant', '')).strip() for action in actions ] if len(actions) == 1: if actions[0].get('variant'): self._label = u'{0} {1}'.format(self._label, actions[0].get('variant')) self._hoverIcon = 'play' self._multiple = False else: self._hoverIcon = 'menu' self._multiple = True self._iconLabel = ActionIcon(self) self._iconLabel.setAlignment(QtCore.Qt.AlignCenter) self._iconLabel.setFixedSize(QtCore.QSize(80, 45)) layout.addWidget(self._iconLabel) self._textLabel = QtWidgets.QLabel(self) self._textLabel.setAlignment(QtCore.Qt.AlignHCenter | QtCore.Qt.AlignTop) self._textLabel.setWordWrap(True) self._textLabel.setFixedSize(QtCore.QSize(80, 35)) layout.addWidget(self._textLabel) self.setText(self._label) self.setIcon(self._icon) if self._description: self.setToolTip(self._description)
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()
def __init__(self, data_dict, options): '''Instanstiate settings from *options*.''' super(ActionSettingsWidget, self).__init__() self.setLayout(QtWidgets.QFormLayout()) self.layout().setContentsMargins(0, 0, 0, 0) for option in options: type_ = option['type'] label = option.get('label', '') name = option['name'] value = option.get('value') empty_text = option.get('empty_text') if name in data_dict.get('options', {}): value = data_dict['options'][name] if value is not None and name not in data_dict: # Set default value from options. data_dict[name] = value field = None if type_ == 'group': nested_dict = data_dict[name] = dict() settings_widget = QtWidgets.QGroupBox(label) settings_widget.setLayout(QtWidgets.QVBoxLayout()) settings_widget.layout().addWidget( ActionSettingsWidget(nested_dict, option.get('options', []))) self.layout().addRow(settings_widget) if type_ == 'boolean': field = QtWidgets.QCheckBox() if value is True: field.setCheckState(QtCore.Qt.Checked) field.stateChanged.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda check_box: (check_box.checkState() == QtCore.Qt. CheckState.Checked))) if type_ == 'textarea': field = textarea.TextAreaField(empty_text or '') if value is not None: field.setPlainText(unicode(value)) field.value_changed.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda textarea_widget: textarea_widget.value())) if type_ == 'text': field = QtWidgets.QLineEdit() if value is not None: field.insert(unicode(value)) field.textChanged.connect( functools.partial(self.update_on_change, data_dict, field, name, lambda line_edit: line_edit.text())) if type_ == 'number': field = QtWidgets.QDoubleSpinBox() if value is not None: field.setValue(float(value)) field.setMaximum(sys.maxint) field.setMinimum(-sys.maxint) field.valueChanged.connect( functools.partial(self.update_on_change, data_dict, field, name, lambda spin_box: spin_box.value())) if type_ == 'enumerator': field = QtWidgets.QComboBox() for item in option['data']: field.addItem(item['label']) field.currentIndexChanged.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda box: (option['data'][box.currentIndex()]['value']))) if type_ == 'qt_widget': field = option['widget'] field.value_changed.connect( functools.partial( self.update_on_change, data_dict, field, name, lambda custom_field: (custom_field.value()))) if field is not None: if label: label_widget = QtWidgets.QLabel(label) self.layout().addRow(label_widget, field) else: self.layout().addRow(field)
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 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 __init__(self, parent=None, session=None, context=None): super(BuildAssetTrackDialog, self).__init__(parent) self.setWindowTitle("Build Track") if not session: session = FnAssetAPI.SessionManager.currentSession() self.__session = session if not context: context = session.createContext() self.__context = context self.__selection = [] self.__entities = [] self.__ignoreClips = False self.__lastIgnoreClips = None self.__lastParentRef = None layout = QtWidgets.QVBoxLayout() self.setLayout(layout) # Asset Manager Widget self.__relationshipWidget = session.getManagerWidget( kWorkflowRelationshipWidgetId, args=[context,]) layout.addWidget(self.__relationshipWidget) # Stretch layout.addStretch() # Options optionsBox = QtWidgets.QGroupBox("Options") optionsLayout = QtWidgets.QVBoxLayout() optionsBox.setLayout(optionsLayout) layout.addWidget(optionsBox) self.__trackName = QtWidgets.QLineEdit() trackNameLayout = QtWidgets.QHBoxLayout() trackNameLayout.addWidget(QtWidgets.QLabel("Track Name")) trackNameLayout.addWidget(self.__trackName) optionsLayout.addLayout(trackNameLayout) self.__useClipsRadio = QtWidgets.QRadioButton("Match by Clip") self.__useShotsRadio = QtWidgets.QRadioButton("Match by Shot") optionsLayout.addWidget(self.__useClipsRadio) optionsLayout.addWidget(self.__useShotsRadio) ## @todo Use the project entityReferences Parent if we have one? context.access = context.kReadMultiple context.retention = context.kTransient specification = specifications.ShotSpecification() self.__shotParentPicker = self.__session.getManagerWidget( FnAssetAPI.ui.constants.kInlinePickerWidgetId, args=[specification, context]) optionsLayout.addWidget(self.__shotParentPicker) # Buttons ## @todo disable the ok button if using shots and no valid entity ref self.__buttons = QtWidgets.QDialogButtonBox(QtWidgets.QDialogButtonBox.Ok | QtWidgets.QDialogButtonBox.Cancel) self.__buttons.button(QtWidgets.QDialogButtonBox.Ok).setText('Build') layout.addWidget(self.__buttons) # Connections self.__buttons.accepted.connect(self.accept) self.__buttons.rejected.connect(self.reject) self.__useShotsRadio.toggled.connect(self.__modeChanged) self.__useClipsRadio.toggled.connect(self.__modeChanged) self.__relationshipWidget.criteriaChanged.connect(self.__syncUI) # This might be better on editingFinished, but there is only one text field # some of the time so loosing focus might not happen as required self.__trackName.textChanged.connect(self.__syncUI) self.__shotParentPicker.selectionChanged.connect(self.__parentChanged) self.__syncUI() # Make sure the name field is ready for editing as we can't create without self.__trackName.setFocus()