use crate::docx::SectionPage;
use crate::font::Fonts;
use super::Editor;
use super::commands::Outcome;
use super::position::StoryId;
use super::step::Step;
#[derive(Clone, Debug, PartialEq)]
pub enum SectionCmd {
Margins([f64; 4]),
Orientation(bool),
Size(f64, f64),
Columns(usize),
DifferentFirst,
Page(SectionPage),
}
impl Editor {
pub(super) fn focus_section(&self) -> usize {
let Some(focus) = self.selection.focus() else { return 0 };
match focus.story {
StoryId::HeaderFooter(k) => {
let name = self.index.part_name(k);
self.doc
.sections
.iter()
.position(|s| s.headers.iter().chain(s.footers.iter()).flatten().any(|n| Some(n.as_str()) == name))
.unwrap_or(0)
}
_ => focus
.para_offset()
.and_then(|(p, _)| self.index.para_slot(p))
.and_then(|s| self.index.top_block(s.container, s.block))
.map_or(0, |(sec, _, _)| sec),
}
}
pub(super) fn section_cmd(&mut self, c: SectionCmd, fonts: &Fonts) -> Outcome {
let section = self.focus_section();
let Some(s) = self.doc.sections.get(section) else { return Outcome::Unchanged("no section") };
let mut page = s.page();
let label = match c {
SectionCmd::Margins([t, b, l, r]) => {
(page.top, page.bottom, page.left, page.right) = (t, b, l, r);
"Margins"
}
SectionCmd::Orientation(landscape) => {
if (page.page_w > page.page_h) != landscape {
(page.page_w, page.page_h) = (page.page_h, page.page_w);
(page.top, page.right, page.bottom, page.left) = (page.left, page.top, page.right, page.bottom);
}
"Orientation"
}
SectionCmd::Size(w, h) => {
let landscape = page.page_w > page.page_h;
(page.page_w, page.page_h) = if landscape { (w.max(h), w.min(h)) } else { (w.min(h), w.max(h)) };
"Size"
}
SectionCmd::Columns(n) => {
page.columns = crate::docx::Columns {
num: n.clamp(1, 45),
equal: true,
cols: Vec::new(),
space: if page.columns.space > 0.0 { page.columns.space } else { 36.0 },
separator: page.columns.separator,
};
"Columns"
}
SectionCmd::DifferentFirst => {
page.title_pg = !page.title_pg;
"Different First Page"
}
SectionCmd::Page(p) => {
page = p;
"Page Setup"
}
};
if page == s.page() {
return Outcome::Unchanged("already so");
}
let mut tx = self.begin(label);
if self.step(&mut tx, Step::SectionPage { section, page }).is_err() {
self.abort(tx);
return Outcome::Unchanged("no section");
}
self.commit(tx, None, fonts)
}
}