mirror of
https://github.com/storytold/designcraft.git
synced 2026-11-14 14:22:39 +00:00
Route UI format dispatch through shared registry
This commit is contained in:
8 files changed
+26
-23
No files matched your search
Generated
+8
-7
@@ -1144,7 +1144,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-eps"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d#6ba1ca33ca21c33de55ef155141db08ca6048e8d"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=b4ada28f1#b4ada28f19067d4693e902e0e5f32eb292241e3a"
|
||||
|
||||
[[package]]
|
||||
name = "craft-eps"
|
||||
@@ -1164,10 +1164,10 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-file-formats"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d#6ba1ca33ca21c33de55ef155141db08ca6048e8d"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=b4ada28f1#b4ada28f19067d4693e902e0e5f32eb292241e3a"
|
||||
dependencies = [
|
||||
"craft-eps 0.1.0 (git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d)",
|
||||
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d)",
|
||||
"craft-eps 0.1.0 (git+https://github.com/storytold/craft-libs?rev=b4ada28f1)",
|
||||
"craft-svg 0.1.0 (git+https://github.com/storytold/craft-libs?rev=b4ada28f1)",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -1362,9 +1362,9 @@ source = "git+https://github.com/storytold/craft-libs?rev=ba24fe2435adb3c81ad605
|
||||
[[package]]
|
||||
name = "craft-svg"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d#6ba1ca33ca21c33de55ef155141db08ca6048e8d"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=b4ada28f1#b4ada28f19067d4693e902e0e5f32eb292241e3a"
|
||||
dependencies = [
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d)",
|
||||
"craft-xml 0.1.0 (git+https://github.com/storytold/craft-libs?rev=b4ada28f1)",
|
||||
"flate2",
|
||||
"kurbo",
|
||||
"roxmltree 0.21.2",
|
||||
@@ -1479,7 +1479,7 @@ dependencies = [
|
||||
[[package]]
|
||||
name = "craft-xml"
|
||||
version = "0.1.0"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=6ba1ca33ca21c33de55ef155141db08ca6048e8d#6ba1ca33ca21c33de55ef155141db08ca6048e8d"
|
||||
source = "git+https://github.com/storytold/craft-libs?rev=b4ada28f1#b4ada28f19067d4693e902e0e5f32eb292241e3a"
|
||||
dependencies = [
|
||||
"quick-xml 0.41.0",
|
||||
"thiserror 2.0.21",
|
||||
@@ -1967,6 +1967,7 @@ name = "designcraft-ui-egui"
|
||||
version = "0.20.1"
|
||||
dependencies = [
|
||||
"craft-dialogs",
|
||||
"craft-file-formats",
|
||||
"craft-keymap",
|
||||
"craft-prepress",
|
||||
"craft-ui",
|
||||
|
||||
+1
-1
@@ -26,7 +26,7 @@ craft-docx = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe243
|
||||
craft-wordmodel = { git = "https://github.com/storytold/craft-libs", rev = "ba24fe2435adb3c81ad6057faf36365fbba736cf", version = "=0.1.0" }
|
||||
craft-image-codecs = { git = "https://github.com/storytold/craft-libs", rev = "a47b78256c6acf3d7fdc4bc7cfbc25c373eac522", version = "=0.1.0" }
|
||||
craft-psd = { git = "https://github.com/storytold/craft-libs", rev = "a47b78256c6acf3d7fdc4bc7cfbc25c373eac522", version = "=0.1.0" }
|
||||
craft-file-formats = { git = "https://github.com/storytold/craft-libs", rev = "6ba1ca33ca21c33de55ef155141db08ca6048e8d", version = "=0.1.0" }
|
||||
craft-file-formats = { git = "https://github.com/storytold/craft-libs", rev = "b4ada28f1", version = "=0.1.0" }
|
||||
# Shared keyboard bindings: chords, overrides, conflicts, egui dispatch, the Keyboard Shortcuts dialog.
|
||||
craft-keymap = { git = "https://github.com/storytold/craft-libs", rev = "92d392cff132eaf53e13afff77f38b5c11b73aa0", version = "=0.1.0", features = ["egui", "ui"] }
|
||||
# Separations, ink coverage and the ink manager; same revision as craft-pdf and the krilla patch.
|
||||
|
||||
@@ -136,7 +136,7 @@ pub(super) fn export_text(s: &mut Session, p: &Value) -> Result<Value> {
|
||||
Some(f @ ("rtf" | "tagged")) => f,
|
||||
Some("txt") | Some("text") => "txt",
|
||||
Some(f) => return Err(bad(ID, format!("unknown format `{f}` (txt, rtf, tagged)"))),
|
||||
None if path.is_some_and(|x| x.to_ascii_lowercase().ends_with(".rtf")) => "rtf",
|
||||
None if path.is_some_and(|x| craft_file_formats::detect(x, &[]) == Some(craft_file_formats::Format::Rtf)) => "rtf",
|
||||
None => "txt",
|
||||
};
|
||||
let text = match format {
|
||||
|
||||
@@ -21,7 +21,7 @@ fn save_bytes(d: &Document, preview: Option<&[u8]>) -> Result<Vec<u8>> {
|
||||
pub fn with_document_extension(path: &str) -> String {
|
||||
let p = std::path::Path::new(path);
|
||||
let ext = p.extension().and_then(std::ffi::OsStr::to_str);
|
||||
if p.file_name().is_none() || ext.is_some_and(|e| e.eq_ignore_ascii_case(designcraft_format::EXTENSION)) {
|
||||
if p.file_name().is_none() || ext.is_some_and(|e| craft_file_formats::from_extension(e) == Some(craft_file_formats::Format::DesignCraft)) {
|
||||
return path.to_string();
|
||||
}
|
||||
format!("{path}.{}", designcraft_format::EXTENSION)
|
||||
@@ -32,7 +32,7 @@ pub fn with_document_extension(path: &str) -> String {
|
||||
/// that kept it would name the file `Brochure.designcraft.designcraft`. A bare `.designcraft` stays.
|
||||
pub(super) fn without_native_extension(name: &str) -> &str {
|
||||
match name.rsplit_once('.') {
|
||||
Some((stem, ext)) if !stem.is_empty() && ext.eq_ignore_ascii_case(designcraft_format::EXTENSION) => stem,
|
||||
Some((stem, ext)) if !stem.is_empty() && craft_file_formats::from_extension(ext) == Some(craft_file_formats::Format::DesignCraft) => stem,
|
||||
_ => name,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,6 +13,7 @@ workspace = true
|
||||
craft-ui = { workspace = true, features = ["native-windows"] }
|
||||
craft-window = { workspace = true }
|
||||
craft-keymap = { workspace = true }
|
||||
craft-file-formats = { workspace = true }
|
||||
designcraft-geom = { workspace = true }
|
||||
designcraft-color = { workspace = true }
|
||||
designcraft-doc = { workspace = true }
|
||||
|
||||
@@ -24,7 +24,7 @@ impl DesignApp {
|
||||
/// Open (`open`) or place (`place`) the file at `path`, chosen in a dialog or passed by a script.
|
||||
pub(crate) fn open_picked(&mut self, purpose: &str, path: String) -> Result<Value, String> {
|
||||
// Image Import Options: a multi-page PDF asks which page.
|
||||
if purpose == "place" && path.to_ascii_lowercase().ends_with(".pdf") {
|
||||
if purpose == "place" && craft_file_formats::detect(&path, &[]) == Some(craft_file_formats::Format::Pdf) {
|
||||
let target = self.session.active().map(|d| d.uid);
|
||||
let pages = self.services.read.as_mut().and_then(|r| r(&path).ok()).and_then(|b| designcraft_render::pdf_page_count(&b)).unwrap_or(1);
|
||||
if pages > 1 {
|
||||
@@ -126,7 +126,7 @@ impl DesignApp {
|
||||
}
|
||||
|
||||
fn import_file(&mut self, file: ImportedFile) -> Result<Value, String> {
|
||||
let lower = file.name.to_ascii_lowercase();
|
||||
let format = craft_file_formats::detect(&file.name, &file.bytes);
|
||||
if let Some(kind) = file.request.purpose.strip_prefix("styles") {
|
||||
self.activate_import_target(&file.request)?;
|
||||
let mut params = json!({"name": file.name, "base64": designcraft_engine::cmd::base64_encode(&file.bytes)});
|
||||
@@ -140,11 +140,11 @@ impl DesignApp {
|
||||
let layout = opens_as_document(&file.name)
|
||||
|| (std::path::Path::new(&file.name).extension().is_none() && designcraft_engine::cmd::is_document(&file.bytes));
|
||||
let place =
|
||||
file.request.purpose == "place" || (matches!(file.request.purpose.as_str(), "drop" | "open") && !layout && !lower.ends_with(".ase"));
|
||||
if place || lower.ends_with(".ase") || file.request.purpose == "swatches" {
|
||||
file.request.purpose == "place" || (matches!(file.request.purpose.as_str(), "drop" | "open") && !layout && format != Some(craft_file_formats::Format::Ase));
|
||||
if place || format == Some(craft_file_formats::Format::Ase) || file.request.purpose == "swatches" {
|
||||
self.activate_import_target(&file.request)?;
|
||||
}
|
||||
if place && lower.ends_with(".pdf") {
|
||||
if place && craft_file_formats::detect(&file.name, &file.bytes) == Some(craft_file_formats::Format::Pdf) {
|
||||
let pages = designcraft_render::pdf_page_count(&file.bytes).unwrap_or(1);
|
||||
if pages > 1 {
|
||||
self.ui.dialog =
|
||||
@@ -154,7 +154,7 @@ impl DesignApp {
|
||||
}
|
||||
}
|
||||
let b64 = designcraft_engine::cmd::base64_encode(&file.bytes);
|
||||
if lower.ends_with(".ase") || file.request.purpose == "swatches" {
|
||||
if format == Some(craft_file_formats::Format::Ase) || file.request.purpose == "swatches" {
|
||||
self.run("swatch.load", json!({"base64": b64}))
|
||||
} else if file.request.purpose == "place" {
|
||||
self.place_file(json!({"name": file.name, "base64": b64}))
|
||||
@@ -198,7 +198,7 @@ impl DesignApp {
|
||||
/// the pointer when there is none, and clears the flag, so the files after it land at the
|
||||
/// pointer instead of replacing that graphic.
|
||||
pub(crate) fn place_dropped(&mut self, path: &str, pointer: Option<egui::Pos2>, frame_free: &mut bool) -> Result<Value, String> {
|
||||
if path.to_ascii_lowercase().ends_with(".ase") {
|
||||
if craft_file_formats::detect(path, &[]) == Some(craft_file_formats::Format::Ase) {
|
||||
return self.run("swatch.load", json!({"path": path}));
|
||||
}
|
||||
let document = opens_as_document(path)
|
||||
@@ -318,8 +318,10 @@ impl DesignApp {
|
||||
/// Files that open as documents (when dropped or picked) rather than being placed: DesignCraft,
|
||||
/// IDML, and InDesign documents and templates (converted to IDML on open).
|
||||
pub fn opens_as_document(name: &str) -> bool {
|
||||
let n = name.to_ascii_lowercase();
|
||||
[".designcraft", ".idml", ".indd", ".indt"].iter().any(|ext| n.ends_with(ext))
|
||||
matches!(
|
||||
craft_file_formats::detect(name, &[]),
|
||||
Some(craft_file_formats::Format::DesignCraft | craft_file_formats::Format::Idml | craft_file_formats::Format::Indd)
|
||||
)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
||||
@@ -92,7 +92,7 @@ pub(super) fn export_bytes(app: &mut DesignApp, p: &Value, ext: &str, cmd: &str)
|
||||
_ => json!({}),
|
||||
};
|
||||
if cmd == "file.exportText" {
|
||||
let txt = path.to_ascii_lowercase().ends_with(".txt");
|
||||
let txt = craft_file_formats::detect(&path, &[]) == Some(craft_file_formats::Format::PlainText);
|
||||
params["format"] = json!(if txt { "txt" } else { "rtf" });
|
||||
}
|
||||
let r = app.run(cmd, params)?;
|
||||
|
||||
@@ -142,8 +142,7 @@ fn run_ui_part1(app: &mut DesignApp, id: &str, p: &Value) -> Option<Result<Value
|
||||
"app.placeWithOptions" => {
|
||||
// Word/RTF Import Options: style mapping and conflicts before the text lands.
|
||||
let Some(path) = p.get("path").and_then(Value::as_str) else { return Some(rerun_with_path(app, "place", id, p, "path")) };
|
||||
let l = path.to_lowercase();
|
||||
if !(l.ends_with(".docx") || l.ends_with(".rtf")) {
|
||||
if !matches!(craft_file_formats::detect(path, &[]), Some(craft_file_formats::Format::Docx | craft_file_formats::Format::Rtf)) {
|
||||
return Some(app.place_file(json!({"path": path})));
|
||||
}
|
||||
let info = match app.run("place.styles", json!({"path": path})) {
|
||||
|
||||
Reference in new issue
Block a user