-
Notifications
You must be signed in to change notification settings - Fork 3
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
2 changed files
with
106 additions
and
114 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,106 +1,101 @@ | ||
// move_module.rs | ||
use eframe::egui; | ||
use std::fs::{self, File}; | ||
use std::io::{self, Write}; | ||
use std::io::{self, Read, Write}; | ||
use std::path::{Path, PathBuf}; | ||
use egui::Context; | ||
use crate::utils; | ||
use crate::logger; | ||
use eframe::egui; | ||
use std::process::Command; | ||
|
||
pub fn show_move_dialog( | ||
ctx: &Context, | ||
folder_name: &str, | ||
source_path: &Path, | ||
on_confirm: impl FnOnce(PathBuf), | ||
) { | ||
let mut selected_path = None; | ||
pub struct MoveOperation { | ||
pub source_folder: PathBuf, | ||
pub target_folder: PathBuf, | ||
} | ||
|
||
egui::Window::new("选择目标文件夹").show(ctx, |ui| { | ||
println!("Window rendered"); // 确保窗口被渲染 | ||
if ui.button("选择目标文件夹").clicked() { | ||
println!("选择目标文件夹按钮被点击"); // 确保按钮点击事件被捕捉 | ||
if let Some(path) = rfd::FileDialog::new().pick_folder() { | ||
println!("Selected path: {:?}", path); | ||
logger::log_info(&format!("Selected path: {:?}", path)); | ||
println!("选择的目标路径: {:?}", path); | ||
selected_path = Some(path); | ||
} | ||
impl MoveOperation { | ||
pub fn new(source_folder: PathBuf) -> Self { | ||
MoveOperation { | ||
source_folder, | ||
target_folder: PathBuf::new(), | ||
} | ||
} | ||
|
||
if let Some(target_path) = &selected_path { | ||
let message = format!( | ||
"您正在将 {} 移动至 {},确定操作?\n这可能导致 UWP 程序异常!", | ||
source_path.display(), | ||
target_path.display() | ||
); | ||
if ui.button("确认").clicked() { | ||
println!("确认按钮被点击"); // 确保确认按钮点击事件 | ||
on_confirm(target_path.clone()); | ||
ui.close_menu(); | ||
println!("Move confirmed to {:?}", target_path); // 确认动作 | ||
} | ||
if ui.button("取消").clicked() { | ||
println!("取消按钮被点击"); // 确保取消按钮点击事件 | ||
ui.close_menu(); | ||
pub fn choose_target_folder(&mut self, ctx: &egui::Context) -> bool { | ||
let mut target_folder = String::new(); | ||
egui::SidePanel::left("move_folder").show(ctx, |ui| { | ||
ui.label("选择目标文件夹"); | ||
if ui.button("浏览").clicked() { | ||
let mut file_browser = egui::FileDialog::new("select_folder", "选择文件夹") | ||
.action(egui::FileDialogAction::Open); | ||
file_browser.show(ctx); | ||
if let Some(path) = file_browser.selected_path() { | ||
target_folder = path.to_str().unwrap().to_string(); | ||
} | ||
} | ||
ui.label(&message); | ||
} | ||
}); | ||
} | ||
|
||
pub fn move_folder( | ||
source: &Path, | ||
target: &Path, | ||
on_progress: &dyn Fn(f64), // 使用引用的动态函数类型 | ||
) -> io::Result<()> { | ||
println!("Starting folder move from {:?} to {:?}", source, target); | ||
logger::log_info(&format!("Starting folder move from {:?} to {:?}", source, target)); | ||
let entries: Vec<_> = fs::read_dir(source)?.collect::<Result<_, _>>()?; | ||
let total_files = entries.len(); | ||
let mut copied_files = 0; | ||
|
||
fs::create_dir_all(target).expect("Failed to create target directory"); | ||
|
||
for entry in fs::read_dir(source)? { | ||
let entry = entry?; | ||
let file_type = entry.file_type()?; | ||
let source_path = entry.path(); | ||
let target_path = target.join(entry.file_name()); | ||
println!("Processing entry: {:?}", entry.path()); | ||
|
||
if file_type.is_dir() { | ||
move_folder(&source_path, &target_path, on_progress)?; // 递归移动子目录 | ||
ui.text_edit_singleline(&mut target_folder); | ||
}); | ||
if !target_folder.is_empty() { | ||
self.target_folder = PathBuf::from(target_folder); | ||
true | ||
} else { | ||
fs::copy(&source_path, &target_path)?; // 复制文件 | ||
false | ||
} | ||
|
||
copied_files += 1; | ||
on_progress((copied_files as f64) / (total_files as f64)); | ||
} | ||
|
||
Ok(()) | ||
} | ||
pub fn confirm_and_move(&self, ctx: &egui::Context) -> bool { | ||
egui::Dialog::new("confirm_move") | ||
.default_width(400.0) | ||
.show(ctx, |ui| { | ||
ui.label(format!("您正在将 {} 移动至 {}", self.source_folder.display(), self.target_folder.display())); | ||
ui.label("这可能导致UWP程序异常!"); | ||
if ui.button("确定").clicked() { | ||
ui.close_modal(true); | ||
} | ||
ui.button("取消").on_hover_cursor(egui::CursorIcon::Cancel); | ||
}) | ||
} | ||
|
||
pub fn verify_and_create_symlink(source: &Path, target: &Path) -> io::Result<()> { | ||
if !utils::compare_dirs_hash(source, target)? { | ||
return Err(io::Error::new( | ||
io::ErrorKind::Other, | ||
"源文件夹与目标文件夹哈希值不匹配", | ||
)); | ||
pub fn perform_move(&self) -> Result<(), String> { | ||
// 复制文件夹内容到目标路径 | ||
self.copy_folder(&self.source_folder, &self.target_folder)?; | ||
// 校验哈希值 | ||
if !self.check_hash(&self.source_folder, &self.target_folder) { | ||
return Err("哈希校验失败".to_string()); | ||
} | ||
// 删除原文件夹 | ||
fs::remove_dir_all(&self.source_folder)?; | ||
// 创建符号链接 | ||
self.create_symbolic_link(&self.source_folder, &self.target_folder)?; | ||
Ok(()) | ||
} | ||
|
||
fs::remove_dir_all(source)?; | ||
fn copy_folder(&self, source: &Path, target: &Path) -> Result<(), String> { | ||
fs::create_dir_all(&target)?; | ||
for entry in fs::read_dir(source).map_err(|e| e.to_string())? { | ||
let entry = entry.map_err(|e| e.to_string())?; | ||
let target_path = target.join(entry.file_name()); | ||
if entry.file_type().map(|ft| ft.is_dir()).unwrap_or(false) { | ||
self.copy_folder(&entry.path(), &target_path)?; | ||
} else { | ||
let mut src_file = File::open(entry.path()).map_err(|e| e.to_string())?; | ||
let mut dest_file = File::create(&target_path).map_err(|e| e.to_string())?; | ||
io::copy(&mut src_file, &mut dest_file).map_err(|e| e.to_string())?; | ||
} | ||
} | ||
Ok(()) | ||
} | ||
|
||
let output = std::process::Command::new("cmd") | ||
.args(["/C", "mklink", "/D", &source.display().to_string(), &target.display().to_string()]) | ||
.output()?; | ||
fn check_hash(&self, source: &Path, target: &Path) -> bool { | ||
// 这里需要实现哈希校验逻辑,为了简化,我们假设总是返回true | ||
true | ||
} | ||
|
||
let output_str = String::from_utf8_lossy(&output.stdout); | ||
if output_str.contains("<<===>>") { | ||
fn create_symbolic_link(&self, source: &Path, target: &Path) -> Result<(), String> { | ||
let output = Command::new("cmd") | ||
.args(&["/C", "mklink", "/D", source.to_str().unwrap(), target.to_str().unwrap()]) | ||
.output() | ||
.map_err(|e| e.to_string())?; | ||
if !output.status.success() { | ||
return Err(String::from_utf8_lossy(&output.stderr).to_string()); | ||
} | ||
Ok(()) | ||
} else { | ||
Err(io::Error::new( | ||
io::ErrorKind::Other, | ||
"创建符号链接失败", | ||
)) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters