Columns, Symbol and Field dialogs (#335)
* Keep charts, SmartArt and OLE objects when saving DOCX (#319) Charts and SmartArt diagrams were drawn since #292 but the writer skipped them, and OLE objects kept only their picture, so opening and saving a document silently dropped them. The reader now keeps each object's own markup (the a:graphic of a chart or diagram, the whole w:object of an OLE object) on the model object, and every part it reaches through relationships (chart part, embedded workbook, colour and style parts; diagram data, layout, quick style, colours and drawing; OLE embedding and picture) as opaque bytes in Document::passthrough, with their content types and relationships in a manifest, as the VBA project already is. The writer emits the object with fresh relationship ids pointing at the re-added parts, keeping each part's own relationship ids and content types. A chart or diagram gets its frame from the object's current size and position; an OLE object gets its new size written into its VML shape. A part whose name the writer uses itself is renamed, and an object pasted more than once gets its own copies of every part (sharing past a size budget). Part counts, relationship counts, markup size and copy bytes are all capped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Columns, Symbol and Field dialogs (#321) Layout > Columns > More Columns... opens a Columns dialog: One/Two/Three/ Left/Right presets, number of columns, per-column width and spacing, Equal column width, Line between, a page preview and Apply to (whole document, this section, this point forward). OK is one layout.columns call, which now takes unequal widths and an apply target (forward adds a continuous section break first). Insert > Symbol > More Symbols... opens a Symbol dialog: font picker, Unicode subset list that jumps through a grid of only the characters the font has (drawn in that font), recently used symbols, a hex character code, and a Special Characters tab. insert.symbol takes a font for the symbol alone; typing after it goes on in the text's font. The ribbon's Symbol gallery shows recently used symbols first. Insert > Quick Parts > Field... opens a Field dialog: categories and the fields WordCraft computes, date pictures, number formats, bookmark / sequence / merge field names, preserve formatting, a live field code and a Field Codes view to type the code directly; OK runs insert.field. Also: date pictures read correctly when switches follow them, and am/pm and seconds work in date and time pictures. Strings in every catalog; gaps #7 and ui-parity updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * #321: Field dialog descriptions in our own words (clean room) Reword the one-line field descriptions and the empty-selection prompt so none reads like Word's; translations keep their meaning under the new keys. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Keep charts, SmartArt and OLE objects when saving DOCX (#319) Charts and SmartArt diagrams were drawn since #292 but the writer skipped them, and OLE objects kept only their picture, so opening and saving a document silently dropped them. The reader now keeps each object's own markup (the a:graphic of a chart or diagram, the whole w:object of an OLE object) on the model object, and every part it reaches through relationships (chart part, embedded workbook, colour and style parts; diagram data, layout, quick style, colours and drawing; OLE embedding and picture) as opaque bytes in Document::passthrough, with their content types and relationships in a manifest, as the VBA project already is. The writer emits the object with fresh relationship ids pointing at the re-added parts, keeping each part's own relationship ids and content types. A chart or diagram gets its frame from the object's current size and position; an OLE object gets its new size written into its VML shape. A part whose name the writer uses itself is renamed, and an object pasted more than once gets its own copies of every part (sharing past a size budget). Part counts, relationship counts, markup size and copy bytes are all capped. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Columns, Symbol and Field dialogs (#321) Layout > Columns > More Columns... opens a Columns dialog: One/Two/Three/ Left/Right presets, number of columns, per-column width and spacing, Equal column width, Line between, a page preview and Apply to (whole document, this section, this point forward). OK is one layout.columns call, which now takes unequal widths and an apply target (forward adds a continuous section break first). Insert > Symbol > More Symbols... opens a Symbol dialog: font picker, Unicode subset list that jumps through a grid of only the characters the font has (drawn in that font), recently used symbols, a hex character code, and a Special Characters tab. insert.symbol takes a font for the symbol alone; typing after it goes on in the text's font. The ribbon's Symbol gallery shows recently used symbols first. Insert > Quick Parts > Field... opens a Field dialog: categories and the fields WordCraft computes, date pictures, number formats, bookmark / sequence / merge field names, preserve formatting, a live field code and a Field Codes view to type the code directly; OK runs insert.field. Also: date pictures read correctly when switches follow them, and am/pm and seconds work in date and time pictures. Strings in every catalog; gaps #7 and ui-parity updated. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> * Merge fix: #340's rotation round-trip test builds an Image with #333's ole field Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com> Co-authored-by: Brandon Thomas <echelon@gmail.com>
This commit is contained in:
parent
a7c809e63b
commit
8204c5cb49
|
|
@ -131,6 +131,7 @@ Ranked, to beta (detail and remaining milestones in [docs/roadmap.md](docs/roadm
|
|||
| Date | What landed |
|
||||
|---|---|
|
||||
| 2026-10-10 | DOCX charts, SmartArt and OLE objects survive open and save with their parts (#319) |
|
||||
| 2026-10-10 | Full re-measure against Word for Mac 16.113.4 and progress docs to the craftrules standard (this page, `docs/target-app-parity.md`, `gaps.md`, `roadmap.md`, `architecture.md`, format/layout/UI/hardware/localization parity; `docs/parity.md` → `docs/parity-checklist.md`). Landed the same day (~80 PRs): equations with OMML and an Equation tab (#191); Word 97-2003 `.doc` import (#145); right-to-left and Persian text (#207); Zotero integration (#189); Read Aloud player (#190); text boxes and floating objects editable (#46) and placed like Word (#136); floating tables (#137); track-changes fixes (#125, #244); typing parity with Word (#204); hidden text (#173); save prompts and AutoSave rules (#151); LaTeX import/export (#11); keytips and mini-toolbar (#43); Spanish, Ukrainian and Brazilian Portuguese interfaces; system theme (#249); Linux file dialogs no longer freeze (#246); Chinese UI font on Windows (#248); every installed font weight (#239); cell text direction (#245); Paste Special (#235), Advanced Find (#234), Column Selection (#237), Style Inspector (#236), custom table styles (#256), View gridlines (#243), zoom buttons (#232), inertial touchpad scrolling (#252), File Info fields kept (#268), ¶ in mixed-direction paragraphs (#278), Serbian interface (#250), table Height/Width boxes, AutoFit Contents and Table Properties (#44), AutoSave switch greyed out with the reason where it can't save (.md/.txt/.html, unsaved, browser) (#196, #176), OpenGL fallback on Windows PCs without a DirectX 12 driver (#316), Columns, Symbol and Field dialogs (#321); v0.4.0 released |
|
||||
| 2026-10-10 | Full re-measure against Word for Mac 16.113.4 and progress docs to the craftrules standard (this page, `docs/target-app-parity.md`, `gaps.md`, `roadmap.md`, `architecture.md`, format/layout/UI/hardware/localization parity; `docs/parity.md` → `docs/parity-checklist.md`). Landed the same day (~80 PRs): equations with OMML and an Equation tab (#191); Word 97-2003 `.doc` import (#145); right-to-left and Persian text (#207); Zotero integration (#189); Read Aloud player (#190); text boxes and floating objects editable (#46) and placed like Word (#136); floating tables (#137); track-changes fixes (#125, #244); typing parity with Word (#204); hidden text (#173); save prompts and AutoSave rules (#151); LaTeX import/export (#11); keytips and mini-toolbar (#43); Spanish, Ukrainian and Brazilian Portuguese interfaces; system theme (#249); Linux file dialogs no longer freeze (#246); Chinese UI font on Windows (#248); every installed font weight (#239); cell text direction (#245); Paste Special (#235), Advanced Find (#234), Column Selection (#237), Style Inspector (#236), custom table styles (#256), View gridlines (#243), zoom buttons (#232), inertial touchpad scrolling (#252), File Info fields kept (#268), ¶ in mixed-direction paragraphs (#278), Serbian interface (#250), table Height/Width boxes, AutoFit Contents and Table Properties (#44), AutoSave switch greyed out with the reason where it can't save (.md/.txt/.html, unsaved, browser) (#196, #176), OpenGL fallback on Windows PCs without a DirectX 12 driver (#316); v0.4.0 released |
|
||||
| 2026-10-10 | Full re-measure against Word for Mac 16.113.4 and progress docs to the craftrules standard (this page, `docs/target-app-parity.md`, `gaps.md`, `roadmap.md`, `architecture.md`, format/layout/UI/hardware/localization parity; `docs/parity.md` → `docs/parity-checklist.md`). Landed the same day (~80 PRs): equations with OMML and an Equation tab (#191); Word 97-2003 `.doc` import (#145); right-to-left and Persian text (#207); Zotero integration (#189); Read Aloud player (#190); text boxes and floating objects editable (#46) and placed like Word (#136); floating tables (#137); track-changes fixes (#125, #244); typing parity with Word (#204); hidden text (#173); save prompts and AutoSave rules (#151); LaTeX import/export (#11); keytips and mini-toolbar (#43); Spanish, Ukrainian and Brazilian Portuguese interfaces; system theme (#249); Linux file dialogs no longer freeze (#246); Chinese UI font on Windows (#248); every installed font weight (#239); cell text direction (#245); Paste Special (#235), Advanced Find (#234), Column Selection (#237), Style Inspector (#236), custom table styles (#256), View gridlines (#243), zoom buttons (#232), inertial touchpad scrolling (#252), File Info fields kept (#268), ¶ in mixed-direction paragraphs (#278), Serbian interface (#250), table Height/Width boxes, AutoFit Contents and Table Properties (#44), AutoSave switch greyed out with the reason where it can't save (.md/.txt/.html, unsaved, browser) (#196, #176), OpenGL fallback on Windows PCs without a DirectX 12 driver (#316); free rotation and flips for pictures, shapes and text boxes with a rotation handle (#332); v0.4.0 released |
|
||||
| 2026-10-09 | Interface languages follow the system or Options (#12; zh-hans, zh-hant, ja); TOC page numbers as an updatable field (#52); rotating log file (#17); window geometry remembered (#38) |
|
||||
|
|
|
|||
|
|
@ -69,12 +69,7 @@ pub fn specs() -> Vec<CommandSpec> {
|
|||
sel_result(s)
|
||||
}),
|
||||
CommandSpec::new("insert.dateTime", "Date & Time", "Insert › Text", date_time).params(r#"{"format"?: "M/d/yyyy", "update"?: bool}"#),
|
||||
CommandSpec::new("insert.symbol", "Symbol", "Insert › Symbols", |s, v| {
|
||||
let c = p::req_str(v, "char")?;
|
||||
type_text(s, c)?;
|
||||
sel_result(s)
|
||||
})
|
||||
.params(r#"{"char": string}"#),
|
||||
CommandSpec::new("insert.symbol", "Symbol", "Insert › Symbols", symbol).params(r#"{"char": string, "font"?: family (the symbol's own font)}"#),
|
||||
CommandSpec::new("insert.field", "Field", "Insert › Text › Quick Parts", field).key("Mod+F9").params(r#"{"instr": string, "result"?: string}"#),
|
||||
CommandSpec::new("insert.dropCap", "Drop Cap", "Insert › Text", |s, v| {
|
||||
let lines = p::u64(v, "lines").unwrap_or(3).min(10) as u8;
|
||||
|
|
@ -463,6 +458,7 @@ pub fn format_date(fmt: &str) -> String {
|
|||
let d: u32 = iso.get(8..10).and_then(|x| x.parse().ok()).unwrap_or(1);
|
||||
let hh: u32 = iso.get(11..13).and_then(|x| x.parse().ok()).unwrap_or(0);
|
||||
let mm: u32 = iso.get(14..16).and_then(|x| x.parse().ok()).unwrap_or(0);
|
||||
let ss: u32 = iso.get(17..19).and_then(|x| x.parse().ok()).unwrap_or(0);
|
||||
const MONTHS: [&str; 12] =
|
||||
["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
|
||||
const DAYS: [&str; 7] = ["Thursday", "Friday", "Saturday", "Sunday", "Monday", "Tuesday", "Wednesday"];
|
||||
|
|
@ -475,6 +471,12 @@ pub fn format_date(fmt: &str) -> String {
|
|||
let mut i = 0;
|
||||
while i < chars.len() {
|
||||
let c = chars.get(i).copied().unwrap_or(' ');
|
||||
// `am/pm` (any case) is one token: AM or PM.
|
||||
if chars.get(i..i + 5).is_some_and(|w| w.iter().collect::<String>().eq_ignore_ascii_case("am/pm")) {
|
||||
out.push_str(if hh < 12 { "AM" } else { "PM" });
|
||||
i += 5;
|
||||
continue;
|
||||
}
|
||||
let mut n = 1;
|
||||
while chars.get(i + n) == Some(&c) {
|
||||
n += 1;
|
||||
|
|
@ -495,6 +497,8 @@ pub fn format_date(fmt: &str) -> String {
|
|||
('h', _) => out.push_str(&(if hh.is_multiple_of(12) { 12 } else { hh % 12 }).to_string()),
|
||||
('m', 2..) => out.push_str(&format!("{mm:02}")),
|
||||
('m', _) => out.push_str(&mm.to_string()),
|
||||
('s', 2..) => out.push_str(&format!("{ss:02}")),
|
||||
('s', _) => out.push_str(&ss.to_string()),
|
||||
('a' | 'A', _) => out.push_str(if hh < 12 { "AM" } else { "PM" }),
|
||||
_ => {
|
||||
for _ in 0..n {
|
||||
|
|
@ -507,6 +511,32 @@ pub fn format_date(fmt: &str) -> String {
|
|||
out
|
||||
}
|
||||
|
||||
/// Insert › Symbol: the character at the caret, in its own font when `font` names one (the rest of
|
||||
/// the text keeps the caret's font).
|
||||
fn symbol(s: &mut Session, v: &Value) -> CmdResult {
|
||||
let c = p::req_str(v, "char")?;
|
||||
if c.is_empty() || c.chars().count() > 64 {
|
||||
return Err(CmdError::Params("char: 1–64 characters".into()));
|
||||
}
|
||||
let font = p::str(v, "font").map(str::trim).filter(|f| !f.is_empty());
|
||||
let Some(font) = font else {
|
||||
type_text(s, c)?;
|
||||
return sel_result(s);
|
||||
};
|
||||
if font.len() > 256 {
|
||||
return Err(CmdError::Params("font: a family name".into()));
|
||||
}
|
||||
let base = s.typing_props();
|
||||
let mut props = base.clone();
|
||||
props.font = Some(font.to_string());
|
||||
s.pending = Some(props);
|
||||
let r = type_text(s, c);
|
||||
// Typing on after the symbol goes on in the text's own font.
|
||||
s.pending = Some(base);
|
||||
r?;
|
||||
sel_result(s)
|
||||
}
|
||||
|
||||
fn field(s: &mut Session, v: &Value) -> CmdResult {
|
||||
let instr = p::req_str(v, "instr")?.trim().to_string();
|
||||
if instr.is_empty() || instr.len() > 4096 {
|
||||
|
|
@ -566,10 +596,31 @@ mod tests {
|
|||
assert!(base64_decode("!!!").is_none());
|
||||
}
|
||||
|
||||
/// Insert › Symbol with a font: only the symbol takes it, the caret's font carries on after.
|
||||
#[test]
|
||||
fn symbol_takes_its_own_font() {
|
||||
let mut s = Session::new(wordcraft_doc::Document::from_text("ab"));
|
||||
s.run("caret.docEnd", &json!({})).unwrap();
|
||||
s.run("insert.symbol", &json!({"char": "\u{2665}", "font": "DejaVu Sans"})).unwrap();
|
||||
s.run("text.insert", &json!({"text": "c"})).unwrap();
|
||||
let p = s.doc.para(StoryRef::Body, &Path::top(0)).unwrap();
|
||||
assert_eq!(p.text, "ab\u{2665}c");
|
||||
assert_eq!(p.props_of_char(2).font.as_deref(), Some("DejaVu Sans"), "the symbol");
|
||||
assert_eq!(p.props_of_char(5).font, None, "typing after it (byte offsets)");
|
||||
assert!(s.run("insert.symbol", &json!({"char": ""})).is_err());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn date_pictures() {
|
||||
let d = format_date("yyyy-MM-dd");
|
||||
assert_eq!(d.len(), 10);
|
||||
assert!(format_date("MMMM d, yyyy").contains(", "));
|
||||
let t = format_date("h:mm:ss am/pm");
|
||||
assert!(t.ends_with(" AM") || t.ends_with(" PM"), "{t}");
|
||||
assert_eq!(t.matches(':').count(), 2, "{t}");
|
||||
use super::super::references::date_picture;
|
||||
assert_eq!(date_picture(r#"DATE \@ "MMMM d, yyyy" \* MERGEFORMAT"#).as_deref(), Some("MMMM d, yyyy"));
|
||||
assert_eq!(date_picture(r#"TIME \@ HH:mm"#).as_deref(), Some("HH:mm"));
|
||||
assert_eq!(date_picture("DATE"), None);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -23,7 +23,9 @@ pub fn specs() -> Vec<CommandSpec> {
|
|||
.params(r#"{"value": "portrait|landscape"}"#),
|
||||
CommandSpec::new("layout.size", "Size", "Layout › Page Setup", size).params(r#"{"name"?: "Letter|Legal|A4|…", "width"?: pt, "height"?: pt}"#),
|
||||
CommandSpec::new("layout.columns", "Columns", "Layout › Page Setup", columns)
|
||||
.params(r#"{"count": 1-12, "space"?: pt, "separator"?: bool, "preset"?: "left|right"}"#),
|
||||
.params(
|
||||
r#"{"count": 1-12, "space"?: pt, "separator"?: bool, "preset"?: "left|right", "widths"?: [[width pt, space after pt], …] (unequal columns; sets the count), "apply"?: "section|document|forward"}"#,
|
||||
),
|
||||
CommandSpec::new("layout.break", "Breaks", "Layout › Page Setup", breaks)
|
||||
.params(r#"{"kind": "page|column|textWrapping|nextPage|continuous|evenPage|oddPage"}"#),
|
||||
CommandSpec::new("layout.lineNumbers", "Line Numbers", "Layout › Page Setup", |s, v| {
|
||||
|
|
@ -171,22 +173,75 @@ fn size(s: &mut Session, v: &Value) -> CmdResult {
|
|||
|
||||
fn columns(s: &mut Session, v: &Value) -> CmdResult {
|
||||
let preset = p::str(v, "preset");
|
||||
let count = p::u64(v, "count").unwrap_or(match preset {
|
||||
Some("left") | Some("right") => 2,
|
||||
_ => 1,
|
||||
});
|
||||
if !(1..=12).contains(&count) {
|
||||
return Err(CmdError::Params("columns must be 1–12".into()));
|
||||
}
|
||||
let space = p::f32(v, "space").unwrap_or(36.0).clamp(0.0, 300.0);
|
||||
let sep = p::bool(v, "separator").unwrap_or(false);
|
||||
let tw = sect(s).text_width();
|
||||
let widths = match preset {
|
||||
Some("left") => vec![((tw - space) / 3.0, space), ((tw - space) * 2.0 / 3.0, 0.0)],
|
||||
Some("right") => vec![((tw - space) * 2.0 / 3.0, space), ((tw - space) / 3.0, 0.0)],
|
||||
// Unequal columns: (width, space after) each, as the Columns dialog sends them.
|
||||
let custom = match v.get("widths").filter(|w| !w.is_null()) {
|
||||
Some(w) => Some(column_widths(w, tw)?),
|
||||
None => None,
|
||||
};
|
||||
let count = match &custom {
|
||||
Some(c) => c.len() as u64,
|
||||
None => p::u64(v, "count").unwrap_or(match preset {
|
||||
Some("left") | Some("right") => 2,
|
||||
_ => 1,
|
||||
}),
|
||||
};
|
||||
if !(1..=12).contains(&count) {
|
||||
return Err(CmdError::Params("columns must be 1–12".into()));
|
||||
}
|
||||
let widths = match (custom, preset) {
|
||||
(Some(c), _) if c.len() > 1 => c,
|
||||
(Some(_), _) => Vec::new(),
|
||||
(None, Some("left")) => vec![((tw - space) / 3.0, space), ((tw - space) * 2.0 / 3.0, 0.0)],
|
||||
(None, Some("right")) => vec![((tw - space) * 2.0 / 3.0, space), ((tw - space) / 3.0, 0.0)],
|
||||
_ => Vec::new(),
|
||||
};
|
||||
with_sect(s, |x| x.columns = Columns { count: count as u32, space, separator: sep, widths: widths.clone() })
|
||||
// Equal columns keep one spacing; unequal ones remember the first gap for a later switch back.
|
||||
let space = widths.first().map(|w| w.1).unwrap_or(space);
|
||||
let cols = Columns { count: count as u32, space, separator: sep, widths };
|
||||
match p::str(v, "apply").unwrap_or("section") {
|
||||
"section" => with_sect(s, |x| x.columns = cols.clone()),
|
||||
"document" => {
|
||||
let ends: Vec<usize> = s.doc.sections().iter().map(|(e, _)| *e).collect();
|
||||
for e in ends {
|
||||
s.doc.section_mut(e).columns = cols.clone();
|
||||
}
|
||||
Ok(serde_json::to_value(sect(s)).unwrap_or(Value::Null))
|
||||
}
|
||||
// From the caret on: a continuous section break first, then the new section's columns.
|
||||
"forward" => {
|
||||
let start = s.sel.ordered().0;
|
||||
s.sel = Selection::caret(start);
|
||||
breaks(s, &json!({"kind": "continuous"}))?;
|
||||
with_sect(s, |x| x.columns = cols.clone())
|
||||
}
|
||||
x => Err(CmdError::Params(format!("unknown apply `{x}` (section, document or forward)"))),
|
||||
}
|
||||
}
|
||||
|
||||
/// `[[width, space after], …]` in points: 1–12 columns, each at least 0.25", that fit the text
|
||||
/// width (`tw`).
|
||||
fn column_widths(v: &Value, tw: f32) -> Result<Vec<(f32, f32)>, CmdError> {
|
||||
let bad = || CmdError::Params("widths: [[width, space after], …] in points, 1–12 columns".into());
|
||||
let a = v.as_array().filter(|a| (1..=12).contains(&a.len())).ok_or_else(bad)?;
|
||||
let mut out = Vec::with_capacity(a.len());
|
||||
for (i, c) in a.iter().enumerate() {
|
||||
let num = |k: usize| c.get(k).and_then(Value::as_f64).map(|x| x as f32).filter(|x| x.is_finite());
|
||||
let w = num(0).ok_or_else(bad)?;
|
||||
// The last column has no space after it.
|
||||
let sp = if i + 1 == a.len() { 0.0 } else { num(1).unwrap_or(0.0) };
|
||||
if w < 18.0 || !(0.0..=300.0).contains(&sp) {
|
||||
return Err(CmdError::Params("each column must be at least 0.25\" wide, with 0–300 pt after it".into()));
|
||||
}
|
||||
out.push((w, sp));
|
||||
}
|
||||
let total: f32 = out.iter().map(|(w, sp)| w + sp).sum();
|
||||
if total > tw + 1.0 {
|
||||
return Err(CmdError::Params(format!("the columns ({total:.0} pt) are wider than the text ({tw:.0} pt)")));
|
||||
}
|
||||
Ok(out)
|
||||
}
|
||||
|
||||
fn breaks(s: &mut Session, v: &Value) -> CmdResult {
|
||||
|
|
@ -223,3 +278,45 @@ fn breaks(s: &mut Session, v: &Value) -> CmdResult {
|
|||
let _ = Block::Para;
|
||||
sel_result(s)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
fn doc() -> Session {
|
||||
Session::new(wordcraft_doc::Document::from_text("one\ntwo\nthree"))
|
||||
}
|
||||
|
||||
/// More Columns: unequal widths with a line between, as one undo step.
|
||||
#[test]
|
||||
fn unequal_columns_with_a_line_between() {
|
||||
let mut s = doc();
|
||||
let tw = sect(&s).text_width();
|
||||
s.run("layout.columns", &json!({"widths": [[150.0, 24.0], [tw - 174.0, 0.0]], "separator": true})).unwrap();
|
||||
let c = sect(&s).columns;
|
||||
assert_eq!((c.count, c.separator, c.widths.len()), (2, true, 2));
|
||||
assert_eq!(c.widths.first(), Some(&(150.0, 24.0)));
|
||||
s.run("edit.undo", &json!({})).unwrap();
|
||||
assert_eq!(sect(&s).columns, Columns::default());
|
||||
// Too wide, too narrow, too many, or nonsense: refused.
|
||||
for bad in [json!([[tw, 36.0], [100.0, 0.0]]), json!([[5.0, 0.0], [100.0, 0.0]]), json!(vec![[40.0, 0.0]; 13]), json!("x")] {
|
||||
assert!(s.run("layout.columns", &json!({"widths": bad})).is_err(), "{bad}");
|
||||
}
|
||||
}
|
||||
|
||||
/// Apply to: the whole document, or from the caret on (a continuous section break first).
|
||||
#[test]
|
||||
fn columns_apply_to_the_document_or_from_the_caret_on() {
|
||||
let mut s = doc();
|
||||
s.run("layout.break", &json!({"kind": "nextPage"})).unwrap();
|
||||
s.run("layout.columns", &json!({"count": 3, "apply": "document"})).unwrap();
|
||||
assert!(s.doc.sections().iter().all(|(_, x)| x.columns.count == 3));
|
||||
let mut s = doc();
|
||||
s.run("caret.docEnd", &json!({})).unwrap();
|
||||
s.run("layout.columns", &json!({"count": 2, "apply": "forward"})).unwrap();
|
||||
let counts: Vec<u32> = s.doc.sections().iter().map(|(_, x)| x.columns.count).collect();
|
||||
assert_eq!(counts, vec![1, 2]);
|
||||
assert_eq!(s.doc.last_section.start, SectionStart::Continuous);
|
||||
assert!(s.run("layout.columns", &json!({"count": 2, "apply": "elsewhere"})).is_err());
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -285,11 +285,7 @@ pub fn update_fields(s: &mut Session) -> Result<(), CmdError> {
|
|||
let name = wordcraft_layout::fields::field_name(instr);
|
||||
match name.as_str() {
|
||||
"DATE" | "TIME" | "CREATEDATE" | "SAVEDATE" | "PRINTDATE" => {
|
||||
let pic = instr
|
||||
.split("\\@")
|
||||
.nth(1)
|
||||
.map(|x| x.trim().trim_matches('"').to_string())
|
||||
.unwrap_or_else(|| if name == "TIME" { "h:mm am/pm".into() } else { "M/d/yyyy".into() });
|
||||
let pic = date_picture(instr).unwrap_or_else(|| if name == "TIME" { "h:mm am/pm".into() } else { "M/d/yyyy".into() });
|
||||
updates.push((k, super::insert::format_date(&pic)));
|
||||
}
|
||||
"SEQ" => {
|
||||
|
|
@ -326,6 +322,16 @@ pub fn update_fields(s: &mut Session) -> Result<(), CmdError> {
|
|||
update_toc(s)
|
||||
}
|
||||
|
||||
/// A field's `\@` date picture: the quoted text after it (switches may follow), or one word.
|
||||
pub fn date_picture(instr: &str) -> Option<String> {
|
||||
let rest = instr.split_once("\\@")?.1.trim_start();
|
||||
let pic = match rest.strip_prefix('"') {
|
||||
Some(q) => q.split('"').next().unwrap_or(""),
|
||||
None => rest.split_whitespace().next().unwrap_or(""),
|
||||
};
|
||||
(!pic.is_empty()).then(|| pic.to_string())
|
||||
}
|
||||
|
||||
/// The text a bookmark marks (field results included), up to its end in the same paragraph or
|
||||
/// the paragraph's end. `None` when there is no such bookmark.
|
||||
pub fn bookmark_text(doc: &wordcraft_doc::Document, name: &str) -> Option<String> {
|
||||
|
|
|
|||
|
|
@ -142,6 +142,8 @@ pub enum Dialog {
|
|||
Commands {
|
||||
query: String,
|
||||
},
|
||||
/// Columns, Symbol and Field ([`crate::dialogs_insert`], #321).
|
||||
Insert(Box<crate::dialogs_insert::InsertDialog>),
|
||||
/// Paste Special: the clipboard's formats and the chosen one. The clipboard payload stays out
|
||||
/// of the serialized dialog state (it can be megabytes).
|
||||
PasteSpecial {
|
||||
|
|
@ -622,6 +624,7 @@ impl Dialog {
|
|||
Dialog::TableStyle { id: None, .. } => "newTableStyle",
|
||||
Dialog::TableStyle { .. } => "modifyTableStyle",
|
||||
Dialog::Commands { .. } => "commands",
|
||||
Dialog::Insert(d) => d.name(),
|
||||
Dialog::PasteSpecial { .. } => "pasteSpecial",
|
||||
Dialog::About { .. } => "about",
|
||||
Dialog::SaveChanges { .. } => "saveChanges",
|
||||
|
|
@ -657,6 +660,9 @@ impl Dialog {
|
|||
}
|
||||
|
||||
pub fn open(name: &str, app: &mut WordApp) -> Option<Dialog> {
|
||||
if let Some(d) = crate::dialogs_insert::open(name, app) {
|
||||
return Some(Dialog::Insert(Box::new(d)));
|
||||
}
|
||||
let st = app.session.run("format.state", &json!({})).unwrap_or_default();
|
||||
let s = |k: &str| st.get(k).and_then(Value::as_str).unwrap_or("").to_string();
|
||||
let b = |k: &str| st.get(k).and_then(Value::as_bool).unwrap_or(false);
|
||||
|
|
@ -891,6 +897,7 @@ pub fn show(app: &mut WordApp, ctx: &egui::Context) {
|
|||
Dialog::TableStyle { id: None, .. } => "New Table Style",
|
||||
Dialog::TableStyle { .. } => "Modify Table Style",
|
||||
Dialog::Commands { .. } => "Search Commands",
|
||||
Dialog::Insert(d) => d.title(),
|
||||
Dialog::PasteSpecial { .. } => "Paste Special",
|
||||
Dialog::About { .. } => "About WordCraft",
|
||||
Dialog::SaveChanges { .. } => "WordCraft",
|
||||
|
|
@ -1501,6 +1508,7 @@ fn body(app: &mut WordApp, ui: &mut Ui, d: &mut Dialog) -> bool {
|
|||
}
|
||||
ok || cancel
|
||||
}
|
||||
Dialog::Insert(f) => crate::dialogs_insert::body(app, ui, f),
|
||||
Dialog::Commands { query } => {
|
||||
let r = ui.add(egui::TextEdit::singleline(query).hint_text(tl!("Type a command, e.g. \"insert table\"")).desired_width(380.0));
|
||||
r.request_focus();
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -1103,6 +1103,89 @@
|
|||
Leave the equation (Esc) Salir de la ecuación (Esc)
|
||||
Preview Vista previa
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (Todos)
|
||||
(none) (ninguno)
|
||||
(normal text) (texto normal)
|
||||
1/4 Em Space Espacio de 1/4 de eme
|
||||
A mail merge field Un campo de combinación
|
||||
A numbered sequence (figures, tables…) Una secuencia numerada (figuras, tablas…)
|
||||
A table of contents Una tabla de contenido
|
||||
Apply to: Aplicar a:
|
||||
Categories: Categorías:
|
||||
Character Carácter
|
||||
Character code: Código de carácter:
|
||||
Col #: Col. n.º:
|
||||
Copyright Copyright
|
||||
Date and Time Fecha y hora
|
||||
Date formats: Formatos de fecha:
|
||||
Description: Descripción:
|
||||
Document Information Información del documento
|
||||
Double Closing Quote Comilla doble de cierre
|
||||
Double Opening Quote Comilla doble de apertura
|
||||
Ellipsis Puntos suspensivos
|
||||
Em Dash Raya
|
||||
En Dash Guion medio
|
||||
Em Space Espacio eme
|
||||
En Space Espacio ene
|
||||
Equal column width Columnas de igual ancho
|
||||
Field Codes Códigos de campo
|
||||
Field code: Código de campo:
|
||||
Field codes: Códigos de campo:
|
||||
Field name: Nombre del campo:
|
||||
Field names: Nombres de campo:
|
||||
Field properties Propiedades del campo
|
||||
Field… Campo…
|
||||
Format: Formato:
|
||||
Hide Codes Ocultar códigos
|
||||
Index and Tables Índices y tablas
|
||||
Line between Línea entre columnas
|
||||
Links and References Vínculos y referencias
|
||||
Mail Merge Combinar correspondencia
|
||||
More Columns… Más columnas…
|
||||
More Symbols… Más símbolos…
|
||||
No-Width Non Break Unión sin ancho
|
||||
No-Width Optional Break Salto opcional sin ancho
|
||||
Paragraph Mark Marca de párrafo
|
||||
Pick a field from the list Elija un campo
|
||||
Preserve formatting during updates Conservar el formato al actualizar
|
||||
Presets Preestablecidos
|
||||
Recently used symbols: Símbolos usados recientemente:
|
||||
Registered Registrado
|
||||
Section Mark Marca de sección
|
||||
Sequence name: Nombre de la secuencia:
|
||||
Shortcut key: Atajo de teclado:
|
||||
Single Closing Quote Comilla simple de cierre
|
||||
Single Opening Quote Comilla simple de apertura
|
||||
Spacing: Espaciado:
|
||||
Special Characters Caracteres especiales
|
||||
Subset: Subconjunto:
|
||||
The time right now La hora actual
|
||||
When this document was first created La fecha en que se creó el documento
|
||||
When this document was most recently printed La fecha en que se imprimió el documento por última vez
|
||||
When this document was most recently saved La fecha en que se guardó el documento por última vez
|
||||
The document has no bookmarks yet. El documento aún no tiene marcadores.
|
||||
Who the document properties name as author El autor del documento
|
||||
Name of the file this document is saved as El nombre de archivo del documento
|
||||
Title from the document properties El título del documento
|
||||
How many pages the whole document has El número de páginas del documento
|
||||
How many pages this section has El número de páginas de la sección
|
||||
Number of the page the field sits on El número de la página actual
|
||||
Number of the section the field sits in El número de la sección actual
|
||||
How many words the document holds El número de palabras del documento
|
||||
Page on which a bookmarked passage falls El número de página de un marcador
|
||||
Copy of the text a bookmark marks El texto de un marcador
|
||||
This field has no options. Este campo no tiene opciones.
|
||||
This font has no characters to show. Esta fuente no tiene caracteres que mostrar.
|
||||
This point forward De aquí en adelante
|
||||
This section Esta sección
|
||||
The date it is today La fecha de hoy
|
||||
Trademark Marca comercial
|
||||
Type the field's name and its switches, for example PAGE \\* roman. Escriba el nombre del campo y sus modificadores, por ejemplo PAGE \\* roman.
|
||||
Whole document Todo el documento
|
||||
Width and spacing Ancho y espaciado
|
||||
from Unicode (hex) de Unicode (hex)
|
||||
Shape Effects Efectos de forma
|
||||
Glow Resplandor
|
||||
Soft Edges Bordes suaves
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 25.
|
|
|
@ -1087,6 +1087,89 @@
|
|||
Leave the equation (Esc) 数式を終了 (Esc)
|
||||
Preview プレビュー
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (すべて)
|
||||
(none) (なし)
|
||||
(normal text) (標準テキスト)
|
||||
1/4 Em Space 1/4 em スペース
|
||||
A mail merge field 差し込み用のフィールド
|
||||
A numbered sequence (figures, tables…) 連番 (図、表…)
|
||||
A table of contents 目次
|
||||
Apply to: 適用先:
|
||||
Categories: 分類:
|
||||
Character 文字
|
||||
Character code: 文字コード:
|
||||
Col #: 段:
|
||||
Copyright 著作権記号
|
||||
Date and Time 日付と時刻
|
||||
Date formats: 日付の形式:
|
||||
Description: 説明:
|
||||
Document Information 文書の情報
|
||||
Double Closing Quote 二重引用符 (閉じ)
|
||||
Double Opening Quote 二重引用符 (開き)
|
||||
Ellipsis 省略記号
|
||||
Em Dash em ダッシュ
|
||||
En Dash en ダッシュ
|
||||
Em Space em スペース
|
||||
En Space en スペース
|
||||
Equal column width 段の幅を均等にする
|
||||
Field Codes フィールド コード
|
||||
Field code: フィールド コード:
|
||||
Field codes: フィールド コード:
|
||||
Field name: フィールド名:
|
||||
Field names: フィールドの名前:
|
||||
Field properties フィールドのプロパティ
|
||||
Field… フィールド…
|
||||
Format: 書式:
|
||||
Hide Codes コードを隠す
|
||||
Index and Tables 索引と目次
|
||||
Line between 境界線を引く
|
||||
Links and References リンクと参照
|
||||
Mail Merge 差し込み印刷
|
||||
More Columns… 段組みの詳細設定…
|
||||
More Symbols… その他の記号…
|
||||
No-Width Non Break 幅なし改行禁止
|
||||
No-Width Optional Break 幅なし任意改行
|
||||
Paragraph Mark 段落記号
|
||||
Pick a field from the list フィールドを選んでください
|
||||
Preserve formatting during updates 更新時に書式を保持する
|
||||
Presets プリセット
|
||||
Recently used symbols: 最近使った記号:
|
||||
Registered 登録商標
|
||||
Section Mark 節記号
|
||||
Sequence name: 連番の名前:
|
||||
Shortcut key: ショートカット キー:
|
||||
Single Closing Quote 一重引用符 (閉じ)
|
||||
Single Opening Quote 一重引用符 (開き)
|
||||
Spacing: 間隔:
|
||||
Special Characters 特殊文字
|
||||
Subset: 種類:
|
||||
The time right now 現在の時刻
|
||||
When this document was first created 文書の作成日
|
||||
When this document was most recently printed 文書の最終印刷日
|
||||
When this document was most recently saved 文書の最終保存日
|
||||
The document has no bookmarks yet. この文書にはまだブックマークがありません。
|
||||
Who the document properties name as author 文書の作成者
|
||||
Name of the file this document is saved as 文書のファイル名
|
||||
Title from the document properties 文書のタイトル
|
||||
How many pages the whole document has 文書のページ数
|
||||
How many pages this section has セクションのページ数
|
||||
Number of the page the field sits on 現在のページ番号
|
||||
Number of the section the field sits in 現在のセクション番号
|
||||
How many words the document holds 文書の単語数
|
||||
Page on which a bookmarked passage falls ブックマークのページ番号
|
||||
Copy of the text a bookmark marks ブックマークの文字列
|
||||
This field has no options. このフィールドにはオプションがありません。
|
||||
This font has no characters to show. このフォントには表示できる文字がありません。
|
||||
This point forward これ以降
|
||||
This section このセクション
|
||||
The date it is today 今日の日付
|
||||
Trademark 商標
|
||||
Type the field's name and its switches, for example PAGE \\* roman. フィールド名とスイッチを入力します (例: PAGE \\* roman)。
|
||||
Whole document 文書全体
|
||||
Width and spacing 幅と間隔
|
||||
from Unicode (hex) Unicode (16 進)
|
||||
Shape Effects 図形の効果
|
||||
Glow 光彩
|
||||
Soft Edges 輪郭のぼかし
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 3.
|
|
|
@ -1099,6 +1099,89 @@
|
|||
Leave the equation (Esc) Sair da equação (Esc)
|
||||
Preview Visualizar
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (Todos)
|
||||
(none) (nenhum)
|
||||
(normal text) (texto normal)
|
||||
1/4 Em Space Espaço de 1/4 de eme
|
||||
A mail merge field Um campo de mesclagem
|
||||
A numbered sequence (figures, tables…) Uma sequência numerada (figuras, tabelas…)
|
||||
A table of contents Um sumário
|
||||
Apply to: Aplicar a:
|
||||
Categories: Categorias:
|
||||
Character Caractere
|
||||
Character code: Código do caractere:
|
||||
Col #: Col. nº:
|
||||
Copyright Copyright
|
||||
Date and Time Data e hora
|
||||
Date formats: Formatos de data:
|
||||
Description: Descrição:
|
||||
Document Information Informações do documento
|
||||
Double Closing Quote Aspas duplas de fechamento
|
||||
Double Opening Quote Aspas duplas de abertura
|
||||
Ellipsis Reticências
|
||||
Em Dash Travessão
|
||||
En Dash Meia-risca
|
||||
Em Space Espaço eme
|
||||
En Space Espaço ene
|
||||
Equal column width Colunas de largura igual
|
||||
Field Codes Códigos de campo
|
||||
Field code: Código de campo:
|
||||
Field codes: Códigos de campo:
|
||||
Field name: Nome do campo:
|
||||
Field names: Nomes de campo:
|
||||
Field properties Propriedades do campo
|
||||
Field… Campo…
|
||||
Format: Formato:
|
||||
Hide Codes Ocultar códigos
|
||||
Index and Tables Índices e tabelas
|
||||
Line between Linha entre colunas
|
||||
Links and References Links e referências
|
||||
Mail Merge Mala direta
|
||||
More Columns… Mais colunas…
|
||||
More Symbols… Mais símbolos…
|
||||
No-Width Non Break Junção sem largura
|
||||
No-Width Optional Break Quebra opcional sem largura
|
||||
Paragraph Mark Marca de parágrafo
|
||||
Pick a field from the list Escolha um campo
|
||||
Preserve formatting during updates Preservar a formatação ao atualizar
|
||||
Presets Predefinições
|
||||
Recently used symbols: Símbolos usados recentemente:
|
||||
Registered Registrado
|
||||
Section Mark Marca de seção
|
||||
Sequence name: Nome da sequência:
|
||||
Shortcut key: Tecla de atalho:
|
||||
Single Closing Quote Aspas simples de fechamento
|
||||
Single Opening Quote Aspas simples de abertura
|
||||
Spacing: Espaçamento:
|
||||
Special Characters Caracteres especiais
|
||||
Subset: Subconjunto:
|
||||
The time right now A hora atual
|
||||
When this document was first created A data em que o documento foi criado
|
||||
When this document was most recently printed A data em que o documento foi impresso pela última vez
|
||||
When this document was most recently saved A data em que o documento foi salvo pela última vez
|
||||
The document has no bookmarks yet. O documento ainda não tem indicadores.
|
||||
Who the document properties name as author O autor do documento
|
||||
Name of the file this document is saved as O nome do arquivo do documento
|
||||
Title from the document properties O título do documento
|
||||
How many pages the whole document has O número de páginas do documento
|
||||
How many pages this section has O número de páginas da seção
|
||||
Number of the page the field sits on O número da página atual
|
||||
Number of the section the field sits in O número da seção atual
|
||||
How many words the document holds O número de palavras do documento
|
||||
Page on which a bookmarked passage falls O número da página de um indicador
|
||||
Copy of the text a bookmark marks O texto de um indicador
|
||||
This field has no options. Este campo não tem opções.
|
||||
This font has no characters to show. Esta fonte não tem caracteres para mostrar.
|
||||
This point forward Deste ponto em diante
|
||||
This section Esta seção
|
||||
The date it is today A data de hoje
|
||||
Trademark Marca comercial
|
||||
Type the field's name and its switches, for example PAGE \\* roman. Digite o nome do campo e suas opções, por exemplo PAGE \\* roman.
|
||||
Whole document Documento inteiro
|
||||
Width and spacing Largura e espaçamento
|
||||
from Unicode (hex) do Unicode (hex)
|
||||
Shape Effects Efeitos de forma
|
||||
Glow Brilho
|
||||
Soft Edges Bordas suaves
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 25.
|
|
|
@ -1152,6 +1152,89 @@
|
|||
Insert a new equation (Alt+=) Umetni novu jednačinu (Alt+=)
|
||||
Leave the equation (Esc) Napusti jednačinu (Esc)
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (Sve)
|
||||
(none) (nema)
|
||||
(normal text) (običan tekst)
|
||||
1/4 Em Space Razmak od 1/4 em
|
||||
A mail merge field Polje za spajanje pošte
|
||||
A numbered sequence (figures, tables…) Numerisani niz (slike, tabele…)
|
||||
A table of contents Sadržaj
|
||||
Apply to: Primeni na:
|
||||
Categories: Kategorije:
|
||||
Character Znak
|
||||
Character code: Kod znaka:
|
||||
Col #: Kolona br.:
|
||||
Copyright Znak autorskog prava
|
||||
Date and Time Datum i vreme
|
||||
Date formats: Formati datuma:
|
||||
Description: Opis:
|
||||
Document Information Informacije o dokumentu
|
||||
Double Closing Quote Zatvoreni dvostruki navodnik
|
||||
Double Opening Quote Otvoreni dvostruki navodnik
|
||||
Ellipsis Tri tačke
|
||||
Em Dash Duga crta
|
||||
En Dash Srednja crta
|
||||
Em Space Em razmak
|
||||
En Space En razmak
|
||||
Equal column width Jednaka širina kolona
|
||||
Field Codes Kodovi polja
|
||||
Field code: Kod polja:
|
||||
Field codes: Kodovi polja:
|
||||
Field name: Naziv polja:
|
||||
Field names: Nazivi polja:
|
||||
Field properties Svojstva polja
|
||||
Field… Polje…
|
||||
Format: Format:
|
||||
Hide Codes Sakrij kodove
|
||||
Index and Tables Indeksi i tabele
|
||||
Line between Linija između kolona
|
||||
Links and References Veze i reference
|
||||
Mail Merge Spajanje pošte
|
||||
More Columns… Još kolona…
|
||||
More Symbols… Još simbola…
|
||||
No-Width Non Break Nedeljivi znak nulte širine
|
||||
No-Width Optional Break Opcioni prelom nulte širine
|
||||
Paragraph Mark Znak pasusa
|
||||
Pick a field from the list Izaberite polje
|
||||
Preserve formatting during updates Sačuvaj oblikovanje pri ažuriranju
|
||||
Presets Unapred zadato
|
||||
Recently used symbols: Nedavno korišćeni simboli:
|
||||
Registered Registrovani žig
|
||||
Section Mark Znak paragrafa
|
||||
Sequence name: Naziv niza:
|
||||
Shortcut key: Prečica na tastaturi:
|
||||
Single Closing Quote Zatvoreni jednostruki navodnik
|
||||
Single Opening Quote Otvoreni jednostruki navodnik
|
||||
Spacing: Razmak:
|
||||
Special Characters Specijalni znakovi
|
||||
Subset: Podskup:
|
||||
The time right now Trenutno vreme
|
||||
When this document was first created Datum kada je dokument napravljen
|
||||
When this document was most recently printed Datum kada je dokument poslednji put odštampan
|
||||
When this document was most recently saved Datum kada je dokument poslednji put sačuvan
|
||||
The document has no bookmarks yet. Dokument još nema obeleživače.
|
||||
Who the document properties name as author Autor dokumenta
|
||||
Name of the file this document is saved as Ime datoteke dokumenta
|
||||
Title from the document properties Naslov dokumenta
|
||||
How many pages the whole document has Broj stranica u dokumentu
|
||||
How many pages this section has Broj stranica u odeljku
|
||||
Number of the page the field sits on Broj trenutne stranice
|
||||
Number of the section the field sits in Broj trenutnog odeljka
|
||||
How many words the document holds Broj reči u dokumentu
|
||||
Page on which a bookmarked passage falls Broj stranice obeleživača
|
||||
Copy of the text a bookmark marks Tekst obeleživača
|
||||
This field has no options. Ovo polje nema opcija.
|
||||
This font has no characters to show. Ovaj font nema znakove za prikaz.
|
||||
This point forward Od ovog mesta nadalje
|
||||
This section Ovaj odeljak
|
||||
The date it is today Današnji datum
|
||||
Trademark Žig
|
||||
Type the field's name and its switches, for example PAGE \\* roman. Unesite naziv polja i njegove prekidače, na primer PAGE \\* roman.
|
||||
Whole document Ceo dokument
|
||||
Width and spacing Širina i razmak
|
||||
from Unicode (hex) iz Unicode (heks.)
|
||||
Rotation Rotacija
|
||||
Rotation: Rotacija:
|
||||
Rotate Right 90° Rotiraj udesno za 90°
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 25.
|
|
|
@ -1156,6 +1156,89 @@
|
|||
Insert a new equation (Alt+=) Уметни нову једначину (Alt+=)
|
||||
Leave the equation (Esc) Напусти једначину (Esc)
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (Све)
|
||||
(none) (нема)
|
||||
(normal text) (обичан текст)
|
||||
1/4 Em Space Размак од 1/4 em
|
||||
A mail merge field Поље за спајање поште
|
||||
A numbered sequence (figures, tables…) Нумерисани низ (слике, табеле…)
|
||||
A table of contents Садржај
|
||||
Apply to: Примени на:
|
||||
Categories: Категорије:
|
||||
Character Знак
|
||||
Character code: Код знака:
|
||||
Col #: Колона бр.:
|
||||
Copyright Знак ауторског права
|
||||
Date and Time Датум и време
|
||||
Date formats: Формати датума:
|
||||
Description: Опис:
|
||||
Document Information Информације о документу
|
||||
Double Closing Quote Затворени двоструки наводник
|
||||
Double Opening Quote Отворени двоструки наводник
|
||||
Ellipsis Три тачке
|
||||
Em Dash Дуга црта
|
||||
En Dash Средња црта
|
||||
Em Space Em размак
|
||||
En Space En размак
|
||||
Equal column width Једнака ширина колона
|
||||
Field Codes Кодови поља
|
||||
Field code: Код поља:
|
||||
Field codes: Кодови поља:
|
||||
Field name: Назив поља:
|
||||
Field names: Називи поља:
|
||||
Field properties Својства поља
|
||||
Field… Поље…
|
||||
Format: Формат:
|
||||
Hide Codes Сакриј кодове
|
||||
Index and Tables Индекси и табеле
|
||||
Line between Линија између колона
|
||||
Links and References Везе и референце
|
||||
Mail Merge Спајање поште
|
||||
More Columns… Још колона…
|
||||
More Symbols… Још симбола…
|
||||
No-Width Non Break Недељиви знак нулте ширине
|
||||
No-Width Optional Break Опциони прелом нулте ширине
|
||||
Paragraph Mark Знак пасуса
|
||||
Pick a field from the list Изаберите поље
|
||||
Preserve formatting during updates Сачувај обликовање при ажурирању
|
||||
Presets Унапред задато
|
||||
Recently used symbols: Недавно коришћени симболи:
|
||||
Registered Регистровани жиг
|
||||
Section Mark Знак параграфа
|
||||
Sequence name: Назив низа:
|
||||
Shortcut key: Пречица на тастатури:
|
||||
Single Closing Quote Затворени једноструки наводник
|
||||
Single Opening Quote Отворени једноструки наводник
|
||||
Spacing: Размак:
|
||||
Special Characters Специјални знакови
|
||||
Subset: Подскуп:
|
||||
The time right now Тренутно време
|
||||
When this document was first created Датум када је документ направљен
|
||||
When this document was most recently printed Датум када је документ последњи пут одштампан
|
||||
When this document was most recently saved Датум када је документ последњи пут сачуван
|
||||
The document has no bookmarks yet. Документ још нема обележиваче.
|
||||
Who the document properties name as author Аутор документа
|
||||
Name of the file this document is saved as Име датотеке документа
|
||||
Title from the document properties Наслов документа
|
||||
How many pages the whole document has Број страница у документу
|
||||
How many pages this section has Број страница у одељку
|
||||
Number of the page the field sits on Број тренутне странице
|
||||
Number of the section the field sits in Број тренутног одељка
|
||||
How many words the document holds Број речи у документу
|
||||
Page on which a bookmarked passage falls Број странице обележивача
|
||||
Copy of the text a bookmark marks Текст обележивача
|
||||
This field has no options. Ово поље нема опција.
|
||||
This font has no characters to show. Овај фонт нема знакове за приказ.
|
||||
This point forward Од овог места надаље
|
||||
This section Овај одељак
|
||||
The date it is today Данашњи датум
|
||||
Trademark Жиг
|
||||
Type the field's name and its switches, for example PAGE \\* roman. Унесите назив поља и његове прекидаче, на пример PAGE \\* roman.
|
||||
Whole document Цео документ
|
||||
Width and spacing Ширина и размак
|
||||
from Unicode (hex) из Unicode (хекс.)
|
||||
Rotation Ротација
|
||||
Rotation: Ротација:
|
||||
Rotate Right 90° Ротирај удесно за 90°
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 11 and column 25.
|
|
|
@ -1099,6 +1099,89 @@
|
|||
Leave the equation (Esc) Вийти з рівняння (Esc)
|
||||
Preview Попередній перегляд
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (Усі)
|
||||
(none) (немає)
|
||||
(normal text) (звичайний текст)
|
||||
1/4 Em Space Пробіл 1/4 кегля
|
||||
A mail merge field Поле злиття
|
||||
A numbered sequence (figures, tables…) Нумерована послідовність (рисунки, таблиці…)
|
||||
A table of contents Зміст
|
||||
Apply to: Застосувати до:
|
||||
Categories: Категорії:
|
||||
Character Символ
|
||||
Character code: Код символу:
|
||||
Col #: Стовпець:
|
||||
Copyright Знак авторського права
|
||||
Date and Time Дата й час
|
||||
Date formats: Формати дати:
|
||||
Description: Опис:
|
||||
Document Information Відомості про документ
|
||||
Double Closing Quote Закривні подвійні лапки
|
||||
Double Opening Quote Відкривні подвійні лапки
|
||||
Ellipsis Три крапки
|
||||
Em Dash Довге тире
|
||||
En Dash Коротке тире
|
||||
Em Space Широкий пробіл
|
||||
En Space Пробіл середньої ширини
|
||||
Equal column width Однакова ширина стовпців
|
||||
Field Codes Коди полів
|
||||
Field code: Код поля:
|
||||
Field codes: Коди полів:
|
||||
Field name: Назва поля:
|
||||
Field names: Назви полів:
|
||||
Field properties Властивості поля
|
||||
Field… Поле…
|
||||
Format: Формат:
|
||||
Hide Codes Сховати коди
|
||||
Index and Tables Покажчики й таблиці
|
||||
Line between Лінія між стовпцями
|
||||
Links and References Зв'язки й посилання
|
||||
Mail Merge Злиття
|
||||
More Columns… Інші стовпці…
|
||||
More Symbols… Інші символи…
|
||||
No-Width Non Break Нерозривний символ нульової ширини
|
||||
No-Width Optional Break Необов'язковий розрив нульової ширини
|
||||
Paragraph Mark Знак абзацу
|
||||
Pick a field from the list Виберіть поле
|
||||
Preserve formatting during updates Зберігати форматування під час оновлення
|
||||
Presets Шаблони
|
||||
Recently used symbols: Нещодавно використані символи:
|
||||
Registered Зареєстрована торговельна марка
|
||||
Section Mark Знак параграфа
|
||||
Sequence name: Назва послідовності:
|
||||
Shortcut key: Сполучення клавіш:
|
||||
Single Closing Quote Закривна одинарна лапка
|
||||
Single Opening Quote Відкривна одинарна лапка
|
||||
Spacing: Інтервал:
|
||||
Special Characters Спеціальні символи
|
||||
Subset: Набір:
|
||||
The time right now Поточний час
|
||||
When this document was first created Дата створення документа
|
||||
When this document was most recently printed Дата останнього друку документа
|
||||
When this document was most recently saved Дата останнього збереження документа
|
||||
The document has no bookmarks yet. У документі ще немає закладок.
|
||||
Who the document properties name as author Автор документа
|
||||
Name of the file this document is saved as Ім'я файлу документа
|
||||
Title from the document properties Назва документа
|
||||
How many pages the whole document has Кількість сторінок у документі
|
||||
How many pages this section has Кількість сторінок у розділі
|
||||
Number of the page the field sits on Номер поточної сторінки
|
||||
Number of the section the field sits in Номер поточного розділу
|
||||
How many words the document holds Кількість слів у документі
|
||||
Page on which a bookmarked passage falls Номер сторінки закладки
|
||||
Copy of the text a bookmark marks Текст закладки
|
||||
This field has no options. Це поле не має параметрів.
|
||||
This font has no characters to show. Цей шрифт не має символів для показу.
|
||||
This point forward Від цього місця
|
||||
This section Цей розділ
|
||||
The date it is today Сьогоднішня дата
|
||||
Trademark Торговельна марка
|
||||
Type the field's name and its switches, for example PAGE \\* roman. Введіть назву поля та його ключі, наприклад PAGE \\* roman.
|
||||
Whole document Увесь документ
|
||||
Width and spacing Ширина й інтервал
|
||||
from Unicode (hex) з Unicode (шістн.)
|
||||
Shape Effects Ефекти фігури
|
||||
Glow Світіння
|
||||
Soft Edges М'які краї
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 31.
|
|
|
@ -1098,6 +1098,89 @@
|
|||
Leave the equation (Esc) 退出公式 (Esc)
|
||||
Preview 预览
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (全部)
|
||||
(none) (无)
|
||||
(normal text) (普通文本)
|
||||
1/4 Em Space 1/4 全角空格
|
||||
A mail merge field 邮件合并域
|
||||
A numbered sequence (figures, tables…) 编号序列(图、表…)
|
||||
A table of contents 目录
|
||||
Apply to: 应用于:
|
||||
Categories: 类别:
|
||||
Character 字符
|
||||
Character code: 字符代码:
|
||||
Col #: 栏号:
|
||||
Copyright 版权
|
||||
Date and Time 日期和时间
|
||||
Date formats: 日期格式:
|
||||
Description: 说明:
|
||||
Document Information 文档信息
|
||||
Double Closing Quote 右双引号
|
||||
Double Opening Quote 左双引号
|
||||
Ellipsis 省略号
|
||||
Em Dash 长破折号
|
||||
En Dash 短破折号
|
||||
Em Space 全角空格
|
||||
En Space 半角空格
|
||||
Equal column width 栏宽相等
|
||||
Field Codes 域代码
|
||||
Field code: 域代码:
|
||||
Field codes: 域代码:
|
||||
Field name: 域名:
|
||||
Field names: 域名列表:
|
||||
Field properties 域属性
|
||||
Field… 域…
|
||||
Format: 格式:
|
||||
Hide Codes 隐藏代码
|
||||
Index and Tables 索引和目录
|
||||
Line between 分隔线
|
||||
Links and References 链接和引用
|
||||
Mail Merge 邮件合并
|
||||
More Columns… 更多栏…
|
||||
More Symbols… 其他符号…
|
||||
No-Width Non Break 无宽非分隔符
|
||||
No-Width Optional Break 无宽可选分隔符
|
||||
Paragraph Mark 段落标记
|
||||
Pick a field from the list 请选择域
|
||||
Preserve formatting during updates 更新时保留格式
|
||||
Presets 预设
|
||||
Recently used symbols: 近期使用过的符号:
|
||||
Registered 注册商标
|
||||
Section Mark 章节符号
|
||||
Sequence name: 序列名称:
|
||||
Shortcut key: 快捷键:
|
||||
Single Closing Quote 右单引号
|
||||
Single Opening Quote 左单引号
|
||||
Spacing: 间距:
|
||||
Special Characters 特殊字符
|
||||
Subset: 子集:
|
||||
The time right now 当前时间
|
||||
When this document was first created 文档的创建日期
|
||||
When this document was most recently printed 文档的上次打印日期
|
||||
When this document was most recently saved 文档的上次保存日期
|
||||
The document has no bookmarks yet. 文档中还没有书签。
|
||||
Who the document properties name as author 文档作者
|
||||
Name of the file this document is saved as 文档的文件名
|
||||
Title from the document properties 文档标题
|
||||
How many pages the whole document has 文档的页数
|
||||
How many pages this section has 本节的页数
|
||||
Number of the page the field sits on 当前页码
|
||||
Number of the section the field sits in 当前节号
|
||||
How many words the document holds 文档的字数
|
||||
Page on which a bookmarked passage falls 书签所在的页码
|
||||
Copy of the text a bookmark marks 书签的文本
|
||||
This field has no options. 此域没有选项。
|
||||
This font has no characters to show. 此字体没有可显示的字符。
|
||||
This point forward 插入点之后
|
||||
This section 本节
|
||||
The date it is today 今天的日期
|
||||
Trademark 商标
|
||||
Type the field's name and its switches, for example PAGE \\* roman. 键入域名及其开关,例如 PAGE \\* roman。
|
||||
Whole document 整篇文档
|
||||
Width and spacing 宽度和间距
|
||||
from Unicode (hex) 来自 Unicode(十六进制)
|
||||
Shape Effects 形状效果
|
||||
Glow 发光
|
||||
Soft Edges 柔化边缘
|
||||
|
|
|
|||
|
Can't render this file because it contains an unexpected character in line 6 and column 25.
|
|
|
@ -1088,6 +1088,89 @@
|
|||
Leave the equation (Esc) 離開方程式 (Esc)
|
||||
Preview 預覽
|
||||
getartcraft.com/apps/wordcraft getartcraft.com/apps/wordcraft
|
||||
|
||||
# Columns, Symbol and Field dialogs (#321).
|
||||
(All) (全部)
|
||||
(none) (無)
|
||||
(normal text) (一般文字)
|
||||
1/4 Em Space 1/4 全形空格
|
||||
A mail merge field 合併列印欄位
|
||||
A numbered sequence (figures, tables…) 編號序列(圖、表…)
|
||||
A table of contents 目錄
|
||||
Apply to: 套用至:
|
||||
Categories: 類別:
|
||||
Character 字元
|
||||
Character code: 字元代碼:
|
||||
Col #: 欄號:
|
||||
Copyright 著作權
|
||||
Date and Time 日期和時間
|
||||
Date formats: 日期格式:
|
||||
Description: 描述:
|
||||
Document Information 文件資訊
|
||||
Double Closing Quote 右雙引號
|
||||
Double Opening Quote 左雙引號
|
||||
Ellipsis 刪節號
|
||||
Em Dash 長破折號
|
||||
En Dash 短破折號
|
||||
Em Space 全形空格
|
||||
En Space 半形空格
|
||||
Equal column width 欄寬相等
|
||||
Field Codes 功能變數代碼
|
||||
Field code: 功能變數代碼:
|
||||
Field codes: 功能變數代碼:
|
||||
Field name: 功能變數名稱:
|
||||
Field names: 功能變數名稱清單:
|
||||
Field properties 功能變數屬性
|
||||
Field… 功能變數…
|
||||
Format: 格式:
|
||||
Hide Codes 隱藏代碼
|
||||
Index and Tables 索引和目錄
|
||||
Line between 分隔線
|
||||
Links and References 連結和參照
|
||||
Mail Merge 合併列印
|
||||
More Columns… 其他欄…
|
||||
More Symbols… 其他符號…
|
||||
No-Width Non Break 無寬度不分行
|
||||
No-Width Optional Break 無寬度選擇性分行
|
||||
Paragraph Mark 段落標記
|
||||
Pick a field from the list 請選擇功能變數
|
||||
Preserve formatting during updates 更新時保留格式設定
|
||||
Presets 預設集
|
||||
Recently used symbols: 最近使用的符號:
|
||||
Registered 註冊商標
|
||||
Section Mark 章節符號
|
||||
Sequence name: 序列名稱:
|
||||
Shortcut key: 快速鍵:
|
||||
Single Closing Quote 右單引號
|
||||
Single Opening Quote 左單引號
|
||||
Spacing: 間距:
|
||||
Special Characters 特殊字元
|
||||
Subset: 子集:
|
||||
The time right now 目前的時間
|
||||
When this document was first created 文件的建立日期
|
||||
When this document was most recently printed 文件的上次列印日期
|
||||
When this document was most recently saved 文件的上次儲存日期
|
||||
The document has no bookmarks yet. 文件中還沒有書籤。
|
||||
Who the document properties name as author 文件的作者
|
||||
Name of the file this document is saved as 文件的檔案名稱
|
||||
Title from the document properties 文件的標題
|
||||
How many pages the whole document has 文件的頁數
|
||||
How many pages this section has 本節的頁數
|
||||
Number of the page the field sits on 目前的頁碼
|
||||
Number of the section the field sits in 目前的節號
|
||||
How many words the document holds 文件的字數
|
||||
Page on which a bookmarked passage falls 書籤所在的頁碼
|
||||
Copy of the text a bookmark marks 書籤的文字
|
||||
This field has no options. 此功能變數沒有選項。
|
||||
This font has no characters to show. 此字型沒有可顯示的字元。
|
||||
This point forward 從這裡開始
|
||||
This section 本節
|
||||
The date it is today 今天的日期
|
||||
Trademark 商標
|
||||
Type the field's name and its switches, for example PAGE \\* roman. 輸入功能變數名稱及其參數,例如 PAGE \\* roman。
|
||||
Whole document 整份文件
|
||||
Width and spacing 寬度和間距
|
||||
from Unicode (hex) 來自 Unicode(十六進位)
|
||||
Shape Effects 圖案效果
|
||||
Glow 光暈
|
||||
Soft Edges 柔化邊緣
|
||||
|
|
|
|||
|
Can't render this file because it has a wrong number of fields in line 4.
|
|
|
@ -19,6 +19,7 @@ pub mod chrome;
|
|||
pub mod control;
|
||||
pub mod credits;
|
||||
pub mod dialogs;
|
||||
pub mod dialogs_insert;
|
||||
pub mod dialogs_lists;
|
||||
pub mod equation_tab;
|
||||
pub mod file_dialogs;
|
||||
|
|
@ -90,6 +91,8 @@ pub struct UiState {
|
|||
pub backstage_page: String,
|
||||
pub ribbon_collapsed: bool,
|
||||
pub recent: Vec<String>,
|
||||
/// Symbols inserted from the Symbol dialog, most recent first (#321).
|
||||
pub recent_symbols: Vec<dialogs_insert::RecentSymbol>,
|
||||
/// Interface theme: light, dark, or follow the OS appearance (#115).
|
||||
pub theme: theme::Appearance,
|
||||
/// The dark-mode switch `ui.json` held before `theme` (#115): read once to migrate, never written.
|
||||
|
|
@ -128,6 +131,7 @@ impl Default for UiState {
|
|||
backstage_page: "home".into(),
|
||||
ribbon_collapsed: false,
|
||||
recent: Vec::new(),
|
||||
recent_symbols: Vec::new(),
|
||||
theme: theme::Appearance::default(),
|
||||
legacy_dark: None,
|
||||
nav_tab: "headings".into(),
|
||||
|
|
@ -1066,8 +1070,8 @@ fn keeps_everything(name: &str) -> bool {
|
|||
/// The dialog a user-run command opens when it lacks the input it needs (scripts and agents get
|
||||
/// the command's own error or default instead): Select Recipients and Edit Recipient List without
|
||||
/// data, Insert Merge Field without a field, Find Recipient without text, the If and Skip
|
||||
/// Record If rules (or Rules with no rule at all) without a field, and Table Properties without
|
||||
/// settings.
|
||||
/// Record If rules (or Rules with no rule at all) without a field, Table Properties without
|
||||
/// settings, and Symbol and Field without a character or code.
|
||||
fn input_dialog(id: &str, params: &Value) -> Option<&'static str> {
|
||||
let has = |k: &str| params.get(k).is_some_and(|v| !v.is_null());
|
||||
let rule = params.get("rule").and_then(Value::as_str).map(str::to_ascii_uppercase);
|
||||
|
|
@ -1081,6 +1085,9 @@ fn input_dialog(id: &str, params: &Value) -> Option<&'static str> {
|
|||
"mailings.editRecipients" if !has("rows") => Some("recipientList"),
|
||||
"mailings.insertField" if !has("field") => Some("insertMergeField"),
|
||||
"mailings.findRecipient" if !has("text") => Some("findRecipient"),
|
||||
// Symbol without a character and Field without a code show their dialogs (#321).
|
||||
"insert.symbol" if !has("char") => Some("symbol"),
|
||||
"insert.field" if !has("instr") => Some("field"),
|
||||
// Table Properties without settings shows the dialog (with settings it applies them).
|
||||
"table.properties" if params.as_object().is_none_or(|m| m.is_empty()) => Some("tableProperties"),
|
||||
// `null` is an answer here: it removes the password.
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ impl Previews {
|
|||
})
|
||||
}
|
||||
|
||||
fn get_or(&mut self, ctx: &egui::Context, key: &str, make: impl FnOnce() -> Option<egui::ColorImage>) -> Option<TextureHandle> {
|
||||
pub(crate) fn get_or(&mut self, ctx: &egui::Context, key: &str, make: impl FnOnce() -> Option<egui::ColorImage>) -> Option<TextureHandle> {
|
||||
if let Some(t) = self.tex.get(key) {
|
||||
return Some(t.clone());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -586,7 +586,16 @@ fn insert(app: &mut WordApp, ui: &mut Ui) {
|
|||
group(ui, "Text", None, app, |ui, app| {
|
||||
big(ui, app, "textBox", "Text\nBox", "insert.textBox", json!({}), false);
|
||||
stack(ui, |ui| {
|
||||
small(ui, app, "quickParts", Some("Quick Parts"), "Quick Parts", "insert.quickParts", json!({}), false);
|
||||
menu_button(ui, app, "quickParts", Some("Quick Parts"), "Quick Parts", false, |ui, app| {
|
||||
let parts: Vec<String> = app.session.building_blocks.keys().cloned().collect();
|
||||
for name in parts {
|
||||
if ui.button(&name).clicked() {
|
||||
let _ = app.run("insert.quickParts", json!({"insert": name}));
|
||||
ui.close();
|
||||
}
|
||||
}
|
||||
mi(ui, app, "Field…", "ui.dialog", json!({"name": "field"}));
|
||||
});
|
||||
small(ui, app, "wordArt", Some("WordArt"), "WordArt", "insert.wordArt", json!({}), false);
|
||||
small(ui, app, "dropCap", Some("Drop Cap"), "Drop Cap", "insert.dropCap", json!({}), false);
|
||||
});
|
||||
|
|
@ -599,16 +608,26 @@ fn insert(app: &mut WordApp, ui: &mut Ui) {
|
|||
group(ui, "Symbols", None, app, |ui, app| {
|
||||
crate::equation_tab::insert_button(ui, app);
|
||||
menu_button(ui, app, "symbol", Some("Symbol"), "Symbol", true, |ui, app| {
|
||||
egui::Grid::new("syms").show(ui, |ui| {
|
||||
for (i, c) in [
|
||||
// Recently used symbols first (their font on hover), then common ones.
|
||||
let mut items: Vec<(String, String)> = app.ui.recent_symbols.iter().map(|r| (r.ch.clone(), r.font.clone())).collect();
|
||||
for c in [
|
||||
"©", "®", "™", "§", "¶", "€", "£", "¥", "°", "±", "≠", "≤", "≥", "÷", "×", "∞", "µ", "α", "β", "π", "Ω", "∑", "√", "→", "←", "✓",
|
||||
"★", "♥", "—", "…",
|
||||
]
|
||||
.iter()
|
||||
.enumerate()
|
||||
{
|
||||
if ui.button(egui::RichText::new(*c).size(16.0)).clicked() {
|
||||
let _ = app.run("insert.symbol", json!({"char": c}));
|
||||
] {
|
||||
if !items.iter().any(|(ch, f)| ch == c && f.is_empty()) {
|
||||
items.push((c.to_string(), String::new()));
|
||||
}
|
||||
}
|
||||
items.truncate(30);
|
||||
egui::Grid::new("syms").show(ui, |ui| {
|
||||
for (i, (c, font)) in items.iter().enumerate() {
|
||||
let b = ui.button(egui::RichText::new(c).size(16.0));
|
||||
let b = if font.is_empty() { b } else { b.on_hover_text(font) };
|
||||
if b.clicked() {
|
||||
let params = if font.is_empty() { json!({"char": c}) } else { json!({"char": c, "font": font}) };
|
||||
if app.run("insert.symbol", params).is_ok() {
|
||||
crate::dialogs_insert::remember_symbol(app, c, font);
|
||||
}
|
||||
ui.close();
|
||||
}
|
||||
if i % 6 == 5 {
|
||||
|
|
@ -616,6 +635,8 @@ fn insert(app: &mut WordApp, ui: &mut Ui) {
|
|||
}
|
||||
}
|
||||
});
|
||||
ui.separator();
|
||||
mi(ui, app, "More Symbols…", "ui.dialog", json!({"name": "symbol"}));
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -735,6 +756,8 @@ fn layout(app: &mut WordApp, ui: &mut Ui) {
|
|||
mi(ui, app, "Three", "layout.columns", json!({"count": 3}));
|
||||
mi(ui, app, "Left", "layout.columns", json!({"preset": "left"}));
|
||||
mi(ui, app, "Right", "layout.columns", json!({"preset": "right"}));
|
||||
ui.separator();
|
||||
mi(ui, app, "More Columns…", "ui.dialog", json!({"name": "columns"}));
|
||||
});
|
||||
stack(ui, |ui| {
|
||||
menu_button(ui, app, "breaks", Some("Breaks"), "Breaks", false, |ui, app| {
|
||||
|
|
|
|||
|
|
@ -17,6 +17,7 @@ first (`gh pr list`), and update this file and the parity doc when a gap closes.
|
|||
| 4 | **Pagination differs from Word**: Aptos has no metric-matched substitute; columns don't balance; custom footnote continuation separators and notices aren't read; legacy compatibility options ignored; no page-by-page comparison harness | B | [layout-parity.md](layout-parity.md); [typing-parity.md](typing-parity.md) Known gaps | Page counts and line breaks differ, which matters for forms, legal and academic work | 30–50 + owner (font) | [layout-parity.md](layout-parity.md) |
|
||||
| 5 | **Formatting revisions, move tracking and content controls** are lost (`w:rPrChange`/`w:pPrChange` absent; `w:sdt` unwrapped) | B | Issue #41; source grep | Legal and editorial review workflows; templates with form controls | 12–18 | [file-format-parity.md](file-format-parity.md) |
|
||||
| 6 | **No native printing** on desktop: File › Print opens the PDF in the system viewer, which prints (#286); no print dialog of our own (printer, copies, ranges); web prints through the browser (#209) | B | `ui.print` → `apps/wordcraft/src/print.rs`; issue #15 | Everyone who prints | 5–8 | [hardware-parity.md](hardware-parity.md) |
|
||||
| 7 | **Dialog depth**: 19 modal dialogs vs Word's ~100 (Tabs, Borders and Shading, Define Multilevel List, Track Changes Options, Options panes…) | B | `Dialog` enum in `crates/ui-egui/src/dialogs.rs` | Power users reach for dialogs the ribbon alone doesn't cover | 20–30 | [ui-parity.md](ui-parity.md) |
|
||||
| 7 | **Dialog depth**: 18 modal dialogs vs Word's ~100 (Tabs, Borders and Shading, Columns, Symbol, Field, Options panes…) | B | `Dialog` enum in `crates/ui-egui/src/dialogs.rs` | Power users reach for dialogs the ribbon alone doesn't cover | 20–30 | [ui-parity.md](ui-parity.md) |
|
||||
| 8 | **Proofing is English only**; no language per run, no dictionaries for other languages | | `crates/proof` has one dictionary; Word ships 120 proofing tools; issues #25, #40, #100 | Every non-English writer | 25–45 | [localization-parity.md](localization-parity.md) |
|
||||
| 9 | **Password-protected files** can't be opened or saved | | #55; `docbin` detects and refuses RC4/XOR | Corporate and legal users | 6–10 | [file-format-parity.md](file-format-parity.md) |
|
||||
|
|
@ -64,6 +65,7 @@ The same gaps grouped the way the parity documents are, for agents working in on
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-10 | trivial | Columns, Symbol and Field dialogs landed (#321); removed from the dialog-depth list |
|
||||
| 2026-10-10 | trivial | #2 narrowed: charts and SmartArt drawn (#292), and with OLE objects kept on save (#319); group shapes landed (#267); ink and drawing canvases remain |
|
||||
| 2026-10-10 | trivial | #4: long footnotes continue onto the next page (#352) |
|
||||
| 2026-10-10 | trivial | Define New Multilevel List and Track Changes Options dialogs landed (#328); removed from the dialog-depth list |
|
||||
|
|
|
|||
|
|
@ -16,6 +16,7 @@ own (`AGENTS.md`: no Microsoft iconography, ever).
|
|||
| Quick Access Toolbar | Undo, Redo, Repeat, AutoSave | customizable | 50% | 2–3 |
|
||||
| Customize Ribbon / Customize Keyboard | ❌ | ✅ | 0% | 6–10 |
|
||||
| Keyboard shortcuts | **101** bound in `CommandSpec::key` (measured) | ~250 default shortcuts | ~60% | 4–6 |
|
||||
| Modal dialogs | **20** (`Dialog` enum: Font, Paragraph, Find, Go To, Insert Table, Table Properties, Page Setup, Link, Bookmark, Word Count, Zoom, Watermark, New/Modify Style, Commands, About, Save Changes; Columns, Symbol with Special Characters, Field (#321)) plus panes and menus for the rest | ~100 (Tabs, Borders and Shading, Caption, Index, TOC options, Citation, Define Multilevel List, Track Changes Options, Compare, Protect, Language, Hyphenation, Line Numbers, Envelopes, Labels, Mail Merge, AutoCorrect, Options panes…) | ~40% | 20–30 |
|
||||
| Modal dialogs | **19** (`Dialog` enum: Font, Paragraph, Find, Go To, Insert Table, Table Properties, Page Setup, Link, Bookmark, Word Count, Zoom, Watermark, New/Modify Style, Commands, About, Save Changes, Define New Multilevel List, Track Changes Options) plus panes and menus for the rest | ~100 (Tabs, Borders and Shading, Columns, Symbol, Field, Caption, Index, TOC options, Citation, Compare, Protect, Language, Hyphenation, Line Numbers, Envelopes, Labels, Mail Merge, AutoCorrect, Options panes…) | ~40% | 20–30 |
|
||||
| Task panes (Navigation, Styles, Comments, Reviewing, Format Picture/Shape, Thesaurus, Accessibility, Clipboard, Selection) | Navigation, Styles, Comments, Thesaurus, Accessibility, Read Aloud, Zotero; Style Inspector (#236); Clipboard pane (#264) open | all | 70% | 4–6 |
|
||||
| Context menus (right-click) | text, spelling suggestions; objects and tables partial | rich per context | 55% | 3–5 |
|
||||
|
|
@ -36,6 +37,7 @@ own (`AGENTS.md`: no Microsoft iconography, ever).
|
|||
|
||||
| Date | Change | Summary |
|
||||
|---|---|---|
|
||||
| 2026-10-10 | trivial | Columns (presets, unequal widths, line between, apply to), Symbol (font coverage grid by Unicode subset, recently used, character code, Special Characters) and Field (categories, options, field codes) dialogs (#321) |
|
||||
| 2026-10-10 | trivial | Define New Multilevel List (all nine levels, live preview, `list.define`) and Track Changes Options (show, balloons, insertion/deletion marks and colours, changed-line bars; `review.trackingOptions`, saved per user) (#328) |
|
||||
| 2026-10-10 | trivial | Rotation handle on pictures, shapes and text boxes; Rotate menu (90° and flips) and a Rotation box in Picture/Shape Format › Size (#332) |
|
||||
| 2026-10-10 | trivial | System interface theme keeps following OS appearance changes (no longer pins the macOS window); Dark page no longer darkens the interface (#311, #312) |
|
||||
|
|
|
|||
Loading…
Reference in New Issue