Forráskód Böngészése

Add: Multilanguage support.

Satoshi Yoneda 3 hete
szülő
commit
29b6071831

+ 18 - 2
CMakeLists.txt

@@ -17,7 +17,7 @@ elseif(CMAKE_CXX_COMPILER_ID MATCHES "GNU|Clang")
 endif()
 
 # Qt 6
-find_package(Qt6 COMPONENTS Widgets Concurrent REQUIRED)
+find_package(Qt6 COMPONENTS Widgets Concurrent Linguist REQUIRED)
 set(CMAKE_AUTOMOC ON)
 set(CMAKE_AUTOUIC ON)
 set(CMAKE_AUTORCC ON)
@@ -61,6 +61,22 @@ set_target_properties(${PROJECT_NAME} PROPERTIES
     MACOSX_BUNDLE ON
 )
 
+# Translations
+qt_add_translations(${PROJECT_NAME}
+    TS_FILES 
+        translations/dupfind_en.ts
+        translations/dupfind_ja.ts
+        translations/dupfind_zh_CN.ts
+        translations/dupfind_zh_TW.ts
+        translations/dupfind_es.ts
+        translations/dupfind_de.ts
+        translations/dupfind_ru.ts
+        translations/dupfind_pt.ts
+        translations/dupfind_pl.ts
+        translations/dupfind_ko.ts
+    RESOURCE translations.qrc
+)
+
 # CLI target
 add_executable(DupFindCmd src/CmdMain.cpp)
 target_link_libraries(DupFindCmd PRIVATE DupFindCore)
@@ -113,7 +129,7 @@ if(WIN32)
         COMMAND ${CMAKE_COMMAND} -E copy ${CMAKE_INSTALL_SYSTEM_RUNTIME_LIBS} "${DEPLOY_DIR}/"
         
         # 5. windeployqt による Qt DLL (--compiler-runtime) の自動収集
-        COMMAND "${WINDEPLOYQT_EXECUTABLE}" --no-translations --dir "${DEPLOY_DIR}" "${DEPLOY_DIR}/$<TARGET_FILE_NAME:${PROJECT_NAME}>"
+        COMMAND "${WINDEPLOYQT_EXECUTABLE}" --dir "${DEPLOY_DIR}" "${DEPLOY_DIR}/$<TARGET_FILE_NAME:${PROJECT_NAME}>"
         
         # 6. vc_redist.x64.exe の削除 (Appxには不要)
         COMMAND ${CMAKE_COMMAND} -E rm -f "${DEPLOY_DIR}/vc_redist.x64.exe"

+ 0 - 0
Deploy/Assets/SplashScreen.png.png → Deploy/Assets/SplashScreen.png


+ 6 - 0
RESOURCE

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Run the update_translations CMake target to populate the source strings in this file.
+-->
+<!DOCTYPE TS>
+<TS version="2.1"/>

+ 25 - 25
src/MainWindow.cpp

@@ -93,10 +93,10 @@ void MainWindow::setupUi() {
 
   // Toolbar-like top section
   auto *toolLayout = new QHBoxLayout();
-  m_addDirBtn = new QPushButton("Add Directory");
-  m_removeDirBtn = new QPushButton("Remove Selected");
-  m_startScanBtn = new QPushButton("Start Scan");
-  m_deleteBtn = new QPushButton("Delete Selected Duplicates");
+  m_addDirBtn = new QPushButton(tr("Add Directory"));
+  m_removeDirBtn = new QPushButton(tr("Remove Selected"));
+  m_startScanBtn = new QPushButton(tr("Start Scan"));
+  m_deleteBtn = new QPushButton(tr("Delete Selected Duplicates"));
   m_deleteBtn->setObjectName("deleteBtn"); // QSS で赤くするため
 
   toolLayout->addWidget(m_addDirBtn);
@@ -104,7 +104,7 @@ void MainWindow::setupUi() {
   toolLayout->addStretch();
 
   // Slider section
-  toolLayout->addWidget(new QLabel("Similarity Threshold:"));
+  toolLayout->addWidget(new QLabel(tr("Similarity Threshold:")));
   m_thresholdSlider = new QSlider(Qt::Horizontal);
   m_thresholdSlider->setRange(0, 32);
   m_thresholdSlider->setValue(m_currentThreshold);
@@ -113,15 +113,15 @@ void MainWindow::setupUi() {
   toolLayout->addWidget(m_thresholdSlider);
   toolLayout->addWidget(m_thresholdLabel);
 
-  m_strictCheckBox = new QCheckBox("Strict");
+  m_strictCheckBox = new QCheckBox(tr("Strict"));
   m_strictCheckBox->setChecked(m_strictMode);
   toolLayout->addWidget(m_strictCheckBox);
 
   toolLayout->addWidget(m_startScanBtn);
-  m_clearBtn = new QPushButton("Clear Results");
+  m_clearBtn = new QPushButton(tr("Clear Results"));
   toolLayout->addWidget(m_clearBtn);
 
-  m_deselectBtn = new QPushButton("Deselect All");
+  m_deselectBtn = new QPushButton(tr("Deselect All"));
   toolLayout->addWidget(m_deselectBtn);
 
   toolLayout->addWidget(m_deleteBtn);
@@ -144,7 +144,7 @@ void MainWindow::setupUi() {
   auto *resultLayout = new QVBoxLayout();
   m_searchBox = new QLineEdit();
   m_searchBox->setPlaceholderText(
-      "Filter results by path or filename... (Press Esc to close)");
+      tr("Filter results by path or filename... (Press Esc to close)"));
   m_searchBox->setVisible(false);
   resultLayout->addWidget(m_searchBox);
 
@@ -250,7 +250,7 @@ void MainWindow::closeEvent(QCloseEvent *event) {
 
 void MainWindow::onAddDirectory() {
   QString dir =
-      QFileDialog::getExistingDirectory(this, "Select Directory to Scan");
+      QFileDialog::getExistingDirectory(this, tr("Select Directory to Scan"));
   if (!dir.isEmpty()) {
     auto *item = new QListWidgetItem(dir, m_dirList);
     item->setToolTip(dir);
@@ -274,8 +274,8 @@ void MainWindow::onRemoveDirectory() {
 // 選択されたディレクトリを再帰的に走査し、並列処理によって高速に画像ハッシュを分散計算し、DB保存する
 void MainWindow::onStartScan() {
   if (m_dirList->count() == 0) {
-    QMessageBox::warning(this, "No Directory",
-                         "Please add at least one directory to scan.");
+    QMessageBox::warning(this, tr("No Directory"),
+                         tr("Please add at least one directory to scan."));
     return;
   }
 
@@ -418,7 +418,7 @@ void MainWindow::performAsyncSearch() {
 
   m_progressBar->setVisible(true);
   m_progressBar->setRange(0, 0);
-  m_progressBar->setFormat("Searching duplicates... %p%");
+  m_progressBar->setFormat(tr("Searching duplicates... %p%"));
 
   // 現在実行中の検索があればキャンセルはできないが、WatcherのFutureを上書きすることで最新のみを追う
   auto future = QtConcurrent::run([images = m_lastScannedImages,
@@ -501,9 +501,9 @@ void MainWindow::onContextMenuRequested(const std::string &path, int groupId,
                                         const QPoint &globalPos) {
   if (!path.empty()) {
     QMenu menu;
-    QAction *copyAction = menu.addAction("Copy Full Path(&C)");
+    QAction *copyAction = menu.addAction(tr("Copy Full Path(&C)"));
     menu.addSeparator();
-    QAction *removeAction = menu.addAction("Remove from List(&R)");
+    QAction *removeAction = menu.addAction(tr("Remove from List(&R)"));
 
     QAction *selectedAction = menu.exec(globalPos);
     if (selectedAction == copyAction) {
@@ -567,11 +567,11 @@ void MainWindow::onDeleteSelected() {
 
   if (allCheckedInSomeGroup) {
     auto warnRes = QMessageBox::warning(
-        this, "Warning: All images selected",
-        "一部の類似画像グループで、すべての画像が削除対象としてチェックされてい"
-        "ます。\n"
-        "このまま削除すると、それらの画像ファイルはすべて失われます。\n\n"
-        "本当に削除を実行しますか?",
+        this, tr("Warning: All images selected"),
+        tr("一部の類似画像グループで、すべての画像が削除対象としてチェックされてい"
+           "ます。\n"
+           "このまま削除すると、それらの画像ファイルはすべて失われます。\n\n"
+           "本当に削除を実行しますか?"),
         QMessageBox::Ok | QMessageBox::Cancel, QMessageBox::Cancel);
     if (warnRes != QMessageBox::Ok) {
       return;
@@ -579,8 +579,8 @@ void MainWindow::onDeleteSelected() {
   }
 
   auto res = QMessageBox::question(
-      this, "Confirm Deletion",
-      QString("Are you sure you want to move %1 images to Trash?").arg(count));
+      this, tr("Confirm Deletion"),
+      tr("Are you sure you want to move %1 images to Trash?").arg(count));
 
   if (res == QMessageBox::Yes) {
     std::vector<QString> failures;
@@ -594,12 +594,12 @@ void MainWindow::onDeleteSelected() {
     }
 
     if (!failures.empty()) {
-      QString msg = "The following files could not be moved to trash and were "
-                    "NOT deleted:\n\n";
+      QString msg = tr("The following files could not be moved to trash and were "
+                       "NOT deleted:\n\n");
       for (const auto &f : failures) {
         msg += f + "\n";
       }
-      QMessageBox::warning(this, "Deletion Error", msg);
+      QMessageBox::warning(this, tr("Deletion Error"), msg);
     }
 
     // リストをリフレッシュ

+ 2 - 2
src/ResultItemDelegate.cpp

@@ -68,7 +68,7 @@ void ResultItemDelegate::paint(QPainter *painter,
       QPixmap pix = model->getThumbnail(imgData.path);
       if (pix.isNull()) {
         painter->setPen(Qt::black);
-        painter->drawText(thumbRect, Qt::AlignCenter, "Loading...");
+        painter->drawText(thumbRect, Qt::AlignCenter, tr("Loading..."));
       } else {
         // center pixmap
         QPoint topLeft(thumbRect.center().x() - pix.width() / 2,
@@ -81,7 +81,7 @@ void ResultItemDelegate::paint(QPainter *painter,
                    20);
       QStyleOptionButton cbOpt;
       cbOpt.rect = cbRect;
-      cbOpt.text = "Delete candidate";
+      cbOpt.text = tr("Delete candidate");
       cbOpt.state = QStyle::State_Enabled;
       if (model->isChecked(imgData.path)) {
         cbOpt.state |= QStyle::State_On;

+ 1 - 1
src/ResultListModel.cpp

@@ -58,7 +58,7 @@ void ResultListModel::setGroups(const std::vector<DuplicateGroup>& groups, bool
         ResultListItem header;
         header.type = ResultListItem::Header;
         header.groupId = groupId;
-        header.headerText = QString("Duplicate Group - %1 images").arg(group.images.size());
+        header.headerText = tr("Duplicate Group - %1 images").arg(group.images.size());
         m_items.push_back(header);
         
         ResultListItem rowItem;

+ 21 - 0
src/main.cpp

@@ -1,9 +1,30 @@
 #include <QApplication>
+#include <QLibraryInfo>
+#include <QLocale>
 #include <QSharedMemory>
+#include <QTranslator>
 #include "MainWindow.hpp"
 
 int main(int argc, char *argv[]) {
     QApplication app(argc, argv);
+
+    // Load translations
+    QTranslator translator;
+    const QStringList uiLanguages = QLocale::system().uiLanguages();
+    for (const QString &locale : uiLanguages) {
+        const QString baseName = "dupfind_" + QLocale(locale).name();
+        if (translator.load(":/i18n/" + baseName)) {
+            app.installTranslator(&translator);
+            break;
+        }
+    }
+
+    // Load standard Qt translations (for QFileDialog, etc.)
+    QTranslator qtTranslator;
+    if (qtTranslator.load(QLocale::system(), "qtbase", "_",
+                          QLibraryInfo::path(QLibraryInfo::TranslationsPath))) {
+        app.installTranslator(&qtTranslator);
+    }
     
     // Create a shared memory object to indicate that the GUI is running
     QSharedMemory sharedMem("DupFind_GUI_Instance");

+ 6 - 0
translations.qrc

@@ -0,0 +1,6 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!--
+Run the update_translations CMake target to populate the source strings in this file.
+-->
+<!DOCTYPE TS>
+<TS version="2.1"/>

+ 119 - 0
translations/dupfind_de.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="de_DE">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Verzeichnis hinzufügen</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Ausgewählte entfernen</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Scan starten</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Ausgewählte Duplikate löschen</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Ähnlichkeitsschwellenwert:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Strenger Modus</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Ergebnisse löschen</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Alle abwählen</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Ergebnisse nach Pfad oder Dateiname filtern... (Esc zum Schließen)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Verzeichnis zum Scannen auswählen</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>Kein Verzeichnis</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Bitte fügen Sie mindestens ein Verzeichnis zum Scannen hinzu.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Suche nach Duplikaten... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Vollständigen Pfad kopieren(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Aus Liste entfernen(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Warnung: Alle Bilder ausgewählt</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>In einigen Duplikatgruppen sind alle Bilder zum Löschen markiert.
+Wenn Sie fortfahren, gehen all diese Bilddateien verloren.
+
+Sind Sie sicher, dass Sie den Löschvorgang ausführen möchten?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Löschen bestätigen</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>Sind Sie sicher, dass Sie %1 Bilder in den Papierkorb verschieben möchten?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>Die folgenden Dateien konnten nicht in den Papierkorb verschoben werden und wurden NICHT gelöscht:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Fehler beim Löschen</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Laden...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Löschkandidat</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Duplikatgruppe - %1 Bilder</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_en.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="en_US">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Add Directory</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Remove Selected</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Start Scan</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Delete Selected Duplicates</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Similarity Threshold:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Strict</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Clear Results</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Deselect All</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Filter results by path or filename... (Press Esc to close)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Select Directory to Scan</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>No Directory</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Please add at least one directory to scan.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Searching duplicates... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Copy Full Path(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Remove from List(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Warning: All images selected</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>In some duplicate groups, all images are checked for deletion.
+If you proceed, all those image files will be lost.
+
+Are you sure you want to execute the deletion?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Confirm Deletion</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>Are you sure you want to move %1 images to Trash?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>The following files could not be moved to trash and were NOT deleted:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Deletion Error</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Loading...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Delete candidate</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Duplicate Group - %1 images</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_es.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="es_ES">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Añadir directorio</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Eliminar seleccionados</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Iniciar escaneo</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Eliminar duplicados seleccionados</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Umbral de similitud:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Modo estricto</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Limpiar resultados</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Desmarcar todo</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Filtrar resultados por ruta o nombre... (Esc para cerrar)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Seleccionar directorio para escanear</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>Sin directorio</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Por favor, añada al menos un directorio para escanear.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Buscando duplicados... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Copiar ruta completa(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Eliminar de la lista(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Advertencia: Todas las imágenes seleccionadas</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>En algunos grupos de duplicados, todas las imágenes están marcadas para eliminar.
+Si continúa, todos esos archivos de imagen se perderán.
+
+¿Está seguro de que desea ejecutar la eliminación?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Confirmar eliminación</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>¿Está seguro de que desea mover %1 imágenes a la papelera?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>Los siguientes archivos no se pudieron mover a la papelera y NO fueron eliminados:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Error de eliminación</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Cargando...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Candidato para eliminar</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Grupo de duplicados - %1 imágenes</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_ja.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ja_JP">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>ディレクトリを追加</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>選択を除外</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>スキャン開始</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>選択した重複ファイルを削除</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>類似度しきい値:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>厳格モード</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>結果をクリア</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>すべての選択を解除</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>パスまたはファイル名で結果をフィルタリング... (Escで閉じる)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>スキャンするディレクトリを選択</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>ディレクトリ未設定</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>スキャンするディレクトリを少なくとも1つ追加してください。</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>重複ファイルを検索中... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>フルパスをコピー(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>リストから除外(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>警告: すべての画像が選択されています</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>削除の確認</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>本当に %1 個の画像をゴミ箱に移動しますか?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>以下のファイルはゴミ箱に移動できず、削除されませんでした:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>削除エラー</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>読み込み中...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>削除候補</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>重複グループ - %1 枚の画像</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_ko.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ko_KR">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>디렉토리 추가</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>선택 항목 삭제</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>스캔 시작</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>선택한 중복 파일 삭제</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>유사성 임계값:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>엄격 모드</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>결과 지우기</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>모두 선택 해제</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>경로 또는 파일 이름으로 결과 필터링... (Esc로 닫기)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>스캔할 디렉토리 선택</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>디렉토리 없음</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>스캔할 디렉토리를 하나 이상 추가하세요.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>중복 파일 검색 중... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>전체 경로 복사(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>목록에서 삭제(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>경로: 모든 이미지가 선택되었습니다</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>일부 유사 이미지 그룹에서 모든 이미지가 삭제 대상으로 선택되었습니다.
+이대로 삭제하면 해당 이미지 파일이 모두 삭제됩니다.
+
+정말 삭제하시겠습니까?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>삭제 확인</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>정말 %1 개의 이미지를 휴지통으로 이동하시겠습니까?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>다음 파일은 휴지통으로 이동할 수 없어 삭제되지 않았습니다:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>삭제 오류</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>불러오는 중...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>삭제 후보</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>중복 그룹 - %1 개의 이미지</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_pl.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="pl_PL">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Dodaj folder</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Usuń zaznaczone</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Rozpocznij skanowanie</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Usuń zaznaczone duplikaty</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Próg podobieństwa:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Tryb ścisły</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Wyczyść wyniki</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Odznacz wszystko</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Filtruj wyniki wg ścieżki lub nazwy pliku... (Esc aby zamknąć)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Wybierz folder do skanowania</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>Brak folderu</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Proszę dodać co najmniej jeden folder do skanowania.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Szukanie duplikatów... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Kopiuj pełną ścieżkę(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Usuń z listy(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Uwaga: Zaznaczono wszystkie obrazy</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>W niektórych grupach duplikatów wszystkie obrazy zostały zaznaczone do usunięcia.
+Jeśli będziesz kontynuować, wszystkie te pliki zostaną utracone.
+
+Czy na pewno chcesz wykonać usuwanie?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Potwierdź usuwanie</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>Czy na pewno chcesz przenieść %1 obrazów do kosza?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>Następujące pliki nie mogły zostać przeniesione do kosza i NIE zostały usunięte:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Błąd usuwania</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Ładowanie...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Kandydat do usunięcia</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Grupa duplikatów - %1 obrazów</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_pt.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="pt_PT">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Adicionar diretório</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Remover selecionado</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Iniciar verificação</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Excluir duplicatas selecionadas</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Limite de similaridade:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Modo estrito</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Limpar resultados</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Desmarcar tudo</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Filtrar resultados por caminho ou nome... (Esc para fechar)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Selecionar diretório para verificar</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>Sem diretório</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Por favor, adicione pelo menos um diretório para verificar.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Buscando duplicatas... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Copiar caminho completo(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Remover da lista(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Aviso: Todas as imagens selecionadas</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>Em alguns grupos de duplicatas, todas as imagens estão marcadas para exclusão.
+Se continuar, todos esses ficheiros de imagem serão perdidos.
+
+Tem a certeza de que deseja executar a exclusão?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Confirmar exclusão</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>Tem a certeza de que deseja mover %1 imagens para a lixeira?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>Os seguintes ficheiros não puderam ser movidos para a lixeira e NÃO foram excluídos:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Erro de exclusão</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Carregando...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Candidato para exclusão</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Grupo de duplicatas - %1 imagens</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_ru.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="ru_RU">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>Добавить директорию</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>Удалить выбранное</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>Начать сканирование</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>Удалить выбранные дубликаты</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>Пороговое значение:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>Строгий режим</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>Очистить результаты</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>Снять выделение</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>Фильтр по пути или имени файла... (Esc для закрытия)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>Выберите директорию для сканирования</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>Нет директории</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>Пожалуйста, добавьте хотя бы одну директорию для сканирования.</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>Поиск дубликатов... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>Копировать полный путь(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>Удалить из списка(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>Предупреждение: Выбраны все изображения</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>В некоторых группах дубликатов выбраны все изображения для удаления.
+Если вы продолжите, все эти файлы будут безвозвратно удалены.
+
+Вы действительно хотите выполнить удаление?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>Подтверждение удаления</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>Вы уверены, что хотите переместить %1 изображений в корзину?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>Следующие файлы не удалось переместить в корзину, и они НЕ были удалены:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>Ошибка удаления</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>Загрузка...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>Кандидат на удаление</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>Группа дубликатов - %1 изображений</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_zh_CN.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_CN">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>添加目录</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>移除所选</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>开始扫描</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>删除所选重复文件</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>相似度阈值:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>严格模式</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>清除结果</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>取消全选</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>按路径或文件名过滤结果... (按 Esc 键关闭)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>选择要扫描的目录</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>无目录</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>请添加至少一个要扫描的目录。</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>正在搜索重复文件... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>复制完整路径(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>从列表中移除(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>警告:已选择所有图像</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>一些重复图像组中,所有图像均已被选中进行删除。
+如果继续,这些图像文件将全部丢失。
+
+确定要执行删除吗?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>确认删除</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>确定要将 %1 个图像移至回收站吗?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>以下文件无法移动到回收站,且未被删除:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>删除错误</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>正在加载...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>待删除</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>重复组 - %1 个图像</translation>
+    </message>
+</context>
+</TS>

+ 119 - 0
translations/dupfind_zh_TW.ts

@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="utf-8"?>
+<!DOCTYPE TS>
+<TS version="2.1" language="zh_TW">
+<context>
+    <name>MainWindow</name>
+    <message>
+        <source>Add Directory</source>
+        <translation>新增資料夾</translation>
+    </message>
+    <message>
+        <source>Remove Selected</source>
+        <translation>移除所選</translation>
+    </message>
+    <message>
+        <source>Start Scan</source>
+        <translation>開始掃描</translation>
+    </message>
+    <message>
+        <source>Delete Selected Duplicates</source>
+        <translation>刪除所選重複檔案</translation>
+    </message>
+    <message>
+        <source>Similarity Threshold:</source>
+        <translation>相似度閾值:</translation>
+    </message>
+    <message>
+        <source>Strict</source>
+        <translation>嚴格模式</translation>
+    </message>
+    <message>
+        <source>Clear Results</source>
+        <translation>清除結果</translation>
+    </message>
+    <message>
+        <source>Deselect All</source>
+        <translation>取消全選</translation>
+    </message>
+    <message>
+        <source>Filter results by path or filename... (Press Esc to close)</source>
+        <translation>按路徑或檔案名稱過濾結果... (按 Esc 鍵關閉)</translation>
+    </message>
+    <message>
+        <source>Select Directory to Scan</source>
+        <translation>選擇要掃描的資料夾</translation>
+    </message>
+    <message>
+        <source>No Directory</source>
+        <translation>無資料夾</translation>
+    </message>
+    <message>
+        <source>Please add at least one directory to scan.</source>
+        <translation>請新增至少一個要掃描的資料夾。</translation>
+    </message>
+    <message>
+        <source>Searching duplicates... %p%</source>
+        <translation>正在搜尋重複檔案... %p%</translation>
+    </message>
+    <message>
+        <source>Copy Full Path(&amp;C)</source>
+        <translation>複製完整路徑(&amp;C)</translation>
+    </message>
+    <message>
+        <source>Remove from List(&amp;R)</source>
+        <translation>從清單中移除(&amp;R)</translation>
+    </message>
+    <message>
+        <source>Warning: All images selected</source>
+        <translation>警告:已選擇所有圖片</translation>
+    </message>
+    <message>
+        <source>一部の類似画像グループで、すべての画像が削除対象としてチェックされています。
+このまま削除すると、それらの画像ファイルはすべて失われます。
+
+本当に削除を実行しますか?</source>
+        <translation>一些重複圖片組中,所有圖片均已被選中進行刪除。
+如果繼續,這些圖片檔案將全部丟失。
+
+確定要執行刪除嗎?</translation>
+    </message>
+    <message>
+        <source>Confirm Deletion</source>
+        <translation>確認刪除</translation>
+    </message>
+    <message>
+        <source>Are you sure you want to move %1 images to Trash?</source>
+        <translation>確定要將 %1 張圖片移至回收站嗎?</translation>
+    </message>
+    <message>
+        <source>The following files could not be moved to trash and were NOT deleted:
+
+</source>
+        <translation>以下檔案無法移動到回收站,且未被刪除:
+
+</translation>
+    </message>
+    <message>
+        <source>Deletion Error</source>
+        <translation>刪除錯誤</translation>
+    </message>
+</context>
+<context>
+    <name>ResultItemDelegate</name>
+    <message>
+        <source>Loading...</source>
+        <translation>正在載入...</translation>
+    </message>
+    <message>
+        <source>Delete candidate</source>
+        <translation>待刪除</translation>
+    </message>
+</context>
+<context>
+    <name>ResultListModel</name>
+    <message>
+        <source>Duplicate Group - %1 images</source>
+        <translation>重複組 - %1 張圖片</translation>
+    </message>
+</context>
+</TS>