11from enum import IntEnum , auto
2+ from typing import Any , cast
23
34from PyQt6 .QtCore import QAbstractItemModel , QFileInfo , QModelIndex , Qt
45from PyQt6 .QtWidgets import QFileIconProvider
78
89
910class TreeNode :
10- def __init__ (self , name : str , parent = None , is_dir = False , size = 0 , entry = None ):
11+ def __init__ (
12+ self ,
13+ name : str ,
14+ parent : "TreeNode | None" = None ,
15+ is_dir : bool = False ,
16+ size : int = 0 ,
17+ entry : Any | None = None ,
18+ ):
1119 self .name = name
1220 self .parent = parent
1321 self .is_dir = is_dir
1422 self .size = size
15- self .children = []
23+ self .children : list [ TreeNode ] = []
1624 self .entry = entry
1725
18- if parent :
26+ if parent is not None :
1927 parent .children .append (self )
2028
2129 def child_count (self ) -> int :
@@ -37,19 +45,19 @@ def path(self) -> str:
3745 return self .parent .path () + "/" + self .name
3846 return self .name
3947
40- def sort_children (self , column : int , order : Qt .SortOrder ):
48+ def sort_children (self , column : int , order : Qt .SortOrder ) -> None :
4149 """Sort children by the specified column and order.
4250 Directories always come before files.
4351 Directories only reorder when column == NAME.
4452 """
45- dirs = [i for i in self .children if i .is_dir ]
53+ dirs : list [ TreeNode ] = [i for i in self .children if i .is_dir ]
4654 if column == ArchiveColumn .NAME :
4755 dirs .sort (
4856 key = lambda node : node .name .lower (),
4957 reverse = (order == Qt .SortOrder .DescendingOrder ),
5058 )
5159
52- files = [i for i in self .children if not i .is_dir ]
60+ files : list [ TreeNode ] = [i for i in self .children if not i .is_dir ]
5361 if column == ArchiveColumn .NAME :
5462 files .sort (
5563 key = lambda node : node .name .lower (),
@@ -78,25 +86,28 @@ class ArchiveColumn(IntEnum):
7886
7987
8088class ArchiveModel (QAbstractItemModel ):
81- def __init__ (self , parent = None ):
89+ def __init__ (self , parent : Any | None = None ):
8290 super ().__init__ (parent )
83- self ._reader = None
91+ self ._reader : ArchiveReader | None = None
8492 self ._icon_provider = QFileIconProvider ()
8593 self ._root_node = TreeNode ("" , None , True )
8694 self ._sort_column = ArchiveColumn .NAME
8795 self ._sort_order = Qt .SortOrder .AscendingOrder
8896
89- def set_data (self , reader : ArchiveReader ):
97+ def set_data (self , reader : ArchiveReader ) -> None :
9098 self .beginResetModel ()
9199 self ._reader = reader
92100 self ._build_tree ()
93101 self ._sort_tree ()
94102 self .endResetModel ()
95103
96- def _build_tree (self ):
104+ def _build_tree (self ) -> None :
97105 """Build the tree structure from archive entries."""
106+ if self ._reader is None :
107+ return
108+
98109 dir_nodes : dict [str , TreeNode ] = {"" : self ._root_node }
99- sorted_entries = sorted (self ._reader ._entries .items (), key = lambda x : x [0 ])
110+ sorted_entries = sorted (self ._reader ._entries .items (), key = lambda x : x [0 ]) # pyright: ignore[reportPrivateUsage]
100111
101112 for name , entry in sorted_entries :
102113 path_parts = name .split ("/" )
@@ -119,18 +130,22 @@ def _build_tree(self):
119130 filename = path_parts [- 1 ]
120131 TreeNode (filename , current_node , False , entry .original_size , entry )
121132
122- def _sort_tree (self ):
133+ def _sort_tree (self ) -> None :
123134 """Sort the entire tree."""
124135 self ._root_node .sort_children (self ._sort_column , self ._sort_order )
125136
126- def sort (self , column : int , order : Qt .SortOrder ):
137+ def sort (
138+ self ,
139+ column : int ,
140+ order : Qt .SortOrder = Qt .SortOrder .AscendingOrder ,
141+ ) -> None :
127142 """Implement sorting with proper persistent index handling"""
128143 persistent_indexes = self .persistentIndexList ()
129144
130- old_nodes = []
145+ old_nodes : list [ TreeNode | None ] = []
131146 for index in persistent_indexes :
132147 if index .isValid ():
133- old_nodes .append (index .internalPointer ())
148+ old_nodes .append (cast ( TreeNode , index .internalPointer () ))
134149 else :
135150 old_nodes .append (None )
136151
@@ -142,7 +157,7 @@ def sort(self, column: int, order: Qt.SortOrder):
142157 self ._sort_order = order
143158 self ._sort_tree ()
144159
145- new_indexes = []
160+ new_indexes : list [ QModelIndex ] = []
146161 for node in old_nodes :
147162 if node is not None :
148163 new_index = self ._find_index_for_node (node )
@@ -162,9 +177,9 @@ def _find_index_for_node(self, target_node: TreeNode) -> QModelIndex:
162177 if target_node == self ._root_node :
163178 return QModelIndex ()
164179
165- path = []
166- current = target_node
167- while current and current != self ._root_node :
180+ path : list [ TreeNode ] = []
181+ current : TreeNode | None = target_node
182+ while current is not None and current != self ._root_node :
168183 path .append (current )
169184 current = current .parent
170185
@@ -176,49 +191,54 @@ def _find_index_for_node(self, target_node: TreeNode) -> QModelIndex:
176191
177192 return current_index
178193
179- def rowCount (self , parent : QModelIndex ) -> int :
194+ def rowCount (self , parent : QModelIndex = QModelIndex () ) -> int :
180195 if not parent .isValid ():
181196 parent_node = self ._root_node
182197 else :
183- parent_node = parent .internalPointer ()
198+ parent_node = cast ( TreeNode , parent .internalPointer () )
184199
185200 return parent_node .child_count ()
186201
187- def columnCount (self , parent : QModelIndex ) -> int :
202+ def columnCount (self , parent : QModelIndex = QModelIndex ()) -> int :
203+ _ = parent
188204 return len (ArchiveColumn )
189205
190- def index (self , row : int , column : int , parent : QModelIndex ) -> QModelIndex :
206+ def index (
207+ self , row : int , column : int , parent : QModelIndex = QModelIndex ()
208+ ) -> QModelIndex :
191209 if not self .hasIndex (row , column , parent ):
192210 return QModelIndex ()
193211
194212 if not parent .isValid ():
195213 parent_node = self ._root_node
196214 else :
197- parent_node = parent .internalPointer ()
215+ parent_node = cast ( TreeNode , parent .internalPointer () )
198216
199217 child_node = parent_node .child (row )
200218 if child_node :
201219 return self .createIndex (row , column , child_node )
202220
203221 return QModelIndex ()
204222
205- def parent (self , index : QModelIndex ) -> QModelIndex :
206- if not index .isValid ():
223+ def parent (self , child : QModelIndex ) -> QModelIndex : # pyright: ignore[reportIncompatibleMethodOverride]
224+ if not child .isValid ():
207225 return QModelIndex ()
208226
209- child_node = index .internalPointer ()
227+ child_node = cast ( TreeNode , child .internalPointer () )
210228 parent_node = child_node .parent
211229
212230 if parent_node == self ._root_node or parent_node is None :
213231 return QModelIndex ()
214232
215233 return self .createIndex (parent_node .row (), 0 , parent_node )
216234
217- def data (self , index : QModelIndex , role : int = Qt .ItemDataRole .DisplayRole ):
235+ def data (
236+ self , index : QModelIndex , role : int = Qt .ItemDataRole .DisplayRole
237+ ) -> Any | None :
218238 if not index .isValid ():
219239 return None
220240
221- node = index .internalPointer ()
241+ node = cast ( TreeNode , index .internalPointer () )
222242 column = index .column ()
223243
224244 if role == Qt .ItemDataRole .DisplayRole :
@@ -270,7 +290,7 @@ def headerData(
270290 def get_node (self , index : QModelIndex ) -> TreeNode | None :
271291 """Get the TreeNode for a given index."""
272292 if index .isValid ():
273- return index .internalPointer ()
293+ return cast ( TreeNode , index .internalPointer () )
274294 return None
275295
276296 @staticmethod
0 commit comments