示例#1
0
class VrayPropTreeView(QtWidgets.QTreeView):
    on_parent_changed = QtCore.Signal(QtCore.QModelIndex)

    def __init__(self, api, parent=None):
        super(VrayPropTreeView, self).__init__(parent=parent)

        self._tree_model = None
        self._tree_proxy = None
        self._api = api
        self._root = Root()
        self._setup()
        self._connect_signals()

    def get_proxy(self):
        return self._tree_proxy

    def get_model(self):
        return self._tree_model

    def _setup(self):
        # setup drag an drop
        self.setDragDropMode(self.InternalMove)
        self.setAcceptDrops(True)
        self.setDropIndicatorShown(True)
        self.setDragDropOverwriteMode(True)

        self._tree_model = TreeModel(self._api, self._root, parent=self)
        self._tree_proxy = makeQSortFilterProxyModel(self)
        self._tree_proxy.setSourceModel(self._tree_model)
        self.setSortingEnabled(True)
        self.sortByColumn(0, QtCore.Qt.AscendingOrder)
        self._tree_proxy.setDynamicSortFilter(True)

        self._tree_proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive)
        self._tree_proxy.setSortRole(TreeModel.sortRole)
        self._tree_proxy.setFilterRole(TreeModel.filterRole)

        self.setModel(self._tree_proxy)
        self.setColumnWidth(0, 175)

        header = self.header()
        header.setStretchLastSection(False)
        setHeaderViewResizeMode(header, QtWidgets.QHeaderView.Stretch, 0)
        self.setAnimated(True)

    def _gen_new_dir(self):
        dir = self._api.create_directory()
        self._tree_model.insertNode(dir)

    def _rcmenu(self, x):
        menu = QtWidgets.QMenu(self)
        new_dir = QtWidgets.QAction(self)
        new_dir.setText('New Directory')
        new_dir.triggered.connect(self._gen_new_dir)
        menu.addAction(new_dir)
        menu.exec_(self.mapToGlobal(x))

    def _connect_signals(self):
        self.setContextMenuPolicy(QtCore.Qt.CustomContextMenu)
        self.customContextMenuRequested.connect(lambda x: self._rcmenu(x))

    def _is_valid_drop(self, drag_node, drop_node):
        if not drop_node and drag_node.parent == self._root:
            return False
        if drag_node == drop_node:
            return False
        if not drop_node:
            return True
        if drag_node.parent == drop_node:
            return False
        if drop_node.is_descendant_of(drag_node):
            return False
        return True

    def _get_importer_at_pos(self, pos):
        index = self._tree_proxy.mapToSource(self.indexAt(pos))
        return self._tree_model.data(index, self._tree_model.itemRole)

    def get_selected_impoter(self):
        selMod = self.selectionModel()
        indx = selMod.selectedIndexes()[0]
        indx = self._tree_proxy.mapToSource(indx)
        return self._tree_model.data(indx, self._tree_model.itemRole)

    def dragMoveEvent(self, event):
        drag_node = self.get_selected_impoter()
        drop_node = self._get_importer_at_pos(event.pos())

        if not self._is_valid_drop(drag_node, drop_node):
            event.ignore()
            return

        event.accept()

    def dropEvent(self, event):
        self._updateSel = False
        drop_node = self._get_importer_at_pos(event.pos())
        drag_node = self.get_selected_impoter()

        if not self._is_valid_drop(drag_node, drop_node):
            event.ignore()
            return

        new_index = self._tree_model.parentNode(drag_node, drop_node)
        self.on_parent_changed.emit(new_index)