class FileItem(GObject.GObject):
- def __init__(self, path, info, cache):
+ def __init__(self, path, info):
super().__init__()
self.name = info.get_name()
self.last_mod_time = info.get_modification_date_time().format_iso8601()
self.full_path = path_join(path, self.name)
+
+
+class DirItem(FileItem):
+
+ def __init__(self, path, info, is_parent=False):
+ super().__init__(path, info)
+ self.name = ' ..' if is_parent else f' {self.name}/'
+ if is_parent:
+ self.full_path = path
+
+
+class ImgItem(FileItem):
+
+ def __init__(self, path, info, cache):
+ super().__init__(path, info)
for param_name in GEN_PARAMS:
if param_name in GEN_PARAMS_STR:
setattr(self, param_name.lower(), '')
setattr(self, k, cached[k])
def set_metadata(self, et, cache):
- for d in et.get_tags([self.name], ['Comment']):
+ for d in et.get_tags([self.full_path], ['Comment']):
for k, v in d.items():
if k.endswith('Comment'):
gen_params = GenParams.from_str(v)
self.dir_box.append(self.sorter)
self.img_dir_absolute = abspath(IMG_DIR)
- self.dir = Gio.File.new_for_path(self.img_dir_absolute)
self.list_store = Gio.ListStore(item_type=FileItem)
self.selection = Gtk.SingleSelection.new(self.list_store)
factory = Gtk.SignalListItemFactory()
factory.connect('bind',
lambda _, i: i.props.child.set_text(i.props.item.name))
self.selector = Gtk.ListView(model=self.selection, factory=factory)
+ self.selector.connect('activate', self.on_selector_activate)
scrolled = Gtk.ScrolledWindow(child=self.selector, vexpand=True,
propagate_natural_width=True)
self.dir_box.append(scrolled)
box_outer.append(self.viewer)
self.props.child = box_outer
- self.item = None
+ self.item_img, self.item_dir = None, None
+ self.unsorted_dirs, self.unsorted_files = [], []
self.sort_order = ['last_mod_time']
self.reload_dir()
+ self.selection.props.selected = self.max_index
+
+ def on_selector_activate(self, _, __):
+ if isinstance(self.selection.props.selected_item, DirItem):
+ self.item_dir = self.selection.props.selected_item
+ self.img_dir_absolute = self.item_dir.full_path
+ self.item_img, self.item_dir = None, None
+ self.unsorted_dirs, self.unsorted_files = [], []
+ self.reload_dir()
def toggle_folder_view(self, _):
self.dir_box.props.visible = not self.dir_box.props.visible
self.list_store.remove_all()
for key in self.sort_order:
if SORT_KEY_RANDOM == key:
- shuffle(self.unsorted)
+ shuffle(self.unsorted_files)
+ shuffle(self.unsorted_dirs)
continue
- self.unsorted.sort(key=attrgetter(key))
- for file_item in self.unsorted:
+ self.unsorted_files.sort(key=attrgetter(key))
+ if key in {'name', 'last_mod_time'}:
+ self.unsorted_dirs.sort(key=attrgetter(key))
+ for file_item in [self.parent_dir_item]\
+ + self.unsorted_dirs + self.unsorted_files:
self.list_store.append(file_item)
- if self.item:
- for pos, item in enumerate(self.list_store):
- if item.full_path == self.item.full_path:
- self.selection.set_selected(pos)
- else:
- self.update_selected()
+ for self_item in (self.item_dir, self.item_img):
+ if self_item:
+ for pos, item in enumerate(self.list_store):
+ if item.full_path == self_item.full_path:
+ self.selection.set_selected(pos)
+ return
+ self.update_selected()
def update_selected(self, *_args):
- self.item = self.selection.props.selected_item
- self.reload_image()
+ if isinstance(self.selection.props.selected_item, ImgItem):
+ self.item_img = self.selection.props.selected_item
+ self.item_dir = None
+ self.reload_image()
+ else:
+ self.item_dir = self.selection.props.selected_item
self.selector.scroll_to(self.selection.props.selected,
Gtk.ListScrollFlags.NONE, None)
def reload_image(self):
self.viewer.remove(self.viewer.get_last_child())
- if self.item:
- params_strs = [f'{k}: ' + str(getattr(self.item, k.lower()))
+ if self.item_img:
+ params_strs = [f'{k}: ' + str(getattr(self.item_img, k.lower()))
for k in GEN_PARAMS]
- self.metadata.props.label = '\n'.join([self.item.full_path]
+ self.metadata.props.label = '\n'.join([self.item_img.full_path]
+ params_strs)
- pic = Gtk.Picture.new_for_filename(self.item.name)
+ pic = Gtk.Picture.new_for_filename(self.item_img.full_path)
pic.props.halign = Gtk.Align.START
self.viewer.append(pic)
else:
def move_selection(self, increment, absolute_position):
cur_index = self.selection.props.selected
+ if len(self.unsorted_files) > 2:
+ self.min_index = len(self.unsorted_dirs) + 1
+ else:
+ self.min_index = 0
if 0 == absolute_position:
- self.selection.props.selected = 0
+ self.selection.props.selected = self.min_index
elif -1 == absolute_position:
self.selection.props.selected = self.max_index
elif (1 == increment and cur_index < self.max_index)\
- or (-1 == increment and cur_index > 0):
+ or (-1 == increment and cur_index > self.min_index):
self.selection.props.selected = cur_index + increment
def reload_dir(self):
- old_item_path = self.item.full_path if self.item else ''
+ self.dir = Gio.File.new_for_path(self.img_dir_absolute)
+ old_dir_path = self.item_dir.full_path if self.item_dir else ''
+ old_img_path = self.item_img.full_path if self.item_img else ''
if not path_exists(CACHE_PATH):
with open(CACHE_PATH, 'w', encoding='utf8') as f:
json_dump({}, f)
with open(CACHE_PATH, 'r', encoding='utf8') as f:
cache = json_load(f)
self.max_index = 0
- self.item = None
+ query_attrs = 'standard::name,standard::type,time::*'
+ self.item_img, self.item_dir = None, None
self.selection.connect('selection-changed', self.update_selected)
- query_attrs = 'standard::name,standard::content-type,time::*'
+ parent_path = abspath(path_join(self.img_dir_absolute, '..'))
+ parent_dir = self.dir.get_parent()
+ parent_dir_info = parent_dir.query_info(
+ query_attrs, Gio.FileQueryInfoFlags.NONE, None)
+ self.parent_dir_item = DirItem(
+ parent_path, parent_dir_info, is_parent=True)
+ self.unsorted_dirs, self.unsorted_files = [], []
enumerator = self.dir.enumerate_children(
query_attrs, Gio.FileQueryInfoFlags.NONE, None)
- self.unsorted = []
for info in [info for info in enumerator
- if info.get_content_type().startswith('image/')]:
- item = FileItem(self.img_dir_absolute, info, cache)
- if old_item_path == item.full_path:
- self.item = item
- self.unsorted += [item]
+ if info.get_file_type() == Gio.FileType.DIRECTORY]:
+ item = DirItem(self.img_dir_absolute, info)
+ if old_dir_path == item.full_path:
+ self.item_dir = item
+ self.unsorted_dirs += [item]
+ enumerator = self.dir.enumerate_children(
+ query_attrs + ',standard::content-type',
+ Gio.FileQueryInfoFlags.NONE, None)
+ for info in [info for info in enumerator
+ if info.get_file_type() == Gio.FileType.REGULAR
+ and info.get_content_type().startswith('image/')]:
+ item = ImgItem(self.img_dir_absolute, info, cache)
+ if old_img_path == item.full_path:
+ self.item_img = item
+ self.unsorted_files += [item]
with ExifToolHelper() as et:
- for item in [item for item in self.unsorted if '' == item.model]:
+ for item in [item for item
+ in self.unsorted_files if '' == item.model]:
item.set_metadata(et, cache)
- self.max_index = len(self.unsorted) - 1
+ self.max_index = len(self.unsorted_files + self.unsorted_dirs)
self.sort()
with open(CACHE_PATH, 'w', encoding='utf8') as f:
json_dump(cache, f)