WIP X-plore b: 가운데 버튼 길게 누르기 = 짝 동작 (복사 ↔ 이동, 삭제 → 영구 삭제로 묻기) (검토 대기)
15 비교표 P1 b (X-plore 의 버튼 길게 누르기). 확인 창은 그대로 - 영구 삭제는 처음 고른 칸만 영구로 (Shift+Delete 와 같음). 풍선 도움말에 "길게 누르면 …". Rsync 화면은 없음. 시험: explorer_test "X-plore b". Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>xplore_p3
parent
818b4a0615
commit
f9cd5f98c9
|
|
@ -730,6 +730,7 @@
|
|||
"기억한 복사가 없습니다. 파일 탐색기에서 복사 · 이동하면 여기에 자동으로 등록됩니다.": "No remembered copies. Copies · moves in the file explorer are added here automatically.",
|
||||
"기타 즐겨찾기": "Other bookmarks",
|
||||
"길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴 (복사 · 이동 · 삭제 · 이름 변경 …). Ctrl + 클릭: 여러 개 고르기": "Long press · right click always opens the action menu (copy · move · delete · rename …). Ctrl + click: select several",
|
||||
"길게 누르면 {0}": "long-press: {0}",
|
||||
"길이": "Length",
|
||||
"길이 {0}": "Length {0}",
|
||||
"끄기": "Off",
|
||||
|
|
|
|||
|
|
@ -730,6 +730,7 @@
|
|||
"기억한 복사가 없습니다. 파일 탐색기에서 복사 · 이동하면 여기에 자동으로 등록됩니다.": "記憶したコピーはありません。ファイルエクスプローラーでコピー · 移動すると自動で登録されます。",
|
||||
"기타 즐겨찾기": "その他のブックマーク",
|
||||
"길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴 (복사 · 이동 · 삭제 · 이름 변경 …). Ctrl + 클릭: 여러 개 고르기": "長押し · 右クリックは常に機能メニュー (コピー · 移動 · 削除 · 名前の変更 …)。Ctrl + クリック: 複数選択",
|
||||
"길게 누르면 {0}": "長押しで{0}",
|
||||
"길이": "長さ",
|
||||
"길이 {0}": "長さ {0}",
|
||||
"끄기": "オフ",
|
||||
|
|
|
|||
|
|
@ -730,6 +730,7 @@
|
|||
"기억한 복사가 없습니다. 파일 탐색기에서 복사 · 이동하면 여기에 자동으로 등록됩니다.": "没有记住的复制。在文件浏览器中复制 · 移动后会自动登记到这里。",
|
||||
"기타 즐겨찾기": "其他书签",
|
||||
"길게 누르기 · 오른쪽 클릭은 늘 기능 메뉴 (복사 · 이동 · 삭제 · 이름 변경 …). Ctrl + 클릭: 여러 개 고르기": "长按 · 右键总是打开功能菜单 (复制 · 移动 · 删除 · 重命名 …)。Ctrl + 点击: 多选",
|
||||
"길게 누르면 {0}": "长按: {0}",
|
||||
"길이": "时长",
|
||||
"길이 {0}": "时长 {0}",
|
||||
"끄기": "关闭",
|
||||
|
|
|
|||
|
|
@ -1718,6 +1718,21 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
}
|
||||
}
|
||||
|
||||
/// X-plore b: 가운데 버튼 길게 누르기 - 복사 ↔ 이동, 지우기 → 영구 삭제로 묻기 (확인 창은 그대로)
|
||||
Future<void> _buttonLong(ExplorerButton b) async {
|
||||
switch (b) {
|
||||
case ExplorerButton.copy:
|
||||
return _button(ExplorerButton.move);
|
||||
case ExplorerButton.move:
|
||||
return _button(ExplorerButton.copy);
|
||||
case ExplorerButton.delete:
|
||||
_shiftDelete = true;
|
||||
return _button(ExplorerButton.delete);
|
||||
default:
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Future<void> _button(ExplorerButton b) async {
|
||||
final pane = _pane;
|
||||
switch (b) {
|
||||
|
|
@ -3461,6 +3476,8 @@ class _ExplorerPageState extends State<ExplorerPage> {
|
|||
final bar = s.explorerToolbar == 'hidden' && !widget.rsync
|
||||
? null
|
||||
: _Toolbar(
|
||||
// X-plore b: 길게 누르기 = 짝 동작 (Rsync 화면은 없음)
|
||||
onLongPress: widget.rsync ? null : _buttonLong,
|
||||
// Rsync 화면: 늘 같은 버튼 (→ ← ⇄ 모니터링) 을 두 창 사이에
|
||||
buttons: widget.rsync ? ExplorerButton.rsyncButtons : ExplorerButton.fromSettings(s.explorerButtons),
|
||||
vertical: side && !rsyncOne,
|
||||
|
|
@ -4511,12 +4528,16 @@ class _Toolbar extends StatelessWidget {
|
|||
|
||||
/// 좁아도 [더 보기] 로 보내지 않는 버튼 (창 배치 · 담아 둔 것이 있을 때 붙여넣기)
|
||||
final Set<ExplorerButton> pinned;
|
||||
|
||||
/// X-plore b: 길게 누르기 = 짝 동작 (복사 ↔ 이동, 지우기 → 영구 삭제). 짝이 없는 버튼은 null
|
||||
final void Function(ExplorerButton)? onLongPress;
|
||||
const _Toolbar(
|
||||
{required this.buttons,
|
||||
required this.vertical,
|
||||
required this.onPressed,
|
||||
required this.enabled,
|
||||
required this.selected,
|
||||
this.onLongPress,
|
||||
this.twoPanes = true,
|
||||
this.pinned = const {ExplorerButton.orient},
|
||||
bool? panesSide})
|
||||
|
|
@ -4526,6 +4547,14 @@ class _Toolbar extends StatelessWidget {
|
|||
/// 191 좁은 Rsync 화면 (창 하나씩, 버튼 줄은 가로) 은 좌우
|
||||
final bool panesSide;
|
||||
|
||||
/// X-plore b: 길게 누르면 하는 짝 동작의 이름 (없으면 null)
|
||||
static String? longPressLabel(ExplorerButton b) => switch (b) {
|
||||
ExplorerButton.copy => '이동',
|
||||
ExplorerButton.move => '복사',
|
||||
ExplorerButton.delete => '영구 삭제',
|
||||
_ => null,
|
||||
};
|
||||
|
||||
/// 118: 지금 배치를 보여 준다 (누르면 반대로)
|
||||
String _orientLabel() => !twoPanes ? '두 창으로' : panesSide ? '좌우 ⇆' : '위아래 ⇅';
|
||||
String _orientTip() => !twoPanes
|
||||
|
|
@ -4562,10 +4591,14 @@ class _Toolbar extends StatelessWidget {
|
|||
Widget btn(ExplorerButton b) {
|
||||
final on = enabled(b);
|
||||
final sel = selected(b);
|
||||
final pair = longPressLabel(b);
|
||||
final long = onLongPress;
|
||||
return Tooltip(
|
||||
message: tr(b == ExplorerButton.orient ? _orientTip() : _label(b)),
|
||||
message: tr(b == ExplorerButton.orient ? _orientTip() : _label(b)) +
|
||||
(pair != null && long != null ? ' · ${trf('길게 누르면 {0}', [tr(pair)])}' : ''),
|
||||
child: InkWell(
|
||||
onTap: on ? () => onPressed(b) : null,
|
||||
onLongPress: on && pair != null && long != null ? () => long(b) : null,
|
||||
borderRadius: BorderRadius.circular(6),
|
||||
child: SizedBox(
|
||||
width: 72,
|
||||
|
|
|
|||
|
|
@ -159,6 +159,23 @@ void main() {
|
|||
await tester.pump(const Duration(seconds: 2));
|
||||
});
|
||||
|
||||
testWidgets('X-plore b: 가운데 버튼 길게 누르기 = 짝 동작 - [복사] 길게 = 이동 창 · [삭제] 길게 = 영구 삭제 창', (tester) async {
|
||||
await open(tester);
|
||||
await act(tester, () => tester.tap(find.text('doc.txt')));
|
||||
await settle(tester, () => false, rounds: 15);
|
||||
await tester.longPress(find.text('복사').first);
|
||||
await calm(tester);
|
||||
expect(find.widgetWithText(FilledButton, '이동'), findsOneWidget, reason: '복사 길게 = 이동');
|
||||
await tester.tap(find.text('취소').last);
|
||||
await calm(tester);
|
||||
await tester.longPress(find.text('삭제').first);
|
||||
await calm(tester);
|
||||
expect(find.widgetWithText(FilledButton, '영구 삭제'), findsOneWidget, reason: '삭제 길게 = 영구 삭제로 묻기');
|
||||
await tester.tap(find.text('취소').last);
|
||||
await calm(tester);
|
||||
expect(File(p.join(left, 'doc.txt')).existsSync(), isTrue);
|
||||
});
|
||||
|
||||
testWidgets('178 보충: 설정의 원본 지우기 옵션은 복사 창에서 빠진 까닭을 알린다 (이동 창에는 없음)', (tester) async {
|
||||
c.settings
|
||||
..copyMethodFile = 'robocopy'
|
||||
|
|
|
|||
Loading…
Reference in New Issue