Merge pull request #676 from vbasky/fix/592-import-replace
Add file.import replace mode for empty-project round-trips
This commit is contained in:
commit
b07df164fa
|
|
@ -945,7 +945,7 @@ fn build() -> Vec<CommandSpec> {
|
|||
Ok(json!({"items": ids.iter().map(|i| i.0).collect::<Vec<_>>()}))
|
||||
}
|
||||
),
|
||||
cmd!("file.import", "Import…", ["File"], Some("Cmd+I"), r#"{"paths":[str],"bin":binId?,"imageSequence":bool?}"#, always, |s, p| {
|
||||
cmd!("file.import", "Import…", ["File"], Some("Cmd+I"), r#"{"paths":[str],"bin":binId?,"imageSequence":bool?,"replace":bool?}"#, always, |s, p| {
|
||||
let bin = u64_p(p, "bin").map(filmcraft_project::BinId);
|
||||
let paths: Vec<String> = match p.get("paths").and_then(Value::as_array) {
|
||||
Some(a) => a.iter().filter_map(|v| v.as_str().map(str::to_string)).collect(),
|
||||
|
|
@ -954,6 +954,10 @@ fn build() -> Vec<CommandSpec> {
|
|||
if paths.is_empty() {
|
||||
return Err(bad("file.import", "need `paths`"));
|
||||
}
|
||||
if bool_p(p, "replace").unwrap_or(false) {
|
||||
let name = s.project.name.clone();
|
||||
s.execute("file.newProject", json!({ "name": name }))?;
|
||||
}
|
||||
let mut ids = Vec::new();
|
||||
let mut errors = Vec::new();
|
||||
let mut sequences = Vec::new();
|
||||
|
|
|
|||
|
|
@ -11,6 +11,24 @@ use serde_json::{Value, json};
|
|||
use crate::Session;
|
||||
use crate::media_test_util::tmp_dir;
|
||||
|
||||
#[test]
|
||||
fn import_replace_starts_from_an_empty_project() {
|
||||
let dir = tmp_dir("import-replace");
|
||||
let wav = dir.join("tone.wav");
|
||||
std::fs::write(&wav, filmcraft_media::wav::write_wav16(&[0.1; 4800], 2, 48_000)).unwrap();
|
||||
let mut s = demo();
|
||||
let demo_items = s.project.items.len();
|
||||
assert!(demo_items > 1);
|
||||
assert!(!s.state.open_sequences.is_empty());
|
||||
s.execute("file.import", json!({"paths": [wav.to_string_lossy()], "replace": true})).unwrap();
|
||||
assert!(s.state.open_sequences.is_empty());
|
||||
assert_eq!(s.project.items.len(), 1);
|
||||
assert!(s.project.items.values().any(|it| it.name == "tone.wav"));
|
||||
let mut merge = demo();
|
||||
merge.execute("file.import", json!({"paths": [wav.to_string_lossy()]})).unwrap();
|
||||
assert!(merge.project.items.len() > demo_items);
|
||||
}
|
||||
|
||||
fn demo() -> Session {
|
||||
let mut s = Session::default();
|
||||
s.execute("file.openDemoProject", json!({})).unwrap();
|
||||
|
|
|
|||
|
|
@ -696,7 +696,9 @@ Video encoders implement `export::VideoEncoder`. Codec crates plug in with `regi
|
|||
|
||||
Timelines can be exchanged as EDL, FCP7 XML, FCPXML, OTIO, AAF or OMF. `file.import` detects these
|
||||
formats and merges the result into the project as one undoable step (AAF / OMF embedded audio is
|
||||
written next to the document first), and `file.exportInterchange`, `file.exportEdl`,
|
||||
written next to the document first). `file.import {replace: true}` starts from an empty project
|
||||
with the same name (`file.newProject`) so a headless import→export round-trip contains only the
|
||||
imported timeline. `file.exportInterchange`, `file.exportEdl`,
|
||||
`file.exportFcpxml`, `file.exportOtio`, `file.exportAaf` and `file.exportOmf` write them.
|
||||
`file.exportInterchange {format}` takes `edl`, `xml` (the default), `fcpxml`, `otio`, `aaf` or `omf`;
|
||||
any other value is a parameter error and nothing is written. For AAF and
|
||||
|
|
|
|||
Loading…
Reference in New Issue