use super::design_paths::design_file_name_for;
use crate::{MainWindow, gui::editor::state::EditorState};
use indicatrix_formats::native::design::{
DESIGN_EXTENSION, DESIGN_EXTENSION_DOTTED, DESIGN_FILE_DESCRIPTION,
};
use std::path::{Path, PathBuf};
pub(super) enum PickKind {
SaveDesign { default_name: String },
SaveAsc { default_name: String },
SaveGcs { default_name: String },
SaveCuttingSheet { default_name: String },
SaveDiagram { default_name: String },
OpenDesign,
LocateAsc,
}
fn asc_filter() -> crate::gui::pickers::PickerFilter {
crate::gui::pickers::PickerFilter {
label: ".asc design".to_string(),
extensions: vec!["asc".to_string()],
}
}
pub(super) fn pick_file(
ui: &MainWindow,
kind: PickKind,
on_done: impl FnOnce(&MainWindow, Option<PathBuf>) + 'static,
) {
use crate::gui::pickers::{PickerFilter, PickerKind, PickerRequest, pick};
let request = match kind {
PickKind::SaveDesign { default_name } => PickerRequest {
kind: PickerKind::SaveFile,
title: None,
filters: vec![PickerFilter {
label: format!("{DESIGN_FILE_DESCRIPTION} (*{DESIGN_EXTENSION_DOTTED})"),
extensions: vec![DESIGN_EXTENSION.to_string()],
}],
default_file_name: Some(default_name),
starting_dir: super::SUGGESTED_SAVE_DIR
.with(|cell| cell.borrow().clone())
.or_else(default_export_dir),
},
PickKind::SaveAsc { default_name } => PickerRequest {
kind: PickerKind::SaveFile,
title: None,
filters: vec![asc_filter()],
default_file_name: Some(default_name),
starting_dir: default_export_dir(),
},
PickKind::SaveGcs { default_name } => PickerRequest {
kind: PickerKind::SaveFile,
title: None,
filters: vec![PickerFilter {
label: "Gem Cut Studio design (.gcs)".to_string(),
extensions: vec!["gcs".to_string()],
}],
default_file_name: Some(default_name),
starting_dir: default_export_dir(),
},
PickKind::SaveCuttingSheet { default_name } => PickerRequest {
kind: PickerKind::SaveFile,
title: None,
filters: vec![PickerFilter {
label: "Cutting sheet (HTML)".to_string(),
extensions: vec!["html".to_string()],
}],
default_file_name: Some(default_name),
starting_dir: None,
},
PickKind::SaveDiagram { default_name } => PickerRequest {
kind: PickerKind::SaveFile,
title: None,
filters: vec![PickerFilter {
label: "Diagram (PNG)".to_string(),
extensions: vec!["png".to_string()],
}],
default_file_name: Some(default_name),
starting_dir: None,
},
PickKind::OpenDesign => PickerRequest {
kind: PickerKind::OpenFile,
title: Some("Open Design".to_string()),
filters: vec![
PickerFilter {
label: format!("{DESIGN_FILE_DESCRIPTION} (*{DESIGN_EXTENSION_DOTTED})"),
extensions: vec![DESIGN_EXTENSION.to_string()],
},
PickerFilter {
label: "Older Indicatrix sidecar (*.indicatrix.toml, *.gemcut.toml)"
.to_string(),
extensions: vec![
indicatrix_cut_core::native::NATIVE_EXTENSION_SUFFIX.to_string(),
indicatrix_cut_core::native::LEGACY_NATIVE_EXTENSION_SUFFIX.to_string(),
],
},
PickerFilter {
label: "All TOML files".to_string(),
extensions: vec!["toml".to_string()],
},
asc_filter(),
PickerFilter {
label: "GemCAD / Gem Cut Studio design (.gem, .gcs)".to_string(),
extensions: vec!["gem".to_string(), "gcs".to_string()],
},
],
default_file_name: None,
starting_dir: None,
},
PickKind::LocateAsc => PickerRequest {
kind: PickerKind::OpenFile,
title: Some("Locate the paired .asc".to_string()),
filters: vec![asc_filter()],
default_file_name: None,
starting_dir: None,
},
};
pick(ui, request, on_done);
}
pub(super) fn suggested_file_name(st: &EditorState) -> String {
if let Some(name) = &st.asc_filename {
return name.clone();
}
match st.design.meta.headers.first() {
Some(header) if !header.trim().is_empty() => {
format!(
"{}.asc",
crate::gui::library::local::sanitize_filename(header)
)
}
_ => "edited_design.asc".to_string(),
}
}
pub(super) fn suggested_design_file_name(st: &EditorState) -> String {
design_file_name_for(&suggested_file_name(st))
}
fn default_export_dir() -> Option<PathBuf> {
let default_dir = Path::new("exports");
default_dir.is_dir().then(|| default_dir.to_path_buf())
}