use std::cell::RefCell; use std::collections::BTreeSet; use std::rc::Rc; #[derive(Default, Clone)] pub(crate) struct WorkbookSheetProperties { inner: Rc>, } impl WorkbookSheetProperties { pub(crate) fn set_selected(&mut self, index: usize, selected: bool) { self.inner.borrow_mut().set_selected(index, selected); } pub(crate) fn selected(&self, index: usize) -> bool { self.inner.borrow().selected(index) } pub(crate) fn set_hidden(&mut self, index: usize, hidden: bool) { self.inner.borrow_mut().set_hidden(index, hidden); } pub(crate) fn hidden(&self, index: usize) -> bool { self.inner.borrow().hidden(index) } pub(crate) fn set_active(&self, index: usize) { self.inner.borrow_mut().set_active(index) } pub(crate) fn active(&self, index: usize) -> bool { self.inner.borrow().active(index) } } #[derive(Default)] struct Inner { active: Option, selected: BTreeSet, hidden: BTreeSet, count: usize, } impl Inner { fn set_selected(&mut self, index: usize, selected: bool) { if selected { self.selected.insert(index); } else { self.selected.remove(&index); } } fn selected(&self, index: usize) -> bool { if self.selected.is_empty() { self.automatic_active() == index } else { self.selected.contains(&index) } } fn set_hidden(&mut self, index: usize, hidden: bool) { if hidden { self.hidden.insert(index); } else { self.hidden.remove(&index); } } fn hidden(&self, index: usize) -> bool { self.hidden.contains(&index) && !self.selected(index) && !self.active(index) } fn active(&self, index: usize) -> bool { match self.active { Some(i) if i == index => true, Some(_) => false, None if index == self.automatic_active() => true, None => false, } } fn set_active(&mut self, index: usize) { self.active = Some(index); } fn automatic_active(&self) -> usize { if let Some(i) = self.active { i } else { // none was selected yet, so we'll find the first that // is not hidden. for i in 0usize..self.count { if !self.hidden.contains(&i) { return i; } } // all sheets are hidden, so the first one is interpreted // as active, it will be unhidden automatically. 0usize } } }