Compare commits

...

4 Commits

Author SHA1 Message Date
TheBobBobs
d54d46e704 fix: persist entry selection across pages and save scroll positions (#1248)
* fix: persist entry selection across pages and save scroll positions

* fix: add badges to all selected entries not just visible ones
2026-01-22 22:45:36 -08:00
Sola-ris
4c484bc4c6 fix: call ripgrep with explicit utf-8 encoding. (#1199) 2026-01-22 22:04:09 -08:00
Jann Stute
4dc06835cb fix: prevent deadlock when wanted mnemonics conflict (#1200)
* fix: prevent deadlock when wanted mnemonics conflict

* fix: remove invalid mnemonics from translations
2026-01-22 21:55:03 -08:00
Weblate (bot)
2a2d279725 translations: update from Hosted Weblate (#1266)
* Translated using Weblate (Thai)

Currently translated at 1.6% (6 of 362 strings)

Added translation using Weblate (Thai)

Co-authored-by: Anucha Hlownonkor <tony.chompoo@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/th/
Translation: TagStudio/Strings

* Translated using Weblate (Tamil)

Currently translated at 100.0% (362 of 362 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ta/
Translation: TagStudio/Strings

* Translated using Weblate (Portuguese (Brazil))

Currently translated at 87.2% (316 of 362 strings)

Co-authored-by: Asmodeus <colligare1Asmodeum@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/pt_BR/
Translation: TagStudio/Strings

* Translated using Weblate (Greek)

Currently translated at 44.7% (162 of 362 strings)

Translated using Weblate (Greek)

Currently translated at 44.7% (162 of 362 strings)

Translated using Weblate (Greek)

Currently translated at 27.0% (98 of 362 strings)

Added translation using Weblate (Greek)

Co-authored-by: Gvol <gvol@ncshosting.org>
Co-authored-by: Gvol <gvol@nexusystems.org>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/el/
Translation: TagStudio/Strings

* Translated using Weblate (Japanese)

Currently translated at 100.0% (362 of 362 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: wany-oh <wany-oh@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ja/
Translation: TagStudio/Strings

* Translated using Weblate (Icelandic)

Currently translated at 11.0% (40 of 362 strings)

Added translation using Weblate (Icelandic)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Kristinn Snær <mortallighting@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/is/
Translation: TagStudio/Strings

* Translated using Weblate (Hungarian)

Currently translated at 100.0% (362 of 362 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/hu/
Translation: TagStudio/Strings

* Translated using Weblate (Italian)

Currently translated at 100.0% (362 of 362 strings)

Translated using Weblate (Italian)

Currently translated at 100.0% (359 of 359 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Omni <omnipresentw@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/it/
Translation: TagStudio/Strings

* Translated using Weblate (Dutch)

Currently translated at 35.9% (130 of 362 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Typfout <timo.pollarini@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/nl/
Translation: TagStudio/Strings

* Translated using Weblate (Spanish)

Currently translated at 100.0% (362 of 362 strings)

Translated using Weblate (Spanish)

Currently translated at 100.0% (359 of 359 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Julen Arratibel Etxabe <jarratibeletxabe@gmail.com>
Co-authored-by: r40s-0 <andre.orenday@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/es/
Translation: TagStudio/Strings

* Translated using Weblate (French)

Currently translated at 100.0% (362 of 362 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/fr/
Translation: TagStudio/Strings

* Translated using Weblate (Cebuano)

Currently translated at 30.3% (109 of 359 strings)

Co-authored-by: Hosted Weblate <hosted@weblate.org>
Co-authored-by: StartsMercury <startsmercury@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/ceb/
Translation: TagStudio/Strings

* Translated using Weblate (Toki Pona)

Currently translated at 94.4% (342 of 362 strings)

Co-authored-by: Bee Crankson <ProfB.crankson@gmail.com>
Co-authored-by: Hosted Weblate <hosted@weblate.org>
Translate-URL: https://hosted.weblate.org/projects/tagstudio/strings/tok/
Translation: TagStudio/Strings

---------

Co-authored-by: Anucha Hlownonkor <tony.chompoo@gmail.com>
Co-authored-by: தமிழ்நேரம் <tamilneram247@gmail.com>
Co-authored-by: Asmodeus <colligare1Asmodeum@gmail.com>
Co-authored-by: Gvol <gvol@ncshosting.org>
Co-authored-by: Gvol <gvol@nexusystems.org>
Co-authored-by: Travis Abendshien <46939827+CyanVoxel@users.noreply.github.com>
Co-authored-by: wany-oh <wany-oh@users.noreply.hosted.weblate.org>
Co-authored-by: Kristinn Snær <mortallighting@gmail.com>
Co-authored-by: Szíjártó Levente Pál <szijartoleventepal@gmail.com>
Co-authored-by: Omni <omnipresentw@users.noreply.hosted.weblate.org>
Co-authored-by: Typfout <timo.pollarini@gmail.com>
Co-authored-by: Julen Arratibel Etxabe <jarratibeletxabe@gmail.com>
Co-authored-by: r40s-0 <andre.orenday@gmail.com>
Co-authored-by: Med <45147847+kitsumed@users.noreply.github.com>
Co-authored-by: StartsMercury <startsmercury@gmail.com>
Co-authored-by: Bee Crankson <ProfB.crankson@gmail.com>
2026-01-22 21:46:31 -08:00
27 changed files with 506 additions and 166 deletions

View File

@@ -43,6 +43,7 @@ jobs:
libxcb-xinerama0 \
libxkbcommon-x11-0 \
libyaml-dev \
ripgrep \
x11-utils
- name: Execute pytest

View File

@@ -1,6 +1,6 @@
import enum
import random
from dataclasses import dataclass, replace
from dataclasses import dataclass, field, replace
from pathlib import Path
import structlog
@@ -78,8 +78,9 @@ class BrowsingState:
"""Represent a state of the Library grid view."""
page_index: int = 0
page_positions: dict[int, int] = field(default_factory=dict)
sorting_mode: SortingModeEnum = SortingModeEnum.DATE_ADDED
ascending: bool = True
ascending: bool = False
random_seed: float = 0
show_hidden_entries: bool = False

View File

@@ -4,7 +4,6 @@ from pathlib import Path
import structlog
from tagstudio.core.library.alchemy.enums import BrowsingState
from tagstudio.core.library.alchemy.library import Library
from tagstudio.core.library.alchemy.models import Entry
from tagstudio.core.utils.types import unwrap
@@ -52,16 +51,12 @@ class DupeFilesRegistry:
# The file is not in the library directory
continue
results = self.library.search_library(
BrowsingState.from_path(path_relative), 500
)
entries = self.library.get_entries(results.ids)
if not results:
entry = self.library.get_entry_full_by_path(path_relative)
if entry is None:
# file not in library
continue
files.append(entries[0])
files.append(entry)
if not len(files) > 1:
# only one file in the group, nothing to do

View File

@@ -105,8 +105,8 @@ class RefreshTracker:
),
cwd=library_dir,
capture_output=True,
text=True,
shell=True,
encoding="UTF-8",
)
compiled_ignore_path.unlink()

View File

@@ -496,13 +496,11 @@ class ItemThumb(FlowWidget):
toggle_value: bool,
tag_id: int,
):
if entry_id in self.driver.selected:
if len(self.driver.selected) == 1:
self.driver.main_window.preview_panel.field_containers_widget.update_toggled_tag(
tag_id, toggle_value
)
else:
pass
selected = self.driver._selected
if len(selected) == 1 and entry_id in selected:
self.driver.main_window.preview_panel.field_containers_widget.update_toggled_tag(
tag_id, toggle_value
)
@override
def mouseMoveEvent(self, event: QMouseEvent) -> None: # type: ignore[misc]

View File

@@ -1,10 +1,13 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
import re
import structlog
from PySide6.QtGui import QAction
from PySide6.QtWidgets import QMenu
logger = structlog.get_logger(__name__)
def remove_mnemonic_marker(label: str) -> str:
"""Remove existing accelerator markers (&) from a label."""
@@ -25,6 +28,31 @@ def remove_mnemonic_marker(label: str) -> str:
return result
def get_wanted_mnemonics(text: str) -> list[str]:
matches = re.findall("(?:^|[^&])&([^&])", text)
return matches
def sanitise_mnemonics(actions: list[QAction]) -> None:
previous = []
for action in actions:
text = action.text()
m = get_wanted_mnemonics(text)
if len(m) == 0:
continue
elif len(m) > 1:
logger.warning("Found multiple wanted mnemonics, removing all", text=text)
action.setText(remove_mnemonic_marker(text))
continue
elif m[0] in previous:
logger.warning("Removing conflicting mnemonic", text=text)
action.setText(remove_mnemonic_marker(text))
continue
previous.append(m[0])
# Additional weight for first character in string
FIRST_CHARACTER_EXTRA_WEIGHT = 50
# Additional weight for the beginning of a word
@@ -97,6 +125,9 @@ def assign_mnemonics(menu: QMenu):
# Collect actions
actions = [a for a in menu.actions() if not a.isSeparator()]
# sanitise mnemonics to prevent deadlocks
sanitise_mnemonics(actions)
# Sequence map: mnemonic key -> QAction
sequence_to_action: dict[str, QAction] = {}

View File

@@ -1,9 +1,10 @@
import math
import time
from collections.abc import Iterable
from pathlib import Path
from typing import TYPE_CHECKING, Any, override
from PySide6.QtCore import QPoint, QRect, QSize
from PySide6.QtCore import QPoint, QRect, QSize, Signal
from PySide6.QtGui import QPixmap
from PySide6.QtWidgets import QLayout, QLayoutItem, QScrollArea
@@ -19,6 +20,9 @@ if TYPE_CHECKING:
class ThumbGridLayout(QLayout):
# Id of first visible entry
visible_changed = Signal(int)
def __init__(self, driver: "QtDriver", scroll_area: QScrollArea) -> None:
super().__init__(None)
self.driver: QtDriver = driver
@@ -26,10 +30,6 @@ class ThumbGridLayout(QLayout):
self._item_thumbs: list[ItemThumb] = []
self._items: list[QLayoutItem] = []
# Entry.id -> _entry_ids[index]
self._selected: dict[int, int] = {}
# _entry_ids[index]
self._last_selected: int | None = None
self._entry_ids: list[int] = []
self._entries: dict[int, Entry] = {}
@@ -47,12 +47,14 @@ class ThumbGridLayout(QLayout):
# _entry_ids[StartIndex:EndIndex]
self._last_page_update: tuple[int, int] | None = None
self._scroll_to: int | None = None
def scroll_to(self, entry_id: int):
self._scroll_to = entry_id
def set_entries(self, entry_ids: list[int]):
self.scroll_area.verticalScrollBar().setValue(0)
self._selected.clear()
self._last_selected = None
self._entry_ids = entry_ids
self._entries.clear()
self._tag_entries.clear()
@@ -83,90 +85,20 @@ class ThumbGridLayout(QLayout):
self._last_page_update = None
def select_all(self):
self._selected.clear()
for index, id in enumerate(self._entry_ids):
self._selected[id] = index
self._last_selected = index
def update_selected(self):
for item_thumb in self._item_thumbs:
value = item_thumb.item_id in self.driver._selected
item_thumb.thumb_button.set_selected(value)
for entry_id in self._entry_items:
self._set_selected(entry_id)
def select_inverse(self):
selected = {}
for index, id in enumerate(self._entry_ids):
if id not in self._selected:
selected[id] = index
self._last_selected = index
for id in self._selected:
if id not in selected:
self._set_selected(id, value=False)
for id in selected:
self._set_selected(id)
self._selected = selected
def select_entry(self, entry_id: int):
if entry_id in self._selected:
index = self._selected.pop(entry_id)
if index == self._last_selected:
self._last_selected = None
self._set_selected(entry_id, value=False)
else:
try:
index = self._entry_ids.index(entry_id)
except ValueError:
index = -1
self._selected[entry_id] = index
self._last_selected = index
self._set_selected(entry_id)
def select_to_entry(self, entry_id: int):
index = self._entry_ids.index(entry_id)
if len(self._selected) == 0:
self.select_entry(entry_id)
return
if self._last_selected is None:
self._last_selected = min(self._selected.values(), key=lambda i: abs(index - i))
start = self._last_selected
self._last_selected = index
if start > index:
index, start = start, index
else:
index += 1
for i in range(start, index):
entry_id = self._entry_ids[i]
self._selected[entry_id] = i
self._set_selected(entry_id)
def clear_selected(self):
for entry_id in self._entry_items:
self._set_selected(entry_id, value=False)
self._selected.clear()
self._last_selected = None
def _set_selected(self, entry_id: int, value: bool = True):
if entry_id not in self._entry_items:
return
index = self._entry_items[entry_id]
if index < len(self._item_thumbs):
self._item_thumbs[index].thumb_button.set_selected(value)
def add_tags(self, entry_ids: list[int], tag_ids: list[int]):
def add_tags(self, entry_ids: Iterable[int], tag_ids: Iterable[int]):
for tag_id in tag_ids:
self._tag_entries.setdefault(tag_id, set()).update(entry_ids)
def remove_tags(self, entry_ids: list[int], tag_ids: list[int]):
def remove_tags(self, entry_ids: Iterable[int], tag_ids: Iterable[int]):
for tag_id in tag_ids:
self._tag_entries.setdefault(tag_id, set()).difference_update(entry_ids)
def _fetch_entries(self, ids: list[int]):
def _fetch_entries(self, ids: Iterable[int]):
ids = [id for id in ids if id not in self._entries]
entries = self.driver.lib.get_entries(ids)
for entry in entries:
@@ -263,12 +195,24 @@ class ThumbGridLayout(QLayout):
per_row, width_offset, height_offset = self._size(rect.right())
view_height = self.parentWidget().parentWidget().height()
offset = self.scroll_area.verticalScrollBar().value()
if self._scroll_to is not None:
try:
index = self._entry_ids.index(self._scroll_to)
value = (index // per_row) * height_offset
self.scroll_area.verticalScrollBar().setMaximum(value)
self.scroll_area.verticalScrollBar().setSliderPosition(value)
offset = value
except ValueError:
pass
self._scroll_to = None
visible_rows = math.ceil((view_height + (offset % height_offset)) / height_offset)
offset = int(offset / height_offset)
start = offset * per_row
end = start + (visible_rows * per_row)
self.visible_changed.emit(self._entry_ids[start])
# Load closest off screen rows
start -= per_row * 3
end += per_row * 3
@@ -363,7 +307,7 @@ class ThumbGridLayout(QLayout):
entry_id = self._entry_ids[i]
item_index = self._entry_items[entry_id]
item_thumb = self._item_thumbs[item_index]
item_thumb.thumb_button.set_selected(entry_id in self._selected)
item_thumb.thumb_button.set_selected(entry_id in self.driver._selected)
item_thumb.assign_badge(BadgeType.ARCHIVED, entry_id in self._tag_entries[TAG_ARCHIVED])
item_thumb.assign_badge(BadgeType.FAVORITE, entry_id in self._tag_entries[TAG_FAVORITE])

View File

@@ -17,6 +17,7 @@ import re
import sys
import time
from argparse import Namespace
from collections import OrderedDict
from pathlib import Path
from queue import Queue
from shutil import which
@@ -206,7 +207,8 @@ class QtDriver(DriverMixin, QObject):
self.lib = Library()
self.rm: ResourceManager = ResourceManager()
self.args = args
self.frame_content: list[int] = [] # List of Entry IDs on the current page
self.frame_content: list[int] = [] # List of Entry IDs for the current query
self._selected: OrderedDict[int, None] = OrderedDict()
self.pages_count = 0
self.scrollbar_pos = 0
@@ -258,7 +260,13 @@ class QtDriver(DriverMixin, QObject):
@property
def selected(self) -> list[int]:
return list(self.main_window.thumb_layout._selected.keys())
return list(self._selected.keys())
@property
def last_selected(self) -> int | None:
if len(self._selected) == 0:
return None
return reversed(self._selected).__next__()
def __reset_navigation(self) -> None:
self.browsing_history = History(BrowsingState.show_all())
@@ -564,6 +572,16 @@ class QtDriver(DriverMixin, QObject):
self.main_window.search_field.textChanged.connect(self.update_completions_list)
def on_visible_changed(entry_id: int | None):
current = self.browsing_history.current
page_index = current.page_index
if entry_id is None:
current.page_positions.pop(page_index)
else:
current.page_positions[page_index] = entry_id
self.main_window.thumb_layout.visible_changed.connect(on_visible_changed)
self.archived_updated.connect(
lambda hidden: self.update_badges(
{BadgeType.ARCHIVED: hidden}, origin_id=0, add_tags=False
@@ -758,6 +776,7 @@ class QtDriver(DriverMixin, QObject):
self.main_window.setWindowTitle(self.base_title)
self.frame_content.clear()
self._selected.clear()
if self.color_manager_panel:
self.color_manager_panel.reset()
@@ -852,7 +871,7 @@ class QtDriver(DriverMixin, QObject):
def select_all_action_callback(self):
"""Set the selection to all visible items."""
self.main_window.thumb_layout.select_all()
self.select_all()
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()
@@ -861,7 +880,7 @@ class QtDriver(DriverMixin, QObject):
def select_inverse_action_callback(self):
"""Invert the selection of all visible items."""
self.main_window.thumb_layout.select_inverse()
self.select_inverse()
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()
@@ -869,7 +888,7 @@ class QtDriver(DriverMixin, QObject):
self.main_window.preview_panel.set_selection(self.selected, update_preview=False)
def clear_select_action_callback(self):
self.main_window.thumb_layout.clear_selected()
self.clear_selected()
self.set_select_actions_visibility()
self.set_clipboard_menu_viability()
@@ -1195,16 +1214,16 @@ class QtDriver(DriverMixin, QObject):
def page_move(self, value: int, absolute=False) -> None:
logger.info("page_move", value=value, absolute=absolute)
current = self.browsing_history.current
if not absolute:
value += self.browsing_history.current.page_index
self.browsing_history.push(
self.browsing_history.current.with_page_index(clamp(value, 0, self.pages_count - 1))
)
# TODO: Re-allow selecting entries across multiple pages at once.
# This works fine with additive selection but becomes a nightmare with bridging.
current.page_index += value
else:
current.page_index = value
current.page_index = clamp(current.page_index, 0, self.pages_count - 1)
# TODO: The back mouse button will no longer move to the previous page and
# instead goto the previous query passing a new state to update_browsing_state
# will get this behaviour back but would mess with persisting page scroll positions
self.update_browsing_state()
def navigation_callback(self, delta: int) -> None:
@@ -1265,12 +1284,12 @@ class QtDriver(DriverMixin, QObject):
"""
logger.info("[QtDriver] Selecting Items:", item_id=item_id, append=append, bridge=bridge)
if append:
self.main_window.thumb_layout.select_entry(item_id)
self.select_entry(item_id)
elif bridge:
self.main_window.thumb_layout.select_to_entry(item_id)
self.select_to_entry(item_id)
else:
self.main_window.thumb_layout.clear_selected()
self.main_window.thumb_layout.select_entry(item_id)
self.clear_selected()
self.select_entry(item_id)
self.set_clipboard_menu_viability()
self.set_select_actions_visibility()
@@ -1385,7 +1404,14 @@ class QtDriver(DriverMixin, QObject):
self.thumb_job_queue.all_tasks_done.notify_all()
self.thumb_job_queue.not_full.notify_all()
self.main_window.thumb_layout.set_entries(self.frame_content)
page_size = (
len(self.frame_content) if self.settings.infinite_scroll else self.settings.page_size
)
page = self.browsing_history.current.page_index
start = page * page_size
end = min(start + page_size, len(self.frame_content))
self.main_window.thumb_layout.set_entries(self.frame_content[start:end])
self.main_window.thumb_layout.update()
self.main_window.update()
@@ -1400,8 +1426,11 @@ class QtDriver(DriverMixin, QObject):
add_tags(bool): Flag determining if tags associated with the badges need to be added to
the items. Defaults to True.
"""
item_ids = self.selected if (not origin_id or origin_id in self.selected) else [origin_id]
pending_entries: dict[BadgeType, list[int]] = {}
entry_ids = (
set(self._selected.keys())
if (origin_id == 0 or origin_id in self._selected)
else {origin_id}
)
logger.info(
"[QtDriver][update_badges] Updating ItemThumb badges",
@@ -1410,12 +1439,9 @@ class QtDriver(DriverMixin, QObject):
add_tags=add_tags,
)
for it in self.main_window.thumb_layout._item_thumbs:
if it.item_id in item_ids:
if it.item_id in entry_ids:
for badge_type, value in badge_values.items():
if add_tags:
if not pending_entries.get(badge_type):
pending_entries[badge_type] = []
pending_entries[badge_type].append(it.item_id)
it.toggle_item_tag(it.item_id, value, BADGE_TAGS[badge_type])
it.assign_badge(badge_type, value)
@@ -1424,10 +1450,9 @@ class QtDriver(DriverMixin, QObject):
logger.info(
"[QtDriver][update_badges] Adding tags to updated entries",
pending_entries=pending_entries,
pending_entries=entry_ids,
)
for badge_type, value in badge_values.items():
entry_ids = pending_entries.get(badge_type, [])
tag_ids = [BADGE_TAGS[badge_type]]
if value:
@@ -1455,8 +1480,7 @@ class QtDriver(DriverMixin, QObject):
# search the library
start_time = time.time()
Ignore.get_patterns(self.lib.library_dir, include_global=True)
page_size = 0 if self.settings.infinite_scroll else self.settings.page_size
results = self.lib.search_library(self.browsing_history.current, page_size)
results = self.lib.search_library(self.browsing_history.current, page_size=0)
logger.info("items to render", count=len(results))
end_time = time.time()
@@ -1471,9 +1495,17 @@ class QtDriver(DriverMixin, QObject):
# update page content
self.frame_content = results.ids
page_index = self.browsing_history.current.page_index
if state is None:
entry_id = self.browsing_history.current.page_positions.get(page_index)
else:
entry_id = self.last_selected
if entry_id is not None:
self.main_window.thumb_layout.scroll_to(entry_id)
self.update_thumbs()
# update pagination
page_size = 0 if self.settings.infinite_scroll else self.settings.page_size
if page_size > 0:
self.pages_count = math.ceil(results.total_count / page_size)
else:
@@ -1689,3 +1721,45 @@ class QtDriver(DriverMixin, QObject):
event.accept()
else:
event.ignore()
def select_all(self):
self._selected = OrderedDict.fromkeys(self.frame_content)
self.main_window.thumb_layout.update_selected()
def select_inverse(self):
selected = OrderedDict()
for id in self.frame_content:
if id not in self._selected:
selected[id] = None
self._selected = selected
self.main_window.thumb_layout.update_selected()
def select_entry(self, entry_id: int):
if entry_id in self._selected:
self._selected.pop(entry_id)
else:
self._selected[entry_id] = None
self.main_window.thumb_layout.update_selected()
def select_to_entry(self, entry_id: int):
if len(self._selected) == 0:
self.select_entry(entry_id)
return
last_selected = reversed(self._selected).__next__()
start = self.frame_content.index(last_selected)
end = self.frame_content.index(entry_id)
if start > end:
end, start = start, end
else:
end += 1
for i in range(start, end):
entry_id = self.frame_content[i]
self._selected[entry_id] = None
self.main_window.thumb_layout.update_selected()
def clear_selected(self):
self._selected.clear()
self.main_window.thumb_layout.update_selected()

View File

@@ -3,8 +3,18 @@
"about.license": "Lisensiya",
"about.module.found": "Makit-i",
"about.title": "Mahitungod sa TagStudio",
"color.color_border": "Gamita ang Ikaduha nga Kolor alang sa Utlanan",
"color.import_pack": "Pag-angkat og Putos sa Kolor",
"color.name": "Ngalan",
"color.namespace.delete.title": "Panas-i ang Bansag sa Kolor",
"color.new": "Bag-o nga Kolor",
"color.placeholder": "Kolor",
"color.primary": "Nag-una nga Kolor",
"color.primary_required": "Nag-una nga Kolor (Kinahanglan)",
"color.secondary": "Ikaduha nga Kolor",
"color.title.no_color": "Walay Kolor",
"color_manager.title": "Pag-atiman ang Mga Kolor sa Timailhan",
"edit.color_manager": "Pag-atiman sa Mga Kolor sa Timailhan",
"entries.generic.refresh_alt": "Pag&lab-as",
"entries.tags": "Mga Timailhan",
"field.edit": "Usba ang Uma",
@@ -54,6 +64,7 @@
"library.name": "Librarya",
"library_info.cleanup": "Paghinlo",
"library_info.stats": "Estatistika",
"library_info.stats.colors": "Mga Kolor sa Timailhan",
"library_info.stats.entries": "Mga sulod:",
"library_info.stats.fields": "Mga uma:",
"library_info.stats.macros": "Mga makro:",
@@ -73,6 +84,9 @@
"menu.tools": "Mga &himan",
"menu.view": "Paglanta&w",
"menu.window": "Tamboanan",
"namespace.create.title": "Paghimo og Bansag",
"namespace.new.button": "Bag-o nga Bansag",
"namespace.new.prompt": "Paghimo og Bag-o nga Bansag aron Makasugod og Dugang og",
"preview.ignored": "Linguglingogon",
"settings.dateformat.english": "Inggles",
"settings.dateformat.international": "Internasyonal",
@@ -80,15 +94,18 @@
"settings.language": "Pinulongan",
"settings.splash.option.random": "Sinalagma",
"settings.tag_click_action.open_edit": "Usba ang Timailhan",
"settings.theme.dark": "Madulom",
"settings.theme.dark": "Dulom",
"settings.theme.label": "Hilisgotan:",
"settings.theme.light": "Hayag",
"settings.theme.system": "Sistema",
"settings.title": "Mga Hmutangan",
"settings.title": "Mga Himutangan",
"sorting.direction.ascending": "Nagasaka",
"sorting.direction.descending": "Naganaog",
"sorting.mode.random": "Sinalagma",
"status.library_version_expected": "Dinahom:",
"status.library_version_found": "Makit-i",
"status.results": "Mga agi",
"tag.choose_color": "Pamili og Kolor sa Timailhan",
"tag.color": "Kolor",
"tag.edit": "Usba ang Timailhan"
}

View File

@@ -0,0 +1,164 @@
{
"about.config_path": "Διαδρομή Config",
"about.description": "ο TagStudio είναι μια εφαρμογή οργάνωσης φωτογραφιών και αρχείων με ένα υποκείμενο σύστημα βασισμένο σε ετικέτες που εστιάζει στην παροχή ελευθερίας και ευελιξίας στον χρήστη. Χωρίς ιδιόκτητα προγράμματα ή μορφές, χωρίς πληθώρα αρχείων και χωρίς πλήρη ανατροπή της δομής του συστήματος αρχείων σας.",
"about.documentation": "Τεκμηρίωση",
"about.license": "Άδεια χρήσης",
"about.module.found": "Βρέθηκε",
"about.title": "Πληροφορίες για το TagStudio",
"about.website": "Ιστοσελίδα",
"app.git": "Git Commit",
"app.pre_release": "Pre-Release",
"app.title": "{base_title} Βιβλιοθήκη \"{library_dir} «««",
"color.color_border": "Χρησιμοποιήστε το δευτερεύον χρώμα για τα σύνορα",
"color.confirm_delete": "Είστε βέβαιοι ότι θέλετε να διαγράψετε το χρώμα \"{color_name}\";",
"color.delete": "Διαγράψτε Tag",
"color.import_pack": "Εισαγωγή Πακέτου Χρωμάτων",
"color.name": "Όνομα",
"color.namespace.delete.prompt": "Είστε βέβαιοι ότι θέλετε να διαγράψετε αυτόν τον χώρο ονόματος χρωμάτων; Αυτό θα διαγράψει όλα τα χρώματα στο χώρο του ονόματος μαζί του!",
"color.namespace.delete.title": "Διαγράψτε Color Namespace",
"color.new": "Νέο χρώμα",
"color.placeholder": "Χρώμα",
"color.primary": "Βασικό Χρώμα",
"color.primary_required": "Βασικό Χρώμα (Υποχρεωτικό)",
"color.secondary": "Δευτερεύον Χρώμα",
"color.title.no_color": "Χωρίς Χρώμα",
"color_manager.title": "Διαχείριση χρωμάτων Tag",
"dependency.missing.title": "{dependency} Δεν υπάρχει",
"drop_import.description": "Τα παρακάτω αρχεία ταιριάζουν μονοπάτια αρχείων που υπάρχουν ήδη στη βιβλιοθήκη",
"drop_import.duplicates_choice.plural": "Τα παρακάτω αρχεία {count} ταιριάζουν μονοπάτια αρχείων που υπάρχουν ήδη στη βιβλιοθήκη.",
"drop_import.duplicates_choice.singular": "Το παρακάτω αρχείο ταιριάζει με ένα μονοπάτι αρχείου που υπάρχει ήδη στη βιβλιοθήκη.",
"drop_import.progress.label.initial": "Εισαγωγή νέων αρχείων...",
"drop_import.progress.label.plural": "Εισαγωγή νέων αρχείων...\n{count} Αρχεία Εισήχθησαν.{suffix}",
"drop_import.progress.label.singular": "Εισαγωγή νέων αρχείων...\n1 Αρχείο εισήχθη.{suffix}",
"drop_import.progress.window_title": "Εισαγωγή αρχείων",
"drop_import.title": "Αντικρουόμενα αρχεία(s)",
"edit.color_manager": "Διαχείριση χρωμάτων Tag",
"edit.copy_fields": "Αντιγραφή πεδίων",
"edit.paste_fields": "Επικόλληση πεδίων",
"edit.tag_manager": "Διαχείριση Tags",
"entries.duplicate.merge": "Συγχώνευση διπλότυπων εγγραφών",
"entries.duplicate.merge.label": "Συγχώνευση διπλότυπων εγγραφών...",
"entries.duplicate.refresh": "Ανανέωση διπλότυπων εγγραφών",
"entries.duplicates.description": "Ως διπλότυπες εγγραφές ορίζονται οι πολλαπλές εγγραφές που υποδεικνύουν το ίδιο αρχείο στον δίσκο. Η συγχώνευση αυτών θα συνδυάσει τις ετικέτες και τα μεταδεδομένα από όλα τα διπλότυπα σε μια ενιαία, ενοποιημένη εγγραφή. Αυτές δεν πρέπει να συγχέονται με τα \"διπλότυπα αρχεία\", τα οποία είναι αντίγραφα των ίδιων των αρχείων σας εκτός του TagStudio.",
"entries.generic.refresh_alt": "&Ανανέωση",
"entries.generic.remove.removing": "Αφαίρεση εγγραφών",
"entries.generic.remove.removing_count": "Αφαίρεση {count} εγγραφών...",
"entries.ignored.description": "Οι εγγραφές αρχείων θεωρούνται \"αγνοημένες\" εάν προστέθηκαν στη βιβλιοθήκη πριν ενημερωθούν οι κανόνες εξαίρεσης του χρήστη (μέσω του αρχείου '.ts_ignore') για να τα αποκλείσουν. Τα αγνοημένα αρχεία διατηρούνται στη βιβλιοθήκη από προεπιλογή, προκειμένου να αποφευχθεί η τυχαία απώλεια δεδομένων κατά την ενημέρωση των κανόνων εξαίρεσης.",
"entries.ignored.ignored_count": "Αγνοημένες εγγραφές: {count}",
"entries.ignored.remove": "Αφαίρεση αγνοημένων εγγραφών",
"entries.ignored.remove_alt": "Α&φαίρεση αγνοημένων εγγραφών",
"entries.ignored.scanning": "Σάρωση βιβλιοθήκης για αγνοημένες εγγραφές...",
"entries.ignored.title": "Διόρθωση αγνοημένων εγγραφών",
"entries.mirror": "&Αντικατοπτρισμός",
"entries.mirror.confirmation": "Είστε βέβαιοι ότι θέλετε να αντικατοπτρίσετε τις ακόλουθες {count} εγγραφές;",
"entries.mirror.label": "Αντικατοπτρισμός {idx}/{total} εγγραφών...",
"entries.mirror.title": "Αντικατοπτρισμός εγγραφών",
"entries.mirror.window_title": "Αντικατοπτρισμός εγγραφών",
"entries.remove.plural.confirm": "Είστε βέβαιοι ότι θέλετε να αφαιρέσετε αυτές τις <b>{count}</b> εγγραφές από τη βιβλιοθήκη σας; Δεν θα διαγραφεί κανένα αρχείο από τον δίσκο.",
"entries.remove.singular.confirm": "Είστε βέβαιοι ότι θέλετε να αφαιρέσετε αυτή την εγγραφή από τη βιβλιοθήκη σας; Δεν θα διαγραφεί κανένα αρχείο από τον δίσκο.",
"entries.running.dialog.new_entries": "Προσθήκη {total} νέων εγγραφών αρχείων...",
"entries.running.dialog.title": "Προσθήκη νέων εγγραφών αρχείων",
"entries.tags": "Tags",
"entries.unlinked.description": "Κάθε εγγραφή της βιβλιοθήκης είναι συνδεδεμένη με ένα αρχείο σε έναν από τους καταλόγους σας. Εάν ένα αρχείο που είναι συνδεδεμένο με μια εγγραφή μετακινηθεί ή διαγραφεί εκτός του TagStudio, τότε θεωρείται αποσυνδεδεμένο.<br><br>Οι αποσυνδεδεμένες εγγραφές μπορούν να επανασυνδεθούν αυτόματα μέσω αναζήτησης στους καταλόγους σας ή να διαγραφούν, εάν το επιθυμείτε.",
"entries.unlinked.relink.attempting": "Προσπάθεια επανασύνδεσης {index}/{unlinked_count} εγγραφών, {fixed_count} επανασυνδέθηκαν επιτυχώς",
"entries.unlinked.relink.manual": "&Χειροκίνητη επανασύνδεση",
"entries.unlinked.relink.title": "Επανασύνδεση εγγραφών",
"entries.unlinked.remove": "Αφαίρεση αποσυνδεδεμένων εγγραφών",
"entries.unlinked.remove_alt": "Α&φαίρεση αποσυνδεδεμένων εγγραφών",
"entries.unlinked.scanning": "Σάρωση βιβλιοθήκης για αποσυνδεδεμένες εγγραφές...",
"entries.unlinked.search_and_relink": "&Αναζήτηση && Επανασύνδεση",
"entries.unlinked.title": "Διόρθωση αποσυνδεδεμένων εγγραφών",
"entries.unlinked.unlinked_count": "Αποσυνδεδεμένες εγγραφές: {count}",
"ffmpeg.missing.description": "Δεν βρέθηκαν τα FFmpeg ή/και FFprobe. Το FFmpeg είναι απαραίτητο για την αναπαραγωγή πολυμέσων και τη δημιουργία μικρογραφιών.",
"ffmpeg.missing.status": "{ffmpeg}: {ffmpeg_status}<br>{ffprobe}: {ffprobe_status}",
"field.copy": "Αντιγραφή πεδίου",
"field.edit": "Επεξεργασία πεδίου",
"field.paste": "Επικόλληση πεδίου",
"file.date_added": "Ημερομηνία προσθήκης",
"file.date_created": "Ημερομηνία δημιουργίας",
"file.date_modified": "Ημερομηνία τροποποίησης",
"file.dimensions": "Διαστάσεις",
"file.duplicates.description": "Το TagStudio υποστηρίζει την εισαγωγή αποτελεσμάτων από το DupeGuru για τη διαχείριση διπλότυπων αρχείων.",
"file.duplicates.dupeguru.advice": "Μετά τον κατοπτρισμό, μπορείτε ελεύθερα να χρησιμοποιήσετε το DupeGuru για να διαγράψετε τα ανεπιθύμητα αρχεία. Στη συνέχεια, χρησιμοποιήστε τη λειτουργία «Διόρθωση αποσυνδεδεμένων εγγραφών» στο μενού «Εργαλεία» του TagStudio, προκειμένου να διαγράψετε τις αποσυνδεδεμένες εγγραφές.",
"file.duplicates.dupeguru.file_extension": "Αρχεία DupeGuru (*.dupeguru)",
"file.duplicates.dupeguru.load_file": "&Φόρτωση αρχείου DupeGuru",
"file.duplicates.dupeguru.no_file": "Δεν επιλέχθηκε αρχείο DupeGuru",
"file.duplicates.dupeguru.open_file": "Άνοιγμα αρχείου αποτελεσμάτων DupeGuru",
"file.duplicates.fix": "Διόρθωση διπλότυπων αρχείων",
"file.duplicates.matches": "Αντιστοιχίες διπλότυπων αρχείων: {count}",
"file.duplicates.matches_uninitialized": "Αντιστοιχίες διπλότυπων αρχείων: Μ/Δ",
"file.duplicates.mirror.description": "Κατοπτρισμός των δεδομένων της εγγραφής σε κάθε σύνολο αντιστοιχισμένων διπλοτύπων, συνδυάζοντας όλα τα δεδομένα χωρίς την αφαίρεση ή την επανάληψη πεδίων. Αυτή η λειτουργία δεν θα διαγράψει αρχεία ή δεδομένα.",
"file.duplicates.mirror_entries": "&Κατοπτρισμός εγγραφών",
"file.duration": "Διάρκεια",
"file.not_found": "Το αρχείο δεν βρέθηκε",
"file.open_file": "Άνοιγμα αρχείου",
"file.open_file_with": "Άνοιγμα αρχείου με",
"file.open_location.generic": "Εμφάνιση αρχείου στην Εξερεύνηση αρχείων",
"file.open_location.mac": "Εμφάνιση στο Finder",
"file.open_location.windows": "Εμφάνιση στην Εξερεύνηση αρχείων",
"file.path": "Διαδρομή αρχείου",
"folders_to_tags.close_all": "Κλείσιμο όλων",
"folders_to_tags.converting": "Μετατροπή φακέλων σε Tags",
"folders_to_tags.description": "Δημιουργεί ετικέτες με βάση τη δομή των φακέλων σας και τις εφαρμόζει στις εγγραφές σας. \nΗ παρακάτω δομή εμφανίζει όλες τις ετικέτες που πρόκειται να δημιουργηθούν, καθώς και σε ποιες εγγραφές θα εφαρμοστούν.",
"folders_to_tags.open_all": "Άνοιγμα όλων",
"folders_to_tags.title": "Δημιουργία ετικετών από φακέλους",
"generic.add": "Προσθήκη",
"generic.apply": "Εφαρμογή",
"generic.apply_alt": "&Εφαρμογή",
"generic.cancel": "Ακύρωση",
"generic.cancel_alt": "&Ακύρωση",
"generic.close": "Κλείσιμο",
"generic.continue": "Συνέχεια",
"generic.copy": "Αντιγραφή",
"generic.cut": "Αποκοπή",
"generic.delete": "Διαγραφή",
"generic.delete_alt": "&Διαγραφή",
"generic.done": "Τέλος",
"generic.done_alt": "&Τέλος",
"generic.edit": "Επεξεργασία",
"generic.edit_alt": "&Επεξεργασία",
"generic.filename": "Όνομα αρχείου",
"generic.missing": "Λείπει",
"generic.navigation.back": "Πίσω",
"generic.navigation.next": "Επόμενο",
"generic.no": "Όχι",
"generic.none": "Κανένα",
"generic.overwrite": "Αντικατάσταση",
"generic.overwrite_alt": "&Αντικατάσταση",
"generic.paste": "Επικόλληση",
"generic.recent_libraries": "Πρόσφατες βιβλιοθήκες",
"generic.remove": "Αφαίρεση",
"generic.remove_alt": "&Αφαίρεση",
"generic.rename": "Μετονομασία",
"generic.rename_alt": "&Μετονομασία",
"generic.reset": "Επαναφορά",
"generic.save": "Αποθήκευση",
"generic.skip": "Παράλειψη",
"generic.skip_alt": "&Παράλειψη",
"generic.yes": "Ναι",
"home.search": "Αναζήτηση",
"home.search_entries": "Αναζήτηση καταχωρίσεων",
"home.search_library": "Αναζήτηση στη βιβλιοθήκη",
"home.search_tags": "Αναζήτηση ετικετών",
"home.show_hidden_entries": "Εμφάνιση κρυφών καταχωρίσεων",
"home.thumbnail_size": "Μέγεθος μικρογραφιών",
"home.thumbnail_size.extra_large": "Πολύ μεγάλες μικρογραφίες",
"home.thumbnail_size.large": "Μεγάλες μικρογραφίες",
"home.thumbnail_size.medium": "Μεσαίες μικρογραφίες",
"home.thumbnail_size.mini": "Μίνι μικρογραφίες",
"home.thumbnail_size.small": "Μικρές μικρογραφίες",
"ignore.open_file": "Εμφάνιση του αρχείου \"{ts_ignore}\" στον δίσκο",
"json_migration.checking_for_parity": "Έλεγχος ισοτιμίας...",
"json_migration.creating_database_tables": "Δημιουργία πινάκων βάσης δεδομένων SQL...",
"json_migration.description": "<br>Εκκινήστε και προεπισκοπήστε τα αποτελέσματα της διαδικασίας μεταφοράς της βιβλιοθήκης. Η μετατραπείσα βιβλιοθήκη <i>δεν</i> θα χρησιμοποιηθεί εκτός αν κάνετε κλικ στο \"Ολοκλήρωση μεταφοράς\". <br><br>Τα δεδομένα της βιβλιοθήκης θα πρέπει είτε να έχουν τιμές που συμπίπτουν είτε να φέρουν την ετικέτα \"Αντιστοιχίστηκε\". Οι τιμές που δεν συμπίπτουν θα εμφανίζονται με κόκκινο χρώμα και θα φέρουν το σύμβολο \"<b>(!)</b>\" δίπλα τους.<br><center><i>Αυτή η διαδικασία μπορεί να διαρκέσει αρκετά λεπτά για μεγάλες βιβλιοθήκες.</i></center>",
"json_migration.discrepancies_found": "Βρέθηκαν ασυμφωνίες στη βιβλιοθήκη",
"json_migration.discrepancies_found.description": "Βρέθηκαν ασυμφωνίες μεταξύ της αρχικής και της μετατραπείσας μορφής της βιβλιοθήκης. Παρακαλούμε ελέγξτε και επιλέξτε αν θα συνεχίσετε με τη μεταφορά ή αν θα την ακυρώσετε.",
"json_migration.finish_migration": "Ολοκλήρωση μεταφοράς",
"json_migration.heading.aliases": "Ψευδώνυμα:",
"json_migration.heading.colors": "Χρώματα:",
"json_migration.heading.differ": "Ασυμφωνία",
"json_migration.heading.extension_list_type": "Τύπος λίστας επεκτάσεων:",
"json_migration.heading.file_extension_list": "Λίστα επεκτάσεων αρχείων:",
"json_migration.heading.match": "Αντιστοιχίστηκε",
"json_migration.heading.names": "Όνομα:"
}

View File

@@ -1,5 +1,5 @@
{
"about.config_path": "Ruta de configuración",
"about.config_path": "Ruta de Configuración",
"about.description": "TagStudio es una aplicación para organizar fotografías y archivos que utiliza un sistema de etiquetas subyacentes centrado en dar libertad y flexibilidad al usuario. Sin programas ni formatos propios, ni un mar de archivos y sin trastornar completamente la estructura de tu sistema de archivos.",
"about.documentation": "Documentación",
"about.license": "Licencia",
@@ -54,7 +54,7 @@
"entries.mirror.label": "Reflejando {idx}/{total} Entradas...",
"entries.mirror.title": "Reflejando entradas",
"entries.mirror.window_title": "Reflejar entradas",
"entries.remove.plural.confirm": "¿Está seguro de que desea eliminar las siguientes {count} entradas?",
"entries.remove.plural.confirm": "¿Está seguro de que desea eliminar estas <b>{count}</b> entradas de su librería? No se eliminará ningún archivo del disco.",
"entries.remove.singular.confirm": "¿Está seguro que quiere eliminar ésta entrada de su librería? Ningún archivo en el disco será eliminado.",
"entries.running.dialog.new_entries": "Añadiendo {total} nuevas entradas de archivos...",
"entries.running.dialog.title": "Añadiendo las nuevas entradas de archivos",
@@ -140,6 +140,7 @@
"home.search_entries": "Buscar entradas",
"home.search_library": "Buscar el biblioteca",
"home.search_tags": "Buscar etiquetas",
"home.show_hidden_entries": "Mostrar entradas ocultas",
"home.thumbnail_size": "Tamaño de la vista previa",
"home.thumbnail_size.extra_large": "Imágenes extra grandes",
"home.thumbnail_size.large": "Imágenes grandes",
@@ -206,8 +207,8 @@
"macros.running.dialog.title": "Ejecución de macros en entradas nuevas",
"media_player.autoplay": "Reproducción automática",
"media_player.loop": "Bucle",
"menu.delete_selected_files_ambiguous": "Mover archivo(s) a la {trash_term}",
"menu.delete_selected_files_plural": "Mover archivos a la {trash_term}",
"menu.delete_selected_files_ambiguous": "Mover Archivo(s) a la {trash_term}",
"menu.delete_selected_files_plural": "Mover Archivos a la {trash_term}",
"menu.delete_selected_files_singular": "Mover archivo a la {trash_term}",
"menu.edit": "Editar",
"menu.edit.ignore_files": "Ignorar archivos y carpetas",
@@ -217,13 +218,13 @@
"menu.file.clear_recent_libraries": "Borrar recientes",
"menu.file.close_library": "&Cerrar biblioteca",
"menu.file.missing_library.message": "La ubicación de la biblioteca \"{library}\" no se ha podido encontrar.",
"menu.file.missing_library.title": "Biblioteca desaparecida",
"menu.file.missing_library.title": "Librería No Encontrada",
"menu.file.new_library": "Nueva biblioteca",
"menu.file.open_backups_folder": "Abrir Carpeta de Respaldos",
"menu.file.open_create_library": "&Abrir/Crear biblioteca",
"menu.file.open_library": "Abrir biblioteca",
"menu.file.open_recent_library": "Abrir reciente",
"menu.file.refresh_directories": "&Actualizar directorios",
"menu.file.refresh_directories": "Actualizar directorios",
"menu.file.save_backup": "&Guardar copia de seguridad de la biblioteca",
"menu.file.save_library": "Guardar biblioteca",
"menu.help": "&Ayuda",
@@ -288,7 +289,7 @@
"settings.theme.label": "Tema:",
"settings.theme.light": "Claro",
"settings.theme.system": "Sistema",
"settings.thumb_cache_size.label": "Tamaño cache de miniaturas",
"settings.thumb_cache_size.label": "Tamaño de la caché de miniaturas",
"settings.title": "Ajustes",
"settings.zeropadding.label": "Rellenar ceros en fechas",
"sorting.direction.ascending": "Ascendiente",
@@ -325,6 +326,7 @@
"tag.disambiguation.tooltip": "Utiliza esta etiqueta para desambiguar",
"tag.edit": "Editar etiqueta",
"tag.is_category": "Es categoría",
"tag.is_hidden": "Está oculto",
"tag.name": "Nombre",
"tag.new": "Nueva etiqueta",
"tag.parent_tags": "Etiquetas principales",
@@ -348,6 +350,9 @@
"trash.dialog.title.singular": "Eliminar archivo",
"trash.name.generic": "Basura",
"trash.name.windows": "Papelera de reciclaje",
"version_modal.description": "¡Ya está disponible una nueva versión de TagStudio! Puedes descargar la última versión desde <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">Github</a>.",
"version_modal.status": "Versión Instalada: {installed_version}<br>Última Versión Publicada: {latest_release_version}",
"version_modal.title": "Actualización de TagStudio disponible",
"view.size.0": "Mini",
"view.size.1": "Pequeño",
"view.size.2": "Medio",

View File

@@ -140,6 +140,7 @@
"home.search_entries": "Recherche",
"home.search_library": "Rechercher dans la Bibliothèque",
"home.search_tags": "Recherche de Tags",
"home.show_hidden_entries": "Afficher les entrées cachées",
"home.thumbnail_size": "Taille de la miniature",
"home.thumbnail_size.extra_large": "Très Grandes Miniatures",
"home.thumbnail_size.large": "Grandes Miniatures",
@@ -325,6 +326,7 @@
"tag.disambiguation.tooltip": "Utilisez ce Tag pour définir une ambiguïté",
"tag.edit": "Modifier un Tag",
"tag.is_category": "Est une Catégorie",
"tag.is_hidden": "Est cachée",
"tag.name": "Nom",
"tag.new": "Nouveau Tag",
"tag.parent_tags": "Tags Parent",
@@ -348,6 +350,9 @@
"trash.dialog.title.singular": "Supprimer le Fichier",
"trash.name.generic": "Poubelle",
"trash.name.windows": "Corbeille",
"version_modal.description": "Une nouvelle version de TagStudio est disponible! Vous pouvez télécharger la version la plus récente sur <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">Github</a>.",
"version_modal.status": "Version installer : {installed_version}<br>Dernière version disponible : {latest_release_version}",
"version_modal.title": "Mise à jour de TagStudio disponible",
"view.size.0": "Mini",
"view.size.1": "Petit",
"view.size.2": "Moyen",

View File

@@ -33,7 +33,7 @@
"drop_import.progress.window_title": "Fájlok importálása",
"drop_import.title": "Fájlütközés",
"edit.color_manager": "&Színek kezelése",
"edit.copy_fields": "Mezők &másolása",
"edit.copy_fields": "Mezők másolása",
"edit.paste_fields": "Mezők &beillesztése",
"edit.tag_manager": "Címkék kezelése",
"entries.duplicate.merge": "Egyező elemek &egyesítése",
@@ -212,7 +212,7 @@
"menu.delete_selected_files_singular": "Fájl {trash_term} &helyezése",
"menu.edit": "S&zerkesztés",
"menu.edit.ignore_files": "Fájlok és mappák figyelmen kívül hagyása",
"menu.edit.manage_tags": "&Címkék ke&zelése",
"menu.edit.manage_tags": "Címkék kezelése",
"menu.edit.new_tag": "Ú&j címke",
"menu.file": "&Fájl",
"menu.file.clear_recent_libraries": "&Legutóbbi könyvtárak listájának törlése",
@@ -350,6 +350,9 @@
"trash.dialog.title.singular": "Fájl törlése",
"trash.name.generic": "kukába",
"trash.name.windows": "lomtárba",
"version_modal.description": "Elérhetővé vált egy TagStudio-frissítés. A legújabb verziót a <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">Githubról</a> töltheti le.",
"version_modal.status": "Telepített verzió: {installed_version}<br>Legújabb stabil verzió: {latest_release_version}",
"version_modal.title": "TagStudio-frissítés",
"view.size.0": "Apró",
"view.size.1": "Kicsi",
"view.size.2": "Közepes",

View File

@@ -0,0 +1,42 @@
{
"about.config_path": "Stillingarslóð",
"about.description": "TagStudio er forrit sem skipuleggur og heldur utan um myndir og skrár í gegnum merkja kerfi, sem einblínir á frelsi og sveigjanleika fyrir notandann. Enginn séreigna-hugbúnaður eða skráarsnið, engar aukaskrár, og engin enduruppröðun á skráarkerfinu þínu í heild.",
"about.documentation": "Skjölun",
"about.license": "Leyfi",
"about.module.found": "Fannst",
"about.title": "Um TagStudio",
"about.website": "Vefsíða",
"app.git": "Git Commit",
"app.pre_release": "Forútgáfa",
"app.title": "{base_title} - Safn '{library_dir}'",
"color.color_border": "Nota aukalit fyrir jaðar",
"color.confirm_delete": "Ertu viss um að þú viljir eyða litnum \"{color_name}\"?",
"color.delete": "Eyða Merki",
"color.import_pack": "Flytja inn Litapakka",
"color.name": "Nafn",
"color.namespace.delete.prompt": "Ertu viss um að þú viljir eyða þessu litanafnrými? Þetta mun eyða ÖLLUM litum sem deila því nafnrými!",
"color.namespace.delete.title": "Eyða Litanafnrými",
"color.new": "Nýr Litur",
"color.placeholder": "Litur",
"color.primary": "Aðal Litur",
"color.primary_required": "Aðal Litur (Nauðsynlegt)",
"color.secondary": "Aukalitur",
"color.title.no_color": "Enginn Litur",
"color_manager.title": "Stjórna litum Merkja",
"dependency.missing.title": "{dependency} Fannst Ekki",
"drop_import.description": "Eftirfarandi skrár passa við skráarslóðir sem eru nú þegar í safninu",
"drop_import.duplicates_choice.plural": "Eftirfarandi {count} skrár passa við skráarslóðir sem eru þegar til í safninu.",
"drop_import.duplicates_choice.singular": "Eftirfarandi skrá passar við skráarslóð sem er þegar til í safninu.",
"drop_import.progress.label.initial": "Flyt inn nýjar skrár...",
"drop_import.progress.label.plural": "Flyt inn nýjar skrár...\n{count} Skrár fluttar inn.{suffix}",
"drop_import.progress.label.singular": "Flyt inn nýjar skrár...\n1 Skrá flutt inn.{suffix}",
"drop_import.progress.window_title": "Flytja inn Skrár",
"drop_import.title": "Áreksur Skráa(r)",
"edit.color_manager": "Stjórna litum Merkja",
"edit.copy_fields": "Afrita Reiti",
"edit.paste_fields": "Líma Reiti",
"edit.tag_manager": "Stjórna Merkjum",
"entries.duplicate.merge": "Sameina tvífaldar skráningar",
"entries.duplicate.merge.label": "Sameina tvífaldar skráningar...",
"entries.duplicate.refresh": "Endurhlaða tvíföldum skráningum"
}

View File

@@ -140,6 +140,7 @@
"home.search_entries": "Cerca Voci",
"home.search_library": "Cerca Biblioteca",
"home.search_tags": "Cerca Etichette",
"home.show_hidden_entries": "Mostra Voci Nascoste",
"home.thumbnail_size": "Dimensione Miniature",
"home.thumbnail_size.extra_large": "Miniature Molto Grandi",
"home.thumbnail_size.large": "Miniature Grandi",
@@ -223,7 +224,7 @@
"menu.file.open_create_library": "&Apri/Crea Biblioteca",
"menu.file.open_library": "Apri Biblioteca",
"menu.file.open_recent_library": "Apri Recenti",
"menu.file.refresh_directories": "&Aggiorna Cartelle",
"menu.file.refresh_directories": "Aggiorna Cartelle",
"menu.file.save_backup": "&Salva Backup della Biblioteca",
"menu.file.save_library": "Salva Biblioteca",
"menu.help": "&Aiuto",
@@ -325,6 +326,7 @@
"tag.disambiguation.tooltip": "Usa questa etichetta per la disambiguazione",
"tag.edit": "Modifica Etichetta",
"tag.is_category": "È Categoria",
"tag.is_hidden": "È Nascosta",
"tag.name": "Nome",
"tag.new": "Nuova Etichetta",
"tag.parent_tags": "Etichette Genitore",
@@ -348,6 +350,9 @@
"trash.dialog.title.singular": "Elimina File",
"trash.name.generic": "Spazzatura",
"trash.name.windows": "Cestino",
"version_modal.description": "Una nuova versione di TagStudio è disponibile! Puoi scaricare l'ultima versione da <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">Github</a>.",
"version_modal.status": "Versione Installata: {installed_version}<br>Ultima Versione Rilasciata: {latest_release_version}",
"version_modal.title": "Aggiornamento di TagStudio Disponibile",
"view.size.0": "Mini",
"view.size.1": "Piccolo",
"view.size.2": "Medio",

View File

@@ -350,6 +350,9 @@
"trash.dialog.title.singular": "ファイルの削除",
"trash.name.generic": "ごみ箱",
"trash.name.windows": "ごみ箱",
"version_modal.description": "TagStudio の新しいバージョンが利用できます。<a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">GitHub</a> から最新リリースをダウンロードできます。",
"version_modal.status": "インストール済みのバージョン: {installed_version}<br>最新リリースのバージョン: {latest_release_version}",
"version_modal.title": "TagStudio の更新があります",
"view.size.0": "極小",
"view.size.1": "小",
"view.size.2": "中",

View File

@@ -195,7 +195,7 @@
"menu.edit.new_tag": "Ny &Etikett",
"menu.file": "Fil",
"menu.file.clear_recent_libraries": "Fjern Nylige",
"menu.file.close_library": "&Lukk Bibliotek",
"menu.file.close_library": "Lukk Bibliotek",
"menu.file.missing_library.message": "Plasseringen til biblioteket \"{library}\" kan ikke finnes.",
"menu.file.missing_library.title": "Manglende Bibliotek",
"menu.file.new_library": "Nytt Bibliotek",
@@ -212,7 +212,7 @@
"menu.select": "Velg",
"menu.settings": "Innstillinger...",
"menu.tools": "Verktøy",
"menu.tools.fix_duplicate_files": "Fiks Duplikate &Filer",
"menu.tools.fix_duplicate_files": "Fiks Duplikate Filer",
"menu.tools.fix_unlinked_entries": "Fiks &Frakoblede Oppføringer",
"menu.view": "&Se",
"menu.window": "Vindu",

View File

@@ -7,8 +7,10 @@
"about.website": "Website",
"app.git": "Git Commit",
"app.pre_release": "Pre-Release",
"color.color_border": "Gebruik Secundaire Kleur voor Rand",
"color.confirm_delete": "Weet u zeker dat u de kleur \"{color_name}\" wilt verwijderen?",
"color.delete": "Verwijder Label",
"color.import_pack": "Importeer Kleurenpakket",
"color.name": "Naam",
"color.new": "Nieuwe Kleur",
"color.placeholder": "Kleur",
@@ -22,10 +24,13 @@
"drop_import.progress.label.plural": "Nieuwe bestanden importeren…\n{count} bestanden geïmporteerd.{suffix}",
"drop_import.progress.label.singular": "Nieuwe bestanden importeren…\n1 bestand geïmporteerd.{suffix}",
"drop_import.progress.window_title": "Importeer bestanden",
"drop_import.title": "Conflicterende bestand(en)",
"edit.color_manager": "Beheer Label Kleuren",
"edit.copy_fields": "Velden Kopiëren",
"edit.paste_fields": "Velden Plakken",
"edit.tag_manager": "Beheer Labels",
"entries.duplicate.merge": "Dubbele Vermeldingen Samenvoegen",
"entries.duplicate.merge.label": "Dubbele vermeldingen samenvoegen...",
"entries.tags": "Labels",
"field.copy": "Veld Kopiëren",
"field.edit": "Veld Aanpassen",

View File

@@ -181,14 +181,14 @@
"menu.edit.new_tag": "Nowy &Tag",
"menu.file": "&Plik",
"menu.file.clear_recent_libraries": "Wyczyść ostatnie",
"menu.file.close_library": "&Zamknij bibliotekę",
"menu.file.close_library": "Zamknij bibliotekę",
"menu.file.missing_library.message": "Lokalizacja biblioteki \"{library}\" nie została odnaleziona.",
"menu.file.missing_library.title": "Brakująca biblioteka",
"menu.file.new_library": "Nowa biblioteka",
"menu.file.open_create_library": "&Otwórz/Stwórz bibliotekę",
"menu.file.open_library": "Otwórz bibliotekę",
"menu.file.open_recent_library": "Otwórz ostatnie",
"menu.file.refresh_directories": "&Odśwież katalogi",
"menu.file.refresh_directories": "Odśwież katalogi",
"menu.file.save_backup": "&Zapisz kopię zapasową biblioteki",
"menu.file.save_library": "Zapisz bibliotekę",
"menu.help": "&Pomoc",

View File

@@ -181,7 +181,7 @@
"menu.file.open_create_library": "&Abrir/Criar Biblioteca",
"menu.file.open_library": "Abrir Biblioteca",
"menu.file.open_recent_library": "Abrir Recente",
"menu.file.refresh_directories": "&Atualizar Pastas",
"menu.file.refresh_directories": "Atualizar Pastas",
"menu.file.save_backup": "&Gravar Backup da Biblioteca",
"menu.file.save_library": "Gravar Biblioteca",
"menu.help": "&Ajuda",

View File

@@ -140,6 +140,7 @@
"home.search_entries": "Buscar Registros",
"home.search_library": "Buscar na Biblioteca",
"home.search_tags": "Buscar Tags",
"home.show_hidden_entries": "Mostrar Itens Ocultos",
"home.thumbnail_size": "Tamanho de miniatura",
"home.thumbnail_size.extra_large": "Miniaturas Extra Grandes",
"home.thumbnail_size.large": "Miniaturas Grandes",
@@ -223,7 +224,7 @@
"menu.file.open_create_library": "&Abrir/Criar Biblioteca",
"menu.file.open_library": "Abrir Biblioteca",
"menu.file.open_recent_library": "Abrir Recente",
"menu.file.refresh_directories": "&Atualizar Pastas",
"menu.file.refresh_directories": "Atualizar Pastas",
"menu.file.save_backup": "&Salvar Backup da Biblioteca",
"menu.file.save_library": "Salvar Biblioteca",
"menu.help": "&Ajuda",
@@ -274,6 +275,7 @@
"settings.restart_required": "Por favor reinicie o TagStudio para que as mudanças façam efeito.",
"settings.show_filenames_in_grid": "Exibir nome dos arquivos",
"settings.show_recent_libraries": "Mostrar Bibliotecas Recentes",
"settings.splash.label": "Tela Inicial",
"settings.splash.option.classic": "Clássico (9.0)",
"settings.splash.option.default": "Padrão",
"settings.splash.option.goo_gears": "Código Aberto (9.4)",
@@ -322,12 +324,15 @@
"tag.disambiguation.tooltip": "Use esta etiqueta para desambiguação",
"tag.edit": "Editar Tag",
"tag.is_category": "É Categoria",
"tag.is_hidden": "Está Oculto",
"tag.name": "Nome",
"tag.new": "Nova Tag",
"tag.parent_tags": "Tags Pai",
"tag.parent_tags.add": "Adicionar Tag Pai",
"tag.remove": "Remover Tag",
"tag.search_for_tag": "Procurar por Tag",
"tag.shorthand": "Abreviação",
"tag.tag_name_required": "Nome da Tag (Obrigatório)",
"tag.view_limit": "Limite de visualização:",
"tag_manager.title": "Tags da sua biblioteca",
"trash.context.ambiguous": "Mover arquivo(s) para {trash_term}",

View File

@@ -195,7 +195,7 @@
"menu.file.open_create_library": "&Открыть/создать библиотеку",
"menu.file.open_library": "Открыть библиотеку",
"menu.file.open_recent_library": "Открыть последнюю",
"menu.file.refresh_directories": "&Обновить папки",
"menu.file.refresh_directories": "Обновить папки",
"menu.file.save_backup": "&Сохранить резервную копию библиотеки",
"menu.file.save_library": "Сохранить библиотеку",
"menu.help": "&Помощь",

View File

@@ -1,10 +1,10 @@
{
"about.config_path": "கட்டமைப்பு பாதை",
"about.description": "டேக்ச்டுடியோ என்பது ஒரு புகைப்படம் மற்றும் கோப்பு அமைப்பு பயன்பாடாகும், இது பயனருக்கு விடுதலை மற்றும் நெகிழ்வுத்தன்மையை வழங்குவதில் கவனம் செலுத்துகிறது. தனியுரிம திட்டங்கள் அல்லது வடிவங்கள் இல்லை, பக்கவாட்டு கோப்புகளின் கடல் இல்லை, உங்கள் கோப்பு முறைமை கட்டமைப்பின் முழுமையான எழுச்சி இல்லை.",
"about.description": "முகவரிச்சீட்டுஅறை என்பது ஒரு புகைப்படம் மற்றும் கோப்பு அமைப்பு பயன்பாடாகும், இது பயனருக்கு விடுதலை மற்றும் நெகிழ்வுத்தன்மையை வழங்குவதில் கவனம் செலுத்துகிறது. தனியுரிம திட்டங்கள் அல்லது வடிவங்கள் இல்லை, பக்கவாட்டு கோப்புகளின் கடல் இல்லை, உங்கள் கோப்பு முறைமை கட்டமைப்பின் முழுமையான எழுச்சி இல்லை.",
"about.documentation": "ஆவணங்கள்",
"about.license": "உரிமம்",
"about.module.found": "காணப்பட்டது",
"about.title": "டேக்ச்டுடியோ பற்றி",
"about.title": "முகவரிச்சீட்டுஅறை பற்றி",
"about.website": "வலைத்தளம்",
"app.git": "அறிவிலி கமிட்",
"app.pre_release": "முன் வெளியீடு",
@@ -39,7 +39,7 @@
"entries.duplicate.merge": "நகல் உள்ளீடுகளை ஒன்றிணைக்கவும்",
"entries.duplicate.merge.label": "நகல் உள்ளீடுகளை ஒன்றிணைத்தல் ...",
"entries.duplicate.refresh": "நகல் உள்ளீடுகளைப் புதுப்பி",
"entries.duplicates.description": "மறுநுழைவுகள் என்பது, ஒரே கோப்பை குறிக்கும் பல நுழைவுகளை குறிக்கும். இவற்றை இணைப்பதால், அனைத்து மறுநுழைவுகளின் குறிச்சொற்களும் மெட்டாடேட்டாவும் ஒரே ஒட்டுமொத்த நுழைவாகச் சேர்க்கப்படும். இவற்றை 'மறுகோப்புகள்' என்பதுடன் குழப்பக் கூடாது, ஏனெனில் அவை டாக் ஸ்டுடியோவுக்கு வெளியேயுள்ள கோப்புகளின் நகல்களாகும்.",
"entries.duplicates.description": "மறுநுழைவுகள் என்பது, ஒரே கோப்பை குறிக்கும் பல நுழைவுகளை குறிக்கும். இவற்றை இணைப்பதால், அனைத்து மறுநுழைவுகளின் குறிச்சொற்களும் மெட்டாடேட்டாவும் ஒரே ஒட்டுமொத்த நுழைவாகச் சேர்க்கப்படும். இவற்றை 'மறுகோப்புகள்' என்பதுடன் குழப்பக் கூடாது, ஏனெனில் அவை முகவரிச்சீட்டுஅறைக்கு வெளியேயுள்ள கோப்புகளின் நகல்களாகும்.",
"entries.generic.refresh_alt": "&புதுப்பி",
"entries.generic.remove.removing": "உள்ளீடுகள் நீக்கப்படுகிறது",
"entries.generic.remove.removing_count": "{count} உள்ளீடுகளை நீக்குகிறது...",
@@ -59,7 +59,7 @@
"entries.running.dialog.new_entries": "{total} புதிய கோப்பு உள்ளீடுகளைச் சேர்ப்பது ...",
"entries.running.dialog.title": "புதிய கோப்பு உள்ளீடுகளைச் சேர்ப்பது",
"entries.tags": "குறிச்சொற்கள்",
"entries.unlinked.description": "ஒவ்வொரு நூலக நுழைவும் உங்கள் கோப்பகங்களில் ஒன்றில் ஒரு கோப்போடு இணைக்கப்பட்டுள்ளது. ஒரு நுழைவுடன் இணைக்கப்பட்ட ஒரு கோப்பு டாக்ச்டுடியோவுக்கு வெளியே நகர்த்தப்பட்டால் அல்லது நீக்கப்பட்டால், அது பின்னர் இணைக்கப்படாததாகக் கருதப்படுகிறது.",
"entries.unlinked.description": "ஒவ்வொரு நூலக நுழைவும் உங்கள் கோப்பகங்களில் ஒன்றில் ஒரு கோப்போடு இணைக்கப்பட்டுள்ளது. ஒரு நுழைவுடன் இணைக்கப்பட்ட ஒரு கோப்பு முகவரிச்சீட்டுஅறைக்கு வெளியே நகர்த்தப்பட்டால் அல்லது நீக்கப்பட்டால், அது பின்னர் இணைக்கப்படாததாகக் கருதப்படுகிறது.",
"entries.unlinked.relink.attempting": "{index}/{unlinked_count} உள்ளீடுகளை மீண்டும் இணைக்க முயற்சிக்கிறது, {fixed_count} மீண்டும் இணைக்கப்பட்டது",
"entries.unlinked.relink.manual": "& கையேடு மறுபரிசீலனை",
"entries.unlinked.relink.title": "உள்ளீடுகள் மீண்டும் இணைக்கப்படுகின்றது",
@@ -78,8 +78,8 @@
"file.date_created": "உருவாக்கப்பட்ட தேதி",
"file.date_modified": "மாற்றப்பட்ட தேதி",
"file.dimensions": "பரிமாணங்கள்",
"file.duplicates.description": "நகல் கோப்புகளை நிர்வகிக்க டுபெகுரு முடிவுகளை இறக்குமதி செய்வதை டேக்ச்டுடியோ ஆதரிக்கிறது.",
"file.duplicates.dupeguru.advice": "படிமம் முடிந்தவுடன், தேவையற்ற கோப்புகளை நீக்க DupeGuru ஐ பயன்படுத்தலாம். அதற்குப் பிறகு, இணைக்காத நுழைவுகளை நீக்க 'டாக் ஸ்டுடியோ' ின் 'இணைக்கப்படாத உள்ளீடுகளைச் சரிசெய்' அம்சத்தைக் கருவிகள் பட்டியில் பயன்படுத்தவும்.",
"file.duplicates.description": "நகல் கோப்புகளை நிர்வகிக்க டுபெகுரு முடிவுகளை இறக்குமதி செய்வதை முகவரிச்சீட்டுஅறை ஆதரிக்கிறது.",
"file.duplicates.dupeguru.advice": "படிமம் முடிந்தவுடன், தேவையற்ற கோப்புகளை நீக்க DupeGuru ஐ பயன்படுத்தலாம். அதற்குப் பிறகு, இணைக்காத நுழைவுகளை நீக்க 'முகவரிச்சீட்டுஅறை' ின் 'இணைக்கப்படாத உள்ளீடுகளைச் சரிசெய்' அம்சத்தைக் கருவிகள் பட்டியில் பயன்படுத்தவும்.",
"file.duplicates.dupeguru.file_extension": "DupeGuru கோப்புகள் (*.dupeguru)",
"file.duplicates.dupeguru.load_file": "& டுபெகுரு கோப்பை ஏற்றவும்",
"file.duplicates.dupeguru.no_file": "DupeGuru கோப்பு எதுவும் தேர்ந்தெடுக்கப்படவில்லை",
@@ -140,6 +140,7 @@
"home.search_entries": "தேடல் உள்ளீடுகள்",
"home.search_library": "தேடல் நூலகம்",
"home.search_tags": "குறிச்சொற்களைத் தேடு",
"home.show_hidden_entries": "மறைக்கப்பட்ட உள்ளீடுகளைக் காட்டு",
"home.thumbnail_size": "சின்னப்பட அளவு",
"home.thumbnail_size.extra_large": "கூடுதல் பெரிய சிறு உருவங்கள்",
"home.thumbnail_size.large": "பெரிய சிறு உருவங்கள்",
@@ -163,7 +164,7 @@
"json_migration.heading.parent_tags": "பெற்றோர் குறிச்சொற்கள்:",
"json_migration.heading.paths": "பாதைகள்:",
"json_migration.heading.shorthands": "சுருக்கெழுத்து:",
"json_migration.info.description": "டேக்ச்டுடியோ பதிப்புகளுடன் உருவாக்கப்பட்ட கோப்புகளை நூலகம் சேமிக்கவும் <b> 9.4 மற்றும் கீழே </b> புதிய <b> v9.5+</b> வடிவத்திற்கு இடம்பெயர வேண்டும். <b> <i> இல்லை </i> </b> நீக்கப்பட வேண்டும், நகர்த்தப்படும் அல்லது மாற்றியமைக்கப்பட வேண்டும் </li> <li> புதிய V9.5+ சேமிக்கும் வடிவமைப்பை டேக்ச்டுடியோவின் முந்தைய பதிப்புகளில் திறக்க முடியாது </li> </ul> <h3> என்ன மாற்றப்பட்டுள்ளது: </h3> <ul> <li> \"குறிச்சொற்கள்\" குறிச்சொற்களால் மாற்றப்பட்டுள்ளன. முதலில் புலங்களில் குறிச்சொற்களைச் சேர்ப்பதற்கு பதிலாக, குறிச்சொற்கள் இப்போது கோப்பு உள்ளீடுகளில் நேரடியாக சேர்க்கப்படுகின்றன. குறிச்சொல் திருத்துதல் பட்டியலில் புதிய \"வகை\" சொத்துடன் குறிக்கப்பட்ட பெற்றோர் குறிச்சொற்களின் அடிப்படையில் அவை தானாகவே வகைகளாக ஒழுங்கமைக்கப்படுகின்றன. எந்தவொரு குறிச்சொல்லையும் ஒரு வகையாகக் குறிக்க முடியும், மேலும் குழந்தை குறிச்சொற்கள் வகைகளாக குறிக்கப்பட்ட பெற்றோர் குறிச்சொற்களுக்கு அடியில் தங்களை வரிசைப்படுத்தும். \"பிடித்த\" மற்றும் \"காப்பகப்படுத்தப்பட்ட\" குறிச்சொற்கள் இப்போது ஒரு புதிய \"மேவு குறிச்சொற்கள்\" குறிச்சொல்லிலிருந்து பெறப்படுகின்றன, இது இயல்புநிலையாக ஒரு வகையாக குறிக்கப்பட்டுள்ளது. </Li> <li> குறிச்சொல் வண்ணங்கள் மாற்றப்பட்டு விரிவாக்கப்பட்டுள்ளன. சில வண்ணங்கள் மறுபெயரிடப்பட்டுள்ளன அல்லது ஒருங்கிணைக்கப்பட்டுள்ளன, இருப்பினும் எல்லா குறிச்சொல் வண்ணங்களும் V9.5 இல் உள்ள சரியான அல்லது நெருக்கமான போட்டிகளாக மாறும். </Li> </ul> <ul>",
"json_migration.info.description": "முகவரிச்சீட்டுஅறை பதிப்புகளுடன் உருவாக்கப்பட்ட கோப்புகளை நூலகம் சேமி <b> 9.4 மற்றும் கீழே </b> புதிய <b> v9.5+</b> வடிவத்திற்கு இடம்பெயர வேண்டும். <b> <i> இல்லை </i> </b> நீக்கப்பட வேண்டும், நகர்த்தப்படும் அல்லது மாற்றியமைக்கப்பட வேண்டும் </li> <li> புதிய V9.5+ சேமிக்கும் வடிவமைப்பை முகவரிச்சீட்டுஅறையின் முந்தைய பதிப்புகளில் திறக்க முடியாது </li> </ul> <h3> என்ன மாற்றப்பட்டுள்ளது: </h3> <ul> <li> \"குறிச்சொற்கள்\" குறிச்சொற்களால் மாற்றப்பட்டுள்ளன. முதலில் புலங்களில் குறிச்சொற்களைச் சேர்ப்பதற்கு பதிலாக, குறிச்சொற்கள் இப்போது கோப்பு உள்ளீடுகளில் நேரடியாகச் சேர்க்கப்படுகின்றன. குறிச்சொல் திருத்துதல் பட்டியலில் புதிய \"வகை\" சொத்துடன் குறிக்கப்பட்ட பெற்றோர் குறிச்சொற்களின் அடிப்படையில் அவை தானாகவே வகைகளாக ஒழுங்கமைக்கப்படுகின்றன. எந்தவொரு குறிச்சொல்லையும் ஒரு வகையாகக் குறிக்க முடியும், மேலும் குழந்தை குறிச்சொற்கள் வகைகளாகக் குறிக்கப்பட்ட பெற்றோர் குறிச்சொற்களுக்கு அடியில் தங்களை வரிசைப்படுத்தும். \"பிடித்த\" மற்றும் \"காப்பகப்படுத்தப்பட்ட\" குறிச்சொற்கள் இப்போது ஒரு புதிய \"மேவு குறிச்சொற்கள்\" குறிச்சொல்லிலிருந்து பெறப்படுகின்றன, இது இயல்புநிலையாக ஒரு வகையாகக் குறிக்கப்பட்டுள்ளது. </li> <li> குறிச்சொல் வண்ணங்கள் மாற்றப்பட்டு விரிவாக்கப்பட்டுள்ளன. சில வண்ணங்கள் மறுபெயரிடப்பட்டுள்ளன அல்லது ஒருங்கிணைக்கப்பட்டுள்ளன, இருப்பினும் எல்லா குறிச்சொல் வண்ணங்களும் V9.5 இல் உள்ள சரியான அல்லது நெருக்கமான போட்டிகளாக மாறும். </li> </ul> <ul>",
"json_migration.migrating_files_entries": "இடம்பெயர்வு {entries:,d} கோப்பு உள்ளீடுகள் ...",
"json_migration.migration_complete": "இடம்பெயர்வு முடிந்தது!",
"json_migration.migration_complete_with_discrepancies": "இடம்பெயர்வு முடிந்தது, முரண்பாடுகள் காணப்படுகின்றன",
@@ -215,7 +216,7 @@
"menu.edit.new_tag": "புதிய & குறிச்சொல்",
"menu.file": "கோப்பு (&f)",
"menu.file.clear_recent_libraries": "சமீபத்தியதை அழிக்கவும்",
"menu.file.close_library": "& நூலகம் மூடு",
"menu.file.close_library": " நூலகம் மூடு",
"menu.file.missing_library.message": "\"{library}\" நூலகத்தின் இருப்பிடத்தைக் கண்டுபிடிக்க முடியாது.",
"menu.file.missing_library.title": "நூலகம் இல்லை",
"menu.file.new_library": "புதிய நூலகம்",
@@ -224,7 +225,7 @@
"menu.file.open_library": "திறந்த நூலகம்",
"menu.file.open_recent_library": "அண்மைக் கால திறப்பு",
"menu.file.refresh_directories": "கோப்பகத்தை புதுப்பிக்கவும்",
"menu.file.save_backup": "& நூலக காப்புப்பிரதியை சேமிக்கவும்",
"menu.file.save_backup": " நூலக காப்புப்பிரதியை சேமிக்கவும்",
"menu.file.save_library": "நூலகத்தை சேமிக்கவும்",
"menu.help": "உதவி (&h)",
"menu.help.about": "பற்றி",
@@ -241,7 +242,7 @@
"menu.view.increase_thumbnail_size": "சிறுபடத்தின் அளவை அதிகரிக்கவும்",
"menu.view.library_info": "நூலகம் &தகவல்",
"menu.window": "சாளரம்",
"namespace.create.description": "குறிச்சொற்கள் மற்றும் வண்ணங்கள் போன்ற பொருட்களின் குழுக்களை ஏற்றுமதி செய்வதற்கும் பகிர்வதற்கும் எளிதாக்கும் வகையில் பிரிக்கப்படுவதற்கு பெயர்வெளிகள் டேக்ச்டுடியோவால் பயன்படுத்தப்படுகின்றன. \"டேக்ச்டுடியோ\" உடன் தொடங்கும் பெயர்வெளிகள் உள் பயன்பாட்டிற்காக டேக்ச்டுடியோவால் ஒதுக்கப்பட்டுள்ளன.",
"namespace.create.description": "குறிச்சொற்கள் மற்றும் வண்ணங்கள் போன்ற பொருட்களின் குழுக்களை ஏற்றுமதி செய்வதற்கும் பகிர்வதற்கும் எளிதாக்கும் வகையில் பிரிக்கப்படுவதற்கு பெயர்வெளிகள் முகவரிச்சீட்டுஅறையால் பயன்படுத்தப்படுகின்றன. \"முகவரிச்சீட்டுஅறை\" உடன் தொடங்கும் பெயர்வெளிகள் உள் பயன்பாட்டிற்காக முகவரிச்சீட்டுஅறையால் ஒதுக்கப்பட்டுள்ளன.",
"namespace.create.description_color": "குறிச்சொல் வண்ணங்கள் பெயர்வெளிகளை வண்ணத் தட்டு குழுக்களாகப் பயன்படுத்துகின்றன. அனைத்து தனிப்பயன் வண்ணங்களும் முதலில் ஒரு பெயர்வெளி குழுவின் கீழ் இருக்க வேண்டும்.",
"namespace.create.title": "பெயர்வெளியை உருவாக்கவும்",
"namespace.new.button": "புதிய பெயர்வெளி",
@@ -271,7 +272,7 @@
"settings.library": "நூலக அமைப்புகள்",
"settings.open_library_on_start": "தொடக்கத்தில் நூலகத்தைத் திறக்கவும்",
"settings.page_size": "பக்க அளவு",
"settings.restart_required": "மாற்றங்கள் நடைமுறைக்கு வருவதற்கு டேக்ச்டுடியோவை மறுதொடக்கம் செய்யுங்கள்.",
"settings.restart_required": "மாற்றங்கள் நடைமுறைக்கு வருவதற்கு முகவரிச்சீட்டுஅறையை மறுதொடக்கம் செய்.",
"settings.show_filenames_in_grid": "கட்டத்தில் கோப்பு பெயர்களைக் காட்டு",
"settings.show_recent_libraries": "அண்மைக் கால நூலகங்களைக் காட்டு",
"settings.splash.label": "ச்பிளாச் திரை",
@@ -325,6 +326,7 @@
"tag.disambiguation.tooltip": "இந்த குறிச்சொல்லைப் பயன்படுத்தவும்",
"tag.edit": "குறிச்சொல்லைத் திருத்து",
"tag.is_category": "வகை",
"tag.is_hidden": "மறைக்கப்பட்டுள்ளது",
"tag.name": "பெயர்",
"tag.new": "புதிய குறிச்சொல்",
"tag.parent_tags": "பெற்றோர் குறிச்சொற்கள்",
@@ -339,8 +341,8 @@
"trash.context.ambiguous": "கோப்புகளை நகர்த்தவும்) {trash_term}",
"trash.context.plural": "கோப்புகளை {trash_term} பெறுநர் க்கு நகர்த்தவும்",
"trash.context.singular": "கோப்பை {trash_term} பெறுநர் க்கு நகர்த்தவும்",
"trash.dialog.disambiguation_warning.plural": "இது அவற்றை டேக்ச்டுடியோ <i> மற்றும் </i> உங்கள் கோப்பு முறைமையிலிருந்து அகற்றும்!",
"trash.dialog.disambiguation_warning.singular": "இது டேக்ச்டுடியோ <i> மற்றும் </i> உங்கள் கோப்பு முறைமையிலிருந்து அகற்றப்படும்!",
"trash.dialog.disambiguation_warning.plural": "இது அவற்றை முகவரிச்சீட்டுஅறை <i> மற்றும் </i> உங்கள் கோப்பு முறைமையிலிருந்து அகற்றும்!",
"trash.dialog.disambiguation_warning.singular": "இது முகவரிச்சீட்டுஅறை <i> மற்றும் </i> உங்கள் கோப்பு முறைமையிலிருந்து அகற்றப்படும்!",
"trash.dialog.move.confirmation.plural": "இந்த {count} கோப்புகளை {trash_term} க்கு நகர்த்த விரும்புகிறீர்களா?",
"trash.dialog.move.confirmation.singular": "இந்த கோப்பை {trash_term} with க்கு நகர்த்த விரும்புகிறீர்களா?",
"trash.dialog.permanent_delete_warning": "<b> எச்சரிக்கை! </b> இந்தக் கோப்பை {trash_term} க்கு மாற்ற முடியாவிட்டால், இது <b> நிரந்தரமாக நீக்கப்படும்! </b>",
@@ -348,6 +350,9 @@
"trash.dialog.title.singular": "கோப்பை அழி",
"trash.name.generic": "குப்பை",
"trash.name.windows": "மறுசுழற்சி பின்",
"version_modal.description": "முகவரிச்சீட்டுஅறை இன் புதிய பதிப்பு கிடைக்கிறது! சமீபத்திய வெளியீட்டை நீங்கள் பதிவிறக்கம் செய்யலாம் <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">அறிவிலிமையம்</a>.",
"version_modal.status": "நிறுவப்பட்ட பதிப்பு: {installed_version}<br>அண்மைகால வெளியீட்டு பதிப்பு: {latest_release_version}",
"version_modal.title": "முகவரிச்சீட்டுஅறை புதுப்பிப்பு கிடைக்கிறது",
"view.size.0": "மினி",
"view.size.1": "சிறிய",
"view.size.2": "சராசரி",

View File

@@ -0,0 +1,8 @@
{
"about.config_path": "เส้นทางกำหนดค่า",
"about.description": "TagStudio เป็นแอปพลิเคชันจัดระเบียบรูปภาพและไฟล์ที่มีระบบพื้นฐานแบบแท็ก ซึ่งเน้นความยืดหยุ่นให้แก่ผู้ใช้ ไม่มีโปรแกรมหรือรูปแบบเฉพาะ ไม่มีไฟล์เสริมจำนวนมาก และไม่มีการเปลี่ยนแปลงโครงสร้างระบบไฟล์ของคุณอย่างสิ้นเชิง",
"about.documentation": "เอกสารประกอบ",
"about.license": "ใบอนุญาต",
"about.module.found": "พบ",
"about.title": "เกี่ยวกับ TagStudio"
}

View File

@@ -137,6 +137,7 @@
"home.search_entries": "o alasa lon ijo",
"home.search_library": "o alasa lon tomo",
"home.search_tags": "o alasa lon poki",
"home.show_hidden_entries": "o ken lukin e lipu pi ken ala lukin",
"home.thumbnail_size": "suli sitelen",
"home.thumbnail_size.extra_large": "sitelen pi suli mute",
"home.thumbnail_size.large": "sitelen suli",
@@ -302,8 +303,10 @@
"tag.confirm_delete": "sina wile ala wile weka e poki \"{tag_name}\"?",
"tag.create": "o pali sin e poki",
"tag.create_add": "o pali sin && o pana e \"{query}\"",
"tag.disambiguation.tooltip": "o kepeken poki ni lon nimi",
"tag.edit": "o ante e poki",
"tag.is_category": "poki ala poki",
"tag.is_hidden": "ken ala lukin",
"tag.name": "nimi",
"tag.new": "poki sin",
"tag.parent_tags": "poki mama",
@@ -327,6 +330,9 @@
"trash.dialog.title.singular": "o weka e lipu",
"trash.name.generic": "poki pi ijo weka",
"trash.name.windows": "poki pi ijo weka",
"version_modal.description": "nanpa sin pi ilo Tagstudio li lon! sina ken kama jo e ona tan <a href=\"https://github.com/TagStudioDev/TagStudio/releases/latest\">ma Github</a>.",
"version_modal.status": "nanpa ni: {installed_version}<br>nanpa sin: {latest_release_version}",
"version_modal.title": "nanpa sin pi ilo Tagstudio li lon",
"view.size.0": "lili mute",
"view.size.1": "lili",
"view.size.2": "meso",

View File

@@ -182,7 +182,7 @@
"menu.edit.new_tag": "Yeni &Etiket",
"menu.file": "&Dosya",
"menu.file.clear_recent_libraries": "Yakın Geçmişi Temizle",
"menu.file.close_library": "Kütüphaneyi &Kapat",
"menu.file.close_library": "Kütüphaneyi Kapat",
"menu.file.new_library": "Yeni Kütüphane",
"menu.file.open_create_library": "Kütüphane &Aç/Oluştur",
"menu.file.open_library": "Kütüphane Aç",

View File

@@ -2,6 +2,7 @@
# Licensed under the GPL-3.0 License.
# Created for TagStudio: https://github.com/CyanVoxel/TagStudio
import shutil
from pathlib import Path
from tempfile import TemporaryDirectory
@@ -29,3 +30,25 @@ def test_refresh_new_files(library: Library, exclude_mode: bool):
# Test if the single file was added
list(registry.refresh_dir(library_dir, force_internal_tools=True))
assert registry.files_not_in_library == [Path("FOO.MD")]
@pytest.mark.parametrize("library", [TemporaryDirectory()], indirect=True)
def test_refresh_multi_byte_filenames_ripgrep(library: Library):
assert shutil.which("rg") is not None
library_dir = unwrap(library.library_dir)
# Given
registry = RefreshTracker(library=library)
library.included_files.clear()
(library_dir / ".TagStudio").mkdir()
(library_dir / "こんにちは.txt").touch()
(library_dir / "emdash.txt").touch()
(library_dir / "apostrophe.txt").touch()
(library_dir / "umlaute äöü.txt").touch()
# Test if all files were added with their correct names and without exceptions
list(registry.refresh_dir(library_dir))
assert Path("こんにちは.txt") in registry.files_not_in_library
assert Path("emdash.txt") in registry.files_not_in_library
assert Path("apostrophe.txt") in registry.files_not_in_library
assert Path("umlaute äöü.txt") in registry.files_not_in_library