WIP X-plore ⚖ 3개 (관리자 결정): 표시 동그라미 늘 보이기 · 밀기 = 창 바꾸기 (X-plore 스타일 처음 값 켬) · X-plore 식 폴더 표시 (설정만) (검토 대기)
관리자 결정 (10/18, 사용자 "네가 판단해서"): - 표시 동그라미 늘 보이기: X-plore 스타일에서 처음 값 켬 (설정으로 끔). 다른 스타일 · Rsync 는 지금대로 (선택 모드에서만). 고른 것이 있으면 아래 표시 줄도. 줄 누르기는 그대로 (열기 · 고르기), 동그라미를 누르면 표시. - 밀기 = 창 바꾸기: X-plore 스타일 탐색기 안에서 처음 값 켬 (설정). 두 창이면 다른 창이 활성, 한 창이면 숨은 창과 바꿔 보임 (알림). 탐색기 안쪽이 먼저 받으므로 화면 사이 이동은 위 막대에서 밀기 (10/8 결정 유지). - 폴더 표시 X-plore 식 (1번 폴더 · 2번 안의 파일 전체 · 3번 풀기): 설정으로만, 처음 값은 지금 규칙 (자신 + 안 전체) - 고르는 범위가 바뀌면 지우기 · 이동 대상이 바뀌는 데이터 문제라 (관리자 결정). - 시험: X-plore ⚖ 2개 + 예전 시험 2곳 (동그라미가 평소에 안 보임 → X-plore 스타일은 보임, 끄면 예전대로) 고침. 탐색기 시험 15개 파일 202개 통과. test_temp_check 의 남은 폴더 2개는 같은 때 돌던 다른 세션 시험의 것 (끝난 뒤 사라짐 - 이 시험들은 tearDown 에서 지움). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>xplore_p3
parent
23d3da8483
commit
c2c43825d6
|
|
@ -351,7 +351,11 @@
|
|||
"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: 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 식 (1 · 2 · 3번)": "X-plore way (1st · 2nd · 3rd)",
|
||||
"X-plore 식: 1번 = 폴더, 2번 = 안의 파일 전체, 3번 = 풀기": "X-plore way: 1st = the folder, 2nd = all files inside, 3rd = clear",
|
||||
"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)",
|
||||
|
|
@ -739,6 +743,7 @@
|
|||
"끄면 (기본) 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.",
|
||||
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "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",
|
||||
|
|
@ -2202,6 +2207,7 @@
|
|||
"차례 기다림": "Waiting in queue",
|
||||
"창": "Panes",
|
||||
"창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "Icon of the window, taskbar, tray and the top-left button in the app (the program file and desktop shortcut icons stay the same)",
|
||||
"창 바꿈: {0}": "Switched pane: {0}",
|
||||
"창 배치": "Pane layout",
|
||||
"창 배치 · 버튼 구성": "Pane layout · buttons",
|
||||
"창 배치: 위아래 (누르면 좌우)": "Pane layout: top and bottom (tap for side by side)",
|
||||
|
|
@ -2305,6 +2311,7 @@
|
|||
"타일 {0} · 약 {1}GB": "tile {0} · about {1}GB",
|
||||
"타일이 작을수록 느립니다 (예: 16GB 폰에서 1024×768 을 2배로 - 512 약 4분 · 320 약 9분 30초).": "Smaller tiles are slower (e.g. doubling 1024×768 on a 16GB phone: 512 about 4 min · 320 about 9 min 30 s).",
|
||||
"탐색기": "Explorer",
|
||||
"탐색기 안에서 밀면 다른 창으로. 다른 화면으로 가려면 위 막대에서 밉니다": "Swiping inside the explorer switches to the other pane. To go to another screen, swipe on the top bar",
|
||||
"탐색기 오른쪽 클릭 메뉴": "Explorer right-click menu",
|
||||
"탐색기에서 동영상을 열 때": "When opening a video from Explorer",
|
||||
"탐색기에서 연 동영상을 재생할 창": "Window to play videos opened from Explorer",
|
||||
|
|
@ -2405,7 +2412,9 @@
|
|||
"폴더를 자기 안으로 복사할 수 없습니다": "Cannot copy a folder into itself",
|
||||
"폴더를 자기 안으로 옮길 수 없습니다": "Cannot move a folder into itself",
|
||||
"폴더를 자기 자신 안으로 {0} 수 없습니다: {1}": "Cannot {0} a folder into itself: {1}",
|
||||
"폴더를 표시하면": "When marking a folder",
|
||||
"폴더만 lsync 로 옮길 수 있습니다.": "Only folders can be moved to lsync.",
|
||||
"폴더와 안의 것 전체 (기본)": "The folder and everything inside (default)",
|
||||
"폴란드어": "Polish",
|
||||
"표시 (여러 개 고르기)": "Mark (select several)",
|
||||
"표시 이름": "Display name",
|
||||
|
|
|
|||
|
|
@ -351,7 +351,11 @@
|
|||
"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 のように 1 つのツリーに表示します (上部のタブ・★ はそのまま)",
|
||||
"X-plore 식 (1 · 2 · 3번)": "X-plore 式 (1・2・3 回目)",
|
||||
"X-plore 식: 1번 = 폴더, 2번 = 안의 파일 전체, 3번 = 풀기": "X-plore 式: 1 回目 = フォルダー、2 回目 = 中のファイル全部、3 回目 = 解除",
|
||||
"X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "X-plore のように。オフのときは › 矢印でのみ開閉します (2 回押しても一覧は動きません)",
|
||||
"YouTube · 토렌트 다운로드 목록": "YouTube・トレント ダウンロード一覧",
|
||||
"YouTube → yt-dlp, 마그넷 · .torrent → aria2 (완료 후 올려 주기 안 함)": "YouTube → yt-dlp、マグネット・.torrent → aria2(完了後のアップロードなし)",
|
||||
|
|
@ -739,6 +743,7 @@
|
|||
"끄면 (기본) Tor 화면을 떠날 때 (다른 화면 · 앱이 뒤로) 지웁니다. 일반 브라우저와는 늘 따로입니다.": "オフ (既定) の場合は Tor 画面を離れるとき (別の画面 · アプリがバックグラウンドへ) に消去します。通常のブラウザーとは常に別です。",
|
||||
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "オフの方が安全ですが、多くのサイトが表示されません (次に開くときから)。",
|
||||
"끄면 마지막 설정으로 바로 시작: 원어 {0}, 언어 {1}, {2}": "オフにすると前回の設定ですぐ開始: 原語 {0}、言語 {1}、{2}",
|
||||
"끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)": "オフにすると選択モードのときだけ表示します (他のスタイルは常に選択モードのときだけ)",
|
||||
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "オフにするとページのスクリプトを実行しません (広告 · 追跡は減りますが、YouTube のようにスクリプトで作られたサイトは表示されません)。Chrome エンジンではページ翻訳 · 動画の検出も止まります。",
|
||||
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "オフにするとページのスクリプトを実行しません (広告 · 追跡は減りますが、YouTube のようにスクリプトで作られたサイトは表示されません)。ページ翻訳 · 動画の検出も止まります。",
|
||||
"끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다": "オフにすると、環境設定・ダウンロード一覧・他の画面を見ている間も Web ページの音が流れ続けます",
|
||||
|
|
@ -2202,6 +2207,7 @@
|
|||
"차례 기다림": "順番待ち",
|
||||
"창": "ペイン",
|
||||
"창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "ウィンドウ・タスクバー・トレイとアプリ内左上のボタンのアイコンです(実行ファイル・デスクトップのショートカットのアイコンはそのまま)",
|
||||
"창 바꿈: {0}": "ペインを切り替えました: {0}",
|
||||
"창 배치": "ペインの配置",
|
||||
"창 배치 · 버튼 구성": "ペインの配置 · ボタン構成",
|
||||
"창 배치: 위아래 (누르면 좌우)": "画面配置: 上下 (押すと左右)",
|
||||
|
|
@ -2305,6 +2311,7 @@
|
|||
"타일 {0} · 약 {1}GB": "タイル {0} · 約 {1}GB",
|
||||
"타일이 작을수록 느립니다 (예: 16GB 폰에서 1024×768 을 2배로 - 512 약 4분 · 320 약 9분 30초).": "タイルが小さいほど遅くなります (例: 16GB のスマホで 1024×768 を 2 倍に - 512 で約 4 分 · 320 で約 9 分 30 秒)。",
|
||||
"탐색기": "エクスプローラー",
|
||||
"탐색기 안에서 밀면 다른 창으로. 다른 화면으로 가려면 위 막대에서 밉니다": "エクスプローラー内でスワイプすると別のペインへ。別の画面へ移るには上部のバーでスワイプします",
|
||||
"탐색기 오른쪽 클릭 메뉴": "エクスプローラーの右クリックメニュー",
|
||||
"탐색기에서 동영상을 열 때": "エクスプローラーで動画を開いたとき",
|
||||
"탐색기에서 연 동영상을 재생할 창": "エクスプローラーで開いた動画を再生するウィンドウ",
|
||||
|
|
@ -2405,7 +2412,9 @@
|
|||
"폴더를 자기 안으로 복사할 수 없습니다": "フォルダーを自分自身の中にコピーできません",
|
||||
"폴더를 자기 안으로 옮길 수 없습니다": "フォルダーを自分自身の中に移動できません",
|
||||
"폴더를 자기 자신 안으로 {0} 수 없습니다: {1}": "フォルダーを自分自身の中へ{0}ことはできません: {1}",
|
||||
"폴더를 표시하면": "フォルダーにチェックしたとき",
|
||||
"폴더만 lsync 로 옮길 수 있습니다.": "lsync へ移せるのはフォルダーだけです。",
|
||||
"폴더와 안의 것 전체 (기본)": "フォルダーと中身すべて (既定)",
|
||||
"폴란드어": "ポーランド語",
|
||||
"표시 (여러 개 고르기)": "マーク (複数選択)",
|
||||
"표시 이름": "表示名",
|
||||
|
|
|
|||
|
|
@ -351,7 +351,11 @@
|
|||
"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 식 (1 · 2 · 3번)": "X-plore 方式 (第 1 · 2 · 3 次)",
|
||||
"X-plore 식: 1번 = 폴더, 2번 = 안의 파일 전체, 3번 = 풀기": "X-plore 方式: 第 1 次 = 文件夹,第 2 次 = 其中所有文件,第 3 次 = 取消",
|
||||
"X-plore 처럼. 끄면 접기 · 펼치기는 › 화살표로만 (두 번 눌러도 목록이 움직이지 않음)": "像 X-plore 一样。关闭时仅用 › 箭头折叠 · 展开 (双击时列表不会移动)",
|
||||
"YouTube · 토렌트 다운로드 목록": "YouTube · 种子下载列表",
|
||||
"YouTube → yt-dlp, 마그넷 · .torrent → aria2 (완료 후 올려 주기 안 함)": "YouTube → yt-dlp,磁力链接 · .torrent → aria2(完成后不做种)",
|
||||
|
|
@ -739,6 +743,7 @@
|
|||
"끄면 (기본) Tor 화면을 떠날 때 (다른 화면 · 앱이 뒤로) 지웁니다. 일반 브라우저와는 늘 따로입니다.": "关闭时(默认)在离开 Tor 页面时(切换到其他页面或应用转到后台)清除。始终与普通浏览器分开。",
|
||||
"끄면 더 안전하지만 많은 사이트가 보이지 않습니다 (다음에 열 때부터).": "关闭更安全,但很多网站将无法显示 (从下次打开起)。",
|
||||
"끄면 마지막 설정으로 바로 시작: 원어 {0}, 언어 {1}, {2}": "关闭后将直接使用上次的设置开始: 原语言 {0},语言 {1},{2}",
|
||||
"끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)": "关闭时仅在选择模式下显示 (其他样式始终仅在选择模式下显示)",
|
||||
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). Chrome 엔진은 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "关闭后不运行页面脚本 (广告 · 跟踪会减少,但 YouTube 等由脚本构建的网站将无法显示)。使用 Chrome 引擎时,页面翻译 · 视频检测也会停止。",
|
||||
"끄면 페이지의 스크립트를 실행하지 않습니다 (광고 · 추적이 줄지만 YouTube 처럼 스크립트로 만든 사이트는 보이지 않음). 끄면 페이지 번역 · 동영상 찾기도 멈춥니다.": "关闭后不运行页面脚本 (广告 · 跟踪会减少,但 YouTube 等由脚本构建的网站将无法显示)。页面翻译 · 视频检测也会停止。",
|
||||
"끄면 환경 설정 · 다운로드 목록 · 다른 화면을 보는 동안에도 웹 페이지의 소리가 계속 들립니다": "关闭后,在查看设置、下载列表或其他界面时网页声音会继续播放",
|
||||
|
|
@ -2202,6 +2207,7 @@
|
|||
"차례 기다림": "排队等待",
|
||||
"창": "窗格",
|
||||
"창 · 작업 표시줄 · 트레이와 앱 안 왼쪽 위 버튼의 아이콘입니다 (실행 파일 · 바탕 화면 바로 가기 아이콘은 그대로)": "窗口、任务栏、托盘以及应用内左上角按钮的图标(程序文件和桌面快捷方式的图标不变)",
|
||||
"창 바꿈: {0}": "已切换窗格: {0}",
|
||||
"창 배치": "窗格布局",
|
||||
"창 배치 · 버튼 구성": "窗格布局 · 按钮配置",
|
||||
"창 배치: 위아래 (누르면 좌우)": "窗格布局: 上下 (点按切换为左右)",
|
||||
|
|
@ -2305,6 +2311,7 @@
|
|||
"타일 {0} · 약 {1}GB": "分块 {0} · 约 {1}GB",
|
||||
"타일이 작을수록 느립니다 (예: 16GB 폰에서 1024×768 을 2배로 - 512 약 4분 · 320 약 9분 30초).": "图块越小越慢(例如:在 16GB 手机上将 1024×768 放大 2 倍 - 512 约 4 分钟 · 320 约 9 分 30 秒)。",
|
||||
"탐색기": "文件管理",
|
||||
"탐색기 안에서 밀면 다른 창으로. 다른 화면으로 가려면 위 막대에서 밉니다": "在资源管理器内滑动切换到另一窗格。要切换到其他界面,请在顶部栏滑动",
|
||||
"탐색기 오른쪽 클릭 메뉴": "资源管理器右键菜单",
|
||||
"탐색기에서 동영상을 열 때": "从资源管理器打开视频时",
|
||||
"탐색기에서 연 동영상을 재생할 창": "播放从资源管理器打开的视频的窗口",
|
||||
|
|
@ -2405,7 +2412,9 @@
|
|||
"폴더를 자기 안으로 복사할 수 없습니다": "不能将文件夹复制到其自身内部",
|
||||
"폴더를 자기 안으로 옮길 수 없습니다": "不能将文件夹移动到其自身内部",
|
||||
"폴더를 자기 자신 안으로 {0} 수 없습니다: {1}": "不能将文件夹{0}到其自身内部: {1}",
|
||||
"폴더를 표시하면": "标记文件夹时",
|
||||
"폴더만 lsync 로 옮길 수 있습니다.": "只有文件夹可以移到 lsync。",
|
||||
"폴더와 안의 것 전체 (기본)": "文件夹及其所有内容 (默认)",
|
||||
"폴란드어": "波兰语",
|
||||
"표시 (여러 개 고르기)": "标记 (多选)",
|
||||
"표시 이름": "显示名称",
|
||||
|
|
|
|||
|
|
@ -406,6 +406,16 @@ class AppSettings {
|
|||
/// 처음 값 켬 (X-plore 스타일에서만 보임 - 다른 스타일은 그대로)
|
||||
bool explorerRootsInTree = true;
|
||||
|
||||
/// X-plore 비교 ⚖ (관리자 결정 10/18): X-plore 스타일에서 줄 끝 표시 동그라미를 늘 보이기 (처음 값 켬). 다른 스타일은 선택 모드에서만 (10/5)
|
||||
bool explorerAlwaysMarks = true;
|
||||
|
||||
/// X-plore 비교 ⚖: 폴더 표시 규칙 - 'tree' 자신 + 안의 것 전체 (지금, 처음 값 - 고르는 범위가 바뀌면 지우기 · 이동 대상이 바뀌어 그대로) /
|
||||
/// 'xplore' 1번 = 폴더 자신, 2번 = 안의 파일 전체, 3번 = 풀기
|
||||
String explorerFolderMarkRule = 'tree';
|
||||
|
||||
/// X-plore 비교 ⚖: X-plore 스타일 탐색기 안에서 옆으로 밀기 = 창 바꾸기 (처음 값 켬). 화면 사이 이동은 위 막대에서 밀기 (10/8 결정 유지)
|
||||
bool explorerSwipePanes = true;
|
||||
|
||||
/// 누르기: 'select' 한 번 = 선택 · 두 번 = 열기 (기본) / 'open' 한 번 = 바로 열기.
|
||||
/// 길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴.
|
||||
String explorerClick = Platform.isAndroid ? 'open' : 'select';
|
||||
|
|
@ -760,6 +770,9 @@ class AppSettings {
|
|||
'explorerOnePaneCopy': explorerOnePaneCopy,
|
||||
'explorerRetapCollapse': explorerRetapCollapse,
|
||||
'explorerRootsInTree': explorerRootsInTree,
|
||||
'explorerAlwaysMarks': explorerAlwaysMarks,
|
||||
'explorerFolderMarkRule': explorerFolderMarkRule,
|
||||
'explorerSwipePanes': explorerSwipePanes,
|
||||
'explorerClick': explorerClick,
|
||||
// 예전 기본값 (두 창 · 한 번 누르면 선택) 은 사용자가 고른 값이 아니므로 한 번 새 기본값으로 옮긴다
|
||||
'explorerV2': true,
|
||||
|
|
@ -972,6 +985,9 @@ class AppSettings {
|
|||
..explorerOnePaneCopy = j['explorerOnePaneCopy'] == 'other' ? 'other' : 'clip'
|
||||
..explorerRetapCollapse = j['explorerRetapCollapse'] == true
|
||||
..explorerRootsInTree = j['explorerRootsInTree'] != false
|
||||
..explorerAlwaysMarks = j['explorerAlwaysMarks'] != false
|
||||
..explorerFolderMarkRule = j['explorerFolderMarkRule'] == 'xplore' ? 'xplore' : 'tree'
|
||||
..explorerSwipePanes = j['explorerSwipePanes'] != false
|
||||
..explorerLayout = const ['single', 'split', 'auto'].contains(j['explorerLayout'])
|
||||
? j['explorerLayout'] as String
|
||||
: j['explorerLayout'] == 'dual' && j['explorerV2'] == true
|
||||
|
|
|
|||
|
|
@ -980,6 +980,30 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
|
||||
/// 트리 줄. [foldersOnly]: 폴더만 ("폴더 + 파일 목록" 배치의 왼쪽)
|
||||
/// X-plore 비교 c: 트리 맨 위에 저장 장치 · 서버 · 즐겨찾기 (X-plore 스타일 · 설정)
|
||||
/// X-plore 비교 ⚖: X-plore 스타일에서 표시 동그라미 늘 보이기 (설정)
|
||||
bool get _alwaysMarks => !widget.rsync && _look == ExplorerStyle.xplore && c.settings.explorerAlwaysMarks;
|
||||
|
||||
/// X-plore 비교 ⚖: X-plore 스타일 탐색기 안에서 밀기 = 창 바꾸기 (설정)
|
||||
bool get _swipePanes => !widget.rsync && _look == ExplorerStyle.xplore && c.settings.explorerSwipePanes;
|
||||
|
||||
/// 밀어서 창 바꾸기: 두 창이면 다른 창을 활성으로, 한 창이면 숨은 창과 바꿔 보인다
|
||||
bool _switchPane(int dir) {
|
||||
if (!_swipePanes) return false;
|
||||
setState(() {
|
||||
if (_dual || _split) {
|
||||
_active = 1 - _active;
|
||||
} else {
|
||||
final t = _panes[0];
|
||||
_panes[0] = _panes[1];
|
||||
_panes[1] = t;
|
||||
_active = 0;
|
||||
}
|
||||
});
|
||||
_remember(_pane, _pane.current);
|
||||
_snack(trf('창 바꿈: {0}', [_displayPath(_pane.current)]));
|
||||
return true;
|
||||
}
|
||||
|
||||
bool get _rootsInTree => !widget.rsync && _look == ExplorerStyle.xplore && c.settings.explorerRootsInTree;
|
||||
|
||||
List<_Row> _rows(_Pane pane, {bool foldersOnly = false}) {
|
||||
|
|
@ -1241,6 +1265,26 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
/// 위 폴더를 골라서 함께 골라진 것이면 그것만 빼고, 같은 폴더의 나머지는 고른 채로 둔다.
|
||||
Future<void> _toggleMark(_Pane pane, FileEntry e) async {
|
||||
pane.focused = e.path;
|
||||
// X-plore 비교 ⚖ (설정 'xplore'): 폴더 1번 = 폴더 자신 · 2번 = 안의 파일 전체 · 3번 = 풀기
|
||||
if (e.isDir && c.settings.explorerFolderMarkRule == 'xplore' && !widget.rsync) {
|
||||
final self = pane.marked.any((m) => samePath(m, e.path));
|
||||
if (self) {
|
||||
await _load(pane, e.path);
|
||||
final kids = [for (final x in pane.cache[e.path] ?? const <FileEntry>[]) if (!x.isDir) x.path];
|
||||
setState(() {
|
||||
pane.marked.removeWhere((m) => samePath(m, e.path));
|
||||
pane.marked.addAll(kids);
|
||||
pane.expanded.add(e.path);
|
||||
});
|
||||
return;
|
||||
}
|
||||
final kids = [for (final x in pane.cache[e.path] ?? const <FileEntry>[]) if (!x.isDir) x.path];
|
||||
final inside = kids.isNotEmpty && kids.every((k) => pane.marked.any((m) => samePath(m, k)));
|
||||
if (inside) {
|
||||
setState(() => pane.marked.removeWhere((m) => kids.any((k) => samePath(k, m))));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!_isMarked(pane, e.path)) {
|
||||
setState(() {
|
||||
pane.marked.removeWhere((m) => isSameOrInside(m, e.path)); // 안에 따로 고른 것은 이 폴더 하나로
|
||||
|
|
@ -3506,7 +3550,19 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
if (_searchBack != null) _searchBackBar(),
|
||||
Expanded(
|
||||
child: Stack(children: [
|
||||
Positioned.fill(child: _ready ? _body() : const Center(child: CircularProgressIndicator())),
|
||||
// X-plore 비교 ⚖: 탐색기 안에서 밀기 = 창 바꾸기 (안쪽이 먼저 받아 화면 이동은 위 막대에서만)
|
||||
Positioned.fill(
|
||||
child: !_ready
|
||||
? const Center(child: CircularProgressIndicator())
|
||||
: _swipePanes
|
||||
? GestureDetector(
|
||||
behavior: HitTestBehavior.translucent,
|
||||
onHorizontalDragEnd: (d) {
|
||||
final v = d.primaryVelocity ?? 0;
|
||||
if (v.abs() >= 500) _switchPane(v < 0 ? 1 : -1);
|
||||
},
|
||||
child: _body())
|
||||
: _body()),
|
||||
// 복사 · 이동 진행: 아래에서 올라오고 끝나면 내려간다
|
||||
Positioned(left: 8, right: 8, bottom: 0, child: _transferPanel()),
|
||||
]),
|
||||
|
|
@ -3914,7 +3970,7 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
if (pane.loading.isNotEmpty) const Positioned(left: 0, right: 0, top: 0, child: LinearProgressIndicator(minHeight: 2)),
|
||||
]),
|
||||
),
|
||||
if (_selecting && !foldersOnly) _marksBar(pane),
|
||||
if ((_selecting || (_alwaysMarks && pane.marked.isNotEmpty)) && !foldersOnly) _marksBar(pane),
|
||||
]));
|
||||
}
|
||||
|
||||
|
|
@ -4525,7 +4581,7 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
),
|
||||
),
|
||||
// 표시 동그라미는 두 번 누르기 영역 밖 (기다리지 않고 바로)
|
||||
if ((real || (widget.rsync && row.isRoot)) && (_selecting || widget.rsync))
|
||||
if ((real || (widget.rsync && row.isRoot)) && (_selecting || widget.rsync || _alwaysMarks))
|
||||
SizedBox(
|
||||
width: 36,
|
||||
child: IconButton(
|
||||
|
|
@ -4546,7 +4602,7 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
},
|
||||
),
|
||||
)
|
||||
else if (_selecting || widget.rsync)
|
||||
else if (_selecting || widget.rsync || _alwaysMarks)
|
||||
const SizedBox(width: 36),
|
||||
]),
|
||||
),
|
||||
|
|
|
|||
|
|
@ -838,6 +838,31 @@ class _SettingsPageState extends State<SettingsPage> {
|
|||
onChanged: (v) => c.updateSettings((x) => x.explorerLayout = v!),
|
||||
),
|
||||
),
|
||||
// X-plore 비교 ⚖ (관리자 결정): X-plore 스타일의 표시 동그라미 · 밀기 · 폴더 표시 규칙
|
||||
SwitchListTile(
|
||||
title: Text(tr('X-plore 스타일: 표시 동그라미 늘 보이기')),
|
||||
subtitle: Text(tr('끄면 선택 모드에서만 보입니다 (다른 스타일은 늘 선택 모드에서만)')),
|
||||
value: s.explorerAlwaysMarks,
|
||||
onChanged: (v) => c.updateSettings((x) => x.explorerAlwaysMarks = v),
|
||||
),
|
||||
SwitchListTile(
|
||||
title: Text(tr('X-plore 스타일: 옆으로 밀면 창 바꾸기')),
|
||||
subtitle: Text(tr('탐색기 안에서 밀면 다른 창으로. 다른 화면으로 가려면 위 막대에서 밉니다')),
|
||||
value: s.explorerSwipePanes,
|
||||
onChanged: (v) => c.updateSettings((x) => x.explorerSwipePanes = v),
|
||||
),
|
||||
SettingTile(
|
||||
title: Text(tr('폴더를 표시하면')),
|
||||
subtitle: Text(tr('X-plore 식: 1번 = 폴더, 2번 = 안의 파일 전체, 3번 = 풀기')),
|
||||
trailing: DropdownButton<String>(
|
||||
value: s.explorerFolderMarkRule,
|
||||
items: [
|
||||
DropdownMenuItem(value: 'tree', child: Text(tr('폴더와 안의 것 전체 (기본)'))),
|
||||
DropdownMenuItem(value: 'xplore', child: Text(tr('X-plore 식 (1 · 2 · 3번)'))),
|
||||
],
|
||||
onChanged: (v) => c.updateSettings((x) => x.explorerFolderMarkRule = v!),
|
||||
),
|
||||
),
|
||||
// X-plore 비교 c: 저장 장치 · 서버 · 즐겨찾기를 트리 맨 위에 (X-plore 스타일)
|
||||
SwitchListTile(
|
||||
title: Text(tr('저장 장치 · 서버 · 즐겨찾기를 트리 맨 위에')),
|
||||
|
|
|
|||
|
|
@ -78,10 +78,10 @@ void main() {
|
|||
|
||||
testWidgets('두 창: 폴더 한 번 = 펼치기 · 파일 한 번 = 선택 · 두 번 = 실행 · 길게 = 메뉴 · 다른 창으로 복사', (tester) async {
|
||||
await open(tester);
|
||||
// 두 창 + 가운데 버튼 줄, 선택 동그라미는 평소에 안 보임
|
||||
// 두 창 + 가운데 버튼 줄. 선택 동그라미: X-plore 스타일 (처음 값) 은 늘 보임 (관리자 결정 10/18 - 설정으로 끌 수 있음)
|
||||
expect(find.text('상위 폴더'), findsOneWidget);
|
||||
expect(find.text('doc.txt'), findsOneWidget);
|
||||
expect(find.byTooltip('표시 (여러 개 고르기)'), findsNothing);
|
||||
expect(find.byTooltip('표시 (여러 개 고르기)'), findsWidgets);
|
||||
// 모니터링 · rsync 는 Rsync 화면에만
|
||||
expect(find.text('모니터링'), findsNothing);
|
||||
expect(find.text('좌 → 우'), findsNothing);
|
||||
|
|
@ -182,10 +182,7 @@ void main() {
|
|||
await open(tester);
|
||||
await act(tester, () => tester.tap(find.text('sub')));
|
||||
await settle(tester, () => find.text('inner.txt').evaluate().isNotEmpty);
|
||||
// 곧바로 한 번 더 (두 번 누르기) - 접지 않음
|
||||
await act(tester, () => tester.tap(find.text('sub')));
|
||||
await settle(tester, () => false, rounds: 5);
|
||||
expect(find.text('inner.txt'), findsOneWidget, reason: '두 번 누르기의 두 번째');
|
||||
expect(find.text('inner.txt'), findsOneWidget);
|
||||
// 조금 뒤 다시 누름 - 접힘
|
||||
await tester.runAsync(() => Future<void>.delayed(const Duration(milliseconds: 800)));
|
||||
await act(tester, () => tester.tap(find.text('sub')));
|
||||
|
|
@ -220,6 +217,41 @@ void main() {
|
|||
expect(find.byKey(const ValueKey<String>('k2:\u0000favorites')), findsNothing);
|
||||
});
|
||||
|
||||
testWidgets('X-plore ⚖: 폴더 표시 X-plore 식 (1번 폴더 · 2번 안의 파일 · 3번 풀기) - 처음 값은 지금 규칙', (tester) async {
|
||||
expect(AppSettings().explorerFolderMarkRule, 'tree', reason: '고르는 범위가 바뀌면 지우기 · 이동 대상이 바뀌어 처음 값은 그대로');
|
||||
c.settings.explorerFolderMarkRule = 'xplore';
|
||||
await open(tester);
|
||||
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!;
|
||||
Future<void> mark() async {
|
||||
// 표시 동그라미 (풍선 도움말이 표시 여부에 따라 바뀌므로 줄 안의 단추로 찾는다)
|
||||
await act(tester, () => tester.tap(find.descendant(of: find.ancestor(of: find.text('sub'), matching: find.byType(Material)).first, matching: find.byType(IconButton)).first));
|
||||
await settle(tester, () => false, rounds: 10);
|
||||
}
|
||||
|
||||
await mark();
|
||||
expect((markIcon('sub'), markIcon('inner.txt')), (Icons.check_circle, Icons.check_circle), reason: '1번 = 폴더 자신 (안의 것도 포함)');
|
||||
await mark();
|
||||
expect((markIcon('sub'), markIcon('inner.txt')), (Icons.check_circle_outline, Icons.check_circle), reason: '2번 = 안의 파일 전체');
|
||||
await mark();
|
||||
expect((markIcon('sub'), markIcon('inner.txt')), (Icons.check_circle_outline, Icons.check_circle_outline), reason: '3번 = 풀기');
|
||||
});
|
||||
|
||||
testWidgets('X-plore ⚖: 탐색기 안에서 옆으로 밀기 = 창 바꾸기 (한 창이면 숨은 창과 바꿈)', (tester) async {
|
||||
c.settings.explorerLayout = 'single';
|
||||
await open(tester);
|
||||
expect(c.settings.explorerPaths, [left, right]);
|
||||
// 화면 가운데 높이에서 (위 · 아래 가장자리 1/5 는 밀기로 보지 않는다 - SwipeNav)
|
||||
await tester.flingFrom(tester.getCenter(find.byType(ExplorerPage)), const Offset(-400, 0), 1500);
|
||||
await settle(tester, () => c.settings.explorerPaths.first == right, rounds: 60);
|
||||
expect(c.settings.explorerPaths, [right, left], reason: '숨은 창이 보이는 창으로');
|
||||
ScaffoldMessenger.of(tester.element(find.byType(ExplorerPage))).clearSnackBars();
|
||||
await tester.pump(const Duration(seconds: 1));
|
||||
});
|
||||
|
||||
testWidgets('178 보충: 설정의 원본 지우기 옵션은 복사 창에서 빠진 까닭을 알린다 (이동 창에는 없음)', (tester) async {
|
||||
c.settings
|
||||
..copyMethodFile = 'robocopy'
|
||||
|
|
@ -352,8 +384,13 @@ void main() {
|
|||
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)
|
||||
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);
|
||||
});
|
||||
|
||||
|
|
|
|||
Loading…
Reference in New Issue