use super::*;
pub const READ_ONLY: &str = "Archives are read-only";
impl AppState {
pub fn panel_archive(&self, is_left: bool) -> Option<&PathBuf> {
if is_left { self.archive_left.as_ref() } else { self.archive_right.as_ref() }
}
pub fn panel_real_dir(&self, is_left: bool) -> PathBuf {
match self.panel_archive(is_left) {
Some(archive) => archive.parent().map_or_else(|| archive.clone(), Path::to_path_buf),
None => self.panel_dir(is_left),
}
}
pub fn refuse_in_archive(&mut self, is_left: bool) -> bool {
let inside = self.panel_archive(is_left).is_some();
if inside {
self.display_error(READ_ONLY.to_string());
}
inside
}
pub fn open_archive_entry(&mut self, path: &Path, view: bool) {
let Some(archive) = self.panel_archive(self.is_left_active).cloned() else {
return;
};
let (Ok(inner), Some(name)) = (path.strip_prefix(&archive), path.file_name()) else {
return;
};
let dest = match crate::archive::scratch_dir() {
Ok(dir) => dir.join(name),
Err(e) => {
self.display_error(format!("Cannot make room to open it: {e}"));
return;
}
};
let after = if view { AfterJob::View(dest.clone()) } else { AfterJob::Open(dest.clone()) };
self.start_extract(archive, vec![(inner.to_path_buf(), dest)], Clashes::ReplaceAll, Some(after));
}
pub fn compare_anywhere(&mut self, left: PathBuf, right: PathBuf) {
let archives: Vec<PathBuf> = [self.archive_left.clone(), self.archive_right.clone()].into_iter().flatten().collect();
let mut out_of: Vec<(PathBuf, Vec<(PathBuf, PathBuf)>)> = Vec::new();
let mut files = Vec::new();
for path in [&left, &right] {
let Some(archive) = archives.iter().find(|archive| path.starts_with(archive)) else {
files.push(path.clone());
continue;
};
let (Ok(inner), Some(name)) = (path.strip_prefix(archive), path.file_name()) else {
return;
};
let dest = match crate::archive::scratch_dir() {
Ok(dir) => dir.join(name),
Err(e) => return self.display_error(format!("Cannot make room to compare: {e}")),
};
match out_of.iter_mut().find(|(known, _)| known == archive) {
Some((_, items)) => items.push((inner.to_path_buf(), dest.clone())),
None => out_of.push((archive.clone(), vec![(inner.to_path_buf(), dest.clone())])),
}
files.push(dest);
}
let (Some(right_file), Some(left_file)) = (files.pop(), files.pop()) else {
return;
};
if out_of.is_empty() {
return self.compare_files(left, right);
}
let (archive, items) = out_of.remove(0);
let after = AfterJob::Compare {
files: (left_file, right_file),
shown: (left, right),
then: out_of.pop(),
};
self.start_extract(archive, items, Clashes::ReplaceAll, Some(after));
}
pub(super) fn compare_shown(&mut self, files: (PathBuf, PathBuf), shown: (PathBuf, PathBuf)) {
self.compare_files(files.0, files.1);
if let Some(state) = self.diff_mut() {
(state.left_path, state.right_path) = shown;
}
}
}