feat: enhance drag-and-drop functionality to support multiple file paths and URLs

This commit is contained in:
claudi 2026-03-04 13:43:21 +01:00
parent 1e848e84b2
commit c612072dc8
5 changed files with 384 additions and 480 deletions

View file

@ -7,7 +7,7 @@ import re
import sys
from datetime import datetime
from pathlib import Path
from typing import Optional
from typing import Optional, Union
from PySide6.QtCore import (
QEvent,
@ -312,21 +312,34 @@ class _DragBridge(QObject):
self.window = window
@Slot(str)
def start_file_drag(self, path_text: str) -> None:
"""Start a native file drag for the given path or Azure URL.
def start_file_drag(self, paths_text: str) -> None:
"""Start a native file drag for the given path(s) or Azure URL(s).
Called from JavaScript when user drags item(s).
Accepts either:
- Single file path string or Azure URL
- JSON array string of file paths or Azure URLs (multiple drag support)
Called from JavaScript when user drags an item.
Accepts either local file paths or Azure Blob Storage URLs.
Defers execution to avoid Qt drag manager state issues.
Args:
path_text: File path string or Azure URL to drag
paths_text: String (single path/URL) or JSON array string (multiple paths/URLs)
"""
logger.debug(f"Bridge: start_file_drag called for {path_text}")
logger.debug(f"Bridge: start_file_drag called with {len(paths_text)} chars")
# Defer to avoid drag manager state issues
# handle_drag() handles URL conversion and validation internally
QTimer.singleShot(0, lambda: self.window.drag_interceptor.handle_drag(path_text))
# Try to parse as JSON array first (for multiple-drag support)
paths_list: Union[str, list] = paths_text
if paths_text.startswith("["):
try:
parsed = json.loads(paths_text)
if isinstance(parsed, list):
paths_list = parsed
logger.debug(f"Parsed JSON array with {len(parsed)} item(s)")
except (json.JSONDecodeError, TypeError) as e:
logger.warning(f"Failed to parse JSON array: {e}, treating as single string")
# Handle both single string and list
QTimer.singleShot(0, lambda: self.window.drag_interceptor.handle_drag(paths_list))
@Slot(str)
def debug_log(self, message: str) -> None: