Codebase dedublication and Cleanup refactor Documentation updated as well Preferences update Removed testfiles from repository
138 lines
7.9 KiB
Python
138 lines
7.9 KiB
Python
# gui/asset_restructure_handler.py
|
|
import logging
|
|
from PySide6.QtCore import QObject, Slot, QModelIndex
|
|
from PySide6.QtGui import QColor # Might be needed if copying logic directly, though unlikely now
|
|
from pathlib import Path
|
|
from .unified_view_model import UnifiedViewModel # Use relative import
|
|
from rule_structure import SourceRule, AssetRule, FileRule
|
|
|
|
log = logging.getLogger(__name__)
|
|
|
|
class AssetRestructureHandler(QObject):
|
|
"""
|
|
Handles the model restructuring logic triggered by changes
|
|
to FileRule target asset overrides in the UnifiedViewModel.
|
|
"""
|
|
def __init__(self, model: UnifiedViewModel, parent=None):
|
|
super().__init__(parent)
|
|
if not isinstance(model, UnifiedViewModel):
|
|
raise TypeError("AssetRestructureHandler requires a UnifiedViewModel instance.")
|
|
self.model = model
|
|
log.debug("AssetRestructureHandler initialized.")
|
|
|
|
@Slot(QModelIndex, object)
|
|
def handle_target_asset_override(self, index: QModelIndex, new_target_path: object):
|
|
"""
|
|
Slot connected to UnifiedViewModel.targetAssetOverrideChanged.
|
|
Orchestrates model changes based on the new target asset path.
|
|
|
|
Args:
|
|
index: The QModelIndex of the FileRule whose override changed.
|
|
new_target_path: The new target asset path (string or None).
|
|
"""
|
|
log.debug(f"Handler received targetAssetOverrideChanged: Index=({index.row()},{index.column()}), New Path='{new_target_path}'")
|
|
|
|
if not index.isValid():
|
|
log.warning("Handler received invalid index. Aborting.")
|
|
return
|
|
|
|
file_item = self.model.getItem(index)
|
|
if not isinstance(file_item, FileRule):
|
|
log.warning(f"Handler received index for non-FileRule item: {type(file_item)}. Aborting.")
|
|
return
|
|
|
|
# Ensure new_target_path is a string or None
|
|
new_target_name = str(new_target_path).strip() if new_target_path is not None else None
|
|
if new_target_name == "": new_target_name = None # Treat empty string as None
|
|
|
|
# --- Get necessary context ---
|
|
old_parent_asset = getattr(file_item, 'parent_asset', None)
|
|
if not old_parent_asset:
|
|
log.error(f"Handler: File item '{Path(file_item.file_path).name}' has no parent asset. Cannot restructure.")
|
|
# Note: Data change already happened in setData, cannot easily revert here.
|
|
return
|
|
|
|
source_rule = getattr(old_parent_asset, 'parent_source', None)
|
|
if not source_rule:
|
|
log.error(f"Handler: Could not find SourceRule for parent asset '{old_parent_asset.asset_name}'. Cannot restructure.")
|
|
return
|
|
|
|
# --- Logic based on the new target name ---
|
|
target_parent_asset = None
|
|
target_parent_index = QModelIndex()
|
|
move_occurred = False
|
|
|
|
# 1. Find existing target parent AssetRule within the same SourceRule
|
|
if new_target_name:
|
|
for i, asset in enumerate(source_rule.assets):
|
|
if asset.asset_name == new_target_name:
|
|
target_parent_asset = asset
|
|
# Get index for the target parent
|
|
try:
|
|
source_rule_row = self.model._source_rules.index(source_rule)
|
|
source_rule_index = self.model.createIndex(source_rule_row, 0, source_rule)
|
|
target_parent_index = self.model.index(i, 0, source_rule_index)
|
|
if not target_parent_index.isValid():
|
|
log.error(f"Handler: Failed to create valid index for existing target parent '{new_target_name}'.")
|
|
target_parent_asset = None # Reset if index is invalid
|
|
except ValueError:
|
|
log.error(f"Handler: Could not find SourceRule index while looking for target parent '{new_target_name}'.")
|
|
target_parent_asset = None # Reset if index is invalid
|
|
break # Found the asset
|
|
|
|
# 2. Handle Move or Creation
|
|
if target_parent_asset:
|
|
# --- Move to Existing Parent ---
|
|
if target_parent_asset != old_parent_asset:
|
|
log.info(f"Handler: Moving file '{Path(file_item.file_path).name}' to existing asset '{target_parent_asset.asset_name}'.")
|
|
if self.model.moveFileRule(index, target_parent_index):
|
|
move_occurred = True
|
|
else:
|
|
log.error(f"Handler: Model failed to move file rule to existing asset '{target_parent_asset.asset_name}'.")
|
|
# Consider how to handle failure - maybe log and continue to cleanup?
|
|
else:
|
|
# Target is the same as the old parent. No move needed.
|
|
log.debug(f"Handler: Target asset '{new_target_name}' is the same as the current parent. No move required.")
|
|
pass # No move needed, but might still need cleanup if old parent becomes empty later (unlikely in this specific case)
|
|
|
|
elif new_target_name: # Only create if a *new* specific target name was given
|
|
# --- Create New Parent AssetRule and Move ---
|
|
log.info(f"Handler: Creating new asset '{new_target_name}' and moving file '{Path(file_item.file_path).name}'.")
|
|
# Create the new asset rule using the model's method
|
|
new_asset_index = self.model.createAssetRule(source_rule, new_target_name, copy_from_asset=old_parent_asset)
|
|
|
|
if new_asset_index.isValid():
|
|
# Now move the file to the newly created asset
|
|
if self.model.moveFileRule(index, new_asset_index):
|
|
move_occurred = True
|
|
target_parent_asset = new_asset_index.internalPointer() # Update for cleanup check
|
|
else:
|
|
log.error(f"Handler: Model failed to move file rule to newly created asset '{new_target_name}'.")
|
|
# If move fails after creation, should we remove the created asset? Maybe.
|
|
# For now, just log the error.
|
|
else:
|
|
log.error(f"Handler: Model failed to create new asset rule '{new_target_name}'. Cannot move file.")
|
|
|
|
else: # new_target_name is None or empty
|
|
# --- Moving back to original/default parent (Clearing Override) ---
|
|
# The file *should* already be under its original parent if the override was just cleared.
|
|
# However, if it was previously moved *away* from its original parent due to an override,
|
|
# clearing the override *should* ideally move it back.
|
|
# This logic is complex: we need to know the *original* parent before any overrides.
|
|
# The current structure doesn't explicitly store this.
|
|
# For now, assume clearing the override means it stays in its *current* parent,
|
|
# and we only handle cleanup if that parent becomes empty.
|
|
# A more robust solution might involve finding the asset matching the file's *directory* name.
|
|
log.debug(f"Handler: Target asset override cleared for '{Path(file_item.file_path).name}'. File remains in parent '{old_parent_asset.asset_name}'.")
|
|
# No move occurs in this simplified interpretation.
|
|
|
|
# 3. Cleanup Empty Old Parent (only if a move occurred)
|
|
# Check the old_parent_asset *after* the potential move
|
|
if move_occurred and old_parent_asset and not old_parent_asset.files:
|
|
log.info(f"Handler: Attempting to remove empty old parent asset '{old_parent_asset.asset_name}'.")
|
|
if not self.model.removeAssetRule(old_parent_asset):
|
|
log.warning(f"Handler: Model failed to remove empty old parent asset '{old_parent_asset.asset_name}'.")
|
|
elif move_occurred:
|
|
log.debug(f"Handler: Old parent asset '{old_parent_asset.asset_name}' still contains files. No removal needed.")
|
|
|
|
log.debug(f"Handler finished processing targetAssetOverrideChanged for '{Path(file_item.file_path).name}'.") |