Python · 3195 bytes Raw Blame History
1 """Custom UI widgets for wulFTP."""
2
3 from PyQt6.QtCore import Qt, pyqtSignal
4 from PyQt6.QtGui import QDragEnterEvent, QDropEvent
5 from PyQt6.QtWidgets import QTreeView
6
7
8 class LocalTreeView(QTreeView):
9 """Custom tree view for local files that handles remote file drops."""
10
11 remoteFilesDropped = pyqtSignal(list, str) # remote_items (path, is_dir), local_directory
12
13 def __init__(self, parent=None):
14 super().__init__(parent)
15 self.setAcceptDrops(True)
16
17 def dragEnterEvent(self, event: QDragEnterEvent):
18 """Accept drops from remote files."""
19 mime_data = event.mimeData()
20
21 # Check if this is a remote file drop
22 if mime_data.hasFormat("application/x-wulftp-remote"):
23 event.acceptProposedAction()
24 else:
25 # Let the parent handle local file drags
26 super().dragEnterEvent(event)
27
28 def dragMoveEvent(self, event):
29 """Handle drag move events."""
30 mime_data = event.mimeData()
31
32 if mime_data.hasFormat("application/x-wulftp-remote"):
33 # Check if we're over a directory
34 index = self.indexAt(event.position().toPoint())
35 if index.isValid():
36 model = self.model()
37 if model and model.isDir(index):
38 event.acceptProposedAction()
39 return
40 # Also accept drops on empty space (root directory)
41 event.acceptProposedAction()
42 else:
43 super().dragMoveEvent(event)
44
45 def dropEvent(self, event: QDropEvent):
46 """Handle drops from remote files."""
47 mime_data = event.mimeData()
48
49 if mime_data.hasFormat("application/x-wulftp-remote"):
50 # Get the target directory
51 index = self.indexAt(event.position().toPoint())
52 model = self.model()
53
54 if index.isValid() and model:
55 if model.isDir(index):
56 target_dir = model.filePath(index)
57 else:
58 # Dropped on a file, use its parent directory
59 target_dir = model.filePath(model.parent(index))
60 else:
61 # Dropped on empty space, use root
62 target_dir = model.rootPath() if model else ""
63
64 # Get remote paths with type info
65 remote_data = mime_data.data("application/x-wulftp-remote").data().decode('utf-8')
66 remote_items = []
67 for line in remote_data.split('\n'):
68 if line.strip() and '|' in line:
69 path, type_flag = line.strip().rsplit('|', 1)
70 is_dir = type_flag == 'D'
71 remote_items.append((path, is_dir))
72 elif line.strip():
73 # Fallback for old format
74 remote_items.append((line.strip(), False))
75
76 if remote_items and target_dir:
77 self.remoteFilesDropped.emit(remote_items, target_dir)
78 event.acceptProposedAction()
79 else:
80 # Let parent handle local file operations
81 super().dropEvent(event)