-
- def update_items_attrs() -> None:
- self.items_attrs.clear()
-
- def separate_items_attrs(basic_items_attrs) -> ItemsAttrs:
- items_attrs: ItemsAttrs = {}
- for attr_name, vals in basic_items_attrs.items():
- sorter = self._sort_order.by_name(attr_name)
- items_attrs[attr_name] = {'incl': [], 'excl': []}
- for v in vals:
- passes_filter = sorter is None
- if sorter:
- passes_filter = sorter.filter_allows_value(v)
- k = 'incl' if passes_filter else 'excl'
- items_attrs[attr_name][k] += [v]
- return items_attrs
-
- items_attrs_tmp_1 = separate_items_attrs(self._basic_items_attrs)
- filtered = filter_entries(items_attrs_tmp_1)
- reduced_basic_items_attrs = self._prep_items_attrs(filtered)
- items_attrs_tmp_2 = separate_items_attrs(reduced_basic_items_attrs)
- for attr_name in (s.name for s in self._sort_order):
- final_values: AttrValsByVisibility = {'incl': [], 'semi': []}
- final_values['excl'] = items_attrs_tmp_1[attr_name]['excl']
- for v in items_attrs_tmp_1[attr_name]['incl']:
- k = ('incl' if v in items_attrs_tmp_2[attr_name]['incl']
- else 'semi')
- final_values[k] += [v]
- for category in ('incl', 'semi', 'excl'):
- final_values[category].sort()
- self.items_attrs[attr_name] = final_values
-
- def filter_entries(items_attrs: ItemsAttrs) -> list[GalleryItem]:
- entries_filtered: list[GalleryItem] = []
- for entry in self.dir_entries:
- if (not self._show_dirs) and isinstance(entry, DirItem):
- continue
- passes_filters = True
- for attr_name in (s.name for s in self._sort_order):
- if isinstance(entry, ImgItem):
- val = (getattr(entry, attr_name)
- if hasattr(entry, attr_name) else None)
- if val not in items_attrs[attr_name]['incl']:
- passes_filters = False
- break
- if passes_filters:
- entries_filtered += [entry]
- return entries_filtered
-
- def build(entries_filtered: list[GalleryItem]) -> None:
- i_row_ref, i_slot_ref = [0], [0]
- if self._grid.get_parent():
- self._fixed_frame.remove(self._grid)
- self._grid = Gtk.Grid()
- if self._col_headers_grid.get_parent():
- self._col_headers_frame.remove(self._col_headers_grid)
- self._col_headers_grid = Gtk.Grid()
- self.slots.clear()
- self._fixed_frame.put(self._grid, 0, 0)
-
- def build_rows_by_attrs(
- remaining: list[tuple[str, AttrVals]],
- items_of_parent: list[GalleryItem],
- ancestors: list[tuple[str, str]]
- ) -> None:
- if not items_of_parent:
- return
- attr_name, attr_values = remaining[0]
- if 1 == len(remaining):
- for i, attr in enumerate(ancestors):
- txt = f'<b>{attr[0]}</b>: {attr[1]}'
- vlabel = _VerticalLabel(txt, self._slots_geometry)
- self._grid.attach(vlabel, i, i_row_ref[0], 1, 1)
- row: list[Optional[GalleryItem]]
- row = [None] * len(attr_values)
- for gallery_item in items_of_parent:
- val = getattr(gallery_item, attr_name)
- idx_val_in_attr_values = attr_values.index(val)
- if row[idx_val_in_attr_values]:
- gallery_item.with_others = True
- row[idx_val_in_attr_values] = gallery_item
- for i_col, item in enumerate(row):
- slot = GallerySlot( # build empty dummy if necessary
- item if item else GalleryItem('', ''),
- self._slots_geometry)
- self.slots += [slot]
- i_slot_ref[0] += 1
- self._grid.attach(slot, i_col + len(ancestors),
- i_row_ref[0], 1, 1)
- i_row_ref[0] += 1
- return
- for attr_value in attr_values:
- items_of_attr_value = [x for x in items_of_parent
- if attr_value == getattr(x,
- attr_name)]
- build_rows_by_attrs(remaining[1:], items_of_attr_value,
- ancestors + [(attr_name, attr_value)])
-
- if self._by_1st:
- self._show_dirs = False
- sort_attrs: list[tuple[str, AttrVals]] = []
- for sorter in reversed(self._sort_order):
- vals: AttrVals = self.items_attrs[sorter.name]['incl']
- if len(vals) > 1:
- sort_attrs += [(sorter.name, vals)]
- if not sort_attrs:
- s_name: str = self._sort_order[0].name
- sort_attrs += [(s_name, self.items_attrs[s_name]['incl'])]
- self._per_row = len(sort_attrs[-1][1])
- build_rows_by_attrs(sort_attrs, entries_filtered, [])
- self._col_headers_frame.put(self._col_headers_grid, 0, 0)
- self._col_headers_grid.attach(Gtk.Box(), 0, 0, 1, 1)
- top_attr_name: str = sort_attrs[-1][0]
- for i, val in enumerate(sort_attrs[-1][1]):
- label = Gtk.Label(label=f'<b>{top_attr_name}</b>: {val}',
- xalign=0,
- ellipsize=Pango.EllipsizeMode.MIDDLE)
- label.set_use_markup(True)
- self._col_headers_grid.attach(label, i + 1, 0, 1, 1)
-
- else:
- dir_entries_filtered_sorted: list[GalleryItem] = sorted(
- entries_filtered, key=cmp_to_key(self._sort_cmp))
- i_row, i_col = 0, 0
- for i, item in enumerate(dir_entries_filtered_sorted):
- if self._per_row == i_col:
- i_col = 0
- i_row += 1
- slot = GallerySlot(item, self._slots_geometry,
- self._on_hit_item)
- self._grid.attach(slot, i_col, i_row, 1, 1)
- self.slots += [slot]
- i_col += 1
- self.update_config_box()
-
- update_items_attrs()
- entries_filtered = filter_entries(self.items_attrs)
- build(entries_filtered)