Refactor FileInfo into GObject

This commit is contained in:
Jan Hamal Dvořák 2025-03-09 17:58:52 +01:00
parent fa24847dce
commit 5e9c6229a4
2 changed files with 48 additions and 23 deletions

View file

@ -130,15 +130,18 @@ class MainWindow(Gtk.ApplicationWindow):
self._navigate_to(file_item.full_path) self._navigate_to(file_item.full_path)
return return
position = file_item.load_attribute("position", 0) position = file_item.saved_position
duration = file_item.load_attribute("duration", 1) or 1 duration = file_item.saved_duration
if (position / duration) >= 0.99: if (position / duration) >= 0.99:
position = 0 position = 0
# Start playing the video # Start playing the video
track = file_item.load_attribute("subtitle_track", -2) self.video_player.play(
self.video_player.play(file_item.full_path, position, track) file_item.full_path,
position,
file_item.saved_subtitle_track,
)
self.last_position_save = self.now self.last_position_save = self.now
self.stack.set_visible_child_name("player") self.stack.set_visible_child_name("player")
@ -204,8 +207,8 @@ class MainWindow(Gtk.ApplicationWindow):
icon.set_from_icon_name("folder-symbolic") icon.set_from_icon_name("folder-symbolic")
icon.set_css_classes(["file-icon"]) icon.set_css_classes(["file-icon"])
else: else:
position = item.load_attribute("position", 0) position = item.saved_position
duration = item.load_attribute("duration", 1) or 1 duration = item.saved_duration
if position == 0: if position == 0:
icon.set_from_icon_name("media-playback-start-symbolic") icon.set_from_icon_name("media-playback-start-symbolic")
@ -218,7 +221,7 @@ class MainWindow(Gtk.ApplicationWindow):
icon.set_css_classes(["file-icon", "in-progress"]) icon.set_css_classes(["file-icon", "in-progress"])
label.set_text(item.name) label.set_text(item.name)
item.connect("notify::attrs-changed", update_icon) item.connect("notify::saved-position", update_icon)
update_icon() update_icon()
def _navigate_to(self, path: Path): def _navigate_to(self, path: Path):
@ -336,15 +339,15 @@ class MainWindow(Gtk.ApplicationWindow):
if file_item.file_type == FileType.DIRECTORY: if file_item.file_type == FileType.DIRECTORY:
return return
position = file_item.load_attribute("position", 0) position = file_item.saved_position
duration = file_item.load_attribute("duration", 1) or 1 duration = file_item.saved_duration
# If position exists and is >= 99% through, clear it # If position exists and is >= 99% through, clear it
if position > 0 and (position / duration) >= 0.99: if position > 0 and (position / duration) >= 0.99:
file_item.save_attribute("position", None) file_item.saved_position = 0
else: else:
# Otherwise mark as complete # Otherwise mark as complete
file_item.save_attribute("position", duration) file_item.saved_position = duration
# Force the list to update the changed item # Force the list to update the changed item
self.list_model.items_changed(self.selection_model.get_selected(), 1, 1) self.list_model.items_changed(self.selection_model.get_selected(), 1, 1)
@ -395,11 +398,11 @@ class MainWindow(Gtk.ApplicationWindow):
position = self.video_player.get_position() position = self.video_player.get_position()
if position is not None: if position is not None:
file_item.save_attribute("position", position) file_item.saved_position = position
duration = self.video_player.get_duration() duration = self.video_player.get_duration()
if duration is not None: if duration is not None:
file_item.save_attribute("duration", duration) file_item.saved_duration = duration
def show_overlay_text(self, text: str, timeout_seconds: float = 1.0) -> None: def show_overlay_text(self, text: str, timeout_seconds: float = 1.0) -> None:
"""Show text in a centered overlay that disappears after timeout""" """Show text in a centered overlay that disappears after timeout"""

View file

@ -22,29 +22,53 @@ class FileItem(GObject.Object):
__gtype_name__ = "FileItem" __gtype_name__ = "FileItem"
attrs_changed = GObject.Property(type=int, default=0)
def __init__(self, name: str, file_type: FileType, full_path: Path): def __init__(self, name: str, file_type: FileType, full_path: Path):
super().__init__() super().__init__()
self.attrs_changed = 0
self.name = name self.name = name
self.file_type = file_type self.file_type = file_type
self.full_path = full_path self.full_path = full_path
@overload @GObject.Property(type=GObject.TYPE_UINT64)
def load_attribute(self, name: str, dfl: str) -> str: ... def saved_position(self) -> int:
return self._load_attribute("position", 0)
@saved_position.setter
def set_saved_position(self, value: int):
self._save_attribute("position", value if value else None)
self.notify("saved-position")
@GObject.Property(type=GObject.TYPE_UINT64)
def saved_duration(self):
return self._load_attribute("duration", 1) or 1
@saved_duration.setter
def set_saved_duration(self, value: int):
self._save_attribute("duration", value if value > 0 else None)
self.notify("saved-duration")
@GObject.Property(type=int)
def saved_subtitle_track(self):
return self._load_attribute("subtitle_track", -2)
@saved_subtitle_track.setter
def set_saved_subtitle_track(self, value: int):
self._save_attribute("subtitle_track", value if value >= -1 else None)
self.notify("saved-subtitle-track")
@overload @overload
def load_attribute(self, name: str, dfl: int) -> int: ... def _load_attribute(self, name: str, dfl: str) -> str: ...
def load_attribute(self, name: str, dfl: str | int) -> str | int: @overload
def _load_attribute(self, name: str, dfl: int) -> int: ...
def _load_attribute(self, name: str, dfl: str | int) -> str | int:
try: try:
strval = os.getxattr(self.full_path, f"user.lazy_player.{name}") strval = os.getxattr(self.full_path, f"user.lazy_player.{name}")
return type(dfl)(strval) return type(dfl)(strval)
except OSError: except OSError:
return dfl return dfl
def save_attribute(self, name: str, value: str | float | int | None) -> None: def _save_attribute(self, name: str, value: str | float | int | None) -> None:
try: try:
if value is None: if value is None:
os.removexattr(self.full_path, f"user.lazy_player.{name}") os.removexattr(self.full_path, f"user.lazy_player.{name}")
@ -53,8 +77,6 @@ class FileItem(GObject.Object):
except OSError: except OSError:
pass pass
self.notify("attrs-changed")
class FileListModel(GObject.Object, Gio.ListModel): class FileListModel(GObject.Object, Gio.ListModel):
"""A ListModel implementation for FileItems""" """A ListModel implementation for FileItems"""