4646# Force the log level for this module
4747# LOG.setLevel(logger.DEBUG) # One of DEBUG, INFO, WARNING, ERROR, CRITICAL
4848
49- # constants
50- _ASCENDING = 0
51- _DESCENDING = 1
52- _FOLDERFIRST = 2
53- _FILEFIRST = 3
49+ ### Constants ##
50+ # Sort order
51+ _SORTORDER_ASCENDING = 0
52+ _SORTORDER_DESCENDING = 1
53+ _SORTORDER_FOLDERFIRST = 2 # legacy
54+ _SORTORDER_FILEFIRST = 3 # legacy
55+
56+ # Sort order by date
57+ _SORTBYDATE_NONE = 0
58+ _SORTBYDATE_ASCENDING = 1
59+ _SORTBYDATE_DESCENDING = 2
60+
61+ # Folder separation
62+ _FOLDER_FIRST = 0
63+ _FOLDER_LAST = 1
64+ _FOLDER_MIXED = 2
65+
5466COL_PATH = 0
5567COL_PIXBUF = 1
5668COL_IS_DIRECTORY = 2
@@ -81,8 +93,13 @@ class IconFileSelection(Gtk.Box):
8193 "~" , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
8294 'filetypes' : (GObject .TYPE_STRING , 'file filter' , 'Sets the filter for the file types to be shown' ,
8395 "ngc,py" , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
84- 'sortorder' : (GObject .TYPE_INT , 'sorting order' , '0 = ASCENDING, 1 = DESCENDING", 2 = FOLDERFIRST, 3 = FILEFIRST' ,
85- 0 , 3 , 2 , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
96+ 'sortorder' : (GObject .TYPE_INT , 'sorting order' , '0 = ASCENDING, 1 = DESCENDING, 2 = FOLDERFIRST, 3 = FILEFIRST' ,
97+ 0 , 3 , 0 , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
98+ # sortbydate overrides parameter sortorder. To sort by name set sortbydate to 0
99+ 'sortbydate' : (GObject .TYPE_INT , 'sort by date' , '0 = DISABLE , 1 = ASCENDING, 2 = DESCENDING' ,
100+ 0 , 2 , 0 , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
101+ 'folderfirst' : (GObject .TYPE_INT , 'folder first' , '0 = FOLDERFIRST , 1 = FILEFIRST, 2 = MIXED' ,
102+ 0 , 2 , 0 , GObject .ParamFlags .READWRITE | GObject .ParamFlags .CONSTRUCT ),
86103 }
87104 __gproperties = __gproperties__
88105
@@ -100,12 +117,14 @@ def __init__(self):
100117
101118 # set some default values'
102119 self .icon_size = 48
103- self .start_dir = os . path . expanduser ( '/' )
120+ self .start_dir = None
104121 self .cur_dir = self .start_dir
105122 self .user_dir = os .path .expanduser ('~' )
106123 self .jump_to_dir = os .path .expanduser ('/tmp' )
107124 self .filetypes = ("ngc,py" )
108- self .sortorder = _FOLDERFIRST
125+ self .sortorder = _SORTORDER_ASCENDING
126+ self .sortbydate = _SORTBYDATE_NONE
127+ self .folderfirst = _FOLDER_FIRST
109128 # This will hold the path we will return
110129 self .path = ""
111130 self .button_state = {}
@@ -303,58 +322,63 @@ def _fill_store(self):
303322 # we don't want to add hidden files
304323 if fl [0 ] == '.' :
305324 continue
325+ # append dirs with date
306326 if os .path .isdir (os .path .join (self .cur_dir , fl )):
307327 try :
308328 os .listdir (os .path .join (self .cur_dir , fl ))
309- dirs .append (fl )
329+ dirs .append (( fl , os . path . getmtime ( os . path . join ( self . cur_dir , fl ))) )
310330 number += 1
311331 except OSError :
312332 #print ("no rights for ", os.path.join(self.cur_dir, fl), " skip that dir")
313333 continue
334+ # append files with date
314335 else :
315336 try :
316337 name , ext = fl .rsplit ("." , 1 )
317- if "*" in self .filetypes :
318- files .append (fl )
319- number += 1
320- elif ext in self .filetypes :
321- files .append (fl )
338+ if "*" in self .filetypes or ext in self .filetypes :
339+ files .append ((fl , os .path .getmtime (os .path .join (self .cur_dir , fl ))))
322340 number += 1
323341 except ValueError as e :
324- LOG .debug ("Tried to split filename without extension ({0 })." . format ( e ) )
342+ LOG .debug (f "Tried to split filename ( { fl } ) without extension ({ e } )." )
325343 except Exception as e :
326344 LOG .exception (e )
327345 pass
328-
329- if self . sortorder not in [ _ASCENDING , _DESCENDING , _FOLDERFIRST , _FILEFIRST ]:
330- self .sortorder = _FOLDERFIRST
331-
332- if self . sortorder == _ASCENDING or self .sortorder == _DESCENDING :
333- allobjects = dirs
334- allobjects . extend ( files )
335- allobjects .sort (reverse = not self .sortorder == _ASCENDING )
336-
337- for obj in allobjects :
346+ ## SORTING ##
347+ # sort ascending/descending (file/folder mixed)
348+ if self .folderfirst == _FOLDER_MIXED :
349+ allobjects = dirs + files
350+ if self .sortbydate == _SORTBYDATE_NONE :
351+ allobjects . sort ( key = lambda x : x [ 0 ]. casefold (), reverse = self . sortorder == _SORTORDER_DESCENDING )
352+ else :
353+ allobjects .sort (key = lambda x : x [ 1 ], reverse = self .sortorder == _SORTBYDATE_DESCENDING )
354+
355+ for obj , date in allobjects :
338356 if os .path .isdir (os .path .join (self .cur_dir , obj )):
339357 self .store .append ([obj , self .dirIcon , True ])
340358 else :
341359 icon = self ._get_icon (obj )
342360 self .store .append ([obj , icon , False ])
343-
344- dirs .sort (key = None , reverse = False )
345- files .sort (key = None , reverse = False )
346- if self .sortorder == _FOLDERFIRST :
347- for dir in dirs :
348- self .store .append ([dir , self .dirIcon , True ])
349- for file in files :
350- icon = self ._get_icon (file )
351- self .store .append ([file , icon , False ])
352- elif self .sortorder == _FILEFIRST :
353- for file in files :
354- icon = self ._get_icon (file )
355- self .store .append ([file , icon , False ])
356- for dir in dirs :
357- self .store .append ([dir , self .dirIcon , True ])
361+
362+ # sort folders/files separately
363+ else :
364+ if self .sortbydate == _SORTBYDATE_NONE :
365+ files .sort (key = lambda x : x [0 ].casefold (), reverse = self .sortorder == _SORTORDER_DESCENDING )
366+ dirs .sort (key = lambda x : x [0 ].casefold (), reverse = self .sortorder == _SORTORDER_DESCENDING )
367+ else :
368+ files .sort (key = lambda x : x [1 ], reverse = self .sortorder == _SORTBYDATE_DESCENDING )
369+ dirs .sort (key = lambda x : x [1 ], reverse = self .sortorder == _SORTBYDATE_DESCENDING )
370+ if self .folderfirst == _FOLDER_FIRST :
371+ for dir , date in dirs :
372+ self .store .append ([dir , self .dirIcon , True ])
373+ for file , date in files :
374+ icon = self ._get_icon (file )
375+ self .store .append ([file , icon , False ])
376+ else :
377+ for file , date in files :
378+ icon = self ._get_icon (file )
379+ self .store .append ([file , icon , False ])
380+ for dir , date in dirs :
381+ self .store .append ([dir , self .dirIcon , True ])
358382 except Exception as e :
359383 LOG .exception (e )
360384 pass
@@ -594,10 +618,30 @@ def do_set_property(self, property, value):
594618 if name == 'filetypes' :
595619 self .set_filetypes (value )
596620 if name == 'sortorder' :
597- if value not in [_ASCENDING , _DESCENDING , _FOLDERFIRST , _FILEFIRST ]:
621+ if value not in [_SORTORDER_ASCENDING , _SORTORDER_DESCENDING , _SORTORDER_FOLDERFIRST , _SORTORDER_FILEFIRST ]:
598622 raise AttributeError ('unknown property of sortorder %s' % value )
599623 else :
600- self .sortorder = value
624+ # legacy
625+ if value == _SORTORDER_FOLDERFIRST :
626+ self .folderfirst = _FOLDER_FIRST
627+ self .sortorder = _SORTORDER_ASCENDING
628+ elif value == _SORTORDER_FILEFIRST :
629+ self .folderfirst = _FOLDER_LAST
630+ self .sortorder = _SORTORDER_ASCENDING
631+ else :
632+ self .sortorder = value
633+ self ._fill_store ()
634+ if name == 'sortbydate' :
635+ if value not in [_SORTBYDATE_ASCENDING , _SORTBYDATE_DESCENDING , _SORTBYDATE_NONE ]:
636+ raise AttributeError ('unknown property of sortbydate %s' % value )
637+ else :
638+ self .sortbydate = value
639+ self ._fill_store ()
640+ if name == 'folderfirst' :
641+ if value not in [_FOLDER_FIRST , _FOLDER_LAST , _FOLDER_MIXED ]:
642+ raise AttributeError ('unknown property of folderfirst %s' % value )
643+ else :
644+ self .folderfirst = value
601645 self ._fill_store ()
602646 else :
603647 raise AttributeError ('unknown iconview set_property %s' % property .name )
0 commit comments