1use get_size2::GetSize;
6use std::collections::{BTreeMap, Bound};
7use std::fmt::{Debug, Display, Formatter};
8use std::iter::FusedIterator;
9use std::ops::RangeBounds;
10use std::{fmt, mem};
11
12use crate::cell_::{CellContent, CellContentRef, CellData};
13use crate::draw::{Annotation, DrawFrame};
14use crate::style::{ColStyleRef, RowStyleRef, TableStyleRef};
15use crate::validation::ValidationRef;
16use crate::value_::Value;
17use crate::xmltree::XmlTag;
18use crate::{CellRange, CellStyleRef, Length, OdsError};
19
20#[cfg(test)]
21mod tests;
22
23#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, GetSize)]
25#[allow(missing_docs)]
26pub enum Visibility {
27 #[default]
28 Visible,
29 Collapsed,
30 Filtered,
31}
32
33impl Display for Visibility {
34 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
35 match self {
36 Visibility::Visible => write!(f, "visible"),
37 Visibility::Collapsed => write!(f, "collapse"),
38 Visibility::Filtered => write!(f, "filter"),
39 }
40 }
41}
42
43#[derive(Debug, Clone, GetSize)]
45pub(crate) struct RowHeader {
46 pub(crate) style: Option<RowStyleRef>,
47 pub(crate) cellstyle: Option<CellStyleRef>,
48 pub(crate) visible: Visibility,
49 pub(crate) repeat: u32,
57 pub(crate) span: u32,
60 pub(crate) height: Length,
61}
62
63impl Default for RowHeader {
64 fn default() -> Self {
65 Self {
66 style: None,
67 cellstyle: None,
68 visible: Default::default(),
69 repeat: 1,
70 span: 1,
71 height: Default::default(),
72 }
73 }
74}
75
76#[derive(Debug, Clone, GetSize)]
78pub(crate) struct ColHeader {
79 pub(crate) style: Option<ColStyleRef>,
80 pub(crate) cellstyle: Option<CellStyleRef>,
81 pub(crate) visible: Visibility,
82 pub(crate) width: Length,
83 pub(crate) span: u32,
86}
87
88impl Default for ColHeader {
89 fn default() -> Self {
90 Self {
91 style: None,
92 cellstyle: None,
93 visible: Default::default(),
94 width: Default::default(),
95 span: 1,
96 }
97 }
98}
99
100#[derive(Clone, Default, GetSize)]
106pub struct Sheet {
107 pub(crate) name: String,
108 pub(crate) style: Option<TableStyleRef>,
109
110 pub(crate) data: BTreeMap<(u32, u32), CellData>,
111
112 pub(crate) col_header: BTreeMap<u32, ColHeader>,
113 pub(crate) row_header: BTreeMap<u32, RowHeader>,
114
115 pub(crate) display: bool,
116 pub(crate) print: bool,
117
118 pub(crate) header_rows: Option<Header>,
119 pub(crate) header_cols: Option<Header>,
120 pub(crate) print_ranges: Option<Vec<CellRange>>,
121
122 pub(crate) group_rows: Vec<Grouped>,
123 pub(crate) group_cols: Vec<Grouped>,
124
125 pub(crate) sheet_config: SheetConfig,
126
127 pub(crate) extra: Vec<XmlTag>,
128}
129
130impl<'a> IntoIterator for &'a Sheet {
131 type Item = ((u32, u32), CellContentRef<'a>);
132 type IntoIter = CellIter<'a>;
133
134 fn into_iter(self) -> Self::IntoIter {
135 CellIter {
136 iter: self.data.iter(),
137 k_data: None,
138 v_data: None,
139 }
140 }
141}
142
143#[derive(Debug)]
145pub(crate) struct CellDataIter<'a> {
146 iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
147 k_data: Option<&'a (u32, u32)>,
148 v_data: Option<&'a CellData>,
149}
150
151impl<'a> CellDataIter<'a> {
152 pub(crate) fn new(iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>) -> Self {
153 Self {
154 iter,
155 k_data: None,
156 v_data: None,
157 }
158 }
159
160 #[allow(dead_code)]
162 pub(crate) fn peek_cell(&mut self) -> Option<(u32, u32)> {
163 self.k_data.copied()
164 }
165
166 fn load_next_data(&mut self) {
167 if let Some((k, v)) = self.iter.next() {
168 self.k_data = Some(k);
169 self.v_data = Some(v);
170 } else {
171 self.k_data = None;
172 self.v_data = None;
173 }
174 }
175}
176
177impl FusedIterator for CellDataIter<'_> {}
178
179impl<'a> Iterator for CellDataIter<'a> {
180 type Item = ((u32, u32), &'a CellData);
181
182 fn next(&mut self) -> Option<Self::Item> {
183 if self.k_data.is_none() {
184 self.load_next_data();
185 }
186
187 if let Some(k_data) = self.k_data {
188 if let Some(v_data) = self.v_data {
189 let r = Some((*k_data, v_data));
190 self.load_next_data();
191 r
192 } else {
193 None
194 }
195 } else {
196 None
197 }
198 }
199
200 fn size_hint(&self) -> (usize, Option<usize>) {
201 self.iter.size_hint()
202 }
203}
204
205#[derive(Debug)]
207pub(crate) struct CellDataIterMut<'a> {
208 iter: std::collections::btree_map::RangeMut<'a, (u32, u32), CellData>,
209 k_data: Option<&'a (u32, u32)>,
210 v_data: Option<&'a mut CellData>,
211}
212
213impl<'a> CellDataIterMut<'a> {
214 pub(crate) fn new(
215 iter: std::collections::btree_map::RangeMut<'a, (u32, u32), CellData>,
216 ) -> Self {
217 Self {
218 iter,
219 k_data: None,
220 v_data: None,
221 }
222 }
223
224 pub(crate) fn peek_cell(&mut self) -> Option<(u32, u32)> {
226 self.k_data.copied()
227 }
228
229 fn load_next_data(&mut self) {
230 if let Some((k, v)) = self.iter.next() {
231 self.k_data = Some(k);
232 self.v_data = Some(v);
233 } else {
234 self.k_data = None;
235 self.v_data = None;
236 }
237 }
238}
239
240impl FusedIterator for CellDataIterMut<'_> {}
241
242impl<'a> Iterator for CellDataIterMut<'a> {
243 type Item = ((u32, u32), &'a mut CellData);
244
245 fn next(&mut self) -> Option<Self::Item> {
246 if self.k_data.is_none() {
247 self.load_next_data();
248 }
249
250 if let Some(k_data) = self.k_data {
251 if let Some(v_data) = self.v_data.take() {
252 let r = Some((*k_data, v_data));
253 self.load_next_data();
254 r
255 } else {
256 None
257 }
258 } else {
259 None
260 }
261 }
262
263 fn size_hint(&self) -> (usize, Option<usize>) {
264 self.iter.size_hint()
265 }
266}
267
268#[derive(Clone, Debug)]
270pub struct CellIter<'a> {
271 iter: std::collections::btree_map::Iter<'a, (u32, u32), CellData>,
272 k_data: Option<&'a (u32, u32)>,
273 v_data: Option<&'a CellData>,
274}
275
276impl CellIter<'_> {
277 pub fn peek_cell(&mut self) -> Option<(u32, u32)> {
279 self.k_data.copied()
280 }
281
282 fn load_next_data(&mut self) {
283 if let Some((k, v)) = self.iter.next() {
284 self.k_data = Some(k);
285 self.v_data = Some(v);
286 } else {
287 self.k_data = None;
288 self.v_data = None;
289 }
290 }
291}
292
293impl FusedIterator for CellIter<'_> {}
294
295impl<'a> Iterator for CellIter<'a> {
296 type Item = ((u32, u32), CellContentRef<'a>);
297
298 fn next(&mut self) -> Option<Self::Item> {
299 if self.k_data.is_none() {
300 self.load_next_data();
301 }
302
303 if let Some(k_data) = self.k_data {
304 if let Some(v_data) = self.v_data {
305 let r = Some((*k_data, v_data.cell_content_ref()));
306 self.load_next_data();
307 r
308 } else {
309 None
310 }
311 } else {
312 None
313 }
314 }
315
316 fn size_hint(&self) -> (usize, Option<usize>) {
317 self.iter.size_hint()
318 }
319}
320
321struct IterRows<'a> {
322 iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
323 start: (u32, u32),
324 end: (u32, u32),
325 hint: usize,
326}
327
328impl<'a> IterRows<'a> {
329 fn new<R: RangeBounds<(u32, u32)>>(sheet: &'a Sheet, range: R) -> Self {
330 let start = match range.start_bound() {
331 Bound::Included((r, c)) => (*r, *c),
332 Bound::Excluded((r, c)) => (r + 1, c + 1),
333 Bound::Unbounded => (0, 0),
334 };
335 let end = match range.end_bound() {
336 Bound::Included((r, c)) => (r + 1, c + 1),
337 Bound::Excluded((r, c)) => (*r, *c),
338 Bound::Unbounded => sheet.used_grid_size(),
339 };
340
341 Self {
342 iter: sheet.data.range(range),
343 start,
344 end,
345 hint: (end.0 - start.0) as usize * (end.1 * start.1) as usize,
346 }
347 }
348}
349
350impl FusedIterator for IterRows<'_> {}
351
352impl<'a> Iterator for IterRows<'a> {
353 type Item = ((u32, u32), CellContentRef<'a>);
354
355 fn next(&mut self) -> Option<Self::Item> {
356 loop {
357 if let Some(((r, c), d)) = self.iter.next() {
358 if *r < self.end.0 && *c >= self.start.1 && *c < self.end.1 {
359 return Some(((*r, *c), d.cell_content_ref()));
360 }
361 } else {
362 return None;
363 }
364 }
365 }
366
367 fn size_hint(&self) -> (usize, Option<usize>) {
368 (0, Some(self.hint))
369 }
370}
371
372struct IterCols<'a> {
373 sheet: &'a Sheet,
374 start: (u32, u32),
375 end: (u32, u32),
376 cell: (u32, u32),
377}
378
379impl Debug for IterCols<'_> {
380 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
381 f.debug_struct("IterCols")
382 .field("start", &self.start)
383 .field("end", &self.end)
384 .field("cell", &self.cell)
385 .finish()
386 }
387}
388
389impl FusedIterator for IterCols<'_> {}
390
391impl<'a> IterCols<'a> {
392 fn new<R: RangeBounds<(u32, u32)>>(sheet: &'a Sheet, range: R) -> Self {
393 let start = match range.start_bound() {
394 Bound::Included((r, c)) => (*r, *c),
395 Bound::Excluded((r, c)) => (r + 1, c + 1),
396 Bound::Unbounded => (0, 0),
397 };
398 let end = match range.end_bound() {
399 Bound::Included((r, c)) => (r + 1, c + 1),
400 Bound::Excluded((r, c)) => (*r, *c),
401 Bound::Unbounded => sheet.used_grid_size(),
402 };
403
404 Self {
405 sheet,
406 start,
407 end,
408 cell: start,
409 }
410 }
411}
412
413impl<'a> Iterator for IterCols<'a> {
414 type Item = ((u32, u32), CellContentRef<'a>);
415
416 #[allow(clippy::comparison_chain)]
417 fn next(&mut self) -> Option<Self::Item> {
418 if self.cell.0 == self.end.0 && self.cell.1 == self.end.1 {
419 return None;
420 }
421
422 loop {
423 let r = self.cell.0;
424 let c = self.cell.1;
425 let d = self.sheet.cell_ref(self.cell.0, self.cell.1);
426
427 if self.cell.0 + 1 < self.end.0 {
428 self.cell.0 += 1;
429 } else if self.cell.0 + 1 == self.end.0 {
430 if self.cell.1 + 1 < self.end.1 {
431 self.cell.0 = self.start.0;
432 self.cell.1 += 1;
433 } else if self.cell.1 + 1 == self.end.1 {
434 self.cell.0 += 1;
435 self.cell.1 += 1;
436 } else {
437 assert_eq!(self.cell, self.end);
438 }
439 } else {
440 assert_eq!(self.cell, self.end);
441 }
442
443 if let Some(d) = d {
444 return Some(((r, c), d));
445 }
446 }
447 }
448
449 fn size_hint(&self) -> (usize, Option<usize>) {
450 (
451 0,
452 Some((self.end.0 - self.start.0) as usize * (self.end.1 - self.start.1) as usize),
453 )
454 }
455}
456
457#[derive(Clone, Debug)]
459pub struct Range<'a> {
460 range: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
461}
462
463impl FusedIterator for Range<'_> {}
464
465impl<'a> Iterator for Range<'a> {
466 type Item = ((u32, u32), CellContentRef<'a>);
467
468 fn next(&mut self) -> Option<Self::Item> {
469 if let Some((k, v)) = self.range.next() {
470 Some((*k, v.cell_content_ref()))
471 } else {
472 None
473 }
474 }
475
476 fn size_hint(&self) -> (usize, Option<usize>) {
477 self.range.size_hint()
478 }
479}
480
481impl DoubleEndedIterator for Range<'_> {
482 fn next_back(&mut self) -> Option<Self::Item> {
483 if let Some((k, v)) = self.range.next_back() {
484 Some((*k, v.cell_content_ref()))
485 } else {
486 None
487 }
488 }
489}
490
491impl ExactSizeIterator for Range<'_> {}
492
493impl Debug for Sheet {
494 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
495 writeln!(f, "name {:?} style {:?}", self.name, self.style)?;
496 for (k, v) in self.data.iter() {
497 writeln!(f, " data {:?} {:?}", k, v)?;
498 }
499 for (k, v) in &self.col_header {
500 writeln!(f, "{:?} {:?}", k, v)?;
501 }
502 for (k, v) in &self.row_header {
503 writeln!(f, "{:?} {:?}", k, v)?;
504 }
505 if let Some(header_rows) = &self.header_rows {
506 writeln!(f, "header rows {:?}", header_rows)?;
507 }
508 if let Some(header_cols) = &self.header_cols {
509 writeln!(f, "header cols {:?}", header_cols)?;
510 }
511 for v in &self.group_cols {
512 writeln!(f, "group cols {:?}", v)?;
513 }
514 for v in &self.group_rows {
515 writeln!(f, "group rows {:?}", v)?;
516 }
517 for xtr in &self.extra {
518 writeln!(f, "extras {:?}", xtr)?;
519 }
520 Ok(())
521 }
522}
523
524impl Sheet {
525 #[deprecated]
527 pub fn new_with_name<S: Into<String>>(name: S) -> Self {
528 Self::new(name)
529 }
530
531 pub fn new<S: Into<String>>(name: S) -> Self {
541 Sheet {
542 name: name.into(),
543 data: BTreeMap::new(),
544 col_header: Default::default(),
545 style: None,
546 header_rows: None,
547 header_cols: None,
548 print_ranges: None,
549 group_rows: Default::default(),
550 group_cols: Default::default(),
551 sheet_config: Default::default(),
552 extra: vec![],
553 row_header: Default::default(),
554 display: true,
555 print: true,
556 }
557 }
558
559 pub fn clone_no_data(&self) -> Self {
561 Self {
562 name: self.name.clone(),
563 style: self.style.clone(),
564 data: Default::default(),
565 col_header: self.col_header.clone(),
566 row_header: self.row_header.clone(),
567 display: self.display,
568 print: self.print,
569 header_rows: self.header_rows,
570 header_cols: self.header_cols,
571 print_ranges: self.print_ranges.clone(),
572 group_rows: self.group_rows.clone(),
573 group_cols: self.group_cols.clone(),
574 sheet_config: Default::default(),
575 extra: self.extra.clone(),
576 }
577 }
578
579 pub fn iter(&self) -> CellIter<'_> {
581 self.into_iter()
582 }
583
584 pub fn cell_count(&self) -> usize {
586 self.data.len()
587 }
588
589 pub fn iter_rows<R: RangeBounds<(u32, u32)>>(
594 &self,
595 range: R,
596 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
597 IterRows::new(self, range)
598 }
599
600 pub fn iter_cols<R: RangeBounds<(u32, u32)>>(
605 &self,
606 range: R,
607 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
608 IterCols::new(self, range)
609 }
610
611 pub fn range<R: RangeBounds<(u32, u32)>>(
613 &self,
614 range: R,
615 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
616 Range {
617 range: self.data.range(range),
618 }
619 }
620
621 pub fn set_name<V: Into<String>>(&mut self, name: V) {
623 self.name = name.into();
624 }
625
626 pub fn name(&self) -> &String {
628 &self.name
629 }
630
631 pub fn config(&self) -> &SheetConfig {
633 &self.sheet_config
634 }
635
636 pub fn config_mut(&mut self) -> &mut SheetConfig {
638 &mut self.sheet_config
639 }
640
641 pub fn set_style(&mut self, style: &TableStyleRef) {
643 self.style = Some(style.clone())
644 }
645
646 pub fn style(&self) -> Option<&TableStyleRef> {
648 self.style.as_ref()
649 }
650
651 pub(crate) fn valid_col_header(&self, col: u32) -> Option<&ColHeader> {
653 if let Some((base_col, col_header)) = self.col_header.range(..=col).last() {
654 if (*base_col..*base_col + col_header.span).contains(&col) {
655 Some(col_header)
656 } else {
657 None
658 }
659 } else {
660 None
661 }
662 }
663
664 #[allow(clippy::comparison_chain)]
668 fn create_split_col_header(&mut self, col: u32) -> &mut ColHeader {
669 if self.col_header.get(&col).filter(|v| v.span == 1).is_none() {
671 let mut col_col = None;
672 let mut left_hdr = None;
673 let mut split_hdr = None;
674 let mut right_hdr = None;
675
676 for (base_col, col_header) in &self.col_header {
677 if col >= *base_col && col < base_col + col_header.span {
678 col_col = Some(*base_col);
680
681 let left_span = col - *base_col;
683 if left_span > 0 {
684 let mut tmp = col_header.clone();
685 tmp.span = left_span;
686 left_hdr = Some((*base_col, tmp));
687 }
688
689 split_hdr = Some((col, col_header.clone()));
690
691 let right_span = (*base_col + col_header.span) - (col + 1);
692 if right_span > 0 {
693 let mut tmp = col_header.clone();
694 tmp.span = right_span;
695 right_hdr = Some((col + 1, tmp));
696 }
697
698 break;
699 }
700 }
701
702 if let Some(col_col) = col_col {
703 self.col_header.remove(&col_col);
705
706 if let Some(left_hdr) = left_hdr {
707 self.col_header.insert(left_hdr.0, left_hdr.1);
708 }
709 if let Some(split_hdr) = split_hdr {
710 self.col_header.insert(split_hdr.0, split_hdr.1);
711 }
712 if let Some(right_hdr) = right_hdr {
713 self.col_header.insert(right_hdr.0, right_hdr.1);
714 }
715 } else {
716 self.col_header.insert(col, ColHeader::default());
718 }
719 } else {
720 }
722
723 self.col_header.get_mut(&col).expect("col-header")
724 }
725
726 pub fn set_colstyle(&mut self, col: u32, style: &ColStyleRef) {
728 self.create_split_col_header(col).style = Some(style.clone());
729 }
730
731 pub fn clear_colstyle(&mut self, col: u32) {
733 self.create_split_col_header(col).style = None;
734 }
735
736 pub fn colstyle(&self, col: u32) -> Option<&ColStyleRef> {
738 if let Some(col_header) = self.valid_col_header(col) {
739 col_header.style.as_ref()
740 } else {
741 None
742 }
743 }
744
745 pub fn set_col_cellstyle(&mut self, col: u32, style: &CellStyleRef) {
747 self.create_split_col_header(col).cellstyle = Some(style.clone());
748 }
749
750 pub fn clear_col_cellstyle(&mut self, col: u32) {
752 self.create_split_col_header(col).cellstyle = None;
753 }
754
755 pub fn col_cellstyle(&self, col: u32) -> Option<&CellStyleRef> {
757 if let Some(col_header) = self.valid_col_header(col) {
758 col_header.cellstyle.as_ref()
759 } else {
760 None
761 }
762 }
763
764 pub fn set_col_visible(&mut self, col: u32, visible: Visibility) {
766 self.create_split_col_header(col).visible = visible;
767 }
768
769 pub fn col_visible(&self, col: u32) -> Visibility {
771 if let Some(col_header) = self.valid_col_header(col) {
772 col_header.visible
773 } else {
774 Default::default()
775 }
776 }
777
778 pub fn _set_col_header_span(&mut self, col: u32, span: u32) {
780 self.create_split_col_header(col).span = span
781 }
782
783 pub fn _col_header_span(&self, col: u32) -> u32 {
785 if let Some(col_header) = self.valid_col_header(col) {
786 col_header.span
787 } else {
788 Default::default()
789 }
790 }
791
792 pub fn set_col_width(&mut self, col: u32, width: Length) {
794 self.create_split_col_header(col).width = width;
795 }
796
797 pub fn col_width(&self, col: u32) -> Length {
799 if let Some(ch) = self.valid_col_header(col) {
800 ch.width
801 } else {
802 Length::Default
803 }
804 }
805
806 pub(crate) fn valid_row_header(&self, row: u32) -> Option<&RowHeader> {
808 if let Some((base_row, row_header)) = self.row_header.range(..=row).last() {
809 if (*base_row..*base_row + row_header.span).contains(&row) {
810 Some(row_header)
811 } else {
812 None
813 }
814 } else {
815 None
816 }
817 }
818
819 #[allow(clippy::comparison_chain)]
823 fn create_split_row_header(&mut self, row: u32) -> &mut RowHeader {
824 let mut cloned = Vec::new();
825
826 if let Some((base_row, row_header)) = self.row_header.range_mut(..=row).last() {
827 if (*base_row..*base_row + row_header.span).contains(&row) {
828 let base_span = row_header.span;
829
830 if *base_row < row {
837 row_header.span = row - *base_row;
838
839 let mut clone = row_header.clone();
840 clone.span = 1;
841 cloned.push((row, clone));
842 } else if *base_row == row {
843 row_header.span = 1;
844 } else {
845 unreachable!();
846 }
847
848 if *base_row + base_span > row {
850 let mut clone = row_header.clone();
851 clone.span = *base_row + base_span - (row + 1);
852 cloned.push((row + 1, clone));
853 } else if *base_row + base_span == row {
854 } else {
856 unreachable!();
857 }
858 } else {
859 self.row_header.insert(row, RowHeader::default());
860 }
861 } else {
862 self.row_header.insert(row, RowHeader::default());
863 }
864
865 for (r, rh) in cloned {
866 self.row_header.insert(r, rh);
867 }
868
869 self.row_header.get_mut(&row).expect("row-header")
870 }
871
872 pub fn _row_header_span(&self, row: u32) -> Option<u32> {
874 self.row_header.get(&row).map(|v| v.span)
875 }
876
877 pub fn _set_row_header_span(&mut self, row: u32, span: u32) {
879 if let Some(row_header) = self.row_header.get_mut(&row) {
880 row_header.span = span;
881 }
882 }
883
884 pub fn set_rowstyle(&mut self, row: u32, style: &RowStyleRef) {
886 self.create_split_row_header(row).style = Some(style.clone());
887 }
888
889 pub fn clear_rowstyle(&mut self, row: u32) {
891 self.create_split_row_header(row).style = None;
892 }
893
894 pub fn rowstyle(&self, row: u32) -> Option<&RowStyleRef> {
896 if let Some(row_header) = self.valid_row_header(row) {
897 row_header.style.as_ref()
898 } else {
899 None
900 }
901 }
902
903 pub fn set_row_cellstyle(&mut self, row: u32, style: &CellStyleRef) {
905 self.create_split_row_header(row).cellstyle = Some(style.clone());
906 }
907
908 pub fn clear_row_cellstyle(&mut self, row: u32) {
910 self.create_split_row_header(row).cellstyle = None;
911 }
912
913 pub fn row_cellstyle(&self, row: u32) -> Option<&CellStyleRef> {
915 if let Some(row_header) = self.valid_row_header(row) {
916 row_header.cellstyle.as_ref()
917 } else {
918 None
919 }
920 }
921
922 pub fn set_row_visible(&mut self, row: u32, visible: Visibility) {
924 self.create_split_row_header(row).visible = visible;
925 }
926
927 pub fn row_visible(&self, row: u32) -> Visibility {
929 if let Some(row_header) = self.valid_row_header(row) {
930 row_header.visible
931 } else {
932 Default::default()
933 }
934 }
935
936 pub fn set_row_repeat(&mut self, row: u32, repeat: u32) {
945 assert!(repeat > 0);
946 self.create_split_row_header(row).repeat = repeat
947 }
948
949 pub fn row_repeat(&self, row: u32) -> u32 {
951 if let Some(row_header) = self.valid_row_header(row) {
952 row_header.repeat
953 } else {
954 Default::default()
955 }
956 }
957
958 pub fn set_row_height(&mut self, row: u32, height: Length) {
960 self.create_split_row_header(row).height = height;
961 }
962
963 pub fn row_height(&self, row: u32) -> Length {
965 if let Some(rh) = self.valid_row_header(row) {
966 rh.height
967 } else {
968 Length::Default
969 }
970 }
971
972 pub fn _col_header_len(&self) -> usize {
974 self.col_header.len()
975 }
976
977 pub fn _row_header_len(&self) -> usize {
979 self.row_header.len()
980 }
981
982 pub fn col_header_max(&self) -> u32 {
984 *self.col_header.keys().max().unwrap_or(&0)
985 }
986
987 pub fn row_header_max(&self) -> u32 {
989 *self.row_header.keys().max().unwrap_or(&0)
990 }
991
992 pub fn used_grid_size(&self) -> (u32, u32) {
994 let max = self.data.keys().fold((0, 0), |mut max, (r, c)| {
995 max.0 = u32::max(max.0, *r);
996 max.1 = u32::max(max.1, *c);
997 max
998 });
999
1000 (max.0 + 1, max.1 + 1)
1001 }
1002
1003 pub fn set_display(&mut self, display: bool) {
1005 self.display = display;
1006 }
1007
1008 pub fn display(&self) -> bool {
1010 self.display
1011 }
1012
1013 pub fn set_print(&mut self, print: bool) {
1015 self.print = print;
1016 }
1017
1018 pub fn print(&self) -> bool {
1020 self.print
1021 }
1022
1023 pub fn is_empty(&self, row: u32, col: u32) -> bool {
1025 !self.data.contains_key(&(row, col))
1026 }
1027
1028 pub fn cell(&self, row: u32, col: u32) -> Option<CellContent> {
1030 self.data
1031 .get(&(row, col))
1032 .map(CellData::cloned_cell_content)
1033 }
1034
1035 pub fn cell_ref(&self, row: u32, col: u32) -> Option<CellContentRef<'_>> {
1037 self.data.get(&(row, col)).map(CellData::cell_content_ref)
1038 }
1039
1040 pub fn add_cell(&mut self, row: u32, col: u32, cell: CellContent) {
1042 self.add_cell_data(row, col, cell.into_celldata());
1043 }
1044
1045 pub fn remove_cell(&mut self, row: u32, col: u32) -> Option<CellContent> {
1047 self.data
1048 .remove(&(row, col))
1049 .map(CellData::into_cell_content)
1050 }
1051
1052 pub(crate) fn add_cell_data(&mut self, row: u32, col: u32, cell: CellData) {
1054 self.data.insert((row, col), cell);
1055 }
1056
1057 #[inline]
1059 pub fn set_styled<V: Into<Value>>(
1060 &mut self,
1061 row: u32,
1062 col: u32,
1063 value: V,
1064 style: &CellStyleRef,
1065 ) {
1066 self.set_styled_value(row, col, value, style)
1067 }
1068
1069 pub fn set_styled_value<V: Into<Value>>(
1071 &mut self,
1072 row: u32,
1073 col: u32,
1074 value: V,
1075 style: &CellStyleRef,
1076 ) {
1077 let cell = self.data.entry((row, col)).or_default();
1078 cell.value = value.into();
1079 cell.style = Some(style.clone());
1080 }
1081
1082 pub fn set_value<V: Into<Value>>(&mut self, row: u32, col: u32, value: V) {
1084 let cell = self.data.entry((row, col)).or_default();
1085 cell.value = value.into();
1086 }
1087
1088 pub fn value(&self, row: u32, col: u32) -> &Value {
1090 if let Some(cell) = self.data.get(&(row, col)) {
1091 &cell.value
1092 } else {
1093 &Value::Empty
1094 }
1095 }
1096
1097 pub fn set_formula<V: Into<String>>(&mut self, row: u32, col: u32, formula: V) {
1099 let cell = self.data.entry((row, col)).or_default();
1100 cell.formula = Some(formula.into());
1101 }
1102
1103 pub fn clear_formula(&mut self, row: u32, col: u32) {
1105 if let Some(cell) = self.data.get_mut(&(row, col)) {
1106 cell.formula = None;
1107 }
1108 }
1109
1110 pub fn formula(&self, row: u32, col: u32) -> Option<&String> {
1112 if let Some(c) = self.data.get(&(row, col)) {
1113 c.formula.as_ref()
1114 } else {
1115 None
1116 }
1117 }
1118
1119 pub fn set_cell_repeat(&mut self, row: u32, col: u32, repeat: u32) {
1121 let cell = self.data.entry((row, col)).or_default();
1122 cell.repeat = repeat;
1123 }
1124
1125 pub fn cell_repeat(&self, row: u32, col: u32) -> u32 {
1127 if let Some(c) = self.data.get(&(row, col)) {
1128 c.repeat
1129 } else {
1130 1
1131 }
1132 }
1133
1134 pub fn set_cellstyle(&mut self, row: u32, col: u32, style: &CellStyleRef) {
1136 let cell = self.data.entry((row, col)).or_default();
1137 cell.style = Some(style.clone());
1138 }
1139
1140 pub fn clear_cellstyle(&mut self, row: u32, col: u32) {
1142 if let Some(cell) = self.data.get_mut(&(row, col)) {
1143 cell.style = None;
1144 }
1145 }
1146
1147 pub fn cellstyle(&self, row: u32, col: u32) -> Option<&CellStyleRef> {
1149 if let Some(c) = self.data.get(&(row, col)) {
1150 c.style.as_ref()
1151 } else {
1152 None
1153 }
1154 }
1155
1156 pub fn set_validation(&mut self, row: u32, col: u32, validation: &ValidationRef) {
1158 let cell = self.data.entry((row, col)).or_default();
1159 cell.extra_mut().validation_name = Some(validation.clone());
1160 }
1161
1162 pub fn clear_validation(&mut self, row: u32, col: u32) {
1164 if let Some(cell) = self.data.get_mut(&(row, col)) {
1165 cell.extra_mut().validation_name = None;
1166 }
1167 }
1168
1169 pub fn validation(&self, row: u32, col: u32) -> Option<&ValidationRef> {
1171 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1172 c.validation_name.as_ref()
1173 } else {
1174 None
1175 }
1176 }
1177
1178 pub fn set_row_span(&mut self, row: u32, col: u32, span: u32) {
1180 let cell = self.data.entry((row, col)).or_default();
1181 cell.extra_mut().span.set_row_span(span);
1182 }
1183
1184 pub fn row_span(&self, row: u32, col: u32) -> u32 {
1186 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1187 c.span.row_span()
1188 } else {
1189 1
1190 }
1191 }
1192
1193 pub fn set_col_span(&mut self, row: u32, col: u32, span: u32) {
1195 assert!(span > 0);
1196 let cell = self.data.entry((row, col)).or_default();
1197 cell.extra_mut().span.set_col_span(span);
1198 }
1199
1200 pub fn col_span(&self, row: u32, col: u32) -> u32 {
1202 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1203 c.span.col_span()
1204 } else {
1205 1
1206 }
1207 }
1208
1209 pub fn set_matrix_row_span(&mut self, row: u32, col: u32, span: u32) {
1211 let cell = self.data.entry((row, col)).or_default();
1212 cell.extra_mut().matrix_span.set_row_span(span);
1213 }
1214
1215 pub fn matrix_row_span(&self, row: u32, col: u32) -> u32 {
1217 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1218 c.matrix_span.row_span()
1219 } else {
1220 1
1221 }
1222 }
1223
1224 pub fn set_matrix_col_span(&mut self, row: u32, col: u32, span: u32) {
1226 let cell = self.data.entry((row, col)).or_default();
1227 cell.extra_mut().matrix_span.set_col_span(span);
1228 }
1229
1230 pub fn matrix_col_span(&self, row: u32, col: u32) -> u32 {
1232 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1233 c.matrix_span.col_span()
1234 } else {
1235 1
1236 }
1237 }
1238
1239 pub fn set_annotation(&mut self, row: u32, col: u32, annotation: Annotation) {
1241 let cell = self.data.entry((row, col)).or_default();
1242 cell.extra_mut().annotation = Some(Box::new(annotation));
1243 }
1244
1245 pub fn clear_annotation(&mut self, row: u32, col: u32) {
1247 if let Some(cell) = self.data.get_mut(&(row, col)) {
1248 cell.extra_mut().annotation = None;
1249 }
1250 }
1251
1252 pub fn annotation(&self, row: u32, col: u32) -> Option<&Annotation> {
1254 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1255 c.annotation.as_ref().map(|v| v.as_ref())
1256 } else {
1257 None
1258 }
1259 }
1260
1261 pub fn annotation_mut(&mut self, row: u32, col: u32) -> Option<&mut Annotation> {
1263 if let Some(CellData { extra: Some(c), .. }) = self.data.get_mut(&(row, col)) {
1264 c.annotation.as_mut().map(|v| v.as_mut())
1265 } else {
1266 None
1267 }
1268 }
1269
1270 pub fn add_draw_frame(&mut self, row: u32, col: u32, draw_frame: DrawFrame) {
1272 let cell = self.data.entry((row, col)).or_default();
1273 cell.extra_mut().draw_frames.push(draw_frame);
1274 }
1275
1276 pub fn clear_draw_frames(&mut self, row: u32, col: u32) {
1278 if let Some(cell) = self.data.get_mut(&(row, col)) {
1279 cell.extra_mut().draw_frames = Vec::new();
1280 }
1281 }
1282
1283 pub fn draw_frames(&self, row: u32, col: u32) -> Option<&Vec<DrawFrame>> {
1285 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1286 Some(c.draw_frames.as_ref())
1287 } else {
1288 None
1289 }
1290 }
1291
1292 pub fn draw_frames_mut(&mut self, row: u32, col: u32) -> Option<&mut Vec<DrawFrame>> {
1294 if let Some(CellData { extra: Some(c), .. }) = self.data.get_mut(&(row, col)) {
1295 Some(c.draw_frames.as_mut())
1296 } else {
1297 None
1298 }
1299 }
1300
1301 pub fn set_header_rows(&mut self, row_start: u32, row_end: u32) {
1304 self.header_rows = Some(Header {
1305 from: row_start,
1306 to: row_end,
1307 });
1308 }
1309
1310 pub fn clear_header_rows(&mut self) {
1312 self.header_rows = None;
1313 }
1314
1315 pub fn header_rows(&self) -> Option<Header> {
1318 self.header_rows
1319 }
1320
1321 pub fn set_header_cols(&mut self, col_start: u32, col_end: u32) {
1324 self.header_cols = Some(Header {
1325 from: col_start,
1326 to: col_end,
1327 });
1328 }
1329
1330 pub fn clear_header_cols(&mut self) {
1332 self.header_cols = None;
1333 }
1334
1335 pub fn header_cols(&self) -> Option<Header> {
1338 self.header_cols
1339 }
1340
1341 pub fn add_print_range(&mut self, range: CellRange) {
1343 self.print_ranges.get_or_insert_with(Vec::new).push(range);
1344 }
1345
1346 pub fn clear_print_ranges(&mut self) {
1348 self.print_ranges = None;
1349 }
1350
1351 pub fn print_ranges(&self) -> Option<&Vec<CellRange>> {
1353 self.print_ranges.as_ref()
1354 }
1355
1356 pub fn split_col_header(&mut self, col: u32) {
1359 self.config_mut().hor_split_mode = SplitMode::Heading;
1360 self.config_mut().hor_split_pos = col + 1;
1361 self.config_mut().position_right = col + 1;
1362 self.config_mut().cursor_x = col + 1;
1363 }
1364
1365 pub fn split_row_header(&mut self, row: u32) {
1368 self.config_mut().vert_split_mode = SplitMode::Heading;
1369 self.config_mut().vert_split_pos = row + 1;
1370 self.config_mut().position_bottom = row + 1;
1371 self.config_mut().cursor_y = row + 1;
1372 }
1373
1374 pub fn split_horizontal(&mut self, col: u32) {
1377 self.config_mut().hor_split_mode = SplitMode::Split;
1378 self.config_mut().hor_split_pos = col;
1379 }
1380
1381 pub fn split_vertical(&mut self, col: u32) {
1384 self.config_mut().vert_split_mode = SplitMode::Split;
1385 self.config_mut().vert_split_pos = col;
1386 }
1387
1388 pub fn add_col_group(&mut self, from: u32, to: u32) {
1395 assert!(from <= to);
1396 let grp = Grouped::new(from, to, true);
1397 for v in &self.group_cols {
1398 assert!(grp.contains(v) || v.contains(&grp) || grp.disjunct(v));
1399 }
1400 self.group_cols.push(grp);
1401 }
1402
1403 pub fn remove_col_group(&mut self, from: u32, to: u32) {
1405 if let Some(idx) = self
1406 .group_cols
1407 .iter()
1408 .position(|v| v.from == from && v.to == to)
1409 {
1410 self.group_cols.remove(idx);
1411 }
1412 }
1413
1414 pub fn set_col_group_displayed(&mut self, from: u32, to: u32, display: bool) {
1418 if let Some(idx) = self
1419 .group_cols
1420 .iter()
1421 .position(|v| v.from == from && v.to == to)
1422 {
1423 self.group_cols[idx].display = display;
1424
1425 for r in from..=to {
1426 self.set_col_visible(
1427 r,
1428 if display {
1429 Visibility::Visible
1430 } else {
1431 Visibility::Collapsed
1432 },
1433 );
1434 }
1435 }
1436 }
1437
1438 pub fn col_group_count(&self) -> usize {
1440 self.group_cols.len()
1441 }
1442
1443 pub fn col_group(&self, idx: usize) -> Option<&Grouped> {
1445 self.group_cols.get(idx)
1446 }
1447
1448 pub fn col_group_mut(&mut self, idx: usize) -> Option<&mut Grouped> {
1450 self.group_cols.get_mut(idx)
1451 }
1452
1453 pub fn col_group_iter(&self) -> impl Iterator<Item = &Grouped> {
1455 self.group_cols.iter()
1456 }
1457
1458 pub fn add_row_group(&mut self, from: u32, to: u32) {
1465 assert!(from <= to);
1466 let grp = Grouped::new(from, to, true);
1467 for v in &self.group_rows {
1468 assert!(grp.contains(v) || v.contains(&grp) || grp.disjunct(v));
1469 }
1470 self.group_rows.push(grp);
1471 }
1472
1473 pub fn remove_row_group(&mut self, from: u32, to: u32) {
1475 if let Some(idx) = self
1476 .group_rows
1477 .iter()
1478 .position(|v| v.from == from && v.to == to)
1479 {
1480 self.group_rows.remove(idx);
1481 }
1482 }
1483
1484 pub fn set_row_group_displayed(&mut self, from: u32, to: u32, display: bool) {
1488 if let Some(idx) = self
1489 .group_rows
1490 .iter()
1491 .position(|v| v.from == from && v.to == to)
1492 {
1493 self.group_rows[idx].display = display;
1494
1495 for r in from..=to {
1496 self.set_row_visible(
1497 r,
1498 if display {
1499 Visibility::Visible
1500 } else {
1501 Visibility::Collapsed
1502 },
1503 );
1504 }
1505 }
1506 }
1507
1508 pub fn row_group_count(&self) -> usize {
1510 self.group_rows.len()
1511 }
1512
1513 pub fn row_group(&self, idx: usize) -> Option<&Grouped> {
1515 self.group_rows.get(idx)
1516 }
1517
1518 pub fn row_group_iter(&self) -> impl Iterator<Item = &Grouped> {
1520 self.group_rows.iter()
1521 }
1522}
1523
1524#[derive(Debug, Copy, Clone, Default, GetSize)]
1526pub struct Header {
1527 pub from: u32,
1528 pub to: u32,
1529}
1530
1531impl From<Header> for (u32, u32) {
1532 fn from(value: Header) -> Self {
1533 (value.from, value.to)
1534 }
1535}
1536
1537#[derive(Debug, PartialEq, Clone, Copy, GetSize)]
1539pub struct Grouped {
1540 pub from: u32,
1542 pub to: u32,
1544 pub display: bool,
1546}
1547
1548impl Grouped {
1549 pub fn new(from: u32, to: u32, display: bool) -> Self {
1551 Self { from, to, display }
1552 }
1553
1554 pub fn from(&self) -> u32 {
1556 self.from
1557 }
1558
1559 pub fn set_from(&mut self, from: u32) {
1561 self.from = from;
1562 }
1563
1564 pub fn to(&self) -> u32 {
1566 self.to
1567 }
1568
1569 pub fn set_to(&mut self, to: u32) {
1571 self.to = to
1572 }
1573
1574 pub fn display(&self) -> bool {
1576 self.display
1577 }
1578
1579 pub fn set_display(&mut self, display: bool) {
1585 self.display = display;
1586 }
1587
1588 pub fn contains(&self, other: &Grouped) -> bool {
1590 self.from <= other.from && self.to >= other.to
1591 }
1592
1593 pub fn disjunct(&self, other: &Grouped) -> bool {
1595 self.from < other.from && self.to < other.from || self.from > other.to && self.to > other.to
1596 }
1597}
1598
1599#[derive(Clone, Copy, Debug, GetSize)]
1603#[allow(missing_docs)]
1604pub enum SplitMode {
1605 None = 0,
1606 Split = 1,
1607 Heading = 2,
1608}
1609
1610impl TryFrom<i16> for SplitMode {
1611 type Error = OdsError;
1612
1613 fn try_from(n: i16) -> Result<Self, Self::Error> {
1614 match n {
1615 0 => Ok(SplitMode::None),
1616 1 => Ok(SplitMode::Split),
1617 2 => Ok(SplitMode::Heading),
1618 _ => Err(OdsError::Ods(format!("Invalid split mode {}", n))),
1619 }
1620 }
1621}
1622
1623#[derive(Clone, Debug, GetSize)]
1625pub struct SheetConfig {
1626 pub cursor_x: u32,
1628 pub cursor_y: u32,
1630 pub hor_split_mode: SplitMode,
1632 pub vert_split_mode: SplitMode,
1634 pub hor_split_pos: u32,
1636 pub vert_split_pos: u32,
1638 pub active_split_range: i16,
1644 pub position_left: u32,
1651 pub position_right: u32,
1657 pub position_top: u32,
1664 pub position_bottom: u32,
1670 pub zoom_type: i16,
1673 pub zoom_value: i32,
1675 pub page_view_zoom_value: i32,
1677 pub show_grid: bool,
1679}
1680
1681impl Default for SheetConfig {
1682 fn default() -> Self {
1683 Self {
1684 cursor_x: 0,
1685 cursor_y: 0,
1686 hor_split_mode: SplitMode::None,
1687 vert_split_mode: SplitMode::None,
1688 hor_split_pos: 0,
1689 vert_split_pos: 0,
1690 active_split_range: 2,
1691 position_left: 0,
1692 position_right: 0,
1693 position_top: 0,
1694 position_bottom: 0,
1695 zoom_type: 0,
1696 zoom_value: 100,
1697 page_view_zoom_value: 60,
1698 show_grid: true,
1699 }
1700 }
1701}
1702
1703pub(crate) fn dedup_colheader(sheet: &mut Sheet) -> Result<(), OdsError> {
1705 fn limited_eq(ch1: &ColHeader, ch2: &ColHeader) -> bool {
1706 ch1.style == ch2.style
1707 && ch1.cellstyle == ch2.cellstyle
1708 && ch1.visible == ch2.visible
1709 && ch1.width == ch2.width
1710 }
1711
1712 let col_header = mem::take(&mut sheet.col_header);
1713
1714 let mut new_col_header = BTreeMap::new();
1715 let mut new = None;
1716 for (col, header) in col_header {
1717 match new.as_mut() {
1718 None => {
1719 new = Some((col, header));
1720 }
1721 Some((new_col, new_header)) => {
1722 if limited_eq(new_header, &header) {
1723 new_header.span += header.span;
1724 } else {
1725 new_col_header
1726 .insert(mem::replace(new_col, col), mem::replace(new_header, header));
1727 }
1728 }
1729 }
1730 }
1731 if let Some((new_col, new_header)) = new {
1732 new_col_header.insert(new_col, new_header);
1733 }
1734
1735 sheet.col_header = new_col_header;
1736
1737 Ok(())
1738}