Skip to content

Commit 3c0d086

Browse files
committed
[app] Allow inputs to be sorted
1 parent 9b63f0c commit 3c0d086

1 file changed

Lines changed: 35 additions & 8 deletions

File tree

dvr_scan/app/application.py

Lines changed: 35 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import tkinter.ttk as ttk
1717
import typing as ty
1818
import webbrowser
19+
from datetime import datetime
1920
from logging import getLogger
2021
from pathlib import Path
2122
from tempfile import NamedTemporaryFile
@@ -86,7 +87,7 @@ def __init__(self, root: tk.Widget):
8687

8788
self._videos = ttk.Treeview(
8889
frame,
89-
columns=("duration", "framerate", "resolution", "path"),
90+
columns=("duration", "framerate", "resolution", "path", "date"),
9091
)
9192

9293
scroll_horizontal = ttk.Scrollbar(frame, orient=tk.HORIZONTAL, command=self._videos.xview)
@@ -100,16 +101,24 @@ def __init__(self, root: tk.Widget):
100101
self._videos.grid(row=0, column=0, sticky=tk.NSEW)
101102
frame.grid(row=0, column=0, rowspan=2, columnspan=6, sticky=tk.NSEW)
102103

103-
self._videos.heading("#0", text="Name")
104+
self._videos.heading("#0", text="Name", command=lambda: self._sort_column("#0", False))
104105
self._videos.column("#0", width=180, minwidth=80, stretch=False)
105-
self._videos.heading("duration", text="Duration")
106+
self._videos.heading(
107+
"duration", text="Duration", command=lambda: self._sort_column("duration", False)
108+
)
106109
self._videos.column("duration", width=80, minwidth=80, stretch=False)
107-
self._videos.heading("framerate", text="Framerate")
110+
self._videos.heading(
111+
"framerate", text="Framerate", command=lambda: self._sort_column("framerate", False)
112+
)
108113
self._videos.column("framerate", width=80, minwidth=80, stretch=False)
109-
self._videos.heading("resolution", text="Resolution")
114+
self._videos.heading(
115+
"resolution", text="Resolution", command=lambda: self._sort_column("resolution", False)
116+
)
110117
self._videos.column("resolution", width=80, minwidth=80, stretch=False)
111-
self._videos.heading("path", text="Path")
118+
self._videos.heading("path", text="Path", command=lambda: self._sort_column("path", False))
112119
self._videos.column("path", width=80, minwidth=80, stretch=False)
120+
self._videos.heading("date", text="Date", command=lambda: self._sort_column("date", False))
121+
self._videos.column("date", width=140, minwidth=80, stretch=False)
113122

114123
self._videos.grid(row=0, column=0, columnspan=6, sticky=tk.NSEW)
115124

@@ -213,6 +222,16 @@ def update(self, settings: ScanSettings) -> ty.Optional[ScanSettings]:
213222
settings.set("regions", self._region_editor.shapes)
214223
return settings
215224

225+
def _sort_column(self, col, reverse):
226+
if col == "#0":
227+
items = [(self._videos.item(k, "text"), k) for k in self._videos.get_children("")]
228+
else:
229+
items = [(self._videos.set(k, col), k) for k in self._videos.get_children("")]
230+
items.sort(reverse=reverse)
231+
for index, (_val, k) in enumerate(items):
232+
self._videos.move(k, "", index)
233+
self._videos.heading(col, command=lambda: self._sort_column(col, not reverse))
234+
216235
def _add_video(self, path: str = ""):
217236
paths = []
218237
if not path:
@@ -232,7 +251,15 @@ def _add_video(self, path: str = ""):
232251
logger.error(f"File does not exist: {path}")
233252
return
234253
try:
235-
video = open_video(path, backend="opencv")
254+
video = open_video(path, backend="opencv") # logs errors on failure
255+
try:
256+
# On Windows, ctime is creation time. On other systems, it may be the
257+
# last metadata change time.
258+
create_time = datetime.fromtimestamp(Path(path).stat().st_ctime)
259+
create_time_str = create_time.strftime("%Y-%m-%d %H:%M:%S")
260+
except OSError as ex:
261+
logger.debug(f"Failed to stat {path}: {ex}")
262+
create_time_str = "N/A"
236263
except VideoOpenFailure:
237264
failed_to_load = True
238265
continue
@@ -244,7 +271,7 @@ def _add_video(self, path: str = ""):
244271
"",
245272
tk.END,
246273
text=video.name,
247-
values=(duration, framerate, resolution, path),
274+
values=(duration, framerate, resolution, path, create_time_str),
248275
)
249276
if failed_to_load:
250277
tkinter.messagebox.showwarning(

0 commit comments

Comments
 (0)