E3: 탐색기 처음 값을 선택 규칙대로 - TC 키 (Windows) · 표시는 선택 모드에서만 (V) · 다시 누르면 접기 · Android 한 번 = 선택 · 두 창

기준: wiki "파일 탐색기 선택 규칙 (사용자 지시 모음)" 규칙 1~7, 관리자 결정 3 · (a) (10/22)
- 규칙 1: Windows 는 스타일과 상관없이 Total Commander 키 (F3 보기 · F5 복사 · F6 이동 · F7 새 폴더 · F8 삭제 ·
  Space/Insert 고르기 · Ctrl+R 새로 고침) + Ctrl+C · X · V · A (explorer_keys · _tcKeys)
- 규칙 2: Android 도 한 번 = 선택 · 두 번 = 실행 (explorerClick 처음 값 'select')
- 규칙 3: 펼친 폴더를 다시 누르면 접기 처음 값 켬 (explorerRetapCollapse)
- 규칙 4: 줄 끝 표시는 선택 모드에서만 (explorerAlwaysMarks 처음 값 끔), 모양 V (Icons.check)
- 규칙 7 · 결정 3: 처음 배치 두 창 (폰 세로도), 'auto' 는 설정으로 남김
- 규칙 이전 판에서 저장된 예전 처음 값은 한 번 새 값으로 옮기고 업데이트 뒤 한 번 알림 (explorerRulesV1,
  알림 explorerMarksRule · explorerRetapRule · explorerClickRule · explorerLayoutRule) - 근거: 10/8 사용자 결정
  "예전 기본값을 옮긴 설정은 업데이트 뒤 한 번 알림". 그 뒤 사용자가 고른 값은 그대로
- 결정 (a): Windows 처음 스타일 = TC 와 저장된 'xplore' 묻기 (결정 1) 는 E6 (TC 모양) 과 함께 - 이번에는 넣지 않음
- 번역 9개 추가 · 안 쓰게 된 5개 뺌 (빠진 번역 0)

기대값을 바꾼 시험 (규칙 번호):
- 규칙 7: decisions_test 처음 배치 'dual' / settings_store_test 예전 'dual' 그대로 · 'explorerLayout' 알림 없음
- 규칙 4: explorer_test "두 창: …" 첫 화면에 표시 없음 / "선택 모드: …" V 모양 · 고름 여부 · [선택 끝] 뒤 표시 없음 ·
  설정 '늘 보이기' 를 켜면 보임 / explorer_text_scale_test 3개 (✔ 칸 자리) 는 사용자 설정 explorerAlwaysMarks 를 켜서
- 규칙 3: explorer_test 다시 눌러 접기 (처음 값 켬)
- 규칙 1: explorer_test 빠른 보기 F3 · 새로 고침 Ctrl+R (2곳, Windows 에서 F5 는 복사)
- 새 시험: settings_store_test "E3: 규칙 이전 판 처음 값 옮기기 · 알림 · 다시 고른 값 그대로"

확인: analyze 0, 전체 단위 2회 통과 1,299 · 건너뜀 17 · 실패 0. Selection 지문 그대로 (d438fac0)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
split_pages
RyuJongJin 2026-10-22 06:09:50 +09:00
parent 797126b297
commit 9ba39e5ed6
12 changed files with 146 additions and 78 deletions

View File

@ -424,10 +424,9 @@
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "Available on Windows only. On this device, documents open in another app.",
"Windows 오류 0x{0}": "Windows error 0x{0}",
"Windows 탐색기": "Windows Explorer",
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore style: always show selection marks",
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore style: swipe sideways to switch panes",
"X-plore 스타일: 표시 동그라미 늘 보이기": "X-plore style: always show the mark circles",
"X-plore 스타일에서 X-plore 처럼 한 트리에 보입니다 (위 줄 탭 · ★ 는 그대로)": "In the X-plore style they appear in one tree like X-plore (the tabs and ★ at the top stay)",
"X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "Like X-plore. When off, folders collapse and expand only with the › arrow (the list doesn't move on a double tap)",
"YouTube · 토렌트 다운로드 목록": "YouTube · torrent download list",
"YouTube → yt-dlp, 마그넷 · .torrent → aria2 (완료 후 올려 주기 안 함)": "YouTube → yt-dlp, magnet · .torrent → aria2 (no seeding after completion)",
"YouTube 가 로봇 확인을 요구합니다. 환경 설정 > 다운로드 > YouTube 쿠키 에서 브라우저(Firefox 권장) 또는 cookies.txt 를 지정한 뒤 다시 받으세요.": "YouTube is asking for a robot check. In Settings > Downloads > YouTube cookies, choose a browser (Firefox recommended) or a cookies.txt, then download again.",
@ -903,9 +902,9 @@
"꺼냈습니다: {0}": "Exported: {0}",
"끄기": "Off",
"끄면 (기본) Tor 화면을 떠날 때 (다른 화면 · 앱이 뒤로) 지웁니다. 일반 브라우저와는 늘 따로입니다.": "When off (default), they are cleared when you leave the Tor screen (another screen, or the app goes to the background). They are always kept separate from the normal browser.",
"끄면 (처음 값) [선택] 을 켰을 때만 보입니다. 다른 스타일은 늘 선택 모드에서만": "When off (default), marks appear only while [Select] is on. Other styles always show them only in select mode",
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "Off is safer, but many sites will not display (from the next time it opens).",
"끄면 마지막 설정으로 바로 시작: 원어 {0}, 언어 {1}, {2}": "When off, starts right away with the last settings: source {0}, languages {1}, {2}",
"끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)": "When off, they show only in selection mode (other styles always show them only in selection mode)",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "When off, page scripts do not run (fewer ads · trackers, but script-built sites such as YouTube will not show). With the Chrome engine, page translation · video detection also stop.",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "When off, page scripts do not run (fewer ads · trackers, but script-built sites such as YouTube will not show). Page translation · video detection also stop.",
"끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다": "When off, the web page keeps playing sound while you look at settings, the download list or other screens",
@ -1196,7 +1195,7 @@
"두 쪽 나눠 보기: 자동 - 가로로 긴 그림만 (누르면 켜기)": "Split two-page spreads: auto - wide images only (tap to turn on)",
"두 쪽 나눠 보기: 자동 - 두 쪽 스캔으로 보이는 그림만 (누르면 켜기)": "Two-page split: Auto - only images that look like two-page scans (tap to turn on)",
"두 쪽 나눠 보기: 켜기 (누르면 끄기)": "Split two-page spreads: on (tap to turn off)",
"두 창": "Two panes",
"두 창 (기본)": "Two panes (default)",
"두 창 배치": "Two-pane arrangement",
"두 창 사이": "Between panes",
"두 창 파일 탐색기 · 복사 · 이동 · WebDAV": "Dual-pane file explorer · copy · move · WebDAV",
@ -2747,6 +2746,7 @@
"채우기 (가운데 잘라냄)": "Fill (crop the center)",
"처리 장치": "Processor",
"처음 · 🏠 주소 (기본: Tor 연결 확인 페이지)": "Start / 🏠 address (default: the Tor connection check page)",
"처음 값 켬. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "On by default. When off, collapse and expand only with the › arrow (the list does not move on a double tap)",
"처음 값으로": "Reset",
"처음 보는 서버 인증서입니다": "This server certificate is new",
"처음 보는 서버 인증서입니다 (자체 서명). 지문을 확인한 뒤 믿을지 정하세요": "This server certificate is new (self-signed). Check the fingerprint, then decide whether to trust it",
@ -2887,7 +2887,11 @@
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "Row height in the file explorer list. Compact rows may be hard to tap with a finger",
"파일 탐색기 위쪽 ⋮ 메뉴에서도 바꿀 수 있습니다 (좌우 · 위아래 · 버튼 줄 위치 · 버튼 구성)": "You can also change it from the ⋮ menu at the top of the file explorer (side by side · top and bottom · button bar position · buttons)",
"파일 탐색기 창: 두 창 → 화면 크기 따라 (폰 세로는 한 창). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "File explorer panes: two panes → by screen size (one pane on a portrait phone). To revert: Settings > File explorer > Pane layout",
"파일 탐색기 창: 화면 크기 따라 → 두 창 (폰 세로도 좌우). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "File explorer panes: by screen size → two panes (side by side even on a phone in portrait). To undo: Settings > File explorer > Pane layout",
"파일 탐색기: 줄 끝 선택 표시는 [선택] 을 켰을 때만 보입니다 (모양 V). 늘 보이게: 환경 설정 > 파일 탐색기 > X-plore 스타일: 선택 표시 늘 보이기": "File explorer: the selection mark at the end of each row (a V) appears only while [Select] is on. To always show it: Settings > File explorer > X-plore style: always show selection marks",
"파일 탐색기: 파일을 한 번 누르면 바로 엽니다 (고르기 · 메뉴는 길게 누르기). 바꾸기: 환경 설정 > 파일 탐색기 > 누르기": "File explorer: a single tap now opens a file right away (long-press to select or for the menu). To change: Settings > File explorer > Tap",
"파일 탐색기: 파일을 한 번 누르면 선택, 두 번 누르면 엽니다. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "File explorer: tap a file once to select it, twice to open it. To undo: Settings > File explorer > Tap",
"파일 탐색기: 펼친 폴더를 다시 누르면 접힙니다. 되돌리기: 환경 설정 > 파일 탐색기 > 펼친 폴더를 다시 누르면 접기": "File explorer: tapping an expanded folder again collapses it. To undo: Settings > File explorer > Tap an open folder again to collapse",
"파일 탐색기의 길게 누르기 [목록에서 숨기기] 로 숨긴 것. 파일은 그대로이고 목록에서만 빠집니다": "Hidden with long-press [Hide from list] in the file explorer. The files are unchanged; they are only left out of the list",
"파일 폴더": "File folder",
"파일 확인 중…": "Checking files…",
@ -3073,7 +3077,7 @@
"화면 크게": "Larger",
"화면 크기": "Size",
"화면 크기 · 종료": "Screen size · Exit",
"화면 크기 따라 (기본)": "By screen size (default)",
"화면 크기 따라": "By screen size",
"화면이 있는 컴포넌트는 하나 이상 남아 있어야 합니다.": "At least one component with a screen must stay installed.",
"화질": "Quality",
"확인": "OK",

View File

@ -424,10 +424,9 @@
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "Windows でのみ使えます。この端末では文書を他のアプリで開きます。",
"Windows 오류 0x{0}": "Windows エラー 0x{0}",
"Windows 탐색기": "Windows エクスプローラー",
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore スタイル: 選択マークを常に表示",
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore スタイル: 横にスワイプでペイン切り替え",
"X-plore 스타일: 표시 동그라미 늘 보이기": "X-plore スタイル: 選択の丸を常に表示",
"X-plore 스타일에서 X-plore 처럼 한 트리에 보입니다 (위 줄 탭 · ★ 는 그대로)": "X-plore スタイルで X-plore のように 1 つのツリーに表示します (上部のタブ・★ はそのまま)",
"X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "X-plore のように。オフのときは › 矢印でのみ開閉します (2 回押しても一覧は動きません)",
"YouTube · 토렌트 다운로드 목록": "YouTube・トレント ダウンロード一覧",
"YouTube → yt-dlp, 마그넷 · .torrent → aria2 (완료 후 올려 주기 안 함)": "YouTube → yt-dlp、マグネット・.torrent → aria2(完了後のアップロードなし)",
"YouTube 가 로봇 확인을 요구합니다. 환경 설정 > 다운로드 > YouTube 쿠키 에서 브라우저(Firefox 권장) 또는 cookies.txt 를 지정한 뒤 다시 받으세요.": "YouTube がロボット確認を求めています。環境設定 > ダウンロード > YouTube クッキー でブラウザー(Firefox 推奨)または cookies.txt を指定してから、もう一度ダウンロードしてください。",
@ -903,9 +902,9 @@
"꺼냈습니다: {0}": "取り出しました: {0}",
"끄기": "オフ",
"끄면 (기본) Tor 화면을 떠날 때 (다른 화면 · 앱이 뒤로) 지웁니다. 일반 브라우저와는 늘 따로입니다.": "オフ (既定) の場合は Tor 画面を離れるとき (別の画面 · アプリがバックグラウンドへ) に消去します。通常のブラウザーとは常に別です。",
"끄면 (처음 값) [선택] 을 켰을 때만 보입니다. 다른 스타일은 늘 선택 모드에서만": "オフ (既定) のときは [選択] をオンにしたときだけ表示されます。ほかのスタイルは常に選択モードのときだけ",
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "オフの方が安全ですが、多くのサイトが表示されません (次に開くときから)。",
"끄면 마지막 설정으로 바로 시작: 원어 {0}, 언어 {1}, {2}": "オフにすると前回の設定ですぐ開始: 原語 {0}、言語 {1}、{2}",
"끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)": "オフにすると選択モードのときだけ表示します (他のスタイルは常に選択モードのときだけ)",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "オフにするとページのスクリプトを実行しません (広告 · 追跡は減りますが、YouTube のようにスクリプトで作られたサイトは表示されません)。Chrome エンジンではページ翻訳 · 動画の検出も止まります。",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "オフにするとページのスクリプトを実行しません (広告 · 追跡は減りますが、YouTube のようにスクリプトで作られたサイトは表示されません)。ページ翻訳 · 動画の検出も止まります。",
"끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다": "オフにすると、環境設定・ダウンロード一覧・他の画面を見ている間も Web ページの音が流れ続けます",
@ -1196,7 +1195,7 @@
"두 쪽 나눠 보기: 자동 - 가로로 긴 그림만 (누르면 켜기)": "見開きを分けて表示: 自動 - 横長の画像のみ (押すとオン)",
"두 쪽 나눠 보기: 자동 - 두 쪽 스캔으로 보이는 그림만 (누르면 켜기)": "見開き分割: 自動 - 見開きスキャンらしい画像だけ (押すとオン)",
"두 쪽 나눠 보기: 켜기 (누르면 끄기)": "見開きを分けて表示: オン (押すとオフ)",
"두 창": "2 ペイン",
"두 창 (기본)": "2 画面 (既定)",
"두 창 배치": "2 ペインの配置",
"두 창 사이": "ペインの間",
"두 창 파일 탐색기 · 복사 · 이동 · WebDAV": "2 画面ファイルエクスプローラー・コピー・移動・WebDAV",
@ -2747,6 +2746,7 @@
"채우기 (가운데 잘라냄)": "フィル(中央を切り抜き)",
"처리 장치": "処理装置",
"처음 · 🏠 주소 (기본: Tor 연결 확인 페이지)": "最初・🏠 のアドレス (既定: Tor 接続確認ページ)",
"처음 값 켬. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "既定でオン。オフにすると折りたたみ · 展開は › 矢印だけ (2 回押しても一覧が動かない)",
"처음 값으로": "既定に戻す",
"처음 보는 서버 인증서입니다": "初めて見るサーバー証明書です",
"처음 보는 서버 인증서입니다 (자체 서명). 지문을 확인한 뒤 믿을지 정하세요": "初めて見るサーバー証明書です (自己署名)。指紋を確認してから信頼するか決めてください",
@ -2887,7 +2887,11 @@
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "ファイルエクスプローラー一覧の行の高さ。狭くすると指でタップしにくい場合があります",
"파일 탐색기 위쪽 ⋮ 메뉴에서도 바꿀 수 있습니다 (좌우 · 위아래 · 버튼 줄 위치 · 버튼 구성)": "ファイルエクスプローラー上部の ⋮ メニューからも変えられます (左右 · 上下 · ボタン列の位置 · ボタン構成)",
"파일 탐색기 창: 두 창 → 화면 크기 따라 (폰 세로는 한 창). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "ファイルエクスプローラーの画面: 2 画面 → 画面サイズに合わせる (縦向きのスマホは 1 画面)。元に戻す: 環境設定 > ファイルエクスプローラー > 画面配置",
"파일 탐색기 창: 화면 크기 따라 → 두 창 (폰 세로도 좌우). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "ファイルエクスプローラーの画面: 画面サイズに合わせる → 2 画面 (スマホ縦でも左右)。戻すには: 環境設定 > ファイルエクスプローラー > ペインの配置",
"파일 탐색기: 줄 끝 선택 표시는 [선택] 을 켰을 때만 보입니다 (모양 V). 늘 보이게: 환경 설정 > 파일 탐색기 > X-plore 스타일: 선택 표시 늘 보이기": "ファイルエクスプローラー: 行末の選択マーク (V) は [選択] をオンにしたときだけ表示されます。常に表示するには: 環境設定 > ファイルエクスプローラー > X-plore スタイル: 選択マークを常に表示",
"파일 탐색기: 파일을 한 번 누르면 바로 엽니다 (고르기 · 메뉴는 길게 누르기). 바꾸기: 환경 설정 > 파일 탐색기 > 누르기": "ファイルエクスプローラー: ファイルを 1 回タップするとすぐ開きます (選択 · メニューは長押し)。変更: 環境設定 > ファイルエクスプローラー > タップ",
"파일 탐색기: 파일을 한 번 누르면 선택, 두 번 누르면 엽니다. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "ファイルエクスプローラー: ファイルを 1 回押すと選択、2 回押すと開きます。戻すには: 環境設定 > ファイルエクスプローラー > タップ",
"파일 탐색기: 펼친 폴더를 다시 누르면 접힙니다. 되돌리기: 환경 설정 > 파일 탐색기 > 펼친 폴더를 다시 누르면 접기": "ファイルエクスプローラー: 展開したフォルダーをもう一度押すと折りたたみます。戻すには: 環境設定 > ファイルエクスプローラー > 開いたフォルダーをもう一度押すと閉じる",
"파일 탐색기의 길게 누르기 [목록에서 숨기기] 로 숨긴 것. 파일은 그대로이고 목록에서만 빠집니다": "ファイルエクスプローラーの長押し [リストから隠す] で隠したもの。ファイルはそのままで、リストから外れるだけです",
"파일 폴더": "ファイル フォルダー",
"파일 확인 중…": "ファイルを確認中…",
@ -3073,7 +3077,7 @@
"화면 크게": "画面を大きく",
"화면 크기": "画面サイズ",
"화면 크기 · 종료": "画面サイズ・終了",
"화면 크기 따라 (기본)": "画面サイズに合わせる (既定)",
"화면 크기 따라": "画面サイズに合わせる",
"화면이 있는 컴포넌트는 하나 이상 남아 있어야 합니다.": "画面のあるコンポーネントを少なくとも1つ残す必要があります。",
"화질": "画質",
"확인": "OK",

View File

@ -424,10 +424,9 @@
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "仅限 Windows。在本设备上会用其他应用打开文档。",
"Windows 오류 0x{0}": "Windows 错误 0x{0}",
"Windows 탐색기": "Windows 资源管理器",
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore 样式: 始终显示选择标记",
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore 样式: 左右滑动切换窗格",
"X-plore 스타일: 표시 동그라미 늘 보이기": "X-plore 样式: 始终显示标记圆圈",
"X-plore 스타일에서 X-plore 처럼 한 트리에 보입니다 (위 줄 탭 · ★ 는 그대로)": "在 X-plore 样式中像 X-plore 一样显示在一棵树中 (顶部的标签 · ★ 保持不变)",
"X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "像 X-plore 一样。关闭时仅用 › 箭头折叠 · 展开 (双击时列表不会移动)",
"YouTube · 토렌트 다운로드 목록": "YouTube · 种子下载列表",
"YouTube → yt-dlp, 마그넷 · .torrent → aria2 (완료 후 올려 주기 안 함)": "YouTube → yt-dlp,磁力链接 · .torrent → aria2(完成后不做种)",
"YouTube 가 로봇 확인을 요구합니다. 환경 설정 > 다운로드 > YouTube 쿠키 에서 브라우저(Firefox 권장) 또는 cookies.txt 를 지정한 뒤 다시 받으세요.": "YouTube 要求进行机器人验证。请在 设置 > 下载 > YouTube Cookie 中指定浏览器(推荐 Firefox)或 cookies.txt 后重新下载。",
@ -903,9 +902,9 @@
"꺼냈습니다: {0}": "已导出: {0}",
"끄기": "关闭",
"끄면 (기본) Tor 화면을 떠날 때 (다른 화면 · 앱이 뒤로) 지웁니다. 일반 브라우저와는 늘 따로입니다.": "关闭时(默认)在离开 Tor 页面时(切换到其他页面或应用转到后台)清除。始终与普通浏览器分开。",
"끄면 (처음 값) [선택] 을 켰을 때만 보입니다. 다른 스타일은 늘 선택 모드에서만": "关闭 (默认) 时仅在打开 [选择] 时显示。其他样式始终仅在选择模式中显示",
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "关闭更安全,但很多网站将无法显示 (从下次打开起)。",
"끄면 마지막 설정으로 바로 시작: 원어 {0}, 언어 {1}, {2}": "关闭后将直接使用上次的设置开始: 原语言 {0},语言 {1},{2}",
"끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)": "关闭时仅在选择模式下显示 (其他样式始终仅在选择模式下显示)",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "关闭后不运行页面脚本 (广告 · 跟踪会减少,但 YouTube 等由脚本构建的网站将无法显示)。使用 Chrome 引擎时,页面翻译 · 视频检测也会停止。",
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "关闭后不运行页面脚本 (广告 · 跟踪会减少,但 YouTube 等由脚本构建的网站将无法显示)。页面翻译 · 视频检测也会停止。",
"끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다": "关闭后,在查看设置、下载列表或其他界面时网页声音会继续播放",
@ -1196,7 +1195,7 @@
"두 쪽 나눠 보기: 자동 - 가로로 긴 그림만 (누르면 켜기)": "拆分双页: 自动 - 仅横向图片 (点按开启)",
"두 쪽 나눠 보기: 자동 - 두 쪽 스캔으로 보이는 그림만 (누르면 켜기)": "双页拆分:自动 - 仅拆分看起来像双页扫描的图片(点按开启)",
"두 쪽 나눠 보기: 켜기 (누르면 끄기)": "拆分双页: 开启 (点按关闭)",
"두 창": "双窗格",
"두 창 (기본)": "双窗格 (默认)",
"두 창 배치": "双窗格排列",
"두 창 사이": "窗格之间",
"두 창 파일 탐색기 · 복사 · 이동 · WebDAV": "双窗格文件浏览器 · 复制 · 移动 · WebDAV",
@ -2747,6 +2746,7 @@
"채우기 (가운데 잘라냄)": "填充(裁切中间)",
"처리 장치": "处理器",
"처음 · 🏠 주소 (기본: Tor 연결 확인 페이지)": "起始 · 🏠 地址 (默认: Tor 连接检查页面)",
"처음 값 켬. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "默认开启。关闭后只能用 › 箭头折叠 · 展开 (双击时列表不会移动)",
"처음 값으로": "恢复默认",
"처음 보는 서버 인증서입니다": "这是首次见到的服务器证书",
"처음 보는 서버 인증서입니다 (자체 서명). 지문을 확인한 뒤 믿을지 정하세요": "这是首次见到的服务器证书 (自签名)。请确认指纹后决定是否信任",
@ -2887,7 +2887,11 @@
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "文件管理器列表的行高。紧凑时可能难以用手指点按",
"파일 탐색기 위쪽 ⋮ 메뉴에서도 바꿀 수 있습니다 (좌우 · 위아래 · 버튼 줄 위치 · 버튼 구성)": "也可以在文件浏览器顶部的 ⋮ 菜单中更改 (左右 · 上下 · 按钮栏位置 · 按钮配置)",
"파일 탐색기 창: 두 창 → 화면 크기 따라 (폰 세로는 한 창). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "文件浏览器窗格: 双窗格 → 按屏幕大小 (竖屏手机为单窗格)。恢复: 设置 > 文件浏览器 > 窗格布局",
"파일 탐색기 창: 화면 크기 따라 → 두 창 (폰 세로도 좌우). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치": "文件浏览器窗格: 随屏幕大小 → 双窗格 (手机竖屏也左右)。恢复: 设置 > 文件浏览器 > 窗格布局",
"파일 탐색기: 줄 끝 선택 표시는 [선택] 을 켰을 때만 보입니다 (모양 V). 늘 보이게: 환경 설정 > 파일 탐색기 > X-plore 스타일: 선택 표시 늘 보이기": "文件浏览器: 行尾的选择标记 (V) 仅在打开 [选择] 时显示。要始终显示: 设置 > 文件浏览器 > X-plore 样式: 始终显示选择标记",
"파일 탐색기: 파일을 한 번 누르면 바로 엽니다 (고르기 · 메뉴는 길게 누르기). 바꾸기: 환경 설정 > 파일 탐색기 > 누르기": "文件浏览器:单击文件会立即打开(选择 · 菜单请长按)。更改:设置 > 文件浏览器 > 点按",
"파일 탐색기: 파일을 한 번 누르면 선택, 두 번 누르면 엽니다. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "文件浏览器: 点按文件一次为选择, 两次为打开。恢复: 设置 > 文件浏览器 > 点按",
"파일 탐색기: 펼친 폴더를 다시 누르면 접힙니다. 되돌리기: 환경 설정 > 파일 탐색기 > 펼친 폴더를 다시 누르면 접기": "文件浏览器: 再次点按已展开的文件夹会将其折叠。恢复: 设置 > 文件浏览器 > 再次点按已展开的文件夹可折叠",
"파일 탐색기의 길게 누르기 [목록에서 숨기기] 로 숨긴 것. 파일은 그대로이고 목록에서만 빠집니다": "在文件浏览器中长按 [从列表中隐藏] 隐藏的项。文件本身不变,只是不在列表中显示",
"파일 폴더": "文件夹",
"파일 확인 중…": "正在检查文件…",
@ -3073,7 +3077,7 @@
"화면 크게": "放大界面",
"화면 크기": "画面大小",
"화면 크기 · 종료": "界面大小 · 退出",
"화면 크기 따라 (기본)": "按屏幕大小 (默认)",
"화면 크기 따라": "随屏幕大小",
"화면이 있는 컴포넌트는 하나 이상 남아 있어야 합니다.": "至少要保留一个带界面的组件。",
"화질": "画质",
"확인": "确定",

View File

@ -412,16 +412,17 @@ class AppSettings {
bool torNoticeSeen = false;
// ── 파일 탐색기 (X-plore 참고) ──
/// 창: 'dual' 두 창 (기본) · 'split' 왼쪽 폴더 트리 + 오른쪽 그 폴더의 파일 목록 · 'single' 한 창
String explorerLayout = 'auto';
/// 창: 'dual' 두 창 (기본 - 폰 세로도, 규칙 7 · 결정 3 10/22) · 'split' 왼쪽 폴더 트리 + 오른쪽 그 폴더의 파일 목록 ·
/// 'single' 한 창 · 'auto' 화면 크기 따라 (폰 세로는 한 창)
String explorerLayout = 'dual';
/// X-plore 비교 a: 한 창일 때 복사 · 이동 - 'clip' 담아 두었다가 붙여넣기 (지금 그대로, 처음 값) /
/// 'other' 숨은 다른 창의 폴더로 바로 (X-plore 처럼, 위에 "갈 곳" 줄). 예전 동작과 달라 처음 값은 그대로 (관리자 결정)
String explorerOnePaneCopy = 'clip';
/// X-plore 비교 d: 펼쳐 둔 지금 폴더를 다시 누르면 접기 (X-plore 처럼). 처음 값 끔 - 189 (관리자 지시: 이름으로는 접지 않아
/// 다시 · 두 번 눌러도 아래 줄이 움직이지 않게) 와 부딪혀 설정으로만. 켜도 두 번 누르기의 두 번째는 접지 않는다
bool explorerRetapCollapse = false;
/// 펼친 폴더를 다시 누르면 접기 (규칙 3 "폴더 한 번 누르기 = 펼치기 · 접기", 처음 값 켬 - E3 10/22).
/// 두 번 누르기의 두 번째는 접지 않는다 ([ClickPolicy] repeat)
bool explorerRetapCollapse = true;
/// X-plore 비교 40 (관리자 지시 10/20): 파일 탐색기 목록만의 글자 크기 (%, 80~150, 처음 100 = 지금 그대로).
/// 앱 화면 크기 · 기기 글자 크기와 곱해진다
@ -438,8 +439,8 @@ class AppSettings {
/// 처음 값 켬 (X-plore 스타일에서만 보임 - 다른 스타일은 그대로)
bool explorerRootsInTree = true;
/// X-plore 비교 ⚖ (관리자 결정 10/18): X-plore 스타일에서 줄 끝 표시 동그라미를 늘 보이기 (처음 값 켬). 다른 스타일은 선택 모드에서만 (10/5)
bool explorerAlwaysMarks = true;
/// X-plore 스타일에서 줄 끝 표시를 늘 보이기. 처음 값 끔 - 규칙 4 "선택 표시는 선택 모드에서만" (E3 10/22)
bool explorerAlwaysMarks = false;
/// X-plore 비교 ⚖: X-plore 스타일 탐색기 안에서 옆으로 밀기 = 창 바꾸기 (설정으로만, 처음 값 끔 - 10/8 사용자 결정 "화면 가운데를 밀면 화면 이동" 을 지킴, 관리자 판단 10/18)
@ -448,11 +449,12 @@ class AppSettings {
/// X-plore 비교 e (관리자 결정): Android 앱 휴지통 보관 일 (처음 14일, 0 = 끔 - 예전처럼 바로 영구 삭제). Windows 는 시스템 휴지통
int androidTrashDays = 14;
/// 누르기: 'select' 한 번 = 선택 · 두 번 = 열기 (기본) / 'open' 한 번 = 바로 열기.
/// 누르기: 'select' 한 번 = 선택 · 두 번 = 열기 (기본, 두 기기 - 규칙 2) / 'open' 한 번 = 바로 열기.
/// 길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴.
String explorerClick = Platform.isAndroid ? 'open' : 'select';
String explorerClick = 'select';
/// 모양: 'xplore' (기본) · 'windows' Windows 탐색기 · 'totalcmd' Total Commander
/// 모양: 'xplore' (기본) · 'windows' Windows 탐색기 · 'totalcmd' Total Commander.
/// 규칙 1 의 Windows 처음 값 (Total Commander) 과 저장된 값 묻기 (결정 1) 는 E6 (TC 모양) 과 함께 (관리자 결정 10/22)
String explorerStyle = 'xplore';
/// 두 창 배치: 'side' 좌우 (기본, 118 - 폰 세로에서도) · 'stacked' 위아래 · 'auto' 화면 모양 따라 (가로로 넓으면 좌우, 세로로 길면 위아래)
@ -885,6 +887,8 @@ class AppSettings {
'explorerClick': explorerClick,
// 예전 기본값 (두 창 · 한 번 누르면 선택) 은 사용자가 고른 값이 아니므로 한 번 새 기본값으로 옮긴다
'explorerV2': true,
// E3 (10/22): 선택 규칙 (사용자 지시 모음) 의 처음 값으로 한 번 옮겼음
'explorerRulesV1': true,
'explorerStyle': explorerStyle,
'explorerOrientation': explorerOrientation,
'explorerOrientV3': true,
@ -1116,7 +1120,8 @@ class AppSettings {
..torNoticeSeen = j['torNoticeSeen'] == true
// 'auto' = 넓은 화면은 두 창, 좁은 화면 (폰 세로) 은 한 창. 예전 기본 'dual' 은 한 번 'auto' 로
..explorerOnePaneCopy = j['explorerOnePaneCopy'] == 'other' ? 'other' : 'clip'
..explorerRetapCollapse = j['explorerRetapCollapse'] == true
// E3: 규칙 이전 판이 저장한 false 는 예전 처음 값 - 한 번 규칙 3 (켬) 으로
..explorerRetapCollapse = j['explorerRulesV1'] == true ? j['explorerRetapCollapse'] != false : true
// 값이 없거나 틀리면 지금 그대로 (100% · 보통), 범위 밖은 끝으로
..explorerTextScale = j['explorerTextScale'] is num
? (j['explorerTextScale'] as num).round().clamp(explorerTextScaleMin, explorerTextScaleMax)
@ -1124,20 +1129,18 @@ class AppSettings {
..explorerRowSpacing = const {'compact', 'normal', 'wide'}.contains(j['explorerRowSpacing']) ? j['explorerRowSpacing'] as String : 'normal'
..batchRenameLast = j['batchRenameLast'] is Map ? Map<String, dynamic>.from(j['batchRenameLast'] as Map) : {}
..explorerRootsInTree = j['explorerRootsInTree'] != false
..explorerAlwaysMarks = j['explorerAlwaysMarks'] != false
// E3: 규칙 이전 판이 저장한 true 는 예전 처음 값 - 한 번 규칙 4 (끔) 로
..explorerAlwaysMarks = j['explorerRulesV1'] == true && j['explorerAlwaysMarks'] == true
..explorerSwipePanes = j['explorerSwipePanes'] == true
..androidTrashDays = switch (j['androidTrashDays']) { final int d when d >= 0 && d <= 365 => d, _ => 14 }
..explorerLayout = const ['single', 'split', 'auto'].contains(j['explorerLayout'])
? j['explorerLayout'] as String
: j['explorerLayout'] == 'dual' && j['explorerV2'] == true
? 'dual'
: 'auto'
// Android 는 손가락으로 한 번 누르면 바로 실행이 기본. 예전 기본 'select' 는 Android 에서 한 번 'open' 으로
..explorerClick = j['explorerClick'] == 'open'
? 'open'
: j['explorerClick'] == 'select' && (j['explorerV2'] == true || !Platform.isAndroid)
? 'select'
: (Platform.isAndroid ? 'open' : 'select')
// E3 (규칙 7 · 결정 3): 처음 값 두 창. 규칙 이전 판의 'auto' 는 예전 처음 값이라 한 번 두 창으로
..explorerLayout = switch (j['explorerLayout']) {
'single' || 'split' => j['explorerLayout'] as String,
'auto' when j['explorerRulesV1'] == true => 'auto',
_ => 'dual',
}
// 규칙 2: 두 기기 모두 한 번 = 선택. 규칙 이전 Android 의 'open' 은 예전 처음 값이라 한 번 'select' 로
..explorerClick = j['explorerClick'] == 'open' && (j['explorerRulesV1'] == true || !Platform.isAndroid) ? 'open' : 'select'
..explorerStyle = const ['windows', 'totalcmd'].contains(j['explorerStyle']) ? j['explorerStyle'] as String : 'xplore'
// 118: 예전 기본 '화면 모양 따라' 는 한 번 좌우로 옮긴다 (사용자가 고른 위아래는 그대로)
..explorerOrientation = j['explorerOrientation'] == 'stacked'
@ -1392,6 +1395,12 @@ class AppSettings {
// 193: 그 설정이 생기기 전 판 (설정 파일은 있는데 그 항목이 없음 - 예: 10.03) 에서 올라온 사람이 바로 겪는 동작 변화.
// 예전 판에는 키가 없어 위의 "예전 값 → 새 값" 조건에 걸리지 않았다 (P11: 탐색기에서 한 번 눌렀는데 바로 열려 놀람)
if (j.isNotEmpty && !j.containsKey('explorerClick') && s.explorerClick == 'open') 'explorerClickNew',
// E3 (10/22): 선택 규칙의 처음 값으로 옮긴 것 - 규칙 이전 판에서 올라온 사람에게 한 번
if (j.isNotEmpty && j['explorerRulesV1'] != true && j['explorerAlwaysMarks'] != false) 'explorerMarksRule',
if (j.isNotEmpty && j['explorerRulesV1'] != true && j['explorerRetapCollapse'] != true) 'explorerRetapRule',
if (j.isNotEmpty && j['explorerRulesV1'] != true && Platform.isAndroid && j['explorerClick'] != 'select')
'explorerClickRule',
if (j.isNotEmpty && j['explorerRulesV1'] != true && (j['explorerLayout'] ?? 'auto') == 'auto') 'explorerLayoutRule',
if (j.isNotEmpty && !j.containsKey('screenOrientation') && s.screenOrientation == 'auto' && Platform.isAndroid) 'orientation',
if (j.isNotEmpty && !j.containsKey('swipeNav') && s.swipeNav) 'swipeNav',
if (j.isNotEmpty && !j.containsKey('runInBackground') && s.runInBackground && Platform.isAndroid) 'background',

View File

@ -35,7 +35,7 @@ String explorerKeyLabel(String id) => switch (id) {
_ => id,
};
/// 스타일의 처음 키 (83 과 같음). [tc] Total Commander 스타일
/// 처음 키. [tc] Total Commander 키 (규칙 1, 10/22: Windows 는 스타일과 상관없이 TC 키 + Ctrl+C · X · V · A)
Map<String, List<SingleActivator>> defaultExplorerKeys({required bool tc}) => {
'delete': [const SingleActivator(LogicalKeyboardKey.delete), if (tc) const SingleActivator(LogicalKeyboardKey.f8)],
'deletePermanent': [const SingleActivator(LogicalKeyboardKey.delete, shift: true)],
@ -53,6 +53,10 @@ Map<String, List<SingleActivator>> defaultExplorerKeys({required bool tc}) => {
'markNext': [const SingleActivator(LogicalKeyboardKey.insert)],
'mark': [const SingleActivator(LogicalKeyboardKey.space)],
'quickLook': [const SingleActivator(LogicalKeyboardKey.f3)],
'clipCopy': [const SingleActivator(LogicalKeyboardKey.keyC, control: true)],
'clipCut': [const SingleActivator(LogicalKeyboardKey.keyX, control: true)],
'paste': [const SingleActivator(LogicalKeyboardKey.keyV, control: true)],
'selectAll': [const SingleActivator(LogicalKeyboardKey.keyA, control: true)],
} else ...{
'quickLook': [const SingleActivator(LogicalKeyboardKey.space)],
'refresh': [const SingleActivator(LogicalKeyboardKey.f5)],

View File

@ -4453,8 +4453,8 @@ class _ExplorerPageState extends State<ExplorerPage> {
width: 420,
child: Column(mainAxisSize: MainAxisSize.min, crossAxisAlignment: CrossAxisAlignment.start, children: [
group(tr('창'), layout, [
('auto', tr('화면 크기 따라 (기본)')),
('dual', tr('두 창')),
('auto', tr('화면 크기 따라')),
('dual', tr('두 창 (기본)')),
('split', tr('폴더 + 파일 목록')),
('single', tr('한 창')),
], (v) => layout = v),
@ -5255,7 +5255,7 @@ class _ExplorerPageState extends State<ExplorerPage> {
}
/// 83: 지금 스타일이 Total Commander 인지 (Rsync 화면은 스타일 단축키를 쓰지 않는다 - 늘 같은 버튼)
bool get _tcKeys => !widget.rsync && _look == ExplorerStyle.totalcmd;
bool get _tcKeys => !widget.rsync && Platform.isWindows;
/// 83 · X-plore 비교 5-1 ⑥ (관리자 지시 10/21): 동작마다의 키 → 할 일. 처음 키는 스타일대로 (Total Commander: F5 복사 · F6 이동 ·
/// F7 새 폴더 · F8 지우기 · Insert/Space 표시 · Ctrl+R 새로 고침 / Windows 탐색기 · X-plore: Ctrl+C · X · V · A · F5 새로 고침),
@ -5925,9 +5925,9 @@ class _ExplorerPageState extends State<ExplorerPage> {
: tr('표시 (여러 개 고르기)'),
visualDensity: VisualDensity.compact,
padding: EdgeInsets.zero,
// ✔ 모양: 고르지 않은 것은 흐리게, 고른 것은 진하게
icon: Icon(marked ? Icons.check_circle : Icons.check_circle_outline,
size: look.rich ? 22 : 18,
// 규칙 4: V 모양 - 고르지 않은 것은 흐리게, 고른 것은 진하게
icon: Icon(Icons.check,
size: look.rich ? 24 : 20,
color: marked ? JjColors.accent : JjColors.textDim.withValues(alpha: 0.35)),
onPressed: () {
setState(() => _active = _panes.indexOf(pane));

View File

@ -33,6 +33,12 @@ Future<void> showMigrationNotice(BuildContext context, AppController c) async {
'끄기: 환경 설정 > 컴포넌트 > 좌우로 밀어 화면 이동'),
'copySkipNewer' => tr('복사 · 이동: 받는 쪽 파일이 더 새것이면 건너뜁니다 (예전에는 예전 원본으로 덮어쓰고, 이동이면 원본도 지웠습니다). '
'건너뛴 파일은 원본에 남고 끝 알림에 그 수가 나옵니다. 되돌리기: 환경 설정 > 파일 탐색기 (또는 Rsync) > 받는 쪽이 더 새것이면 건너뛰기'),
'explorerMarksRule' => tr('파일 탐색기: 줄 끝 선택 표시는 [선택] 을 켰을 때만 보입니다 (모양 V). '
'늘 보이게: 환경 설정 > 파일 탐색기 > X-plore 스타일: 선택 표시 늘 보이기'),
'explorerRetapRule' => tr('파일 탐색기: 펼친 폴더를 다시 누르면 접힙니다. 되돌리기: 환경 설정 > 파일 탐색기 > 펼친 폴더를 다시 누르면 접기'),
'explorerClickRule' => tr('파일 탐색기: 파일을 한 번 누르면 선택, 두 번 누르면 엽니다. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기'),
'explorerLayoutRule' =>
tr('파일 탐색기 창: 화면 크기 따라 → 두 창 (폰 세로도 좌우). 되돌리기: 환경 설정 > 파일 탐색기 > 창 배치'),
'robocopyLinks' => tr('robocopy 복사 · 이동: 원본 안의 링크 · junction 은 따라가지 않고 건너뜁니다 (/XJ - 예전에는 링크가 가리키는 바깥 폴더의 파일까지 '
'복사 · 이동했습니다). 링크째 복사하려면 robocopy 옵션 칸에 /SJ 를 넣으세요'),
_ => id,

View File

@ -987,8 +987,8 @@ class _SettingsPageState extends State<SettingsPage> {
trailing: DropdownButton<String>(
value: s.explorerLayout,
items: [
DropdownMenuItem(value: 'auto', child: Text(tr('화면 크기 따라 (기본)'))),
DropdownMenuItem(value: 'dual', child: Text(tr('두 창'))),
DropdownMenuItem(value: 'auto', child: Text(tr('화면 크기 따라'))),
DropdownMenuItem(value: 'dual', child: Text(tr('두 창 (기본)'))),
DropdownMenuItem(value: 'split', child: Text(tr('폴더 + 파일 목록'))),
DropdownMenuItem(value: 'single', child: Text(tr('한 창'))),
],
@ -1011,8 +1011,8 @@ class _SettingsPageState extends State<SettingsPage> {
),
// X-plore 비교 ⚖ (관리자 결정): X-plore 스타일의 표시 동그라미 · 밀기 · 폴더 표시 규칙
SwitchListTile(
title: Text(tr('X-plore 스타일: 표시 동그라미 늘 보이기')),
subtitle: Text(tr('끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)')),
title: Text(tr('X-plore 스타일: 선택 표시 늘 보이기')),
subtitle: Text(tr('끄면 (처음 값) [선택] 을 켰을 때만 보입니다. 다른 스타일은 늘 선택 모드에서만')),
value: s.explorerAlwaysMarks,
onChanged: (v) => c.updateSettings((x) => x.explorerAlwaysMarks = v),
),
@ -1032,7 +1032,7 @@ class _SettingsPageState extends State<SettingsPage> {
// X-plore 비교 d: 지금 폴더를 다시 누르면 접기
SwitchListTile(
title: Text(tr('펼친 폴더를 다시 누르면 접기')),
subtitle: Text(tr('X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)')),
subtitle: Text(tr('처음 값 켬. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)')),
value: s.explorerRetapCollapse,
onChanged: (v) => c.updateSettings((x) => x.explorerRetapCollapse = v),
),

View File

@ -36,7 +36,8 @@ void main() {
// 이미 있던 설정의 기본값도 결정대로
expect([s.webPauseOnLeave, s.autoCheckUpdates, s.youtubeAdSkip, s.youtubeAdHide, s.runInBackground, s.swipeNav],
everyElement(isTrue));
expect([s.liveSyncOnStart, s.liveSyncIntervalSec, s.explorerLayout, s.zipComic], ['auto', 30, 'auto', false]);
// 탐색기 처음 배치 = 두 창 (규칙 7 · 관리자 결정 3, 10/22)
expect([s.liveSyncOnStart, s.liveSyncIntervalSec, s.explorerLayout, s.zipComic], ['auto', 30, 'dual', false]);
expect([AppSettings.uiScaleMin, AppSettings.uiScaleMax], [0.5, 2.5]);
// 바꾼 값은 남는다
final b = AppSettings.fromJson((AppSettings()

View File

@ -91,10 +91,10 @@ void main() {
testWidgets('두 창: 폴더 한 번 = 펼치기 · 파일 한 번 = 선택 · 두 번 = 실행 · 길게 = 메뉴 · 다른 창으로 복사', (tester) async {
await open(tester);
// 두 창 + 가운데 버튼 줄. 선택 동그라미: X-plore 스타일 (처음 값) 은 늘 보임 (관리자 결정 10/18 - 설정으로 끌 수 있음)
// 두 창 + 가운데 버튼 줄. 선택 표시는 선택 모드에서만 (규칙 4, 10/22 - 설정으로 늘 보이게 할 수 있음)
expect(find.text('상위 폴더'), findsOneWidget);
expect(find.text('doc.txt'), findsOneWidget);
expect(find.byTooltip('표시 (여러 개 고르기)'), findsWidgets);
expect(find.byTooltip('표시 (여러 개 고르기)'), findsNothing);
// 모니터링 · rsync 는 Rsync 화면에만
expect(find.text('모니터링'), findsNothing);
expect(find.text('좌 → 우'), findsNothing);
@ -265,9 +265,8 @@ void main() {
expect(File(p.join(left, 'doc.txt')).existsSync(), isTrue);
});
testWidgets('X-plore d: 설정 "다시 누르면 접기" - 펼친 지금 폴더를 다시 누르면 접힘 · 두 번 누르기의 두 번째는 접지 않음 (처음 값 끔)', (tester) async {
expect(AppSettings().explorerRetapCollapse, isFalse, reason: '189 그대로');
c.settings.explorerRetapCollapse = true;
testWidgets('규칙 3: 펼친 폴더를 다시 누르면 접힘 · 두 번 누르기의 두 번째는 접지 않음 (처음 값 켬)', (tester) async {
expect(AppSettings().explorerRetapCollapse, isTrue, reason: '규칙 3 (10/22)');
await open(tester);
await act(tester, () => tester.tap(find.text('sub')));
await settle(tester, () => find.text('inner.txt').evaluate().isNotEmpty);
@ -382,7 +381,7 @@ void main() {
..addFile(ArchiveFile.string('new.txt', 'new content'))
..addFile(ArchiveFile.string('more.txt', 'more'))));
});
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f5));
await act(tester, () => refreshKey(tester));
await settle(tester, () => find.text('new.txt').evaluate().isNotEmpty);
expect(find.text('new.txt'), findsOneWidget);
expect(find.text('more.txt'), findsOneWidget);
@ -567,37 +566,38 @@ void main() {
expect(find.textContaining('0개 표시함'), findsNWidgets(2)); // 두 창 모두 (각 창의 선택 수)
expect(shell.opened, isEmpty);
IconData markIcon(String name) => (tester
.widget<IconButton>(find.descendant(
of: find.ancestor(of: find.text(name), matching: find.byType(Material)).first,
matching: find.byType(IconButton)))
.icon as Icon)
.icon!;
// 줄 끝 표시 단추: 규칙 4 - 모양은 V (Icons.check), 고른 것은 "표시 지우기"
IconButton markOf(String name) => tester.widget<IconButton>(find.descendant(
of: find.ancestor(of: find.text(name), matching: find.byType(Material)).first, matching: find.byType(IconButton)));
bool markIcon(String name) {
expect((markOf(name).icon as Icon).icon, Icons.check, reason: '규칙 4: V 모양');
return markOf(name).tooltip == '표시 지우기';
}
// 폴더: 누르면 자기 자신과 안의 것 모두 선택 (펼쳐서 ✔ 로 보여 줌)
await act(tester, () => tester.tap(find.text('sub')));
await settle(tester, () => find.text('inner.txt').evaluate().isNotEmpty);
expect(find.textContaining('1개 표시함'), findsOneWidget); // 폴더 하나로 안의 것까지
expect([markIcon('sub'), markIcon('inner.txt'), markIcon('second.txt')], everyElement(Icons.check_circle));
expect([markIcon('sub'), markIcon('inner.txt'), markIcon('second.txt')], everyElement(isTrue));
// 안의 것 하나를 누르면 그것만 빠지고 나머지는 고른 채로
await act(tester, () => tester.tap(find.text('inner.txt')));
await settle(tester, () => false, rounds: 5);
expect(markIcon('inner.txt'), Icons.check_circle_outline);
expect(markIcon('second.txt'), Icons.check_circle);
expect(markIcon('sub'), Icons.check_circle_outline);
expect(markIcon('inner.txt'), isFalse);
expect(markIcon('second.txt'), isTrue);
expect(markIcon('sub'), isFalse);
// 하나를 뺀 폴더를 다시 누르면 그 폴더와 안의 것 모두 취소 (관리자 결정 2, 10/22 - 규칙 6 "다시 누르면 전체 취소")
await act(tester, () => tester.tap(find.text('sub')));
await settle(tester, () => false, rounds: 5);
expect(find.textContaining('0개 표시함'), findsNWidgets(2));
expect([markIcon('sub'), markIcon('inner.txt'), markIcon('second.txt')], everyElement(Icons.check_circle_outline));
// [선택 끝] → 표시가 모두 풀린다 (X-plore 스타일은 동그라미 자체는 늘 보임 - 관리자 결정 10/18)
expect([markIcon('sub'), markIcon('inner.txt'), markIcon('second.txt')], everyElement(isFalse));
// [선택 끝] → 표시가 모두 풀리고 표시 단추도 사라진다 (규칙 4: 선택 모드에서만)
await act(tester, () => tester.tap(find.text('선택 끝').first)); // 두 창 모두에 있음
expect(find.byTooltip('표시 지우기'), findsNothing);
expect(find.byTooltip('표시 (여러 개 고르기)'), findsWidgets);
// 설정에서 끄면 선택 모드에서만 (예전대로)
await tester.runAsync(() => c.updateSettings((x) => x.explorerAlwaysMarks = false));
await settle(tester, () => false, rounds: 5);
expect(find.byTooltip('표시 (여러 개 고르기)'), findsNothing);
// 설정 "늘 보이기" 를 켜면 X-plore 스타일은 선택 모드 밖에서도 보임
await tester.runAsync(() => c.updateSettings((x) => x.explorerAlwaysMarks = true));
await settle(tester, () => false, rounds: 5);
expect(find.byTooltip('표시 (여러 개 고르기)'), findsWidgets);
});
testWidgets('65: 여러 개를 지울 때 하나가 실패해도 나머지는 지우고, 못 지운 것을 알린다', (tester) async {
@ -1524,12 +1524,12 @@ void main() {
await calm(tester);
});
testWidgets('81: Space 로 빠른 보기 (글 파일 앞부분) · 필터에 치는 중에는 그냥 빈칸 · TC 는 F3', (tester) async {
testWidgets('81: 빠른 보기 (글 파일 앞부분) - Windows 는 TC 키 F3 (규칙 1), Android 는 Space · 필터에 치는 중에는 그냥 빈칸', (tester) async {
c.settings.explorerStyle = 'windows';
await open(tester);
await act(tester, () => tester.tap(find.text('doc.txt')));
await settle(tester, () => false, rounds: 15);
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.space));
await act(tester, () => tester.sendKeyEvent(Platform.isWindows ? LogicalKeyboardKey.f3 : LogicalKeyboardKey.space));
await settle(tester, () => find.byType(QuickLook).evaluate().isNotEmpty);
expect(find.byType(QuickLook), findsOneWidget);
await settle(tester, () => find.text('hello').evaluate().isNotEmpty);
@ -1875,7 +1875,7 @@ void main() {
// 바뀌면 (새로 고침) 다시 계산
File(p.join(left, 'sub', 'more.bin')).writeAsBytesSync(List.filled(3000, 1));
await act(tester, () => tester.sendKeyEvent(LogicalKeyboardKey.f5));
await act(tester, () => refreshKey(tester));
await settle(tester, () => find.text('6KB').evaluate().isNotEmpty);
expect(find.text('6KB'), findsWidgets);
});
@ -1951,6 +1951,17 @@ Finder markOf(String name) => find.descendant(
);
/// 누르기 등을 실제 비동기 구역에서 (그 때 시작한 파일 작업이 테스트의 가짜 시간에 묶이지 않게)
/// 새로 고침 키: Windows 는 TC 키 Ctrl+R (규칙 1 - F5 는 복사), 그 밖은 F5
Future<void> refreshKey(WidgetTester tester) async {
if (!Platform.isWindows) {
await tester.sendKeyEvent(LogicalKeyboardKey.f5);
return;
}
await tester.sendKeyDownEvent(LogicalKeyboardKey.controlLeft);
await tester.sendKeyEvent(LogicalKeyboardKey.keyR);
await tester.sendKeyUpEvent(LogicalKeyboardKey.controlLeft);
}
Future<void> act(WidgetTester tester, Future<void> Function() f) async {
await tester.runAsync(f);
await tester.pump();

View File

@ -58,6 +58,8 @@ void main() {
// 폴더 + 파일 목록: 오른쪽 목록은 그 폴더의 것만이라 짧다 (트리는 Temp 의 다른 폴더가 많아 아래로 밀린다)
..explorerLayout = 'split'
..explorerStyle = style
// ✔ 칸 자리를 보는 시험: 표시를 늘 보이게 (설정 - 처음 값은 규칙 4 로 선택 모드에서만)
..explorerAlwaysMarks = true
..explorerTextScale = scale
..explorerRowSpacing = spacing;
await tester.runAsync(() => tester.pumpWidget(MaterialApp(

View File

@ -141,9 +141,11 @@ void main() {
'runInBackground': false,
});
expect(old.screenOrientation, 'auto');
expect(old.explorerLayout, 'auto');
// 규칙 7 · 결정 3 (10/22): 처음 배치가 두 창이 되어 예전 'dual' 은 그대로 (옮겼다는 알림 없음)
expect(old.explorerLayout, 'dual');
expect(old.zipComic, isFalse);
expect(old.migrated, containsAll(['orientation', 'explorerLayout', 'zipComic']));
expect(old.migrated, containsAll(['orientation', 'zipComic']));
expect(old.migrated, isNot(contains('explorerLayout')));
// 다시 저장 · 읽기: 이제 사용자가 고른 값으로 보고 그대로 · 알림 없음
final again = AppSettings.fromJson((old
..explorerLayout = 'dual'
@ -156,6 +158,27 @@ void main() {
expect(AppSettings.fromJson({}).migrated, isEmpty);
});
test('E3 (10/22): 선택 규칙 이전 판의 처음 값은 한 번 규칙대로 옮기고 알림, 저장한 뒤에는 고른 값 그대로', () {
final old = AppSettings.fromJson({
'explorerV2': true,
'explorerLayout': 'auto',
'explorerAlwaysMarks': true,
'explorerRetapCollapse': false,
'explorerClick': 'open',
});
expect([old.explorerLayout, old.explorerAlwaysMarks, old.explorerRetapCollapse], ['dual', false, true]);
expect(old.explorerClick, Platform.isAndroid ? 'select' : 'open'); // Windows 의 'open' 은 사용자가 고른 값
expect(old.migrated, containsAll(['explorerLayoutRule', 'explorerMarksRule', 'explorerRetapRule']));
// 저장한 뒤 사용자가 다시 고른 값은 그대로 · 다시 묻지 않음
final again = AppSettings.fromJson((old
..explorerLayout = 'auto'
..explorerAlwaysMarks = true
..explorerRetapCollapse = false)
.toJson());
expect([again.explorerLayout, again.explorerAlwaysMarks, again.explorerRetapCollapse], ['auto', true, false]);
expect(again.migrated, isEmpty);
});
test('193: 예전 판에서 올라오면 바뀐 동작 (229 받는 쪽이 더 새것이면 건너뜀 · robocopy 링크) 을 한 번 알린다', () {
final old = AppSettings.fromJson({'copyMethodFolder': 'robocopy', 'explorerV2': true});
expect(old.migrated, contains('copySkipNewer'));