Drag and drop fix
This commit is contained in:
parent
4bf2513f31
commit
415a3d64e8
@ -907,21 +907,22 @@ class UnifiedViewModel(QAbstractItemModel):
|
||||
stream = QDataStream(encoded_data, QIODevice.OpenModeFlag.WriteOnly)
|
||||
|
||||
# Store QPersistentModelIndex for robustness
|
||||
persistent_indices = []
|
||||
# Collect file paths of dragged FileRule items
|
||||
file_paths = []
|
||||
for index in indexes:
|
||||
if index.isValid() and index.column() == 0:
|
||||
item = index.internalPointer()
|
||||
if isinstance(item, FileRule):
|
||||
persistent_indices.append(QPersistentModelIndex(index))
|
||||
log.debug(f"mimeData: Added persistent index for file: {Path(item.file_path).name}")
|
||||
file_paths.append(item.file_path)
|
||||
log.debug(f"mimeData: Added file path for file: {Path(item.file_path).name}")
|
||||
|
||||
# Write the number of items first, then each persistent index
|
||||
stream.writeInt32(len(persistent_indices)) # Use writeInt32 for potentially more items
|
||||
for p_index in persistent_indices:
|
||||
stream.writeQPersistentModelIndex(p_index)
|
||||
# Write the number of items first, then each file path string
|
||||
stream.writeInt32(len(file_paths)) # Use writeInt32 for potentially more items
|
||||
for file_path in file_paths:
|
||||
stream.writeQString(file_path) # Use writeQString for strings
|
||||
|
||||
mime_data.setData(self.MIME_TYPE, encoded_data)
|
||||
log.debug(f"mimeData: Encoded {len(persistent_indices)} FileRule persistent indices.")
|
||||
log.debug(f"mimeData: Encoded {len(file_paths)} FileRule file paths.")
|
||||
return mime_data
|
||||
|
||||
def canDropMimeData(self, data: QMimeData, action: Qt.DropAction, row: int, column: int, parent: QModelIndex) -> bool:
|
||||
@ -956,48 +957,68 @@ class UnifiedViewModel(QAbstractItemModel):
|
||||
encoded_data = data.data(self.MIME_TYPE)
|
||||
stream = QDataStream(encoded_data, QIODevice.OpenModeFlag.ReadOnly)
|
||||
|
||||
# Read QPersistentModelIndex objects
|
||||
persistent_indices = []
|
||||
# Read file paths from the stream
|
||||
dragged_file_paths = []
|
||||
num_items = stream.readInt32()
|
||||
log.debug(f"dropMimeData: Decoding {num_items} persistent indices.")
|
||||
log.debug(f"dropMimeData: Decoding {num_items} file paths.")
|
||||
for _ in range(num_items):
|
||||
p_index = stream.readQPersistentModelIndex()
|
||||
if p_index.isValid():
|
||||
persistent_indices.append(p_index)
|
||||
dragged_file_paths.append(stream.readQString()) # Use readQString for strings
|
||||
|
||||
log.debug(f"dropMimeData: Decoded {len(dragged_file_paths)} file paths. Target Asset: '{target_asset_item.asset_name}'")
|
||||
|
||||
if not dragged_file_paths:
|
||||
log.warning("dropMimeData: No file path information decoded.")
|
||||
return False
|
||||
|
||||
# Find the current FileRule objects and their indices based on file paths
|
||||
dragged_items_with_indices = []
|
||||
for file_path in dragged_file_paths:
|
||||
found_item = None
|
||||
found_index = QModelIndex()
|
||||
# Iterate through the model to find the FileRule object by file_path
|
||||
for sr_row, source_rule in enumerate(self._source_rules):
|
||||
for ar_row, asset_rule in enumerate(source_rule.assets):
|
||||
for fr_row, file_rule in enumerate(asset_rule.files):
|
||||
if file_rule.file_path == file_path:
|
||||
found_item = file_rule
|
||||
# Get the current index for this item
|
||||
parent_asset_index = self.index(ar_row, 0, self.createIndex(sr_row, 0, source_rule))
|
||||
if parent_asset_index.isValid():
|
||||
found_index = self.index(fr_row, 0, parent_asset_index)
|
||||
if found_index.isValid():
|
||||
dragged_items_with_indices.append((found_item, found_index))
|
||||
log.debug(f"dropMimeData: Found item and index for file: {Path(file_path).name}")
|
||||
else:
|
||||
log.warning("dropMimeData: Decoded invalid persistent index. Skipping.")
|
||||
log.warning(f"dropMimeData: Could not get valid index for found file item: {Path(file_path).name}")
|
||||
else:
|
||||
log.warning(f"dropMimeData: Could not get valid parent asset index for found file item: {Path(file_path).name}")
|
||||
break # Found the file rule, move to the next dragged file path
|
||||
if found_item: break # Found the file rule, move to the next dragged file path
|
||||
if found_item: break # Found the file rule, move to the next dragged file path
|
||||
|
||||
log.debug(f"dropMimeData: Decoded {len(persistent_indices)} valid persistent indices. Target Asset: '{target_asset_item.asset_name}'")
|
||||
if not found_item:
|
||||
log.warning(f"dropMimeData: Could not find FileRule item for path: {file_path}. Skipping.")
|
||||
|
||||
if not persistent_indices:
|
||||
log.warning("dropMimeData: No valid persistent index information decoded.")
|
||||
|
||||
if not dragged_items_with_indices:
|
||||
log.warning("dropMimeData: No valid FileRule items found in the model for the dragged paths.")
|
||||
return False
|
||||
|
||||
# Keep track of original parents that might become empty
|
||||
original_parents_to_check = set()
|
||||
moved_files_new_indices = {}
|
||||
|
||||
# Process moves using the persistent indices
|
||||
for p_source_index in persistent_indices:
|
||||
# Convert persistent index back to a model index
|
||||
source_file_index = QModelIndex(p_source_index)
|
||||
|
||||
if not source_file_index.isValid():
|
||||
log.warning(f"dropMimeData: Persistent index is no longer valid. Skipping item.")
|
||||
continue
|
||||
|
||||
# Get the file item
|
||||
file_item = source_file_index.internalPointer()
|
||||
if not isinstance(file_item, FileRule):
|
||||
log.error(f"dropMimeData: Index points to non-FileRule item after conversion. Skipping.")
|
||||
continue
|
||||
|
||||
# Process moves using the retrieved items and their current indices
|
||||
for file_item, source_file_index in dragged_items_with_indices:
|
||||
# Track original parent for cleanup using the parent back-reference
|
||||
old_parent_asset = getattr(file_item, 'parent_asset', None)
|
||||
if old_parent_asset and isinstance(old_parent_asset, AssetRule):
|
||||
original_parents_to_check.add(old_parent_asset)
|
||||
source_rule = getattr(old_parent_asset, 'parent_source', None)
|
||||
if source_rule:
|
||||
# Store a hashable representation (tuple of identifiers)
|
||||
original_parents_to_check.add((source_rule.input_path, old_parent_asset.asset_name))
|
||||
else:
|
||||
log.warning(f"dropMimeData: File '{Path(file_item.file_path).name}' has no valid parent asset reference for cleanup tracking.")
|
||||
log.warning(f"dropMimeData: Original parent asset '{old_parent_asset.asset_name}' has no parent source reference for cleanup tracking.")
|
||||
|
||||
|
||||
# Perform the move using the model's method and the valid source_file_index
|
||||
@ -1009,16 +1030,25 @@ class UnifiedViewModel(QAbstractItemModel):
|
||||
if file_item.target_asset_name_override != target_asset_item.asset_name:
|
||||
log.debug(f" Updating target override for '{Path(file_item.file_path).name}' to '{target_asset_item.asset_name}'")
|
||||
file_item.target_asset_name_override = target_asset_item.asset_name
|
||||
# Need the *new* index of the moved file to emit dataChanged
|
||||
# Need the *new* index of the moved file to emit dataChanged AND the override changed signal
|
||||
try:
|
||||
# Find the new row of the file item within the target parent's list
|
||||
new_row = target_asset_item.files.index(file_item)
|
||||
# Create the index for the target asset column
|
||||
# Create the index for the target asset column (for dataChanged)
|
||||
new_file_index_target_col = self.index(new_row, self.COL_TARGET_ASSET, parent)
|
||||
if new_file_index_target_col.isValid():
|
||||
moved_files_new_indices[file_item.file_path] = new_file_index_target_col
|
||||
else:
|
||||
log.warning(f" Could not get valid *new* index for target column of moved file: {Path(file_item.file_path).name}")
|
||||
|
||||
# Emit the targetAssetOverrideChanged signal for the handler
|
||||
new_file_index_col_0 = self.index(new_row, 0, parent) # Index for column 0
|
||||
if new_file_index_col_0.isValid():
|
||||
self.targetAssetOverrideChanged.emit(file_item, target_asset_item.asset_name, new_file_index_col_0)
|
||||
log.debug(f" Emitted targetAssetOverrideChanged for '{Path(file_item.file_path).name}'")
|
||||
else:
|
||||
log.warning(f" Could not get valid *new* index for column 0 of moved file to emit signal: {Path(file_item.file_path).name}")
|
||||
|
||||
except ValueError:
|
||||
log.error(f" Could not find moved file '{Path(file_item.file_path).name}' in target parent's list after move.")
|
||||
|
||||
@ -1034,30 +1064,43 @@ class UnifiedViewModel(QAbstractItemModel):
|
||||
self.dataChanged.emit(new_index, new_index, [Qt.DisplayRole, Qt.EditRole])
|
||||
|
||||
# --- Cleanup: Remove any original parent AssetRules that are now empty ---
|
||||
log.debug(f"dropMimeData: Checking original parents for cleanup: {[asset.asset_name for asset in original_parents_to_check]}")
|
||||
# Convert set to list to iterate and allow removal from the model
|
||||
for asset_rule_to_check in list(original_parents_to_check):
|
||||
log.debug(f"dropMimeData: Checking original parents for cleanup: {[f'{path}/{name}' for path, name in original_parents_to_check]}")
|
||||
# Convert set to list to iterate
|
||||
for source_path, asset_name_to_check in list(original_parents_to_check):
|
||||
found_asset_rule_to_check = None
|
||||
# Find the AssetRule object based on source_path and asset_name
|
||||
for source_rule in self._source_rules:
|
||||
if source_rule.input_path == source_path:
|
||||
for asset_rule in source_rule.assets:
|
||||
if asset_rule.asset_name == asset_name_to_check:
|
||||
found_asset_rule_to_check = asset_rule
|
||||
break
|
||||
if found_asset_rule_to_check: break
|
||||
|
||||
if found_asset_rule_to_check:
|
||||
try:
|
||||
# Re-check if the asset is still in the model and is now empty
|
||||
# Use parent back-reference to find the source rule
|
||||
source_rule = getattr(asset_rule_to_check, 'parent_source', None)
|
||||
# Use parent back-reference to find the source rule (should be the same as source_rule found above)
|
||||
source_rule = getattr(found_asset_rule_to_check, 'parent_source', None)
|
||||
if source_rule:
|
||||
# Check if the asset rule is still in its parent's list
|
||||
if asset_rule_to_check in source_rule.assets:
|
||||
if not asset_rule_to_check.files and asset_rule_to_check is not target_asset_item:
|
||||
log.info(f"dropMimeData: Attempting cleanup of now empty original parent: '{asset_rule_to_check.asset_name}'")
|
||||
if not self.removeAssetRule(asset_rule_to_check):
|
||||
log.warning(f"dropMimeData: Failed to remove empty original parent '{asset_rule_to_check.asset_name}'.")
|
||||
elif asset_rule_to_check.files:
|
||||
log.debug(f"dropMimeData: Original parent '{asset_rule_to_check.asset_name}' is not empty after moves. Skipping cleanup.")
|
||||
if found_asset_rule_to_check in source_rule.assets:
|
||||
if not found_asset_rule_to_check.files and found_asset_rule_to_check is not target_asset_item:
|
||||
log.info(f"dropMimeData: Attempting cleanup of now empty original parent: '{found_asset_rule_to_check.asset_name}'")
|
||||
if not self.removeAssetRule(found_asset_rule_to_check):
|
||||
log.warning(f"dropMimeData: Failed to remove empty original parent '{found_asset_rule_to_check.asset_name}'.")
|
||||
elif found_asset_rule_to_check.files:
|
||||
log.debug(f"dropMimeData: Original parent '{found_asset_rule_to_check.asset_name}' is not empty after moves. Skipping cleanup.")
|
||||
# If it's the target asset, we don't remove it
|
||||
else:
|
||||
log.warning(f"dropMimeData: Cleanup check failed. Original parent asset '{asset_rule_to_check.asset_name}' not found in its source rule's list.")
|
||||
log.warning(f"dropMimeData: Cleanup check failed. Original parent asset '{found_asset_rule_to_check.asset_name}' not found in its source rule's list.")
|
||||
else:
|
||||
log.warning(f"dropMimeData: Cleanup check failed. Original parent asset '{asset_rule_to_check.asset_name}' has no parent source reference.")
|
||||
log.warning(f"dropMimeData: Cleanup check failed. Original parent asset '{found_asset_rule_to_check.asset_name}' has no parent source reference.")
|
||||
|
||||
except Exception as e:
|
||||
log.exception(f"dropMimeData: Error during cleanup check for parent '{asset_rule_to_check.asset_name}': {e}")
|
||||
log.exception(f"dropMimeData: Error during cleanup check for parent '{found_asset_rule_to_check.asset_name}': {e}")
|
||||
else:
|
||||
log.warning(f"dropMimeData: Could not find original parent asset '{asset_name_to_check}' for cleanup.")
|
||||
|
||||
|
||||
return True
|
||||
Loading…
x
Reference in New Issue
Block a user