diff --git a/openpype/tools/utils/widgets.py b/openpype/tools/utils/widgets.py index 493255071d..8346db211b 100644 --- a/openpype/tools/utils/widgets.py +++ b/openpype/tools/utils/widgets.py @@ -38,293 +38,6 @@ class PlaceholderLineEdit(QtWidgets.QLineEdit): self.setPalette(filter_palette) -class AssetWidget(QtWidgets.QWidget): - """A Widget to display a tree of assets with filter - - To list the assets of the active project: - >>> # widget = AssetWidget() - >>> # widget.refresh() - >>> # widget.show() - - """ - - refresh_triggered = QtCore.Signal() # on model refresh - refreshed = QtCore.Signal() - selection_changed = QtCore.Signal() # on view selection change - current_changed = QtCore.Signal() # on view current index change - - def __init__(self, dbcon, multiselection=False, parent=None): - super(AssetWidget, self).__init__(parent=parent) - - self.dbcon = dbcon - - # Tree View - model = AssetModel(dbcon=self.dbcon, parent=self) - proxy = RecursiveSortFilterProxyModel() - proxy.setSourceModel(model) - proxy.setFilterCaseSensitivity(QtCore.Qt.CaseInsensitive) - - view = AssetsView(self) - view.setModel(proxy) - if multiselection: - asset_delegate = AssetDelegate() - view.setSelectionMode(view.ExtendedSelection) - view.setItemDelegate(asset_delegate) - - icon = qtawesome.icon("fa.arrow-down", color=style.colors.light) - set_current_asset_btn = QtWidgets.QPushButton(icon, "") - set_current_asset_btn.setToolTip("Go to Asset from current Session") - # Hide by default - set_current_asset_btn.setVisible(False) - - icon = qtawesome.icon("fa.refresh", color=style.colors.light) - refresh = QtWidgets.QPushButton(icon, "", parent=self) - refresh.setToolTip("Refresh items") - - filter_input = QtWidgets.QLineEdit(self) - filter_input.setPlaceholderText("Filter assets..") - - # Header - header_layout = QtWidgets.QHBoxLayout() - header_layout.addWidget(filter_input) - header_layout.addWidget(set_current_asset_btn) - header_layout.addWidget(refresh) - - # Layout - layout = QtWidgets.QVBoxLayout(self) - layout.setContentsMargins(0, 0, 0, 0) - layout.setSpacing(4) - layout.addLayout(header_layout) - layout.addWidget(view) - - # Signals/Slots - filter_input.textChanged.connect(proxy.setFilterFixedString) - - selection = view.selectionModel() - selection.selectionChanged.connect(self.selection_changed) - selection.currentChanged.connect(self.current_changed) - refresh.clicked.connect(self.refresh) - set_current_asset_btn.clicked.connect(self.set_current_session_asset) - - self.set_current_asset_btn = set_current_asset_btn - self.model = model - self.proxy = proxy - self.view = view - - self.model_selection = {} - - def set_current_asset_btn_visibility(self, visible=None): - """Hide set current asset button. - - Not all tools support using of current context asset. - """ - if visible is None: - visible = not self.set_current_asset_btn.isVisible() - self.set_current_asset_btn.setVisible(visible) - - def _refresh_model(self): - # Store selection - self._store_model_selection() - time_start = time.time() - - self.set_loading_state( - loading=True, - empty=True - ) - - def on_refreshed(has_item): - self.set_loading_state(loading=False, empty=not has_item) - self._restore_model_selection() - self.model.refreshed.disconnect() - self.refreshed.emit() - print("Duration: %.3fs" % (time.time() - time_start)) - - # Connect to signal - self.model.refreshed.connect(on_refreshed) - # Trigger signal before refresh is called - self.refresh_triggered.emit() - # Refresh model - self.model.refresh() - - def refresh(self): - self._refresh_model() - - def get_active_asset(self): - """Return the asset item of the current selection.""" - current = self.view.currentIndex() - return current.data(self.model.ItemRole) - - def get_active_asset_document(self): - """Return the asset document of the current selection.""" - current = self.view.currentIndex() - return current.data(self.model.DocumentRole) - - def get_active_index(self): - return self.view.currentIndex() - - def get_selected_assets(self): - """Return the documents of selected assets.""" - selection = self.view.selectionModel() - rows = selection.selectedRows() - assets = [row.data(self.model.DocumentRole) for row in rows] - - # NOTE: skip None object assumed they are silo (backwards comp.) - return [asset for asset in assets if asset] - - def select_assets(self, assets, expand=True, key="name"): - """Select assets by item key. - - Args: - assets (list): List of asset values that can be found under - specified `key` - expand (bool): Whether to also expand to the asset in the view - key (string): Key that specifies where to look for `assets` values - - Returns: - None - - Default `key` is "name" in that case `assets` should contain single - asset name or list of asset names. (It is good idea to use "_id" key - instead of name in that case `assets` must contain `ObjectId` object/s) - It is expected that each value in `assets` will be found only once. - If the filters according to the `key` and `assets` correspond to - the more asset, only the first found will be selected. - - """ - - if not isinstance(assets, (tuple, list)): - assets = [assets] - - # convert to list - tuple cant be modified - assets = set(assets) - - # Clear selection - selection_model = self.view.selectionModel() - selection_model.clearSelection() - - # Select - mode = selection_model.Select | selection_model.Rows - for index in lib.iter_model_rows( - self.proxy, column=0, include_root=False - ): - # stop iteration if there are no assets to process - if not assets: - break - - value = index.data(self.model.ItemRole).get(key) - if value not in assets: - continue - - # Remove processed asset - assets.discard(value) - - selection_model.select(index, mode) - if expand: - # Expand parent index - self.view.expand(self.proxy.parent(index)) - - # Set the currently active index - self.view.setCurrentIndex(index) - - def set_loading_state(self, loading, empty): - if self.view.is_loading != loading: - if loading: - self.view.spinner.repaintNeeded.connect( - self.view.viewport().update - ) - else: - self.view.spinner.repaintNeeded.disconnect() - - self.view.is_loading = loading - self.view.is_empty = empty - - def _store_model_selection(self): - index = self.view.currentIndex() - current = None - if index and index.isValid(): - current = index.data(self.model.ObjectIdRole) - - expanded = set() - model = self.view.model() - for index in lib.iter_model_rows( - model, column=0, include_root=False - ): - if self.view.isExpanded(index): - value = index.data(self.model.ObjectIdRole) - expanded.add(value) - - selection_model = self.view.selectionModel() - - selected = None - selected_rows = selection_model.selectedRows() - if selected_rows: - selected = set( - row.data(self.model.ObjectIdRole) - for row in selected_rows - ) - - self.model_selection = { - "expanded": expanded, - "selected": selected, - "current": current - } - - def _restore_model_selection(self): - model = self.view.model() - not_set = object() - expanded = self.model_selection.pop("expanded", not_set) - selected = self.model_selection.pop("selected", not_set) - current = self.model_selection.pop("current", not_set) - - if ( - expanded is not_set - or selected is not_set - or current is not_set - ): - return - - if expanded: - for index in lib.iter_model_rows( - model, column=0, include_root=False - ): - is_expanded = index.data(self.model.ObjectIdRole) in expanded - self.view.setExpanded(index, is_expanded) - - if not selected and not current: - self.set_current_session_asset() - return - - current_index = None - selected_indexes = [] - # Go through all indices, select the ones with similar data - for index in lib.iter_model_rows( - model, column=0, include_root=False - ): - object_id = index.data(self.model.ObjectIdRole) - if object_id in selected: - selected_indexes.append(index) - - if not current_index and object_id == current: - current_index = index - - if current_index: - self.view.setCurrentIndex(current_index) - - if not selected_indexes: - return - selection_model = self.view.selectionModel() - flags = selection_model.Select | selection_model.Rows - for index in selected_indexes: - # Ensure item is visible - self.view.scrollTo(index) - selection_model.select(index, flags) - - def set_current_session_asset(self): - asset_name = self.dbcon.Session.get("AVALON_ASSET") - if asset_name: - self.select_assets([asset_name]) - - class OptionalMenu(QtWidgets.QMenu): """A subclass of `QtWidgets.QMenu` to work with `OptionalAction`