示例#1
0
    def _setup_ui(self):

        self.setWindowTitle('Scene Publisher')
        self.setLayout(Q.VBoxLayout())

        hbox = Q.HBoxLayout()      

        self._exporter = SceneExporter()
        
        self._publish_widget = PublishWidget(self._exporter)
        self._publish_widget.layout().setContentsMargins(0, 0, 0, 0)
        self.layout().addWidget(self._publish_widget)
        
        self._publish_widget.beforeScreenshot.connect(self.hide)
        self._publish_widget.afterScreenshot.connect(self.show)
        
        cancel_button = Q.PushButton('Cancel')
        cancel_button.clicked.connect(self._on_cancel)
        hbox.addWidget(cancel_button)
        hbox.addStretch()

        publish_button = Q.PushButton('Publish')
        publish_button.clicked.connect(self._on_submit)
        hbox.addWidget(publish_button)
          
        self.layout().addLayout(ui_utils.vbox(hbox))
        self._publish_widget.beforePlayblast.connect(self._before_playblast)
        self._publish_widget.afterPlayblast.connect(self._after_playblast)
        
        self._msgbox = None
示例#2
0
    def _setup_ui(self):
        self.setWindowTitle('Open A Ticket')
        self.setMinimumSize(400, 300)
        self.setLayout(Q.FormLayout())

        self._exception = Q.ComboBox()

        if self._allow_no_exception:
            self._exception.addItem('None', None)

        for exc_type, exc_value, exc_traceback in self._exc_infos:
            uuid = tickets.exception_uuid(exc_type, exc_value, exc_traceback)
            self._exception.addItem('%s: %s [%s]' %
                                    (exc_type.__name__, exc_value, uuid))
        self._exception.setCurrentIndex(self._exception.count() - 1)
        self._exception.currentIndexChanged.connect(self._on_exception)

        if not self._allow_no_exception and len(self._exc_infos) == 1:
            self.layout().addRow("Exception",
                                 Q.Label(self._exception.currentText()))
        else:
            self.layout().addRow("Exception", self._exception)

        self._title_label = Q.Label("Title")
        self._title = Q.LineEdit('Bug Report')
        self.layout().addRow(self._title_label, self._title)

        self._description = Q.TextEdit(
            'Please describe the problem, and any steps to reproduce it and/or fix it.'
        )
        self._description.focusInEvent = lambda *args: self._description.selectAll(
        )
        self.layout().addRow("Description", self._description)

        self._screenshot_path = None
        self._screenshot = Q.Label()
        self._screenshot.setFixedSize(133, 100)
        self._screenshot.setPixmap(
            Q.Pixmap(
                os.path.abspath(
                    os.path.join(__file__, '..', 'art',
                                 'no_screenshot.png'))).scaledToHeight(
                                     100, Q.SmoothTransformation))
        self._screenshot.setFrameShadow(Q.Frame.Sunken)
        self._screenshot.setFrameShape(Q.Frame.Panel)
        self._screenshot.mouseReleaseEvent = self._on_screenshot
        self.layout().addRow("Screenshot", self._screenshot)

        buttons = Q.HBoxLayout()
        self.layout().addRow("", buttons)

        buttons.addStretch()

        button = Q.PushButton('Submit')
        button.clicked.connect(self._on_submit)
        buttons.addWidget(button)

        self._description.setFocus()
        self._description.selectAll()
        self._on_exception(self._exception.currentIndex())
示例#3
0
def icon(name, size=None, as_icon=False):

    try:
        icon = _icons_by_name[name]
    except KeyError:

        path = os.path.abspath(
            os.path.join(__file__, '..', 'art', 'icons',
                         name + (os.path.splitext(name)[1] or '.png')))

        if os.path.exists(path):
            icon = Q.QPixmap(path)
        else:
            icon = None

        _icons_by_name[name] = icon

    if icon and size:
        icon = icon.scaled(size, size, Q.IgnoreAspectRatio,
                           Q.SmoothTransformation)

    if icon and as_icon:
        icon = Q.QIcon(icon)

    return icon
示例#4
0
def announce_publish_success(
    publisher,
    title="Published \"{publisher.type}\"",
    message="Version {publisher.version} of \"{publisher.name}\" has been published.",
    open_folder=True,
    open_shotgun=True,
):

    msg = Q.QMessageBox()
    msg.setWindowTitle(title.format(publisher=publisher))
    msg.setText(message.format(publisher=publisher))

    if open_folder:
        folder_button = msg.addButton("Open Folder", Q.QMessageBox.AcceptRole)
        folder_button.clicked.connect(
            functools.partial(call_open, publisher.directory))

    if open_shotgun:
        shotgun_button = msg.addButton("Open Shotgun",
                                       Q.QMessageBox.AcceptRole)
        shotgun_button.clicked.connect(
            functools.partial(call_open, publisher.entity.url))

    msg.addButton("Close", Q.QMessageBox.RejectRole)

    msg.exec_()
示例#5
0
    def _setupGui(self):
        super(ReferenceItem, self)._setupGui()

        if self.publish:

            self.combo = combo = Q.ComboBox()
            for i, sibling in enumerate(self.status.all):
                combo.addItem('v%04d' % sibling['sg_version'], sibling)
                if sibling['sg_version'] == self.publish['sg_version']:
                    combo.setCurrentIndex(i)
            combo.currentIndexChanged.connect(self._combo_changed)

        else:

            self.button = button = Q.PushButton("Pick a Publish")
            button.clicked.connect(self._pick_publish)
示例#6
0
文件: view.py 项目: vfxetc/sgfs
    def resizeToContents(self):

        width = self.sizeHintForColumn(0)

        # Don't bother if we can't figure it out.
        if width <= 0:
            return

        # Pad for icons and decorations.
        width += 27

        # Determine our depth in the view.
        column = 0
        index = self.rootIndex()
        while index.isValid():
            column += 1
            index = index.parent()

        widths = self._master.columnWidths()
        if not widths:
            widths = [self.minimumWidth()]
        while len(widths) <= column:
            widths.append(widths[-1])
        if width <= widths[column]:
            return
        widths[column] = width
        self._master.setColumnWidths(widths)

        # Force it to perform a reflow of the columns.
        size = self._master.size()
        self._master.resizeEvent(Q.ResizeEvent(size, size))
示例#7
0
    def _setup_ui(self):

        self.setMinimumWidth(200)
        self.setLayout(Q.VBoxLayout())

        self._thumbnail = Q.Label('')
        self._thumbnail.setFrameShape(Q.Frame.StyledPanel)
        self._thumbnail.setFrameShadow(Q.Frame.Raised)
        self.layout().addWidget(self._thumbnail)

        form = Q.FormLayout()
        self.layout().addLayout(form)

        self._created_by_label = Q.Label()
        form.addRow("<b>By:</b>", self._created_by_label)

        self._created_at_label = Q.Label()
        form.addRow("<b>At:</b>", self._created_at_label)

        self._description_label = Q.Label()
        self._description_label.setWordWrap(True)
        form.addRow("<b>Desc:</b>", self._description_label)

        self._timeRangeLabel = Q.Label()
        form.addRow("<b>Frames:</b>", self._timeRangeLabel)

        self.layout().addStretch()
示例#8
0
 def __init__(self, path):
     self._path = path
     self._loaded = False
     super(PlayblastThumbnail, self).__init__()
     self.setAlignment(Qt.AlignCenter)
     self.setPixmap(
         Q.Pixmap(self._path).scaled(100, 57, Qt.KeepAspectRatio,
                                     Qt.SmoothTransformation))
     self._loaded = True
示例#9
0
def _box(layout, *args):
    for arg in args:
        if isinstance(arg, basestring):
            layout.addWidget(Q.QLabel(arg))
        elif isinstance(arg, Q.QLayout):
            layout.addLayout(arg)
        else:
            layout.addWidget(arg)
    return layout
示例#10
0
    def update(self, entity):

        # TODO: Do this async.
        # We're also priming the sg_default_reference_namespace (assuming
        # it exists).
        by, at, desc, _ = entity.fetch((
            'created_by.HumanUser.name',
            'created_at',
            'description',
            'sg_link.Task.entity.Asset.sg_default_reference_namespace',
        ),
                                       force=True)
        self._created_by_label.setText(str(by))
        self._created_at_label.setText(str(at.strftime('%y-%m-%d %I:%M %p')))
        self._description_label.setText(str(desc))

        sgfs = SGFS(session=entity.session)
        path = sgfs.path_for_entity(entity)
        tags = sgfs.get_directory_entity_tags(path)
        tags = [t for t in tags if t['entity'] is entity]
        tag = tags[0]

        maya_data = tag.get('maya', {})
        time_range = '%s - %s' % (maya_data.get('min_time'),
                                  maya_data.get('max_time'))
        self._timeRangeLabel.setText(time_range)

        if entity not in self._pixmaps:
            thumbnail_path = tag.get('sgpublish',
                                     {}).get('thumbnail') if tags else None
            thumbnail_path = thumbnail_path or os.path.join(
                path, '.sgfs.thumbnail.jpg')
            if os.path.exists(thumbnail_path):
                pixmap = Q.Pixmap(thumbnail_path)
            else:
                path = os.path.abspath(
                    os.path.join(__file__, '..', '..', '..', '..', 'art',
                                 'no-thumbnail.png'))
                pixmap = Q.Pixmap(path)
            self._pixmaps[entity] = pixmap.scaledToWidth(
                165, Q.SmoothTransformation)

        self._thumbnail.setPixmap(self._pixmaps[entity])
        self._thumbnail.setFixedSize(self._pixmaps[entity].size())
示例#11
0
文件: widget.py 项目: vfxetc/sgfs
 def _setup_ui(self):
     
     # Main layouts.
     self._layout = Q.VBoxLayout()
     self.setLayout(self._layout)
     self._form_layout = Q.GridLayout()
     self._layout.addLayout(self._form_layout)
     self._columns = 0
 
     # Entity name.
     edit = self._entity_name_edit = Q.LineEdit()
     edit.setText(self._namer.entity_name)
     edit.textChanged.connect(self.update_preview)
     self._add_form_column('Shot/Asset Name', edit)
     
     # Step name.
     self._step_name_combo = Q.ComboBox()
     self._build_step_combo()
     self._step_name_combo.activated.connect(self.update_preview)
     self._add_form_column('Task', self._step_name_combo)
     
     # Description.
     edit = self._detail_edit = Q.LineEdit()
     edit.setText(self._namer.detail)
     edit.textChanged.connect(self.update_preview)
     edit.setFocus()
     self._add_form_column('Detail (optional)', edit)
     
     # Version.
     spinner = self._version_spinner = Q.SpinBox()
     spinner.textFromValue = lambda x: '%04d' % x
     spinner.setValue(self._namer.version)
     spinner.setMinimum(0)
     spinner.setMaximum(9999)
     spinner.valueChanged.connect(self.update_preview)
     self._add_form_column('Version', spinner)
     
     # Revision.
     spinner = self._revision_spinner = Q.SpinBox()
     spinner.textFromValue = lambda x: '%04d' % x
     spinner.setValue(self._namer.revision)
     spinner.setMinimum(0)
     spinner.setMaximum(9999)
     spinner.valueChanged.connect(self.update_preview)
     self._add_form_column('Revision', spinner)
     
     # Name preview.
     label = self._preview_label = Q.Label()
     label.setAlignment(Q.AlignHCenter)
     label.setContentsMargins(6, 6, 6, 6)
     self._layout.addWidget(label)
     
     # Prime the preview.
     self.update_preview()
示例#12
0
    def add_playblasts(self, playblasts):
        for playblast in sorted(
                playblasts,
                key=lambda pb:
            (' None'
             if pb.user_category == 'none' else pb.user_category, pb.name)):
            row = self.rowCount()
            self.setRowCount(row + 1)
            self.setRowHeight(row, 57)

            thumb = PlayblastThumbnail(playblast.first_frame)
            thumb.playblast = playblast
            self.setCellWidget(row, 0, thumb)

            name = Q.TableWidgetItem(playblast.name)
            self.setItem(row, 1, name)

            date = Q.TableWidgetItem(playblast.created_at.isoformat(' '))
            self.setItem(row, 2, date)
示例#13
0
 def _setup_ui(self):
     
     self._pairs = []
     
     for section in self._sections:
         self.addLayout(section)
     
     self._custom_field = Q.LineEdit(parent=self._parent)
     self._custom_field.editingFinished.connect(self._on_custom_edited)
     self._custom_pair = Labeled("Custom Path", self._custom_field)
     self.addLayout(self._custom_pair)
     
     self._browse_button = Q.PushButton(silk_icon('folder', 12), "Browse", parent=self._parent)
     self._browse_button.setMaximumSize(Q.Size(75, 20))
     self._browse_button.clicked.connect(self._on_browse)
     self._browse_pair = Labeled("", self._browse_button)
     self.addLayout(self._browse_pair)
     
     self._sections[0].repopulate(self.root())
示例#14
0
 def contextMenuEvent(self, event):
     menu = Q.Menu(self)
     flipbook_action = menu.addAction("Flipbook")
     flipbook_action.triggered.connect(self.flipbook_playblast)
     qt_action = menu.addAction("Make Quicktime")
     qt_action.triggered.connect(self.make_quicktime)
     refresh_action = menu.addAction("Refresh")
     refresh_action.triggered.connect(self.refresh.emit)
     delete_action = menu.addAction("Delete")
     delete_action.triggered.connect(self.delete_playblasts)
     action = menu.exec_(event.globalPos())
示例#15
0
    def _setup_ui(self):
        self.setWindowTitle("Copy Publish to Work Area")

        self.setLayout(Q.VBoxLayout())

        self._workspace = workspace = self._path or cmds.workspace(
            q=True, rootDirectory=True)
        self._model, self._picker = picker_presets.publishes_from_path(
            workspace)
        self._model.register_node_type(ScenePickerNode)
        self._picker.setMaximumHeight(400)
        self._picker.nodeChanged.connect(self._on_node_changed)
        self._picker.setColumnWidths([200] * 10)
        self.layout().addWidget(self._picker)

        self._namer = SceneNameWidget(dict(workspace=workspace))
        self.layout().addWidget(self._namer)

        button_layout = Q.HBoxLayout()
        self.layout().addLayout(button_layout)

        self._cancel_button = Q.PushButton("Cancel")
        self._cancel_button.clicked.connect(self._on_cancel_pressed)
        button_layout.addWidget(self._cancel_button)

        button_layout.addStretch()

        self._copy_button = Q.PushButton("Copy")
        self._copy_button.setEnabled(False)
        self._copy_button.clicked.connect(self._on_copy_pressed)
        button_layout.addWidget(self._copy_button)

        self._open_button = Q.PushButton("Copy and Open")
        self._open_button.setEnabled(False)
        self._open_button.clicked.connect(self._on_open_pressed)
        button_layout.addWidget(self._open_button)

        self._preview = Preview()
        self._picker.setPreviewWidget(self._preview)
        self._picker.updatePreviewWidget.connect(self._on_update_preview)
示例#16
0
文件: widget.py 项目: vfxetc/sgfs
    def __init__(self, kwargs=None, parent=None):
        super(Dialog, self).__init__(parent)
        
        self.setWindowTitle('(Re)Name Scene')
        
        # The main widget.
        self._widget = SceneNameWidget(kwargs)
        self.setLayout(self._widget.layout())
        
        # Save button.
        save_button = Q.PushButton('Save')
        save_button.clicked.connect(self._on_save_button)
    
        # Cancel button.
        cancel_button = Q.PushButton('Cancel')
        cancel_button.clicked.connect(self._on_cancel_button)

        # Adding Save ane Cancel button to a box so they can be on the same line
        hbox = Q.HBoxLayout()
        hbox.addWidget(save_button)
        hbox.addWidget(cancel_button)
        self.layout().addLayout(hbox)
示例#17
0
    def _setupGui(self):
        
        self.setWindowTitle("Update References")
        self.setLayout(Q.VBoxLayout())
        
        self._tree = Q.TreeWidget()
        self._tree.setIndentation(0)
        self._tree.setItemsExpandable(False)
        self._tree.setHeaderLabels(["Name", "Entity", "Step", "Task", "Type", "Publish Name", "Version"])
        self.layout().addWidget(self._tree)
        
        button_layout = Q.HBoxLayout()
        button_layout.addStretch()
        
        #TO-DO: Finish implementing Update all
        self._update_button = Q.PushButton('Update All')
        #button_layout.addWidget(self._update_button)
        
        self._close_button = Q.PushButton('Close')
        self._close_button.clicked.connect(self._on_close_button)
        button_layout.addWidget(self._close_button)

        self.layout().addLayout(button_layout)
示例#18
0
文件: view.py 项目: vfxetc/sgfs
    def _on_context_menu(self, view, point):
        index = view.indexAt(point)
        node = self.model().node_from_index(index)

        menu = Q.Menu()
        if node.parent and not isinstance(node, base.Group):
            node.parent.add_child_menu_actions(node, menu)

        if not menu.isEmpty():
            menu.addSeparator()

        menu.addAction(icon('fatcow/arrow_refresh', as_icon=True), "Reload",
                       functools.partial(self._reload_node, node))
        menu.exec_(view.mapToGlobal(point))
示例#19
0
文件: dialog.py 项目: vfxetc/sgfs
    def _setupGui(self):

        self.setMinimumWidth(1000)
        self.setMinimumHeight(400)
        
        self.setLayout(Q.VBoxLayout())
        
        self._model, self._picker = self._buildPicker()

        self._picker.setMaximumHeight(400)
        self._picker.setPreviewVisible(False)
        self._picker.nodeChanged.connect(self._onNodeChanged)

        self.layout().addWidget(self._picker)
        
        button_layout = Q.HBoxLayout()
        self.layout().addLayout(button_layout)

        self._cancelButton = Q.PushButton("Cancel")
        self._cancelButton.clicked.connect(self._onCancel)
        button_layout.addWidget(self._cancelButton)

        button_layout.addStretch()

        self._makeButton = Q.PushButton("Make Folder")
        self._makeButton.setEnabled(False)
        self._makeButton.clicked.connect(self._onSelectMakeFolder)
        button_layout.addWidget(self._makeButton)
        
        self._selectButton = Q.PushButton("Select")
        self._selectButton.setEnabled(False)
        self._selectButton.clicked.connect(self._onSelect)
        button_layout.addWidget(self._selectButton)

        # Trigger a button update.
        self._onNodeChanged(self._picker.currentNode())
示例#20
0
 def __init__(self, parent, widget, index, name, iter_func):
     super(Section, self).__init__()
     
     self._widget = widget
     self._index = index
     
     self._name = name
     self._iter_func = iter_func
     
     self._label = Q.Label(name, parent=parent)
     self.addWidget(self._label)
     
     self._combobox = ComboBox(parent=parent)
     self._combobox.activated.connect(self._on_activated)
     self.addWidget(self._combobox)
示例#21
0
    def _on_screenshot(self, *args):
        self.hide()
        path = tempfile.NamedTemporaryFile(suffix=".png",
                                           prefix="tanktmp",
                                           delete=False).name
        if sys.platform.startswith('darwin'):
            # use built-in screenshot command on the mac
            proc = subprocess.Popen(['screencapture', '-mis', path])
        else:
            proc = subprocess.Popen(['import', path])
        proc.wait()
        self.show()

        self._screenshot_path = path
        pixmap = Q.Pixmap(path).scaledToHeight(100, Q.SmoothTransformation)
        self._screenshot.setPixmap(pixmap)
        self._screenshot.setFixedSize(pixmap.size())
示例#22
0
 def _on_movie_browse(self):
     
     existing = str(self._movie_path.text())
     
     dialog = Q.QFileDialog(None, "Select Movie or First Frame")
     dialog.setFilter('Movie or Frame (*.mov *.exr *.tif *.tiff *.jpg *.jpeg)')
     dialog.setFileMode(dialog.ExistingFile)
     dialog.setDirectory(os.path.dirname(existing) if existing else os.getcwd())
     if existing:
         dialog.selectFile(existing)
     
     if not dialog.exec_():
         return
     
     files = dialog.selectedFiles()
     path = str(files.First())
     self.setFrames(path)
示例#23
0
def ticket_current_exception(dialog_class=None):

    msgbox = Q.MessageBox()

    exc_type, exc_value, exc_traceback = sys.exc_info()

    msgbox.setIcon(msgbox.Critical)
    msgbox.setWindowTitle('Python Exception')
    msgbox.setText("Uncaught Python Exception: %s" % exc_type.__name__)

    if str(exc_value
           ) == 'super(type, obj): obj must be an instance or subtype of type':
        msgbox.setInformativeText(
            '%s<br/><br/>'
            '<b><i>This appears to be a code reloading issue. '
            'Restarting this program should fix it.</i></b>' % exc_value)
    else:
        msgbox.setInformativeText(str(exc_value))
        msgbox.setDetailedText(traceback.format_exc())
        msgbox.setStyleSheet("* { font-family: monospace; }")

    msgbox.addButton("Submit Ticket", msgbox.AcceptRole)

    ignore = msgbox.addButton(msgbox.Ignore)
    msgbox.setDefaultButton(ignore)  # <- This does not seem to do much.
    msgbox.setEscapeButton(ignore)

    # Returns an int of the button code. Our custom one is 0.
    res = msgbox.exec_()
    if res:
        return False

    dialog_class = dialog_class or Dialog
    dialog = dialog_class([(exc_type, exc_value, exc_traceback)],
                          allow_no_exception=False)
    dialog.show()

    return True
示例#24
0
    def _setup_ui(self):
        self.setWindowTitle("Create Reference")

        self.setLayout(Q.VBoxLayout())

        workspace = self._path or cmds.workspace(q=True, rootDirectory=True)
        self._model, self._picker = picker_presets.publishes_from_path(
            workspace)
        self._model.register_node_type(ScenePickerNode)
        self._picker.setMaximumHeight(400)
        self._picker.nodeChanged.connect(self._on_node_changed)
        self._picker.setColumnWidths([200] * 10)
        self.layout().addWidget(self._picker)

        button_layout = Q.HBoxLayout()
        bottom_button_layout = Q.HBoxLayout()

        self._namespace_field = Q.LineEdit()
        if self._custom_namespace:
            button_layout.addWidget(Q.Label("Namespace:"))
            button_layout.addWidget(self._namespace_field)

        button_layout.addStretch()
        self.layout().addLayout(button_layout)

        self._button = Q.PushButton("Create Reference")
        self._button.setEnabled(False)
        self._button.clicked.connect(self._on_create_reference)

        self._cancel_button = Q.PushButton("Cancel")
        self._cancel_button.clicked.connect(self._on_cancel)
        bottom_button_layout.addWidget(self._cancel_button)
        bottom_button_layout.addStretch()
        bottom_button_layout.addWidget(self._button)

        self.layout().addLayout(bottom_button_layout)

        self._preview = Preview()
        self._picker.setPreviewWidget(self._preview)
        self._picker.updatePreviewWidget.connect(self._on_update_preview)
示例#25
0
    def __init__(self):

        super(Dialog, self).__init__()

        self.setWindowFlags(Q.WindowStaysOnTopHint)

        self.show()

        self.progressDialog = Q.ProgressDialog(self,
            windowModality=Q.WindowModal,
            minimum=0,
            maximum=0,
        )
        self.progressDialog.canceled.connect(self.close)
        self.progressDialog.show()

        future = call_in_background(self._discoverCaches)
        @future.add_done_callback
        def _(f):
            print 'done1'
            if f.exception():
                print 'done2'
                self.close()
示例#26
0
 def __init__(self, label, widget):
     super(Labeled, self).__init__()
     self._label = Q.Label(label)
     self.addWidget(self._label)
     self._widget = widget
     self.addWidget(widget)
示例#27
0
def silk_icon(name, size=16):
    icon = Q.Icon(silk(name))
    if size != 16:
        icon = Q.Icon(icon.pixmap(size, size))
    return icon
示例#28
0
class PlayblastTable(Q.TableWidget):
    refresh = Q.pyqtSignal()

    def __init__(self, parent=None):
        super(PlayblastTable, self).__init__(parent)
        self.setColumnCount(3)
        self.setColumnWidth(0, 100)
        self.verticalHeader().hide()
        self.horizontalHeader().setStretchLastSection(True)
        self.setHorizontalHeaderLabels(
            ['First Frame', 'Name', 'Creation Time'])
        self.setAlternatingRowColors(True)
        self.setSelectionBehavior(self.SelectRows)
        self.setSortingEnabled(True)
        self.sortItems(2, Qt.DescendingOrder)
        self.setEditTriggers(Q.AbstractItemView.NoEditTriggers)
        self.itemDoubleClicked.connect(lambda x: self.flipbook_playblast())

    def add_playblasts(self, playblasts):
        for playblast in sorted(
                playblasts,
                key=lambda pb:
            (' None'
             if pb.user_category == 'none' else pb.user_category, pb.name)):
            row = self.rowCount()
            self.setRowCount(row + 1)
            self.setRowHeight(row, 57)

            thumb = PlayblastThumbnail(playblast.first_frame)
            thumb.playblast = playblast
            self.setCellWidget(row, 0, thumb)

            name = Q.TableWidgetItem(playblast.name)
            self.setItem(row, 1, name)

            date = Q.TableWidgetItem(playblast.created_at.isoformat(' '))
            self.setItem(row, 2, date)

    def contextMenuEvent(self, event):
        menu = Q.Menu(self)
        flipbook_action = menu.addAction("Flipbook")
        flipbook_action.triggered.connect(self.flipbook_playblast)
        qt_action = menu.addAction("Make Quicktime")
        qt_action.triggered.connect(self.make_quicktime)
        refresh_action = menu.addAction("Refresh")
        refresh_action.triggered.connect(self.refresh.emit)
        delete_action = menu.addAction("Delete")
        delete_action.triggered.connect(self.delete_playblasts)
        action = menu.exec_(event.globalPos())

    def current_playblast(self):
        row = self.currentRow()
        thumb = self.cellWidget(row, 0) if row is not None else None
        playblast = thumb and thumb.playblast
        return playblast

    def current_path(self):
        playblast = self.current_playblast()
        path = playblast and playblast.directory
        return path if path and os.path.exists(path) else None

    def delete_playblasts(self):
        rows = []
        for item in self.selectedItems():
            if not item.row() in rows:
                rows.append(item.row())

        for row in reversed(sorted(rows)):
            dirname = None
            thumb = self.cellWidget(row, 0) if row is not None else None
            if thumb and thumb.playblast and thumb.playblast.directory and os.path.exists(
                    thumb.playblast.directory):
                dirname = thumb.playblast.directory

            print "rm", dirname, row
            self.removeRow(row)
            if dirname:
                shutil.rmtree(dirname)

    def flipbook_playblast(self):
        playblast = self.current_playblast()

        cmd = [
            'rv', '[',
            os.path.join(playblast.directory, '*.jpg'), '-fps',
            str(24), ']'
        ]
        if playblast.audio:
            cmd.extend(['-over', '[', playblast.audio, ']'])

        # fix for launching rv from maya on mac
        # http://www.tweaksoftware.com/static/documentation/rv/current/html/maya_tools_help.html#_osx_maya_2014
        env = dict(os.environ)
        if 'QT_MAC_NO_NATIVE_MENUBAR' in env:
            del env['QT_MAC_NO_NATIVE_MENUBAR']

        print subprocess.list2cmdline(cmd)
        proc = subprocess.Popen(cmd, env=env)

    def make_quicktime(self):
        playblast = self.current_playblast()

        cmd = ['make_quicktime', playblast.first_frame]

        if playblast.audio:
            cmd.extend(['--audio', playblast.audio])

        if playblast.maya_file:
            cmd.extend(['--shotdir', playblast.maya_file])

        print subprocess.list2cmdline(cmd)
        subprocess.Popen(cmd)
示例#29
0
 def sizeHint(self):
     if self._loaded:
         return self.pixmap().size()
     else:
         return Q.Size(100, 57)
示例#30
0
class Picker(Q.TabWidget):

    pathChanged = Q.pyqtSignal(object)

    def __init__(
        self,
        parent=None,
        selection_mode=Q.TableWidget.SingleSelection,
    ):
        super(Picker, self).__init__(parent)

        self._playblasts = []
        self._selection_mode = selection_mode
        self._find_legacy_playblasts()
        self._tables_by_name = {}
        self._setup_ui()

    def _setup_ui(self):
        self.currentChanged.connect(self._current_tab_changed)
        tables = self._tables_by_name
        for playblast in sorted(
                self._playblasts,
                key=lambda pb:
            (' None'
             if pb.user_category == 'none' else pb.user_category, pb.name)):
            if playblast.user_category not in tables:

                table = PlayblastTable()
                table.itemSelectionChanged.connect(
                    self._table_selection_changed)
                table.refresh.connect(self.refresh)
                if self._selection_mode:
                    table.setSelectionMode(self._selection_mode)
                tables[playblast.user_category] = table
                self.addTab(
                    table, "Playblasts" if playblast.user_category == "none"
                    else playblast.user_category.title())

            table = tables[playblast.user_category]
            table.add_playblasts([playblast])

        for table in tables.itervalues():
            table.resizeColumnToContents(1)
            table.resizeColumnToContents(2)

    def refresh(self):
        for table in self._tables_by_name.itervalues():
            table.clearContents()
            table.setRowCount(0)
        self._playblasts = []
        self._find_legacy_playblasts()
        self._setup_ui()

    def _find_legacy_playblasts(self):

        # This is the folder that they are stored in.
        if not os.path.exists('/var/tmp/srv_playblast'):
            return

        for name in os.listdir('/var/tmp/srv_playblast'):

            directory = os.path.join('/var/tmp/srv_playblast', name)

            # Try to grab the first frame.
            try:
                file_names = os.listdir(directory)
            except OSError as e:
                if e.errno == 20:  # Not a folder.
                    continue
                raise

            frame_gen = (x for x in sorted(file_names)
                         if os.path.splitext(x)[1] in ('.jpg', '.jpeg'))
            first_frame = next(frame_gen, None)
            if first_frame is None:
                continue

            audio = None
            maya_file = None
            audio_text = next((x for x in sorted(file_names)
                               if os.path.splitext(x)[1] in ('.txt', )))
            if audio_text:
                audio, maya_file, frame_rate = parse_audio_txt(
                    os.path.join(directory, audio_text))

            first_frame = os.path.join(directory, first_frame)

            user_category_path = os.path.join(directory, 'approval_status')
            user_category = open(user_category_path).read() if os.path.exists(
                user_category_path) else None
            user_category = str(user_category).lower()

            self._playblasts.append(
                PlayblastInfo(name=name,
                              directory=directory,
                              user_category=user_category,
                              first_frame=first_frame,
                              created_at=datetime.datetime.fromtimestamp(
                                  os.path.getctime(first_frame)),
                              audio=audio,
                              maya_file=maya_file))

    def autoSetMinimumWidth(self):
        width = 0
        for table in self._tables_by_name.itervalues():
            width = max(
                width,
                sum(table.columnWidth(i) for i in xrange(table.columnCount())))
        if width:
            self.setMinimumWidth(width)

    def _table_selection_changed(self):
        path = self.currentPath()
        self.pathChanged.emit(path)

    def _current_tab_changed(self):
        path = self.currentPath()
        self.pathChanged.emit(path)

    def currentPath(self):
        table = self.currentWidget()
        return table.current_path()