コード例 #1
0
ファイル: outliner.py プロジェクト: noizfactory/usd-qt
    def __init__(self, stage, role=None, parent=None):
        # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None
        """
        Parameters
        ----------
        stage : Usd.Stage
        role : Optional[Union[Type[OutlinerRole], OutlinerRole]]
        parent : Optional[QtGui.QWidget]
        """
        assert isinstance(stage, Usd.Stage), 'A Stage instance is required'
        super(UsdOutliner, self).__init__(parent=parent)

        self._stage = stage
        self._dataModel = HierarchyBaseModel(stage=stage, parent=self)
        self._listener = Tf.Notice.Register(Usd.Notice.StageEditTargetChanged,
                                            self._OnEditTargetChanged, stage)

        self.setModal(False)
        self.UpdateTitle()

        if role is None:
            role = OutlinerRole
        self.role = role

        view = self._CreateView(stage, self.role)
        view.setColumnWidth(0, 360)
        view.setModel(self._dataModel)
        self.view = view

        delegate = OutlinerViewDelegate(stage, parent=view)
        view.setItemDelegate(delegate)

        self.menuBarBuilder = MenuBarBuilder(
            self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(4, 4, 4, 4)
        layout.setSpacing(2)
        layout.addWidget(self.menuBarBuilder.menuBar)
        layout.addWidget(view)

        self.resize(900, 600)

        # Instances of child dialogs (for reference-counting purposes)
        self.editTargetDialog = None
        self.variantEditorDialog = None
コード例 #2
0
    def __init__(self, stage, role=None, parent=None):
        # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None
        """
        Parameters
        ----------
        stage : Usd.Stage
        role : Optional[Union[Type[OutlinerRole], OutlinerRole]]
        parent : Optional[QtGui.QWidget]
        """
        super(UsdOutliner, self).__init__(parent=parent)

        self._stage = None
        self._listener = None
        self._dataModel = HierarchyBaseModel(stage=stage, parent=self)
        self.ResetStage(stage)

        if role is None:
            role = OutlinerRole
        self.role = role

        view = self._CreateView(stage, self.role)
        view.setColumnWidth(0, 360)
        view.setModel(self._dataModel)
        self.view = view

        delegate = OutlinerViewDelegate(stage, parent=view)
        view.setItemDelegate(delegate)
        self.stageChanged.connect(delegate.ResetStage)

        self.menuBarBuilder = MenuBarBuilder(
            self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(4, 4, 4, 4)
        layout.setSpacing(2)
        layout.addWidget(self.menuBarBuilder.menuBar)
        layout.addWidget(view)

        # Instances of child dialogs (for reference-counting purposes)
        self._sharedLayerTextEditors = {}
        self.editTargetDialog = None
        self.variantEditorDialog = None
コード例 #3
0
class UsdOutliner(QtWidgets.QWidget):
    """UsdStage editing application which displays the hierarchy of a stage."""
    # Emitted when a new stage should be loaded into the outliners models
    stageChanged = QtCore.Signal(Usd.Stage)

    def __init__(self, stage, role=None, parent=None):
        # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None
        """
        Parameters
        ----------
        stage : Usd.Stage
        role : Optional[Union[Type[OutlinerRole], OutlinerRole]]
        parent : Optional[QtGui.QWidget]
        """
        super(UsdOutliner, self).__init__(parent=parent)

        self._stage = None
        self._listener = None
        self._dataModel = HierarchyBaseModel(stage=stage, parent=self)
        self.ResetStage(stage)

        if role is None:
            role = OutlinerRole
        self.role = role

        view = self._CreateView(stage, self.role)
        view.setColumnWidth(0, 360)
        view.setModel(self._dataModel)
        self.view = view

        delegate = OutlinerViewDelegate(stage, parent=view)
        view.setItemDelegate(delegate)
        self.stageChanged.connect(delegate.ResetStage)

        self.menuBarBuilder = MenuBarBuilder(
            self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(4, 4, 4, 4)
        layout.setSpacing(2)
        layout.addWidget(self.menuBarBuilder.menuBar)
        layout.addWidget(view)

        # Instances of child dialogs (for reference-counting purposes)
        self._sharedLayerTextEditors = {}
        self.editTargetDialog = None
        self.variantEditorDialog = None

    def _CreateView(self, stage, role):
        # type: (Usd.Stage, Union[Type[OutlinerRole], OutlinerRole]) -> QtWidgets.QAbstractItemView
        """Create the hierarchy view for the outliner.

        This is provided as a convenience for subclass implementations.

        Parameters
        ----------
        stage : Usd.Stage
        role : Union[Type[OutlinerRole], OutlinerRole]

        Returns
        -------
        QtWidgets.QAbstractItemView
        """
        return OutlinerTreeView(
            contextMenuActions=role.GetContextMenuActions(self),
            contextProvider=self,
            parent=self)

    @property
    def stage(self):
        return self._stage

    def _LayerDialogEditTargetChangeCallback(self, newLayer):
        currentLayer = self.GetEditTargetLayer()
        if newLayer == currentLayer or not newLayer.permissionToEdit:
            return False

        if currentLayer.dirty:
            box = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Warning,
                'Unsaved Layer Changes',
                'The current edit target layer contains unsaved edits which '
                'will not be accessible after changing edit targets. Are you '
                'sure you want to switch?',
                buttons=QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes,
                parent=self)
            if box.exec_() != QtWidgets.QMessageBox.Yes:
                return False
        return True

    def GetMenuContext(self):
        # type: () -> OutlinerContext
        """
        Returns
        -------
        OutlinerContext
        """
        selectedPrims = self.view.SelectedPrims()
        selectedPrim = selectedPrims[0] if selectedPrims else None
        return OutlinerContext(qtParent=self,
                               outliner=self,
                               stage=self._stage,
                               editTargetLayer=self.GetEditTargetLayer(),
                               selectedPrim=selectedPrim,
                               selectedPrims=selectedPrims)

    def GetEditTargetLayer(self):
        # type: () -> Sdf.Layer
        """
        Returns
        -------
        Sdf.Layer
        """
        if self._stage:
            return self._stage.GetEditTarget().GetLayer()

    def ResetStage(self, stage):
        """Reset the stage for this outliner and child dialogs.

        Parameters
        ----------
        stage : Union[Usd.Stage, None]
            If None is given, this will clear the current stage
        """
        self._stage = stage
        self._dataModel.ResetStage(stage)
        self.stageChanged.emit(stage)

    def _OnLayerTextEditorFinished(self, layer):
        dialog = self._sharedLayerTextEditors.pop(layer, None)
        if dialog:
            dialog.deleteLater()

    def GetSharedLayerTextEditorInstance(self, layer):
        # type: (Sdf.Layer, bool, Optional[QtWidgets.QWidget]) -> LayerTextEditorDialog
        """Convenience method to get or create a shared editor dialog instance.

        Parameters
        ----------
        key : Any
        parent : Optional[QtWidgets.QWidget]

        Returns
        -------
        LayerTextEditorDialog
        """
        dialog = self._sharedLayerTextEditors.get(layer)
        if dialog is None:
            readOnly = not layer.permissionToEdit
            dialog = LayerTextEditorDialog(layer,
                                           readOnly=readOnly,
                                           parent=self)
            self._sharedLayerTextEditors[layer] = dialog
            dialog.finished.connect(
                lambda result: self._OnLayerTextEditorFinished(layer))
        return dialog

    def ShowLayerTextDialog(self, layer=None):
        if layer is None:
            layer = self.GetEditTargetLayer()
        dialog = self.GetSharedLayerTextEditorInstance(layer)
        self.stageChanged.connect(dialog.close)
        dialog.show()
        dialog.raise_()
        dialog.activateWindow()

    def ShowEditTargetDialog(self):
        if not self.editTargetDialog:
            dialog = EditTargetDialog(self._stage,
                                      editTargetChangeCallback=self.
                                      _LayerDialogEditTargetChangeCallback,
                                      parent=self)
            self.stageChanged.connect(dialog.editor.ResetStage)
            self.editTargetDialog = dialog
        self.editTargetDialog.show()
        self.editTargetDialog.raise_()
        self.editTargetDialog.activateWindow()
コード例 #4
0
ファイル: outliner.py プロジェクト: noizfactory/usd-qt
class UsdOutliner(QtWidgets.QDialog):
    """UsdStage editing application which displays the hierarchy of a stage."""
    def __init__(self, stage, role=None, parent=None):
        # type: (Usd.Stage, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> None
        """
        Parameters
        ----------
        stage : Usd.Stage
        role : Optional[Union[Type[OutlinerRole], OutlinerRole]]
        parent : Optional[QtGui.QWidget]
        """
        assert isinstance(stage, Usd.Stage), 'A Stage instance is required'
        super(UsdOutliner, self).__init__(parent=parent)

        self._stage = stage
        self._dataModel = HierarchyBaseModel(stage=stage, parent=self)
        self._listener = Tf.Notice.Register(Usd.Notice.StageEditTargetChanged,
                                            self._OnEditTargetChanged, stage)

        self.setModal(False)
        self.UpdateTitle()

        if role is None:
            role = OutlinerRole
        self.role = role

        view = self._CreateView(stage, self.role)
        view.setColumnWidth(0, 360)
        view.setModel(self._dataModel)
        self.view = view

        delegate = OutlinerViewDelegate(stage, parent=view)
        view.setItemDelegate(delegate)

        self.menuBarBuilder = MenuBarBuilder(
            self, menuBuilders=role.GetMenuBarMenuBuilders(self), parent=self)

        layout = QtWidgets.QVBoxLayout(self)
        layout.setContentsMargins(4, 4, 4, 4)
        layout.setSpacing(2)
        layout.addWidget(self.menuBarBuilder.menuBar)
        layout.addWidget(view)

        self.resize(900, 600)

        # Instances of child dialogs (for reference-counting purposes)
        self.editTargetDialog = None
        self.variantEditorDialog = None

    def _CreateView(self, stage, role):
        # type: (Usd.Stage, Union[Type[OutlinerRole], OutlinerRole]) -> QtWidgets.QAbstractItemView
        """Create the hierarchy view for the outliner.

        This is provided as a convenience for subclass implementations.

        Parameters
        ----------
        stage : Usd.Stage
        role : Union[Type[OutlinerRole], OutlinerRole]

        Returns
        -------
        QtWidgets.QAbstractItemView
        """
        return OutlinerTreeView(
            self._dataModel,
            contextMenuActions=role.GetContextMenuActions(self),
            contextProvider=self,
            parent=self)

    @property
    def stage(self):
        return self._stage

    def _OnEditTargetChanged(self, notice, stage):
        self.UpdateTitle()

    def _LayerDialogEditTargetChangeCallback(self, newLayer):
        currentLayer = self.GetEditTargetLayer()
        if newLayer == currentLayer or not newLayer.permissionToEdit:
            return False

        if currentLayer.dirty:
            box = QtWidgets.QMessageBox(
                QtWidgets.QMessageBox.Warning,
                'Unsaved Layer Changes',
                'The current edit target layer contains unsaved edits which '
                'will not be accessible after changing edit targets. Are you '
                'sure you want to switch?',
                buttons=QtWidgets.QMessageBox.No | QtWidgets.QMessageBox.Yes,
                parent=self)
            if box.exec_() != QtWidgets.QMessageBox.Yes:
                return False
        return True

    def GetMenuContext(self):
        # type: () -> OutlinerContext
        """
        Returns
        -------
        OutlinerContext
        """
        selectedPrims = self.view.SelectedPrims()
        selectedPrim = selectedPrims[0] if selectedPrims else None
        return OutlinerContext(qtParent=self,
                               outliner=self,
                               stage=self._stage,
                               editTargetLayer=self.GetEditTargetLayer(),
                               selectedPrim=selectedPrim,
                               selectedPrims=selectedPrims)

    def GetEditTargetLayer(self):
        # type: () -> Sdf.Layer
        """
        Returns
        -------
        Sdf.Layer
        """
        return self._stage.GetEditTarget().GetLayer()

    def ResetStage(self):
        # TODO: Need to make sure this is still safe
        self._dataModel.ResetStage(self._stage)

    def UpdateTitle(self, identifier=None):
        # type: (Optional[str]) -> None
        """
        Parameters
        ----------
        identifier : Optional[str]
            If not provided, it is acquired from the curent edit target.
        """
        if not identifier:
            identifier = self.GetEditTargetLayer().identifier
        self.setWindowTitle('Outliner - %s' % identifier)

    def ShowLayerTextDialog(self, layer=None):
        if layer is None:
            layer = self.GetEditTargetLayer()
        dialog = LayerTextEditorDialog.GetSharedInstance(layer, parent=self)
        dialog.show()
        dialog.raise_()
        dialog.activateWindow()

    def ShowEditTargetDialog(self):
        if not self.editTargetDialog:
            dialog = EditTargetDialog(self._stage,
                                      editTargetChangeCallback=self.
                                      _LayerDialogEditTargetChangeCallback,
                                      parent=self)
            self.editTargetDialog = dialog
        self.editTargetDialog.show()
        self.editTargetDialog.raise_()
        self.editTargetDialog.activateWindow()

    @classmethod
    def FromUsdFile(cls, usdFile, role=None, parent=None):
        # type: (str, Optional[Union[Type[OutlinerRole], OutlinerRole]], Optional[QtGui.QWidget]) -> UsdOutliner
        """
        Parameters
        ----------
        usdFile : str
        role : Optional[Union[Type[OutlinerRole], OutlinerRole]]
        parent : Optional[QtGui.QWidget]

        Returns
        -------
        UsdOutliner
        """
        with Usd.StageCacheContext(Usd.BlockStageCaches):
            stage = Usd.Stage.Open(usdFile, Usd.Stage.LoadNone)
            assert stage, 'Failed to open stage'
            stage.SetEditTarget(stage.GetSessionLayer())
        return cls(stage, role=role, parent=parent)
コード例 #5
0
        model : HierarchyBaseModel
        """
        self._filterModel.setSourceModel(model)


if __name__ == "__main__":
    import sys
    from pxr.UsdQt.hierarchyModel import HierarchyBaseModel

    app = QtWidgets.QApplication(sys.argv)

    with Usd.StageCacheContext(UsdUtils.StageCache.Get()):
        stage = Usd.Stage.Open(
            '../usdQt/testenv/testUsdQtHierarchyModel/simpleHierarchy.usda')

    model = HierarchyBaseModel(stage)

    class Listener(QtCore.QObject):
        def __init__(self, parent=None):
            super(Listener, self).__init__(parent=parent)

        @QtCore.Slot()
        def OnPrimSelectionChanged(self, selected=None, deselected=None):
            for index in self.sender().selectedIndexes():
                prim = index.data(role=roles.HierarchyPrimRole)
                # print(prim)

    editor = HierarchyEditor()
    editor.SetSourceModel(model)
    editor.show()