E6 1: 탐색기 모양 처음 값을 기기마다 (Windows = Total Commander) · 예전 판이 저장한 X-plore 는 한 번만 묻기
- ExplorerSettings: 처음 값 defaultStyle (Windows totalcmd · Android xplore). 예전 파일에 모양 키가 없으면 그때의 X-plore. Windows 에서 저장된 xplore 이고 물었다는 표시 (explorerStyleV2) 가 없으면 styleAskPending (저장 안 함) - style_ask: 탐색기를 열 때 한 번 [바꾸기] (Total Commander) / [그대로] (X-plore) - 창 밖으로 닫지 못함, 어느 쪽이든 다시 묻지 않음. 환경 설정에서 직접 고르면 묻지 않음 - 약속 시험 explorer_style_contract_test: 새 설치 · 저장된 xplore (키 없던 예전 파일 포함) · windows/totalcmd 안 물음 · [그대로] · [바꾸기] - X-plore 모양 (트리) 을 보는 기존 시험 14개 파일 + 공용 하네스에 style = 'xplore' 를 밝힘 (기대값 그대로, 관리자 승인 10/23) - 설정 JSON 골든: 새 키 explorerStyleV2 한 줄 · 처음 값 출력의 Windows 모양 totalcmd 만 바꿈. 사전 4개 (en · ja · zh-Hans) Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>modular
parent
8c561a6133
commit
20f9d083b2
|
|
@ -423,6 +423,7 @@
|
|||
"Windows 에서 이 앱의 알림이 꺼져 있어 보이지 않습니다": "Notifications for this app are turned off in Windows, so they won't appear",
|
||||
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "Available on Windows only. On this device, documents open in another app.",
|
||||
"Windows 오류 0x{0}": "Windows error 0x{0}",
|
||||
"Windows 의 처음 모양이 Total Commander 로 바뀌었습니다 (목록 · \"..\" · 아래 F3~F8 단추 줄). 지금 쓰는 X-plore 모양을 바꿀까요? 환경 설정 > 파일 탐색기 > 모양에서 언제든 바꿀 수 있습니다.": "The default look on Windows is now Total Commander (list · \"..\" · F3–F8 buttons at the bottom). Change the X-plore look you are using now? You can change it any time in Settings > File explorer > Look.",
|
||||
"Windows 탐색기": "Windows Explorer",
|
||||
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore style: always show selection marks",
|
||||
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore style: swipe sideways to switch panes",
|
||||
|
|
@ -827,6 +828,7 @@
|
|||
"규칙상 허용되지 않음": "not allowed by ruleset",
|
||||
"그 자리로": "Go to location",
|
||||
"그 파일 하나만": "Only that file",
|
||||
"그대로": "Keep",
|
||||
"그대로 두기": "Keep",
|
||||
"그래도 Chrome 엔진 쓰기…": "Use the Chrome engine anyway…",
|
||||
"그래도 맞추기 ({0}개 지움)": "Sync anyway (delete {0})",
|
||||
|
|
@ -2884,6 +2886,7 @@
|
|||
"파일 탐색기 누르기: 한 번 누르면 선택 → 한 번 누르면 바로 실행. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "File explorer tap: single tap selects → single tap opens. To revert: Settings > File explorer > Tap",
|
||||
"파일 탐색기 단축키": "File explorer shortcuts",
|
||||
"파일 탐색기 두 창 배치: 화면 모양 따라 → 좌우. 되돌리기: 파일 탐색기의 [좌우 ⇆ / 위아래 ⇅] 버튼 또는 창 배치": "File explorer two-pane layout: follow screen shape → side by side. To revert: the [Columns ⇆ / Rows ⇅] button in the file explorer, or Pane layout",
|
||||
"파일 탐색기 모양": "File explorer look",
|
||||
"파일 탐색기 목록의 이름 · 크기 글자만. 앱 화면 크기 · 기기 글자 크기와 곱해집니다": "Only the name and size text in the file explorer list. Multiplied by the app screen size and the device text size",
|
||||
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "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)",
|
||||
|
|
@ -2918,6 +2921,7 @@
|
|||
"페이지 열기": "Open page",
|
||||
"페이지 지우기": "Delete page",
|
||||
"페이지를 바꾼 것을 저장할까요?": "Save the page changes?",
|
||||
"편집": "Edit",
|
||||
"편집 목록 {0}개": "{0} in the edit list",
|
||||
"편집 목록에 있음": "In the edit list",
|
||||
"편집 목록에 추가": "Add to the edit list",
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@
|
|||
"Windows 에서 이 앱의 알림이 꺼져 있어 보이지 않습니다": "Windows でこのアプリの通知がオフのため表示されません",
|
||||
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "Windows でのみ使えます。この端末では文書を他のアプリで開きます。",
|
||||
"Windows 오류 0x{0}": "Windows エラー 0x{0}",
|
||||
"Windows 의 처음 모양이 Total Commander 로 바뀌었습니다 (목록 · \"..\" · 아래 F3~F8 단추 줄). 지금 쓰는 X-plore 모양을 바꿀까요? 환경 설정 > 파일 탐색기 > 모양에서 언제든 바꿀 수 있습니다.": "Windows の既定の見た目が Total Commander になりました (一覧 · \"..\" · 下の F3~F8 ボタン列)。今使っている X-plore の見た目を変えますか? 設定 > ファイルエクスプローラー > 見た目でいつでも変えられます。",
|
||||
"Windows 탐색기": "Windows エクスプローラー",
|
||||
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore スタイル: 選択マークを常に表示",
|
||||
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore スタイル: 横にスワイプでペイン切り替え",
|
||||
|
|
@ -827,6 +828,7 @@
|
|||
"규칙상 허용되지 않음": "ルールで許可されていません",
|
||||
"그 자리로": "その場所へ",
|
||||
"그 파일 하나만": "そのファイルだけ",
|
||||
"그대로": "このまま",
|
||||
"그대로 두기": "そのままにする",
|
||||
"그래도 Chrome 엔진 쓰기…": "それでも Chrome エンジンを使う…",
|
||||
"그래도 맞추기 ({0}개 지움)": "それでも同期 ({0} 個を削除)",
|
||||
|
|
@ -2884,6 +2886,7 @@
|
|||
"파일 탐색기 누르기: 한 번 누르면 선택 → 한 번 누르면 바로 실행. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "ファイルエクスプローラーのタップ: 1 回で選択 → 1 回ですぐ開く。元に戻す: 環境設定 > ファイルエクスプローラー > タップ",
|
||||
"파일 탐색기 단축키": "ファイルエクスプローラーのショートカット",
|
||||
"파일 탐색기 두 창 배치: 화면 모양 따라 → 좌우. 되돌리기: 파일 탐색기의 [좌우 ⇆ / 위아래 ⇅] 버튼 또는 창 배치": "ファイルエクスプローラーの 2 画面配置: 画面の形に合わせる → 左右。元に戻す: ファイルエクスプローラーの [左右 ⇆ / 上下 ⇅] ボタンまたは画面配置",
|
||||
"파일 탐색기 모양": "ファイルエクスプローラーの見た目",
|
||||
"파일 탐색기 목록의 이름 · 크기 글자만. 앱 화면 크기 · 기기 글자 크기와 곱해집니다": "ファイルエクスプローラー一覧の名前・サイズの文字のみ。アプリの画面サイズ・端末の文字サイズと掛け合わされます",
|
||||
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "ファイルエクスプローラー一覧の行の高さ。狭くすると指でタップしにくい場合があります",
|
||||
"파일 탐색기 위쪽 ⋮ 메뉴에서도 바꿀 수 있습니다 (좌우 · 위아래 · 버튼 줄 위치 · 버튼 구성)": "ファイルエクスプローラー上部の ⋮ メニューからも変えられます (左右 · 上下 · ボタン列の位置 · ボタン構成)",
|
||||
|
|
@ -2918,6 +2921,7 @@
|
|||
"페이지 열기": "ページを開く",
|
||||
"페이지 지우기": "ページを削除",
|
||||
"페이지를 바꾼 것을 저장할까요?": "ページの変更を保存しますか?",
|
||||
"편집": "編集",
|
||||
"편집 목록 {0}개": "編集リスト {0}個",
|
||||
"편집 목록에 있음": "編集リストにあり",
|
||||
"편집 목록에 추가": "編集リストに追加",
|
||||
|
|
|
|||
|
|
@ -423,6 +423,7 @@
|
|||
"Windows 에서 이 앱의 알림이 꺼져 있어 보이지 않습니다": "Windows 中此应用的通知已关闭,因此不会显示",
|
||||
"Windows 에서만 쓸 수 있습니다. 이 기기에서는 문서를 다른 앱으로 엽니다.": "仅限 Windows。在本设备上会用其他应用打开文档。",
|
||||
"Windows 오류 0x{0}": "Windows 错误 0x{0}",
|
||||
"Windows 의 처음 모양이 Total Commander 로 바뀌었습니다 (목록 · \"..\" · 아래 F3~F8 단추 줄). 지금 쓰는 X-plore 모양을 바꿀까요? 환경 설정 > 파일 탐색기 > 모양에서 언제든 바꿀 수 있습니다.": "Windows 的默认外观已改为 Total Commander (列表 · \"..\" · 底部 F3~F8 按钮栏)。要更改当前使用的 X-plore 外观吗? 可随时在 设置 > 文件浏览器 > 外观 中更改。",
|
||||
"Windows 탐색기": "Windows 资源管理器",
|
||||
"X-plore 스타일: 선택 표시 늘 보이기": "X-plore 样式: 始终显示选择标记",
|
||||
"X-plore 스타일: 옆으로 밀면 창 바꾸기": "X-plore 样式: 左右滑动切换窗格",
|
||||
|
|
@ -827,6 +828,7 @@
|
|||
"규칙상 허용되지 않음": "规则不允许",
|
||||
"그 자리로": "转到所在位置",
|
||||
"그 파일 하나만": "仅该文件",
|
||||
"그대로": "保持不变",
|
||||
"그대로 두기": "保留",
|
||||
"그래도 Chrome 엔진 쓰기…": "仍然使用 Chrome 引擎…",
|
||||
"그래도 맞추기 ({0}개 지움)": "仍然同步 (删除 {0} 个)",
|
||||
|
|
@ -2884,6 +2886,7 @@
|
|||
"파일 탐색기 누르기: 한 번 누르면 선택 → 한 번 누르면 바로 실행. 되돌리기: 환경 설정 > 파일 탐색기 > 누르기": "文件浏览器点击: 单击选择 → 单击直接打开。恢复: 设置 > 文件浏览器 > 点击",
|
||||
"파일 탐색기 단축키": "文件管理器快捷键",
|
||||
"파일 탐색기 두 창 배치: 화면 모양 따라 → 좌우. 되돌리기: 파일 탐색기의 [좌우 ⇆ / 위아래 ⇅] 버튼 또는 창 배치": "文件浏览器双窗格布局: 跟随屏幕形状 → 左右。恢复: 文件浏览器中的 [左右 ⇆ / 上下 ⇅] 按钮或窗格布局",
|
||||
"파일 탐색기 모양": "文件浏览器外观",
|
||||
"파일 탐색기 목록의 이름 · 크기 글자만. 앱 화면 크기 · 기기 글자 크기와 곱해집니다": "仅文件管理器列表中的名称和大小文字。会与应用界面大小及设备文字大小相乘",
|
||||
"파일 탐색기 목록의 줄 높이. 좁게는 손가락으로 누르기 어려울 수 있습니다": "文件管理器列表的行高。紧凑时可能难以用手指点按",
|
||||
"파일 탐색기 위쪽 ⋮ 메뉴에서도 바꿀 수 있습니다 (좌우 · 위아래 · 버튼 줄 위치 · 버튼 구성)": "也可以在文件浏览器顶部的 ⋮ 菜单中更改 (左右 · 上下 · 按钮栏位置 · 按钮配置)",
|
||||
|
|
@ -2918,6 +2921,7 @@
|
|||
"페이지 열기": "打开页面",
|
||||
"페이지 지우기": "删除页面",
|
||||
"페이지를 바꾼 것을 저장할까요?": "保存页面的更改吗?",
|
||||
"편집": "编辑",
|
||||
"편집 목록 {0}개": "编辑列表 {0} 个",
|
||||
"편집 목록에 있음": "已在编辑列表中",
|
||||
"편집 목록에 추가": "加入编辑列表",
|
||||
|
|
|
|||
|
|
@ -45,9 +45,15 @@ class ExplorerSettings implements SettingsGroup {
|
|||
/// 길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴.
|
||||
String click = 'select';
|
||||
|
||||
/// 모양: 'xplore' (기본) · 'windows' Windows 탐색기 · 'totalcmd' Total Commander.
|
||||
/// 규칙 1 의 Windows 처음 값 (Total Commander) 과 저장된 값 묻기 (결정 1) 는 E6 (TC 모양) 과 함께 (관리자 결정 10/22)
|
||||
String style = 'xplore';
|
||||
/// 모양: 'xplore' X-plore · 'windows' Windows 탐색기 · 'totalcmd' Total Commander.
|
||||
/// 처음 값은 기기마다 (규칙 1 · E6): Windows = Total Commander, Android = X-plore
|
||||
String style = defaultStyle;
|
||||
|
||||
static String get defaultStyle => Platform.isWindows ? 'totalcmd' : 'xplore';
|
||||
|
||||
/// E6 (결정 10/22 ①): Windows 에서 예전 판이 저장한 'xplore' 를 한 번 물을지 (처음 값이었는지 사용자가 고른 것인지 알 수 없어서).
|
||||
/// 읽을 때 정하고 저장하지 않는다 - 물었다는 표시 (explorerStyleV2) 는 늘 저장한다
|
||||
bool styleAskPending = false;
|
||||
|
||||
/// 두 창 배치: 'side' 좌우 (기본, 118 - 폰 세로에서도) · 'stacked' 위아래 · 'auto' 화면 모양 따라 (가로로 넓으면 좌우, 세로로 길면 위아래)
|
||||
String orientation = 'side';
|
||||
|
|
@ -123,6 +129,7 @@ class ExplorerSettings implements SettingsGroup {
|
|||
j['androidTrashDays'] = androidTrashDays;
|
||||
j['explorerClick'] = click;
|
||||
j['explorerStyle'] = style;
|
||||
j['explorerStyleV2'] = true;
|
||||
j['explorerOrientation'] = orientation;
|
||||
j['explorerToolbar'] = toolbar;
|
||||
j['explorerButtons'] = buttons;
|
||||
|
|
@ -174,7 +181,13 @@ class ExplorerSettings implements SettingsGroup {
|
|||
};
|
||||
// 규칙 2: 두 기기 모두 한 번 = 선택. 규칙 이전 Android 의 'open' 은 예전 처음 값이라 한 번 'select' 로
|
||||
click = j['explorerClick'] == 'open' && (j['explorerRulesV1'] == true || !Platform.isAndroid) ? 'open' : 'select';
|
||||
style = const ['windows', 'totalcmd'].contains(j['explorerStyle']) ? j['explorerStyle'] as String : 'xplore';
|
||||
// 예전 판의 파일에 모양이 없으면 그때의 처음 값 (X-plore) - 새로 설치 (빈 설정) 만 기기의 처음 값
|
||||
style = const ['xplore', 'windows', 'totalcmd'].contains(j['explorerStyle'])
|
||||
? j['explorerStyle'] as String
|
||||
: j.isEmpty
|
||||
? defaultStyle
|
||||
: 'xplore';
|
||||
styleAskPending = Platform.isWindows && j.isNotEmpty && j['explorerStyleV2'] != true && style == 'xplore';
|
||||
// 118: 예전 기본 '화면 모양 따라' 는 한 번 좌우로 옮긴다 (사용자가 고른 위아래는 그대로)
|
||||
orientation = j['explorerOrientation'] == 'stacked'
|
||||
? 'stacked'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,33 @@
|
|||
/// 약속 (E6, 결정 10/22 ①): Windows 에서 예전 판이 저장한 X-plore 모양을 한 번만 묻는다.
|
||||
/// [ExplorerSettings.styleAskPending] 일 때만 창을 띄우고, [바꾸기] 면 Total Commander, [그대로] 면 X-plore 를 둔다.
|
||||
/// 어느 쪽이든 다시 묻지 않는다 (물었다는 표시는 설정 저장에 늘 들어감). 창 밖을 눌러 닫지 못한다 (답을 골라야 함).
|
||||
library;
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
|
||||
import '../../app/app_controller.dart';
|
||||
import '../../l10n/tr.dart';
|
||||
|
||||
/// 물었으면 true (답과 상관없이). 물을 것이 없으면 false
|
||||
Future<bool> askExplorerStyleOnce(BuildContext context, AppController c) async {
|
||||
if (!c.settings.explorer.styleAskPending) return false;
|
||||
c.settings.explorer.styleAskPending = false; // 창을 띄우는 동안 다시 부르면 또 띄우지 않게
|
||||
final change = await showDialog<bool>(
|
||||
context: context,
|
||||
barrierDismissible: false,
|
||||
builder: (ctx) => AlertDialog(
|
||||
title: Text(tr('파일 탐색기 모양')),
|
||||
content: Text(tr('Windows 의 처음 모양이 Total Commander 로 바뀌었습니다 (목록 · ".." · 아래 F3~F8 단추 줄). '
|
||||
'지금 쓰는 X-plore 모양을 바꿀까요? 환경 설정 > 파일 탐색기 > 모양에서 언제든 바꿀 수 있습니다.')),
|
||||
actions: [
|
||||
TextButton(onPressed: () => Navigator.pop(ctx, false), child: Text(tr('그대로'))),
|
||||
FilledButton(onPressed: () => Navigator.pop(ctx, true), child: Text(tr('바꾸기'))),
|
||||
],
|
||||
),
|
||||
);
|
||||
await c.updateSettings((x) {
|
||||
x.explorer.styleAskPending = false;
|
||||
if (change == true) x.explorer.style = 'totalcmd';
|
||||
});
|
||||
return true;
|
||||
}
|
||||
|
|
@ -17,6 +17,7 @@ import '../core/thumb_cache.dart' show thumbMemoryForgetters;
|
|||
import 'explorer_drag.dart';
|
||||
import '../core/wifi_share.dart' show WifiShare;
|
||||
import '../app/volumes.dart';
|
||||
import 'explorer/style_ask.dart';
|
||||
import 'explorer/explorer_controller.dart';
|
||||
import 'explorer/explorer_host.dart';
|
||||
import 'explorer/explorer_pane.dart';
|
||||
|
|
@ -152,6 +153,8 @@ class _ExplorerPageState extends State<ExplorerPage> implements ExplorerHost, Ex
|
|||
_kindSeen = c.settings.explorer.sortByKind;
|
||||
c.addListener(_onSettings);
|
||||
_init();
|
||||
// E6: 예전 판이 저장한 X-plore 모양이면 한 번 묻는다 (Windows - Rsync 화면은 묻지 않음)
|
||||
if (!widget.rsync) afterFrame(() => mounted ? unawaited(askExplorerStyleOnce(context, c)) : null);
|
||||
}
|
||||
|
||||
/// 232: 앱으로 돌아오면 (다른 앱 · 탐색기에서 파일을 바꾸고 오면) 보이는 폴더를 다시 읽는다
|
||||
|
|
|
|||
|
|
@ -205,7 +205,10 @@ class _FilesSettingsSectionState extends State<FilesSettingsSection> {
|
|||
for (final st in ExplorerStyle.values)
|
||||
DropdownMenuItem(value: st.name, child: Text(tr(st.label))),
|
||||
],
|
||||
onChanged: (v) => c.updateSettings((x) => x.explorer.style = v!),
|
||||
// 직접 골랐으면 예전 모양을 묻지 않는다 (E6)
|
||||
onChanged: (v) => c.updateSettings((x) => x.explorer
|
||||
..style = v!
|
||||
..styleAskPending = false),
|
||||
),
|
||||
),
|
||||
SettingTile(
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void main() {
|
|||
setUp(() {
|
||||
tmp = Directory.systemTemp.createTempSync('jj_dismiss_');
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
});
|
||||
tearDown(() => tmp.deleteSync(recursive: true));
|
||||
|
||||
|
|
|
|||
|
|
@ -40,6 +40,7 @@ void main() {
|
|||
File(p.join(left, 'doc.txt')).setLastModifiedSync(DateTime(2026, 10, 9, 12));
|
||||
File(p.join(right, 'doc.txt')).setLastModifiedSync(DateTime(2026, 10, 1, 8));
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings.explorer.paths = [left, right];
|
||||
final root = p.rootPrefix(tmp.path);
|
||||
device.volumes = () => [(root, root.replaceAll(RegExp(r'[\\/]+$'), ''))];
|
||||
|
|
|
|||
|
|
@ -29,6 +29,7 @@ void main() {
|
|||
..writeAsStringSync('x');
|
||||
Directory(p.join(tmp.path, 'right')).createSync();
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings.explorer.paths = [p.join(tmp.path, 'left'), p.join(tmp.path, 'right')];
|
||||
stuck = Completer<bool>();
|
||||
dead = {r'R:\'};
|
||||
|
|
|
|||
|
|
@ -51,6 +51,7 @@ void main() {
|
|||
|
||||
Future<(ExplorerController, GlobalKey<_HostState>)> open(WidgetTester t, {double width = 800}) async {
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
final key = GlobalKey<_HostState>();
|
||||
await t.binding.setSurfaceSize(Size(width, 600));
|
||||
addTearDown(() => t.binding.setSurfaceSize(null));
|
||||
|
|
|
|||
|
|
@ -28,6 +28,7 @@ void main() {
|
|||
File(p.join(left, 'doc.txt')).writeAsStringSync('hello');
|
||||
Directory(right).createSync();
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.paths = [left, right]
|
||||
..copy.bandwidthKBps = 512; // 큰 파일이 6초쯤 걸리게
|
||||
|
|
@ -68,6 +69,7 @@ void main() {
|
|||
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
||||
device.volumes = () => [(tmp.path, 'T:')];
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.orientation = 'side'
|
||||
..copy.rsyncPaths = [l, r];
|
||||
|
|
@ -108,6 +110,7 @@ void main() {
|
|||
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
||||
device.volumes = () => [(tmp.path, 'T:')];
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.orientation = 'side'
|
||||
..copy.rsyncPaths = [l, r];
|
||||
|
|
@ -144,6 +147,7 @@ void main() {
|
|||
Directory(r).createSync(recursive: true);
|
||||
device.volumes = () => [(tmp.path, 'T:')];
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.orientation = 'side'
|
||||
..copy.rsyncPaths = [l, r];
|
||||
|
|
@ -166,6 +170,7 @@ void main() {
|
|||
Directory(p.join(sd, 'R')).createSync(recursive: true);
|
||||
device.volumes = () => [(inner, '내장 저장소'), (sd, 'SD 카드')];
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.orientation = 'side'
|
||||
..copy.rsyncPaths = [p.join(inner, 'L'), p.join(sd, 'R')];
|
||||
|
|
@ -192,6 +197,7 @@ void main() {
|
|||
Directory(p.join(l, 'sub')).createSync(recursive: true);
|
||||
Directory(p.join(r, 'rsub')).createSync(recursive: true);
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.layout = 'single'
|
||||
..copy.rsyncPaths = [l, r];
|
||||
|
|
@ -225,6 +231,7 @@ void main() {
|
|||
..writeAsStringSync('d');
|
||||
File(p.join(l, 'top.txt')).writeAsStringSync('t');
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.layout = 'single'
|
||||
..explorer.paths = [l, l];
|
||||
|
|
@ -258,6 +265,7 @@ void main() {
|
|||
..writeAsStringSync('$i');
|
||||
}
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.layout = 'single'
|
||||
..explorer.paths = [dl, dl];
|
||||
|
|
@ -292,6 +300,7 @@ void main() {
|
|||
}
|
||||
File(p.join(l, 'zz_file.txt')).writeAsStringSync('t');
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.layout = 'dual'
|
||||
..explorer.orientation = 'stacked'
|
||||
|
|
@ -333,6 +342,7 @@ void main() {
|
|||
..createSync(recursive: true)
|
||||
..writeAsStringSync('a');
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.layout = 'single'
|
||||
..explorer.paths = [l, l];
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ void main() {
|
|||
// 저장 장치는 시험 폴더 하나 (실제 Temp 폴더의 많은 항목 사이에서 찾지 않게)
|
||||
device.volumes = () => [(tmp.path, 'T:')];
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService(), shell: NoopShell()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..explorer.paths = [left, right]
|
||||
..copy.methodFile = 'builtin'
|
||||
|
|
|
|||
|
|
@ -0,0 +1,75 @@
|
|||
import 'dart:io';
|
||||
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:flutter_test/flutter_test.dart';
|
||||
import 'package:jj_mkvmaker/app/app_controller.dart';
|
||||
import 'package:jj_mkvmaker/app/settings.dart';
|
||||
import 'package:jj_mkvmaker/platform/windows/desktop_storage_service.dart';
|
||||
import 'package:jj_mkvmaker/platform/windows/process_media_tool.dart';
|
||||
import 'package:jj_mkvmaker/services/platform_services.dart';
|
||||
import 'package:jj_mkvmaker/ui/explorer/style_ask.dart';
|
||||
|
||||
/// E6 약속: 파일 탐색기 모양의 처음 값은 기기마다 (Windows = Total Commander) · 예전 판이 저장한 X-plore 는 한 번만 묻는다
|
||||
void main() {
|
||||
final win = Platform.isWindows;
|
||||
|
||||
test('처음 값: 새로 설치 (빈 설정) 는 기기의 처음 값 - Windows 는 Total Commander, 묻지 않음', () {
|
||||
final s = AppSettings.fromJson({});
|
||||
expect(s.explorer.style, win ? 'totalcmd' : 'xplore');
|
||||
expect(s.explorer.styleAskPending, isFalse);
|
||||
expect(AppSettings().explorer.style, ExplorerSettings.defaultStyle);
|
||||
});
|
||||
|
||||
test('저장된 값: 예전 판의 xplore (또는 모양 키가 없던 예전 파일) 는 Windows 에서 한 번 묻고, 고른 windows · totalcmd 는 묻지 않음', () {
|
||||
final old = AppSettings.fromJson({'explorerStyle': 'xplore', 'explorerLayout': 'dual'});
|
||||
expect([old.explorer.style, old.explorer.styleAskPending], ['xplore', win]);
|
||||
final noKey = AppSettings.fromJson({'explorerLayout': 'dual'});
|
||||
expect([noKey.explorer.style, noKey.explorer.styleAskPending], ['xplore', win], reason: '그때의 처음 값 (X-plore) 을 덮지 않음');
|
||||
for (final v in ['windows', 'totalcmd']) {
|
||||
final s = AppSettings.fromJson({'explorerStyle': v, 'explorerLayout': 'dual'});
|
||||
expect([s.explorer.style, s.explorer.styleAskPending], [v, false]);
|
||||
}
|
||||
final again = AppSettings.fromJson(old.toJson());
|
||||
expect([again.explorer.style, again.explorer.styleAskPending], ['xplore', false], reason: '한 번 저장하면 (물었다는 표시) 다시 묻지 않음');
|
||||
});
|
||||
|
||||
group('묻는 창 (askExplorerStyleOnce)', () {
|
||||
AppController ctl(Map<String, dynamic> saved) =>
|
||||
AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()))
|
||||
..settings = AppSettings.fromJson(saved);
|
||||
|
||||
Future<bool> ask(WidgetTester t, AppController c, {String? pick}) async {
|
||||
final key = GlobalKey<NavigatorState>();
|
||||
await t.pumpWidget(MaterialApp(navigatorKey: key, home: const Scaffold(body: SizedBox())));
|
||||
final f = askExplorerStyleOnce(key.currentContext!, c);
|
||||
await t.pumpAndSettle();
|
||||
if (pick != null) {
|
||||
expect(find.text('파일 탐색기 모양'), findsOneWidget);
|
||||
await t.tapAt(const Offset(5, 5)); // 창 밖을 눌러도 닫히지 않음
|
||||
await t.pumpAndSettle();
|
||||
expect(find.text('파일 탐색기 모양'), findsOneWidget);
|
||||
await t.tap(find.text(pick));
|
||||
await t.pumpAndSettle();
|
||||
}
|
||||
return f;
|
||||
}
|
||||
|
||||
testWidgets('[그대로] 면 X-plore 를 두고 다시 묻지 않음', (t) async {
|
||||
final c = ctl({'explorerStyle': 'xplore', 'explorerLayout': 'dual'})..settings.explorer.styleAskPending = true;
|
||||
expect(await ask(t, c, pick: '그대로'), isTrue);
|
||||
expect([c.settings.explorer.style, c.settings.explorer.styleAskPending], ['xplore', false]);
|
||||
expect(await ask(t, c), isFalse);
|
||||
expect(find.text('파일 탐색기 모양'), findsNothing, reason: '두 번째는 창을 띄우지 않음');
|
||||
expect(c.settings.toJson()['explorerStyleV2'], isTrue);
|
||||
});
|
||||
|
||||
testWidgets('[바꾸기] 면 Total Commander · 물을 것이 없으면 창 없음', (t) async {
|
||||
final c = ctl({'explorerStyle': 'xplore', 'explorerLayout': 'dual'})..settings.explorer.styleAskPending = true;
|
||||
expect(await ask(t, c, pick: '바꾸기'), isTrue);
|
||||
expect([c.settings.explorer.style, c.settings.explorer.styleAskPending], ['totalcmd', false]);
|
||||
final picked = ctl({'explorerStyle': 'windows', 'explorerLayout': 'dual'});
|
||||
expect(await ask(t, picked), isFalse);
|
||||
expect(picked.settings.explorer.style, 'windows');
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -56,6 +56,7 @@ void main() {
|
|||
device.volumes = () => [(root, root.replaceAll(RegExp(r'[\\/]+$'), ''))];
|
||||
c = AppController(PlatformServices(
|
||||
mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService(), shell: shell));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
});
|
||||
tearDown(() async {
|
||||
DavRegistry.configure([]);
|
||||
|
|
|
|||
|
|
@ -114,7 +114,8 @@
|
|||
"explorerSortByKind": false,
|
||||
"explorerSortDesc": false,
|
||||
"explorerSortPerFolder": false,
|
||||
"explorerStyle": "xplore",
|
||||
"explorerStyle": "totalcmd",
|
||||
"explorerStyleV2": true,
|
||||
"explorerSwipePanes": false,
|
||||
"explorerTextScale": 100,
|
||||
"explorerToolbar": "middle",
|
||||
|
|
|
|||
|
|
@ -126,6 +126,7 @@
|
|||
"explorerSortDesc": false,
|
||||
"explorerSortPerFolder": false,
|
||||
"explorerStyle": "xplore",
|
||||
"explorerStyleV2": true,
|
||||
"explorerSwipePanes": false,
|
||||
"explorerTextScale": 100,
|
||||
"explorerToolbar": "middle",
|
||||
|
|
|
|||
|
|
@ -120,6 +120,7 @@
|
|||
"explorerSortDesc": true,
|
||||
"explorerSortPerFolder": true,
|
||||
"explorerStyle": "xplore",
|
||||
"explorerStyleV2": true,
|
||||
"explorerSwipePanes": true,
|
||||
"explorerTextScale": 107,
|
||||
"explorerToolbar": "middle",
|
||||
|
|
|
|||
|
|
@ -128,6 +128,7 @@ void main() {
|
|||
|
||||
AppController ctl({bool on = true}) {
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..tools.rootEnabled = on
|
||||
..explorer.paths = [tmp.path, tmp.path]
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ void main() {
|
|||
await server.start();
|
||||
final s = DavServer(id: 'nas', name: '집 NAS', url: server.url, user: 'user', password: 'pass');
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..remote.webdavServers = [s]
|
||||
..explorer.layout = 'single'
|
||||
|
|
|
|||
|
|
@ -50,6 +50,7 @@ void main() {
|
|||
server = s;
|
||||
final local = Directory(p.join(tmp.path, 'local'))..createSync();
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
await tester.runAsync(() => c.updateSettings((x) => x
|
||||
..remote.sftpServers = [SftpServer(id: 's1', name: 'NAS', host: '127.0.0.1', port: s!.port, user: 'jj', password: 'pw')]
|
||||
..explorer.paths = ['sftp://s1/', local.path]));
|
||||
|
|
|
|||
|
|
@ -111,6 +111,7 @@ void main() {
|
|||
|
||||
AppController ctl({bool on = true}) {
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings
|
||||
..tools.shizukuEnabled = on
|
||||
..explorer.paths = [tmp.path, tmp.path]
|
||||
|
|
|
|||
|
|
@ -66,6 +66,7 @@ void useExplorerFixture() {
|
|||
_c = AppController(PlatformServices(
|
||||
mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService(), shell: shell));
|
||||
c.settings.explorer.paths = [left, right];
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험들은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
});
|
||||
// Windows: 방금 닫은 파일 (65 의 잠금 시험) 이나 색인 · 백신이 잠깐 잡고 있으면 지우기가 실패한다 - 될 때까지 기다린다
|
||||
tearDown(() async {
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ void main() {
|
|||
..createSync(recursive: true)
|
||||
..writeAsStringSync('2');
|
||||
c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
});
|
||||
tearDown(() => tmp.deleteSync(recursive: true));
|
||||
|
||||
|
|
|
|||
|
|
@ -48,6 +48,7 @@ void main() {
|
|||
|
||||
AppController ctl() {
|
||||
final c = AppController(PlatformServices(mediaTool: ProcessMediaTool('x', 'y'), storage: DesktopStorageService()));
|
||||
c.settings.explorer.style = 'xplore'; // E6: 이 시험은 X-plore 모양 (트리) 을 본다 - Windows 처음 값은 Total Commander
|
||||
c.settings.vault.enabled = true;
|
||||
return c;
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue