모니터링 카드에 실제로 실행할 것 · 이동 / 복사 (209)
관리자 지시: 카드의 옵션 칸은 저장된 원문이라 이동 카드는 "-avPog", 복사 카드는 "… --remove-source-files" (실제로는 빠짐) 로 거꾸로 읽혔다. 칸 옆에 "이동 · 실제 실행: rsync -avPog --remove-source-files" / "복사 · 실제 실행: rsync -avPog" 를 보이고, 복사 카드 칸에 원본 지우기 옵션이 있으면 쓰지 않는다고 알린다. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>fix_mkv
parent
f59e2f75a1
commit
37d7c0da31
|
|
@ -981,6 +981,7 @@
|
||||||
"복사 끝 ({0}): {1}개 → {2}": "Copy done ({0}): {1} → {2}",
|
"복사 끝 ({0}): {1}개 → {2}": "Copy done ({0}): {1} → {2}",
|
||||||
"복사 모니터링": "Copy monitor",
|
"복사 모니터링": "Copy monitor",
|
||||||
"복사 실패 ({0}): {1}": "Copy failed ({0}): {1}",
|
"복사 실패 ({0}): {1}": "Copy failed ({0}): {1}",
|
||||||
|
"복사 작업이라 칸의 원본 지우기 옵션 (--remove-source-files · /MOV) 은 쓰지 않습니다. 옮기려면 Rsync 화면에서 [원본 파일 지우기] 를 켜세요": "This is a copy task, so source-removing options in the field (--remove-source-files · /MOV) are not used. To move, turn on [Remove source files] on the Rsync screen",
|
||||||
"복사(Ctrl+C)한 주소 자동 다운로드": "Auto-download copied (Ctrl+C) URLs",
|
"복사(Ctrl+C)한 주소 자동 다운로드": "Auto-download copied (Ctrl+C) URLs",
|
||||||
"복사하는 중": "Copying",
|
"복사하는 중": "Copying",
|
||||||
"복사할": "copy",
|
"복사할": "copy",
|
||||||
|
|
@ -1174,6 +1175,7 @@
|
||||||
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "No live sync. [Add] one, or use [Move to lsync] in the copy · rsync tab.",
|
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "No live sync. [Add] one, or use [Move to lsync] in the copy · rsync tab.",
|
||||||
"실시간 동기화를 지울까요?": "Delete this live sync?",
|
"실시간 동기화를 지울까요?": "Delete this live sync?",
|
||||||
"실시간 동기화의 [최종 정리]": "[Final cleanup] in live sync",
|
"실시간 동기화의 [최종 정리]": "[Final cleanup] in live sync",
|
||||||
|
"실제 실행: {0}": "Actually runs: {0}",
|
||||||
"실패": "Failed",
|
"실패": "Failed",
|
||||||
"실패 · {0}": "Failed · {0}",
|
"실패 · {0}": "Failed · {0}",
|
||||||
"실패: {0}": "Failed: {0}",
|
"실패: {0}": "Failed: {0}",
|
||||||
|
|
|
||||||
|
|
@ -981,6 +981,7 @@
|
||||||
"복사 끝 ({0}): {1}개 → {2}": "コピー完了 ({0}): {1} 件 → {2}",
|
"복사 끝 ({0}): {1}개 → {2}": "コピー完了 ({0}): {1} 件 → {2}",
|
||||||
"복사 모니터링": "コピーのモニタリング",
|
"복사 모니터링": "コピーのモニタリング",
|
||||||
"복사 실패 ({0}): {1}": "コピー失敗 ({0}): {1}",
|
"복사 실패 ({0}): {1}": "コピー失敗 ({0}): {1}",
|
||||||
|
"복사 작업이라 칸의 원본 지우기 옵션 (--remove-source-files · /MOV) 은 쓰지 않습니다. 옮기려면 Rsync 화면에서 [원본 파일 지우기] 를 켜세요": "コピー作業のため、欄の元ファイル削除オプション (--remove-source-files · /MOV) は使いません。移動するには Rsync 画面で [元ファイルを削除] をオンにしてください",
|
||||||
"복사(Ctrl+C)한 주소 자동 다운로드": "コピー(Ctrl+C)した URL を自動ダウンロード",
|
"복사(Ctrl+C)한 주소 자동 다운로드": "コピー(Ctrl+C)した URL を自動ダウンロード",
|
||||||
"복사하는 중": "コピー中",
|
"복사하는 중": "コピー中",
|
||||||
"복사할": "コピーする",
|
"복사할": "コピーする",
|
||||||
|
|
@ -1174,6 +1175,7 @@
|
||||||
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "リアルタイム同期はありません。[追加] するか、コピー · rsync タブで [lsync へ移動] してください。",
|
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "リアルタイム同期はありません。[追加] するか、コピー · rsync タブで [lsync へ移動] してください。",
|
||||||
"실시간 동기화를 지울까요?": "このリアルタイム同期を削除しますか?",
|
"실시간 동기화를 지울까요?": "このリアルタイム同期を削除しますか?",
|
||||||
"실시간 동기화의 [최종 정리]": "リアルタイム同期の [最終整理]",
|
"실시간 동기화의 [최종 정리]": "リアルタイム同期の [最終整理]",
|
||||||
|
"실제 실행: {0}": "実際の実行: {0}",
|
||||||
"실패": "失敗",
|
"실패": "失敗",
|
||||||
"실패 · {0}": "失敗 · {0}",
|
"실패 · {0}": "失敗 · {0}",
|
||||||
"실패: {0}": "失敗: {0}",
|
"실패: {0}": "失敗: {0}",
|
||||||
|
|
|
||||||
|
|
@ -981,6 +981,7 @@
|
||||||
"복사 끝 ({0}): {1}개 → {2}": "复制完成 ({0}): {1} 个 → {2}",
|
"복사 끝 ({0}): {1}개 → {2}": "复制完成 ({0}): {1} 个 → {2}",
|
||||||
"복사 모니터링": "复制监控",
|
"복사 모니터링": "复制监控",
|
||||||
"복사 실패 ({0}): {1}": "复制失败 ({0}): {1}",
|
"복사 실패 ({0}): {1}": "复制失败 ({0}): {1}",
|
||||||
|
"복사 작업이라 칸의 원본 지우기 옵션 (--remove-source-files · /MOV) 은 쓰지 않습니다. 옮기려면 Rsync 화면에서 [원본 파일 지우기] 를 켜세요": "这是复制任务,栏中的删除源文件选项(--remove-source-files · /MOV)不会使用。要移动,请在 Rsync 界面打开 [删除源文件]",
|
||||||
"복사(Ctrl+C)한 주소 자동 다운로드": "自动下载复制(Ctrl+C)的地址",
|
"복사(Ctrl+C)한 주소 자동 다운로드": "自动下载复制(Ctrl+C)的地址",
|
||||||
"복사하는 중": "正在复制",
|
"복사하는 중": "正在复制",
|
||||||
"복사할": "复制",
|
"복사할": "复制",
|
||||||
|
|
@ -1174,6 +1175,7 @@
|
||||||
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "没有实时同步。请 [添加],或在 复制 · rsync 标签中 [移到 lsync]。",
|
"실시간 동기화가 없습니다. [추가] 하거나 복사 · rsync 탭에서 [lsync 로 이동] 하세요.": "没有实时同步。请 [添加],或在 复制 · rsync 标签中 [移到 lsync]。",
|
||||||
"실시간 동기화를 지울까요?": "删除此实时同步吗?",
|
"실시간 동기화를 지울까요?": "删除此实时同步吗?",
|
||||||
"실시간 동기화의 [최종 정리]": "实时同步的 [最终整理]",
|
"실시간 동기화의 [최종 정리]": "实时同步的 [最终整理]",
|
||||||
|
"실제 실행: {0}": "实际执行:{0}",
|
||||||
"실패": "失败",
|
"실패": "失败",
|
||||||
"실패 · {0}": "失败 · {0}",
|
"실패 · {0}": "失败 · {0}",
|
||||||
"실패: {0}": "失败: {0}",
|
"실패: {0}": "失败: {0}",
|
||||||
|
|
|
||||||
|
|
@ -19,11 +19,20 @@ import 'copy_sync_settings.dart' show addLiveSyncPairDialog, editLiveSyncPairDia
|
||||||
import 'path_label.dart';
|
import 'path_label.dart';
|
||||||
import 'rsync_setup.dart';
|
import 'rsync_setup.dart';
|
||||||
import 'schedule_editor.dart';
|
import 'schedule_editor.dart';
|
||||||
import '../core/sync_preview.dart' show withoutSourceRemovingOptions;
|
import '../core/sync_preview.dart' show withoutSourceRemovingOptions, optionsRemoveSource;
|
||||||
import 'sync_preview_view.dart' show confirmDeletingRun;
|
import 'sync_preview_view.dart' show confirmDeletingRun;
|
||||||
import 'theme.dart';
|
import 'theme.dart';
|
||||||
|
|
||||||
/// 모니터링 (파일 탐색기 > 모니터링): 복사 · rsync 와 lsync (실시간 동기화) 를 따로 보여 준다.
|
/// 모니터링 (파일 탐색기 > 모니터링): 복사 · rsync 와 lsync (실시간 동기화) 를 따로 보여 준다.
|
||||||
|
/// 178 · 209: 실제로 실행할 방법 · 옵션 (원본 지우기 옵션은 빼고, 이동일 때만 그 방법의 원본 지우기를 붙인다)
|
||||||
|
String effectiveRunText(String method, String options, {required bool move}) {
|
||||||
|
final name = method == 'builtin' ? tr('현재 방식') : method;
|
||||||
|
if (method == 'builtin') return name;
|
||||||
|
final opts = withoutSourceRemovingOptions(options);
|
||||||
|
final extra = move ? (method == 'robocopy' ? ' /MOVE' : method == 'rsync' ? ' --remove-source-files' : '') : '';
|
||||||
|
return '$name $opts$extra'.trim();
|
||||||
|
}
|
||||||
|
|
||||||
class MonitorPage extends StatelessWidget {
|
class MonitorPage extends StatelessWidget {
|
||||||
final AppController c;
|
final AppController c;
|
||||||
final int initialTab;
|
final int initialTab;
|
||||||
|
|
@ -376,7 +385,7 @@ class _CopyCardState extends State<_CopyCard> {
|
||||||
content: Text(trf('칸에 보이는 옵션: {0}\n저장된 옵션: {1}\n\n고친 옵션을 저장하고 실행할까요?', [
|
content: Text(trf('칸에 보이는 옵션: {0}\n저장된 옵션: {1}\n\n고친 옵션을 저장하고 실행할까요?', [
|
||||||
'${_method == 'builtin' ? tr('현재 방식') : _method} ${_options.text.trim()}',
|
'${_method == 'builtin' ? tr('현재 방식') : _method} ${_options.text.trim()}',
|
||||||
// 178: 실제로 쓰는 옵션 (원본 지우기는 이동일 때만)
|
// 178: 실제로 쓰는 옵션 (원본 지우기는 이동일 때만)
|
||||||
'${t.method == 'builtin' ? tr('현재 방식') : t.method} ${withoutSourceRemovingOptions(t.options)}${t.move ? (t.method == 'robocopy' ? ' /MOVE' : t.method == 'rsync' ? ' --remove-source-files' : '') : ''}',
|
effectiveRunText(t.method, t.options, move: t.move),
|
||||||
])),
|
])),
|
||||||
actions: [
|
actions: [
|
||||||
TextButton(onPressed: () => Navigator.pop(ctx), child: Text(tr('취소'))),
|
TextButton(onPressed: () => Navigator.pop(ctx), child: Text(tr('취소'))),
|
||||||
|
|
@ -540,6 +549,19 @@ class _CopyCardState extends State<_CopyCard> {
|
||||||
onChanged: (_) => setState(() {}),
|
onChanged: (_) => setState(() {}),
|
||||||
),
|
),
|
||||||
),
|
),
|
||||||
|
// 209: 실제로 실행할 것 - 이동 / 복사를 분명히 (칸의 원본 지우기 옵션은 이동일 때만 쓰인다)
|
||||||
|
SizedBox(
|
||||||
|
width: 460,
|
||||||
|
child: Column(crossAxisAlignment: CrossAxisAlignment.start, mainAxisSize: MainAxisSize.min, children: [
|
||||||
|
Text(
|
||||||
|
'${t.move ? tr('이동') : tr('복사')} · ${trf('실제 실행: {0}', [effectiveRunText(_method, _options.text.trim(), move: t.move)])}',
|
||||||
|
style: TextStyle(fontSize: 12, color: t.move ? Colors.orangeAccent : JjColors.textDim),
|
||||||
|
),
|
||||||
|
if (!t.move && optionsRemoveSource(_options.text))
|
||||||
|
Text(tr('복사 작업이라 칸의 원본 지우기 옵션 (--remove-source-files · /MOV) 은 쓰지 않습니다. 옮기려면 Rsync 화면에서 [원본 파일 지우기] 를 켜세요'),
|
||||||
|
style: const TextStyle(fontSize: 12, color: Colors.orangeAccent)),
|
||||||
|
]),
|
||||||
|
),
|
||||||
SizedBox(
|
SizedBox(
|
||||||
width: 130,
|
width: 130,
|
||||||
child: TextField(
|
child: TextField(
|
||||||
|
|
|
||||||
|
|
@ -230,6 +230,27 @@ void main() {
|
||||||
await tester.pumpAndSettle();
|
await tester.pumpAndSettle();
|
||||||
});
|
});
|
||||||
|
|
||||||
|
testWidgets('209: 모니터링 카드는 실제로 실행할 것을 이동 / 복사와 함께 보인다 (복사 카드 칸의 원본 지우기 옵션은 쓰지 않는다고 알림)', (tester) async {
|
||||||
|
expect(effectiveRunText('rsync', '-avPog', move: true), 'rsync -avPog --remove-source-files');
|
||||||
|
expect(effectiveRunText('rsync', '-avPog --remove-source-files', move: false), 'rsync -avPog');
|
||||||
|
expect(effectiveRunText('robocopy', '/E /MOV', move: true), 'robocopy /E /MOVE');
|
||||||
|
final a = p.join(tmp.path, 'ca'), b = p.join(tmp.path, 'cb');
|
||||||
|
Directory(a).createSync(recursive: true);
|
||||||
|
Directory(b).createSync(recursive: true);
|
||||||
|
c.settings.copyTasks = [
|
||||||
|
CopyTask(id: '1', sources: [a], dest: b, contents: true, method: 'rsync', options: '-avPog --remove-source-files'),
|
||||||
|
CopyTask(id: '2', sources: [b], dest: a, contents: true, move: true, method: 'rsync', options: '-avPog'),
|
||||||
|
];
|
||||||
|
tester.view.physicalSize = const Size(1500, 1200);
|
||||||
|
tester.view.devicePixelRatio = 1;
|
||||||
|
addTearDown(tester.view.reset);
|
||||||
|
await tester.pumpWidget(MaterialApp(home: MonitorPage(c: c)));
|
||||||
|
await tester.pump();
|
||||||
|
expect(find.text('복사 · 실제 실행: rsync -avPog'), findsOneWidget);
|
||||||
|
expect(find.textContaining('복사 작업이라 칸의 원본 지우기 옵션'), findsOneWidget);
|
||||||
|
expect(find.text('이동 · 실제 실행: rsync -avPog --remove-source-files'), findsOneWidget);
|
||||||
|
});
|
||||||
|
|
||||||
testWidgets('112 · 114: 모니터링 작업 - 짧은 경로, 저장하지 않은 고침이 있으면 [실행] 할 때 묻는다 (저장하면 그 옵션 · 지우기면 미리 보기)',
|
testWidgets('112 · 114: 모니터링 작업 - 짧은 경로, 저장하지 않은 고침이 있으면 [실행] 할 때 묻는다 (저장하면 그 옵션 · 지우기면 미리 보기)',
|
||||||
(tester) async {
|
(tester) async {
|
||||||
final src = p.join(tmp.path, 'Download', 'movies'), dst = p.join(tmp.path, 'backup', 'movies');
|
final src = p.join(tmp.path, 'Download', 'movies'), dst = p.join(tmp.path, 'backup', 'movies');
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue