diff --git a/res/fonts/NotoSansCJK-Subset.ttf b/res/fonts/NotoSansCJK-Subset.ttf index 67c8994..d908fd2 100644 Binary files a/res/fonts/NotoSansCJK-Subset.ttf and b/res/fonts/NotoSansCJK-Subset.ttf differ diff --git a/res/lang/de.json b/res/lang/de.json index 85302ae..e707e69 100644 --- a/res/lang/de.json +++ b/res/lang/de.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "Diese Wallet konnte nicht an ihrem Ort geöffnet werden. Sie liegt vermutlich auf einem anderen Laufwerk als dein Datenverzeichnis — verschiebe sie auf dasselbe Laufwerk (unter Windows erlaubt auch der aktivierte Entwicklermodus laufwerkübergreifende Verknüpfungen).", "wallets_open_folder": "Ordnerpfad öffnen", "wallets_open_inplace_tt": "Öffnet diese Wallet an ihrem Ort — im Datenverzeichnis verlinkt (keine Kopie)", + "wallets_remove_folder": "Diesen Ordner nicht mehr durchsuchen", "wallets_reveal": "Ordner anzeigen", + "wallets_scanned_folders": "Durchsuchte Ordner:", "wallets_sort_addresses": "Adressen", "wallets_sort_asc": "Aufsteigend (ältestes / wenigste / kleinstes zuerst)", "wallets_sort_by": "Sortieren:", diff --git a/res/lang/es.json b/res/lang/es.json index 36cb94d..7da60f6 100644 --- a/res/lang/es.json +++ b/res/lang/es.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "No se pudo abrir esta cartera en su ubicación. Probablemente está en una unidad distinta a tu directorio de datos: muévela a la misma unidad (en Windows, activar el Modo de desarrollador también permite enlazar entre unidades).", "wallets_open_folder": "Abrir ubicación de la carpeta", "wallets_open_inplace_tt": "Abre esta cartera donde está, enlazándola al directorio de datos (sin copiar)", + "wallets_remove_folder": "Dejar de escanear esta carpeta", "wallets_reveal": "Mostrar carpeta", + "wallets_scanned_folders": "Carpetas escaneadas:", "wallets_sort_addresses": "Direcciones", "wallets_sort_asc": "Ascendente (más antiguo / menos / más pequeño primero)", "wallets_sort_by": "Ordenar:", diff --git a/res/lang/fr.json b/res/lang/fr.json index 2fab1c6..01ba68b 100644 --- a/res/lang/fr.json +++ b/res/lang/fr.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "Impossible d'ouvrir ce portefeuille à son emplacement. Il se trouve probablement sur un lecteur différent de votre répertoire de données — déplacez-le sur le même lecteur (sous Windows, activer le mode développeur permet aussi de créer des liens entre lecteurs).", "wallets_open_folder": "Ouvrir l'emplacement du dossier", "wallets_open_inplace_tt": "Ouvre ce portefeuille à son emplacement — lié au répertoire de données (sans copie)", + "wallets_remove_folder": "Ne plus analyser ce dossier", "wallets_reveal": "Afficher le dossier", + "wallets_scanned_folders": "Dossiers analysés :", "wallets_sort_addresses": "Adresses", "wallets_sort_asc": "Croissant (plus ancien / moins / plus petit d'abord)", "wallets_sort_by": "Trier :", diff --git a/res/lang/ja.json b/res/lang/ja.json index 2a3cf5d..c7de9c1 100644 --- a/res/lang/ja.json +++ b/res/lang/ja.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "このウォレットをその場で開けませんでした。データディレクトリとは別のドライブにある可能性があります — 同じドライブに移動してください(Windows では開発者モードを有効にするとドライブ間のリンクも可能になります)。", "wallets_open_folder": "フォルダーの場所を開く", "wallets_open_inplace_tt": "このウォレットをその場で開きます — データディレクトリにリンク(コピーなし)", + "wallets_remove_folder": "このフォルダーのスキャンを停止", "wallets_reveal": "フォルダを開く", + "wallets_scanned_folders": "スキャン対象フォルダー:", "wallets_sort_addresses": "アドレス", "wallets_sort_asc": "昇順(古い/少ない/小さい順)", "wallets_sort_by": "並べ替え:", diff --git a/res/lang/ko.json b/res/lang/ko.json index 0b04f66..3246144 100644 --- a/res/lang/ko.json +++ b/res/lang/ko.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "이 지갑을 제자리에서 열 수 없습니다. 데이터 디렉터리와 다른 드라이브에 있을 가능성이 높습니다 — 같은 드라이브로 옮기세요 (Windows에서는 개발자 모드를 켜면 드라이브 간 링크도 가능합니다).", "wallets_open_folder": "폴더 위치 열기", "wallets_open_inplace_tt": "이 지갑을 있는 자리에서 엽니다 — 데이터 디렉터리에 링크 (복사 없음)", + "wallets_remove_folder": "이 폴더 스캔 중지", "wallets_reveal": "폴더 열기", + "wallets_scanned_folders": "스캔한 폴더:", "wallets_sort_addresses": "주소", "wallets_sort_asc": "오름차순 (오래된/적은/작은 순)", "wallets_sort_by": "정렬:", diff --git a/res/lang/pt.json b/res/lang/pt.json index 18fe9c4..51d71f0 100644 --- a/res/lang/pt.json +++ b/res/lang/pt.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "Não foi possível abrir esta carteira no lugar. Provavelmente está em uma unidade diferente do seu diretório de dados — mova-a para a mesma unidade (no Windows, ativar o Modo de Desenvolvedor também permite vincular entre unidades).", "wallets_open_folder": "Abrir local da pasta", "wallets_open_inplace_tt": "Abre esta carteira onde está — vinculada ao diretório de dados (sem cópia)", + "wallets_remove_folder": "Parar de verificar esta pasta", "wallets_reveal": "Mostrar pasta", + "wallets_scanned_folders": "Pastas verificadas:", "wallets_sort_addresses": "Endereços", "wallets_sort_asc": "Crescente (mais antigo / menos / menor primeiro)", "wallets_sort_by": "Ordenar:", diff --git a/res/lang/ru.json b/res/lang/ru.json index 06642a5..c4b49e8 100644 --- a/res/lang/ru.json +++ b/res/lang/ru.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "Не удалось открыть этот кошелёк на месте. Вероятно, он на другом диске, чем каталог данных — переместите его на тот же диск (в Windows включённый режим разработчика также позволяет создавать ссылки между дисками).", "wallets_open_folder": "Открыть расположение папки", "wallets_open_inplace_tt": "Открывает этот кошелёк на месте — по ссылке в каталоге данных (без копирования)", + "wallets_remove_folder": "Больше не сканировать эту папку", "wallets_reveal": "Открыть папку", + "wallets_scanned_folders": "Просканированные папки:", "wallets_sort_addresses": "Адреса", "wallets_sort_asc": "По возрастанию (сначала старые / меньше / меньший)", "wallets_sort_by": "Сортировка:", diff --git a/res/lang/zh.json b/res/lang/zh.json index 674a8b1..076aabb 100644 --- a/res/lang/zh.json +++ b/res/lang/zh.json @@ -1356,7 +1356,9 @@ "wallets_open_failed": "无法在原位置打开此钱包。它可能与数据目录位于不同的驱动器上 — 请将其移动到同一驱动器(在 Windows 上,启用开发者模式也可跨驱动器链接)。", "wallets_open_folder": "打开文件夹位置", "wallets_open_inplace_tt": "在原位置打开此钱包 — 链接到数据目录(不复制)", + "wallets_remove_folder": "停止扫描此文件夹", "wallets_reveal": "打开文件夹", + "wallets_scanned_folders": "已扫描的文件夹:", "wallets_sort_addresses": "地址", "wallets_sort_asc": "升序(最早/最少/最小优先)", "wallets_sort_by": "排序:", diff --git a/scripts/add_missing_translations.py b/scripts/add_missing_translations.py index d2990e6..fac0c86 100644 --- a/scripts/add_missing_translations.py +++ b/scripts/add_missing_translations.py @@ -2232,6 +2232,18 @@ TRANSLATIONS = { "ja": "データディレクトリの外 —「開く」はその場でリンクします(コピーなし)。", "ko": "데이터 디렉터리 밖 — '열기'는 제자리에 링크합니다 (복사 없음)." }, + "wallets_scanned_folders": { + "es": "Carpetas escaneadas:", "de": "Durchsuchte Ordner:", + "fr": "Dossiers analysés :", "pt": "Pastas verificadas:", + "ru": "Просканированные папки:", "zh": "已扫描的文件夹:", + "ja": "スキャン対象フォルダー:", "ko": "스캔한 폴더:" + }, + "wallets_remove_folder": { + "es": "Dejar de escanear esta carpeta", "de": "Diesen Ordner nicht mehr durchsuchen", + "fr": "Ne plus analyser ce dossier", "pt": "Parar de verificar esta pasta", + "ru": "Больше не сканировать эту папку", "zh": "停止扫描此文件夹", + "ja": "このフォルダーのスキャンを停止", "ko": "이 폴더 스캔 중지" + }, } def main(): diff --git a/src/ui/windows/wallets_dialog.h b/src/ui/windows/wallets_dialog.h index db6022f..b132f35 100644 --- a/src/ui/windows/wallets_dialog.h +++ b/src/ui/windows/wallets_dialog.h @@ -71,7 +71,9 @@ public: const int kMaxVisibleRows = 7; ImFont* nameFont = Type().subtitle1(); ImFont* metaFont = Type().caption(); - const int visRows = std::min(std::max(1, (int)s_rows.size()), kMaxVisibleRows); + // The list is always sized to its MAX height (kMaxVisibleRows) for a consistent modal size — it + // does not shrink to fit a few wallets; fewer rows leave empty space, more than 7 scroll. + const int visRows = kMaxVisibleRows; const float cardPadY = Layout::spacingMd(); // roomier cards (was spacingSm) const float walRowH = cardPadY * 2.0f + nameFont->LegacySize + Layout::spacingSm() + metaFont->LegacySize; const float cardGap = Layout::spacingMd(); // more breathing room between wallet cards @@ -81,9 +83,14 @@ public: const float ctrlRow = ImGui::GetFrameHeightWithSpacing(); const float capRow = Type().caption()->LegacySize + style.ItemSpacing.y; + const int numScanFolders = app ? (int)app->walletIndex().extraFolders().size() : 0; + const float foldersH = numScanFolders > 0 + ? (capRow + (float)numScanFolders * ctrlRow + Layout::spacingXs()) // "Scanned folders:" + one row each + : 0.0f; const float belowH = 4.0f * Layout::spacingSm() + (capRow + ctrlRow) // Create label + input row + ctrlRow // full-width "scan folder" button + + foldersH // scanned-folders manager + (style.ItemSpacing.y + 1.0f) // separator + ctrlRow // footer buttons + 6.0f * style.ItemSpacing.y; // uncounted inter-item gaps @@ -422,6 +429,51 @@ public: }); } + // ---- Manage scanned folders: list each user-added folder with a control to stop scanning it. + // (The datadir is always scanned and isn't listed here — only the folders the user added.) ----- + { + const auto& scanFolders = app->walletIndex().extraFolders(); + if (!scanFolders.empty()) { + ImGui::Dummy(ImVec2(0, Layout::spacingXs())); + Type().textColored(TypeStyle::Caption, OnSurfaceMedium(), TR("wallets_scanned_folders")); + ImFont* pf = Type().caption(); + const float bh2 = ImGui::GetFrameHeight(); + // Front-elide a long path so its identifying tail (the leaf folder) stays visible. + auto elideFront = [&](std::string s, float maxW) { + auto w = [&](const std::string& t){ return pf->CalcTextSizeA(pf->LegacySize, FLT_MAX, 0, t.c_str()).x; }; + if (w(s) <= maxW) return s; + while (s.size() > 1 && w("\xE2\x80\xA6" + s) > maxW) { + s.erase(s.begin()); + while (!s.empty() && (static_cast(s.front()) & 0xC0) == 0x80) s.erase(s.begin()); + } + return "\xE2\x80\xA6" + s; + }; + std::string toRemove; + for (const auto& folder : scanFolders) { + ImGui::PushID(folder.c_str()); + IconButtonStyle rm; + rm.color = OnSurfaceMedium(); + rm.hoverColor = Error(); + rm.hoverBg = StateHover(); + rm.bgRounding = 4.0f * dp; + rm.tooltip = TR("wallets_remove_folder"); + if (IconButton("##rmScanFolder", ICON_MD_CLOSE, Type().iconSmall(), ImVec2(bh2, bh2), rm)) + toRemove = folder; + ImGui::SameLine(0, Layout::spacingSm()); + ImGui::AlignTextToFramePadding(); + const float textW = listW - bh2 - 2.0f * Layout::spacingSm(); + Type().textColored(TypeStyle::Caption, OnSurface(), elideFront(folder, textW).c_str()); + if (ImGui::IsItemHovered()) ImGui::SetTooltip("%s", folder.c_str()); + ImGui::PopID(); + } + if (!toRemove.empty()) { + app->walletIndex().removeExtraFolder(toRemove); + app->walletIndex().save(); + s_needScan = true; // re-scan so wallets from the dropped folder disappear + } + } + } + ImGui::Dummy(ImVec2(0, Layout::spacingSm())); ImGui::Separator(); // ---- Refresh: icon-only, de-emphasized next to the text actions ----------------------- diff --git a/src/util/i18n.cpp b/src/util/i18n.cpp index b51d52f..00c78d5 100644 --- a/src/util/i18n.cpp +++ b/src/util/i18n.cpp @@ -287,6 +287,8 @@ void I18n::loadBuiltinEnglish() strings_["wallets_never"] = "Never opened"; strings_["wallets_external_tt"] = "Outside your data directory \xE2\x80\x94 Open links it in place (no copy)."; strings_["wallets_scan_folder"] = "Scan another folder for wallets\xE2\x80\xA6"; + strings_["wallets_scanned_folders"] = "Scanned folders:"; + strings_["wallets_remove_folder"] = "Stop scanning this folder"; strings_["wallets_folder_invalid"] = "That folder doesn't exist."; strings_["wallets_new_label"] = "Create a new wallet:"; strings_["wallets_new_hint"] = "Name (e.g. savings)";