-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathFileTableView.py
More file actions
146 lines (112 loc) · 5.13 KB
/
FileTableView.py
File metadata and controls
146 lines (112 loc) · 5.13 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
from PySide6.QtWidgets import QTableView , QMenu ,QHeaderView
from PySide6.QtCore import Signal ,Qt , QAbstractTableModel
from PySide6.QtGui import QAction
from catchExecptions import catch_exceptions
import os
class FileTableModel(QAbstractTableModel):
COLUMNS = ['Name', 'Path', 'Size', 'Type', 'Modified Date']
def __init__(self):
super().__init__()
self._data: list[tuple] = []
def rowCount(self, parent=None):
return len(self._data)
def columnCount(self, parent=None):
return len(self.COLUMNS)
@catch_exceptions
def data(self, index, role=Qt.DisplayRole):
if not index.isValid():
return None
value = self._data[index.row()][index.column()]
if role == Qt.DisplayRole:
if isinstance(value, int): # File size
# Convert bytes to human-readable format
for unit in ['B', 'KB', 'MB', 'GB']:
if value < 1024:
return f"{value:.1f} {unit}"
value /= 1024
return f"{value:.1f} TB"
return str(value)
elif role == Qt.TextAlignmentRole:
if isinstance(self._data[index.row()][index.column()], int):
return Qt.AlignRight | Qt.AlignVCenter
return Qt.AlignLeft | Qt.AlignVCenter
return None
def headerData(self, section, orientation, role=Qt.DisplayRole):
if orientation == Qt.Horizontal and role == Qt.DisplayRole:
return self.COLUMNS[section]
return None
def sort(self, column, order=Qt.AscendingOrder):
self.layoutAboutToBeChanged.emit()
self._data.sort(
key=lambda x: x[column],
reverse=(order == Qt.DescendingOrder)
)
self.layoutChanged.emit()
def update_results(self, file_tuples: list[tuple]):
self.beginResetModel()
self._data = file_tuples
self.endResetModel()
class FileTableView(QTableView):
path_double_clicked = Signal(str)
def __init__(self, parent=None):
super().__init__(parent)
self.order = Qt.AscendingOrder
# Create and set the file_table_model
self.file_table_model = FileTableModel()
self.setModel(self.file_table_model)
# Setup the view
self.setup_appearance()
self.doubleClicked.connect(self.onDoubleClick)
def setup_appearance(self):
# Enable sorting
self.setSortingEnabled(True)
# Enable alternating row colors
self.setAlternatingRowColors(True)
# Setup header
header = self.horizontalHeader()
header.setStretchLastSection(False)
# Set column resize modes
for i in range(len(FileTableModel.COLUMNS)):
if i == 1: # Path column
# Path column stretches to fill space
header.setSectionResizeMode(i, QHeaderView.Stretch)
else:
# Other columns resize to content
header.setSectionResizeMode(i, QHeaderView.ResizeToContents)
# Optional: Set selection behavior
self.setSelectionBehavior(QTableView.SelectRows) # Select entire rows
self.setSelectionMode(QTableView.SingleSelection) # One row at a time
def updateResults(self, results: list[tuple]):
print('updating results')
self.file_table_model.update_results(results)
def toggleReverseOrder(self):
"""Toggles the reverse order flag and updates the sorting order."""
self.order = Qt.DescendingOrder if self.order == Qt.AscendingOrder else Qt.AscendingOrder
@catch_exceptions
def contextMenuEvent(self, event):
menu = QMenu(self)
# Add sorting actions
sort_by_name_action = QAction("Sort by Name", self)
sort_by_size_action = QAction("Sort by Size", self)
sort_by_date_action = QAction("Sort by Date Modified", self)
# Connect actions to sorting methods
sort_by_name_action.triggered.connect(lambda: self.sortByColumn(0, self.order))
sort_by_size_action.triggered.connect(lambda: self.sortByColumn(2, self.order))
sort_by_date_action.triggered.connect(lambda: self.sortByColumn(3, self.order))
# Add a checkable action for reverse order
reverse_order_action = QAction("Reverse Order", self, checkable=True)
reverse_order_action.setChecked(self.order == Qt.DescendingOrder)
reverse_order_action.triggered.connect(self.toggleReverseOrder)
# Add actions to the menu
menu.addAction(sort_by_name_action)
menu.addAction(sort_by_size_action)
menu.addAction(sort_by_date_action)
menu.addAction(reverse_order_action)
# Show the menu at the cursor position
menu.exec(event.globalPos())
@catch_exceptions
def onDoubleClick(self, index):
path = os.path.dirname(self.file_table_model._data[index.row()][1])
print(path)
print(type(path))
self.path_double_clicked.emit(path)