Skip to content

Commit 2dec959

Browse files
committed
iconview: add option to sort by date
1 parent 3eb14f0 commit 2dec959

1 file changed

Lines changed: 87 additions & 43 deletions

File tree

lib/python/gladevcp/iconview.py

Lines changed: 87 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,23 @@
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+
5466
COL_PATH = 0
5567
COL_PIXBUF = 1
5668
COL_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

Comments
 (0)