1use get_size::GetSize;
6use get_size_derive::GetSize;
7use std::collections::{BTreeMap, Bound};
8use std::fmt::{Debug, Display, Formatter};
9use std::iter::FusedIterator;
10use std::ops::RangeBounds;
11use std::{fmt, mem};
12
13use crate::cell_::{CellContent, CellContentRef, CellData};
14use crate::draw::{Annotation, DrawFrame};
15use crate::style::{ColStyleRef, RowStyleRef, TableStyleRef};
16use crate::validation::ValidationRef;
17use crate::value_::Value;
18use crate::xmltree::XmlTag;
19use crate::{CellRange, CellStyleRef, Length, OdsError};
20
21#[cfg(test)]
22mod tests;
23
24#[derive(Debug, Clone, Copy, Eq, PartialEq, Default, GetSize)]
26#[allow(missing_docs)]
27pub enum Visibility {
28 #[default]
29 Visible,
30 Collapsed,
31 Filtered,
32}
33
34impl Display for Visibility {
35 fn fmt(&self, f: &mut Formatter<'_>) -> Result<(), fmt::Error> {
36 match self {
37 Visibility::Visible => write!(f, "visible"),
38 Visibility::Collapsed => write!(f, "collapse"),
39 Visibility::Filtered => write!(f, "filter"),
40 }
41 }
42}
43
44#[derive(Debug, Clone, GetSize)]
46pub(crate) struct RowHeader {
47 pub(crate) style: Option<RowStyleRef>,
48 pub(crate) cellstyle: Option<CellStyleRef>,
49 pub(crate) visible: Visibility,
50 pub(crate) repeat: u32,
58 pub(crate) span: u32,
61 pub(crate) height: Length,
62}
63
64impl Default for RowHeader {
65 fn default() -> Self {
66 Self {
67 style: None,
68 cellstyle: None,
69 visible: Default::default(),
70 repeat: 1,
71 span: 1,
72 height: Default::default(),
73 }
74 }
75}
76
77#[derive(Debug, Clone, GetSize)]
79pub(crate) struct ColHeader {
80 pub(crate) style: Option<ColStyleRef>,
81 pub(crate) cellstyle: Option<CellStyleRef>,
82 pub(crate) visible: Visibility,
83 pub(crate) width: Length,
84 pub(crate) span: u32,
87}
88
89impl Default for ColHeader {
90 fn default() -> Self {
91 Self {
92 style: None,
93 cellstyle: None,
94 visible: Default::default(),
95 width: Default::default(),
96 span: 1,
97 }
98 }
99}
100
101#[derive(Clone, Default, GetSize)]
107pub struct Sheet {
108 pub(crate) name: String,
109 pub(crate) style: Option<TableStyleRef>,
110
111 pub(crate) data: BTreeMap<(u32, u32), CellData>,
112
113 pub(crate) col_header: BTreeMap<u32, ColHeader>,
114 pub(crate) row_header: BTreeMap<u32, RowHeader>,
115
116 pub(crate) display: bool,
117 pub(crate) print: bool,
118
119 pub(crate) header_rows: Option<Header>,
120 pub(crate) header_cols: Option<Header>,
121 pub(crate) print_ranges: Option<Vec<CellRange>>,
122
123 pub(crate) group_rows: Vec<Grouped>,
124 pub(crate) group_cols: Vec<Grouped>,
125
126 pub(crate) sheet_config: SheetConfig,
127
128 pub(crate) extra: Vec<XmlTag>,
129}
130
131impl<'a> IntoIterator for &'a Sheet {
132 type Item = ((u32, u32), CellContentRef<'a>);
133 type IntoIter = CellIter<'a>;
134
135 fn into_iter(self) -> Self::IntoIter {
136 CellIter {
137 iter: self.data.iter(),
138 k_data: None,
139 v_data: None,
140 }
141 }
142}
143
144#[derive(Debug)]
146pub(crate) struct CellDataIter<'a> {
147 iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
148 k_data: Option<&'a (u32, u32)>,
149 v_data: Option<&'a CellData>,
150}
151
152impl<'a> CellDataIter<'a> {
153 pub(crate) fn new(iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>) -> Self {
154 Self {
155 iter,
156 k_data: None,
157 v_data: None,
158 }
159 }
160
161 #[allow(dead_code)]
163 pub(crate) fn peek_cell(&mut self) -> Option<(u32, u32)> {
164 self.k_data.copied()
165 }
166
167 fn load_next_data(&mut self) {
168 if let Some((k, v)) = self.iter.next() {
169 self.k_data = Some(k);
170 self.v_data = Some(v);
171 } else {
172 self.k_data = None;
173 self.v_data = None;
174 }
175 }
176}
177
178impl FusedIterator for CellDataIter<'_> {}
179
180impl<'a> Iterator for CellDataIter<'a> {
181 type Item = ((u32, u32), &'a CellData);
182
183 fn next(&mut self) -> Option<Self::Item> {
184 if self.k_data.is_none() {
185 self.load_next_data();
186 }
187
188 if let Some(k_data) = self.k_data {
189 if let Some(v_data) = self.v_data {
190 let r = Some((*k_data, v_data));
191 self.load_next_data();
192 r
193 } else {
194 None
195 }
196 } else {
197 None
198 }
199 }
200
201 fn size_hint(&self) -> (usize, Option<usize>) {
202 self.iter.size_hint()
203 }
204}
205
206#[derive(Debug)]
208pub(crate) struct CellDataIterMut<'a> {
209 iter: std::collections::btree_map::RangeMut<'a, (u32, u32), CellData>,
210 k_data: Option<&'a (u32, u32)>,
211 v_data: Option<&'a mut CellData>,
212}
213
214impl<'a> CellDataIterMut<'a> {
215 pub(crate) fn new(
216 iter: std::collections::btree_map::RangeMut<'a, (u32, u32), CellData>,
217 ) -> Self {
218 Self {
219 iter,
220 k_data: None,
221 v_data: None,
222 }
223 }
224
225 pub(crate) fn peek_cell(&mut self) -> Option<(u32, u32)> {
227 self.k_data.copied()
228 }
229
230 fn load_next_data(&mut self) {
231 if let Some((k, v)) = self.iter.next() {
232 self.k_data = Some(k);
233 self.v_data = Some(v);
234 } else {
235 self.k_data = None;
236 self.v_data = None;
237 }
238 }
239}
240
241impl FusedIterator for CellDataIterMut<'_> {}
242
243impl<'a> Iterator for CellDataIterMut<'a> {
244 type Item = ((u32, u32), &'a mut CellData);
245
246 fn next(&mut self) -> Option<Self::Item> {
247 if self.k_data.is_none() {
248 self.load_next_data();
249 }
250
251 if let Some(k_data) = self.k_data {
252 if let Some(v_data) = self.v_data.take() {
253 let r = Some((*k_data, v_data));
254 self.load_next_data();
255 r
256 } else {
257 None
258 }
259 } else {
260 None
261 }
262 }
263
264 fn size_hint(&self) -> (usize, Option<usize>) {
265 self.iter.size_hint()
266 }
267}
268
269#[derive(Clone, Debug)]
271pub struct CellIter<'a> {
272 iter: std::collections::btree_map::Iter<'a, (u32, u32), CellData>,
273 k_data: Option<&'a (u32, u32)>,
274 v_data: Option<&'a CellData>,
275}
276
277impl CellIter<'_> {
278 pub fn peek_cell(&mut self) -> Option<(u32, u32)> {
280 self.k_data.copied()
281 }
282
283 fn load_next_data(&mut self) {
284 if let Some((k, v)) = self.iter.next() {
285 self.k_data = Some(k);
286 self.v_data = Some(v);
287 } else {
288 self.k_data = None;
289 self.v_data = None;
290 }
291 }
292}
293
294impl FusedIterator for CellIter<'_> {}
295
296impl<'a> Iterator for CellIter<'a> {
297 type Item = ((u32, u32), CellContentRef<'a>);
298
299 fn next(&mut self) -> Option<Self::Item> {
300 if self.k_data.is_none() {
301 self.load_next_data();
302 }
303
304 if let Some(k_data) = self.k_data {
305 if let Some(v_data) = self.v_data {
306 let r = Some((*k_data, v_data.cell_content_ref()));
307 self.load_next_data();
308 r
309 } else {
310 None
311 }
312 } else {
313 None
314 }
315 }
316
317 fn size_hint(&self) -> (usize, Option<usize>) {
318 self.iter.size_hint()
319 }
320}
321
322struct IterRows<'a> {
323 iter: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
324 start: (u32, u32),
325 end: (u32, u32),
326 hint: usize,
327}
328
329impl<'a> IterRows<'a> {
330 fn new<R: RangeBounds<(u32, u32)>>(sheet: &'a Sheet, range: R) -> Self {
331 let start = match range.start_bound() {
332 Bound::Included((r, c)) => (*r, *c),
333 Bound::Excluded((r, c)) => (r + 1, c + 1),
334 Bound::Unbounded => (0, 0),
335 };
336 let end = match range.end_bound() {
337 Bound::Included((r, c)) => (r + 1, c + 1),
338 Bound::Excluded((r, c)) => (*r, *c),
339 Bound::Unbounded => sheet.used_grid_size(),
340 };
341
342 Self {
343 iter: sheet.data.range(range),
344 start,
345 end,
346 hint: (end.0 - start.0) as usize * (end.1 * start.1) as usize,
347 }
348 }
349}
350
351impl FusedIterator for IterRows<'_> {}
352
353impl<'a> Iterator for IterRows<'a> {
354 type Item = ((u32, u32), CellContentRef<'a>);
355
356 fn next(&mut self) -> Option<Self::Item> {
357 loop {
358 if let Some(((r, c), d)) = self.iter.next() {
359 if *r < self.end.0 && *c >= self.start.1 && *c < self.end.1 {
360 return Some(((*r, *c), d.cell_content_ref()));
361 }
362 } else {
363 return None;
364 }
365 }
366 }
367
368 fn size_hint(&self) -> (usize, Option<usize>) {
369 (0, Some(self.hint))
370 }
371}
372
373struct IterCols<'a> {
374 sheet: &'a Sheet,
375 start: (u32, u32),
376 end: (u32, u32),
377 cell: (u32, u32),
378}
379
380impl Debug for IterCols<'_> {
381 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
382 f.debug_struct("IterCols")
383 .field("start", &self.start)
384 .field("end", &self.end)
385 .field("cell", &self.cell)
386 .finish()
387 }
388}
389
390impl FusedIterator for IterCols<'_> {}
391
392impl<'a> IterCols<'a> {
393 fn new<R: RangeBounds<(u32, u32)>>(sheet: &'a Sheet, range: R) -> Self {
394 let start = match range.start_bound() {
395 Bound::Included((r, c)) => (*r, *c),
396 Bound::Excluded((r, c)) => (r + 1, c + 1),
397 Bound::Unbounded => (0, 0),
398 };
399 let end = match range.end_bound() {
400 Bound::Included((r, c)) => (r + 1, c + 1),
401 Bound::Excluded((r, c)) => (*r, *c),
402 Bound::Unbounded => sheet.used_grid_size(),
403 };
404
405 Self {
406 sheet,
407 start,
408 end,
409 cell: start,
410 }
411 }
412}
413
414impl<'a> Iterator for IterCols<'a> {
415 type Item = ((u32, u32), CellContentRef<'a>);
416
417 #[allow(clippy::comparison_chain)]
418 fn next(&mut self) -> Option<Self::Item> {
419 if self.cell.0 == self.end.0 && self.cell.1 == self.end.1 {
420 return None;
421 }
422
423 loop {
424 let r = self.cell.0;
425 let c = self.cell.1;
426 let d = self.sheet.cell_ref(self.cell.0, self.cell.1);
427
428 if self.cell.0 + 1 < self.end.0 {
429 self.cell.0 += 1;
430 } else if self.cell.0 + 1 == self.end.0 {
431 if self.cell.1 + 1 < self.end.1 {
432 self.cell.0 = self.start.0;
433 self.cell.1 += 1;
434 } else if self.cell.1 + 1 == self.end.1 {
435 self.cell.0 += 1;
436 self.cell.1 += 1;
437 } else {
438 assert_eq!(self.cell, self.end);
439 }
440 } else {
441 assert_eq!(self.cell, self.end);
442 }
443
444 if let Some(d) = d {
445 return Some(((r, c), d));
446 }
447 }
448 }
449
450 fn size_hint(&self) -> (usize, Option<usize>) {
451 (
452 0,
453 Some((self.end.0 - self.start.0) as usize * (self.end.1 - self.start.1) as usize),
454 )
455 }
456}
457
458#[derive(Clone, Debug)]
460pub struct Range<'a> {
461 range: std::collections::btree_map::Range<'a, (u32, u32), CellData>,
462}
463
464impl FusedIterator for Range<'_> {}
465
466impl<'a> Iterator for Range<'a> {
467 type Item = ((u32, u32), CellContentRef<'a>);
468
469 fn next(&mut self) -> Option<Self::Item> {
470 if let Some((k, v)) = self.range.next() {
471 Some((*k, v.cell_content_ref()))
472 } else {
473 None
474 }
475 }
476
477 fn size_hint(&self) -> (usize, Option<usize>) {
478 self.range.size_hint()
479 }
480}
481
482impl DoubleEndedIterator for Range<'_> {
483 fn next_back(&mut self) -> Option<Self::Item> {
484 if let Some((k, v)) = self.range.next_back() {
485 Some((*k, v.cell_content_ref()))
486 } else {
487 None
488 }
489 }
490}
491
492impl ExactSizeIterator for Range<'_> {}
493
494impl Debug for Sheet {
495 fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
496 writeln!(f, "name {:?} style {:?}", self.name, self.style)?;
497 for (k, v) in self.data.iter() {
498 writeln!(f, " data {:?} {:?}", k, v)?;
499 }
500 for (k, v) in &self.col_header {
501 writeln!(f, "{:?} {:?}", k, v)?;
502 }
503 for (k, v) in &self.row_header {
504 writeln!(f, "{:?} {:?}", k, v)?;
505 }
506 if let Some(header_rows) = &self.header_rows {
507 writeln!(f, "header rows {:?}", header_rows)?;
508 }
509 if let Some(header_cols) = &self.header_cols {
510 writeln!(f, "header cols {:?}", header_cols)?;
511 }
512 for v in &self.group_cols {
513 writeln!(f, "group cols {:?}", v)?;
514 }
515 for v in &self.group_rows {
516 writeln!(f, "group rows {:?}", v)?;
517 }
518 for xtr in &self.extra {
519 writeln!(f, "extras {:?}", xtr)?;
520 }
521 Ok(())
522 }
523}
524
525impl Sheet {
526 #[deprecated]
528 pub fn new_with_name<S: Into<String>>(name: S) -> Self {
529 Self::new(name)
530 }
531
532 pub fn new<S: Into<String>>(name: S) -> Self {
542 Sheet {
543 name: name.into(),
544 data: BTreeMap::new(),
545 col_header: Default::default(),
546 style: None,
547 header_rows: None,
548 header_cols: None,
549 print_ranges: None,
550 group_rows: Default::default(),
551 group_cols: Default::default(),
552 sheet_config: Default::default(),
553 extra: vec![],
554 row_header: Default::default(),
555 display: true,
556 print: true,
557 }
558 }
559
560 pub fn clone_no_data(&self) -> Self {
562 Self {
563 name: self.name.clone(),
564 style: self.style.clone(),
565 data: Default::default(),
566 col_header: self.col_header.clone(),
567 row_header: self.row_header.clone(),
568 display: self.display,
569 print: self.print,
570 header_rows: self.header_rows,
571 header_cols: self.header_cols,
572 print_ranges: self.print_ranges.clone(),
573 group_rows: self.group_rows.clone(),
574 group_cols: self.group_cols.clone(),
575 sheet_config: Default::default(),
576 extra: self.extra.clone(),
577 }
578 }
579
580 pub fn iter(&self) -> CellIter<'_> {
582 self.into_iter()
583 }
584
585 pub fn cell_count(&self) -> usize {
587 self.data.len()
588 }
589
590 pub fn iter_rows<R: RangeBounds<(u32, u32)>>(
595 &self,
596 range: R,
597 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
598 IterRows::new(self, range)
599 }
600
601 pub fn iter_cols<R: RangeBounds<(u32, u32)>>(
606 &self,
607 range: R,
608 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
609 IterCols::new(self, range)
610 }
611
612 pub fn range<R: RangeBounds<(u32, u32)>>(
614 &self,
615 range: R,
616 ) -> impl Iterator<Item = ((u32, u32), CellContentRef<'_>)> {
617 Range {
618 range: self.data.range(range),
619 }
620 }
621
622 pub fn set_name<V: Into<String>>(&mut self, name: V) {
624 self.name = name.into();
625 }
626
627 pub fn name(&self) -> &String {
629 &self.name
630 }
631
632 pub fn config(&self) -> &SheetConfig {
634 &self.sheet_config
635 }
636
637 pub fn config_mut(&mut self) -> &mut SheetConfig {
639 &mut self.sheet_config
640 }
641
642 pub fn set_style(&mut self, style: &TableStyleRef) {
644 self.style = Some(style.clone())
645 }
646
647 pub fn style(&self) -> Option<&TableStyleRef> {
649 self.style.as_ref()
650 }
651
652 pub(crate) fn valid_col_header(&self, col: u32) -> Option<&ColHeader> {
654 if let Some((base_col, col_header)) = self.col_header.range(..=col).last() {
655 if (*base_col..*base_col + col_header.span).contains(&col) {
656 Some(col_header)
657 } else {
658 None
659 }
660 } else {
661 None
662 }
663 }
664
665 #[allow(clippy::comparison_chain)]
669 fn create_split_col_header(&mut self, col: u32) -> &mut ColHeader {
670 let mut cloned = Vec::new();
671
672 if let Some((base_col, col_header)) = self.col_header.range_mut(..=col).last() {
673 if (*base_col..*base_col + col_header.span).contains(&col) {
674 let base_span = col_header.span;
675
676 if *base_col < col {
683 col_header.span = col - *base_col;
684
685 let mut clone = col_header.clone();
686 clone.span = 1;
687 cloned.push((col, clone));
688 } else if *base_col == col {
689 col_header.span = 1;
690 } else {
691 unreachable!();
692 }
693
694 if *base_col + base_span > col {
696 let mut clone = col_header.clone();
697 clone.span = *base_col + base_span - (col + 1);
698 cloned.push((col + 1, clone));
699 } else if *base_col + base_span == col {
700 } else {
702 unreachable!();
703 }
704 } else {
705 self.col_header.insert(col, ColHeader::default());
706 }
707 } else {
708 self.col_header.insert(col, ColHeader::default());
709 }
710
711 for (r, ch) in cloned {
712 self.col_header.insert(r, ch);
713 }
714
715 self.col_header.get_mut(&col).expect("col-header")
716 }
717
718 pub fn set_colstyle(&mut self, col: u32, style: &ColStyleRef) {
720 self.create_split_col_header(col).style = Some(style.clone());
721 }
722
723 pub fn clear_colstyle(&mut self, col: u32) {
725 self.create_split_col_header(col).style = None;
726 }
727
728 pub fn colstyle(&self, col: u32) -> Option<&ColStyleRef> {
730 if let Some(col_header) = self.valid_col_header(col) {
731 col_header.style.as_ref()
732 } else {
733 None
734 }
735 }
736
737 pub fn set_col_cellstyle(&mut self, col: u32, style: &CellStyleRef) {
739 self.create_split_col_header(col).cellstyle = Some(style.clone());
740 }
741
742 pub fn clear_col_cellstyle(&mut self, col: u32) {
744 self.create_split_col_header(col).cellstyle = None;
745 }
746
747 pub fn col_cellstyle(&self, col: u32) -> Option<&CellStyleRef> {
749 if let Some(col_header) = self.valid_col_header(col) {
750 col_header.cellstyle.as_ref()
751 } else {
752 None
753 }
754 }
755
756 pub fn set_col_visible(&mut self, col: u32, visible: Visibility) {
758 self.create_split_col_header(col).visible = visible;
759 }
760
761 pub fn col_visible(&self, col: u32) -> Visibility {
763 if let Some(col_header) = self.valid_col_header(col) {
764 col_header.visible
765 } else {
766 Default::default()
767 }
768 }
769
770 pub fn _set_col_header_span(&mut self, col: u32, span: u32) {
772 self.create_split_col_header(col).span = span
773 }
774
775 pub fn _col_header_span(&self, col: u32) -> u32 {
777 if let Some(col_header) = self.valid_col_header(col) {
778 col_header.span
779 } else {
780 Default::default()
781 }
782 }
783
784 pub fn set_col_width(&mut self, col: u32, width: Length) {
786 self.create_split_col_header(col).width = width;
787 }
788
789 pub fn col_width(&self, col: u32) -> Length {
791 if let Some(ch) = self.valid_col_header(col) {
792 ch.width
793 } else {
794 Length::Default
795 }
796 }
797
798 pub(crate) fn valid_row_header(&self, row: u32) -> Option<&RowHeader> {
800 if let Some((base_row, row_header)) = self.row_header.range(..=row).last() {
801 if (*base_row..*base_row + row_header.span).contains(&row) {
802 Some(row_header)
803 } else {
804 None
805 }
806 } else {
807 None
808 }
809 }
810
811 #[allow(clippy::comparison_chain)]
815 fn create_split_row_header(&mut self, row: u32) -> &mut RowHeader {
816 let mut cloned = Vec::new();
817
818 if let Some((base_row, row_header)) = self.row_header.range_mut(..=row).last() {
819 if (*base_row..*base_row + row_header.span).contains(&row) {
820 let base_span = row_header.span;
821
822 if *base_row < row {
829 row_header.span = row - *base_row;
830
831 let mut clone = row_header.clone();
832 clone.span = 1;
833 cloned.push((row, clone));
834 } else if *base_row == row {
835 row_header.span = 1;
836 } else {
837 unreachable!();
838 }
839
840 if *base_row + base_span > row {
842 let mut clone = row_header.clone();
843 clone.span = *base_row + base_span - (row + 1);
844 cloned.push((row + 1, clone));
845 } else if *base_row + base_span == row {
846 } else {
848 unreachable!();
849 }
850 } else {
851 self.row_header.insert(row, RowHeader::default());
852 }
853 } else {
854 self.row_header.insert(row, RowHeader::default());
855 }
856
857 for (r, rh) in cloned {
858 self.row_header.insert(r, rh);
859 }
860
861 self.row_header.get_mut(&row).expect("row-header")
862 }
863
864 pub fn _row_header_span(&self, row: u32) -> Option<u32> {
866 self.row_header.get(&row).map(|v| v.span)
867 }
868
869 pub fn _set_row_header_span(&mut self, row: u32, span: u32) {
871 if let Some(row_header) = self.row_header.get_mut(&row) {
872 row_header.span = span;
873 }
874 }
875
876 pub fn set_rowstyle(&mut self, row: u32, style: &RowStyleRef) {
878 self.create_split_row_header(row).style = Some(style.clone());
879 }
880
881 pub fn clear_rowstyle(&mut self, row: u32) {
883 self.create_split_row_header(row).style = None;
884 }
885
886 pub fn rowstyle(&self, row: u32) -> Option<&RowStyleRef> {
888 if let Some(row_header) = self.valid_row_header(row) {
889 row_header.style.as_ref()
890 } else {
891 None
892 }
893 }
894
895 pub fn set_row_cellstyle(&mut self, row: u32, style: &CellStyleRef) {
897 self.create_split_row_header(row).cellstyle = Some(style.clone());
898 }
899
900 pub fn clear_row_cellstyle(&mut self, row: u32) {
902 self.create_split_row_header(row).cellstyle = None;
903 }
904
905 pub fn row_cellstyle(&self, row: u32) -> Option<&CellStyleRef> {
907 if let Some(row_header) = self.valid_row_header(row) {
908 row_header.cellstyle.as_ref()
909 } else {
910 None
911 }
912 }
913
914 pub fn set_row_visible(&mut self, row: u32, visible: Visibility) {
916 self.create_split_row_header(row).visible = visible;
917 }
918
919 pub fn row_visible(&self, row: u32) -> Visibility {
921 if let Some(row_header) = self.valid_row_header(row) {
922 row_header.visible
923 } else {
924 Default::default()
925 }
926 }
927
928 pub fn set_row_repeat(&mut self, row: u32, repeat: u32) {
937 assert!(repeat > 0);
938 self.create_split_row_header(row).repeat = repeat
939 }
940
941 pub fn row_repeat(&self, row: u32) -> u32 {
943 if let Some(row_header) = self.valid_row_header(row) {
944 row_header.repeat
945 } else {
946 Default::default()
947 }
948 }
949
950 pub fn set_row_height(&mut self, row: u32, height: Length) {
952 self.create_split_row_header(row).height = height;
953 }
954
955 pub fn row_height(&self, row: u32) -> Length {
957 if let Some(rh) = self.valid_row_header(row) {
958 rh.height
959 } else {
960 Length::Default
961 }
962 }
963
964 pub fn _col_header_len(&self) -> usize {
966 self.col_header.len()
967 }
968
969 pub fn _row_header_len(&self) -> usize {
971 self.row_header.len()
972 }
973
974 pub fn col_header_max(&self) -> u32 {
976 *self.col_header.keys().max().unwrap_or(&0)
977 }
978
979 pub fn row_header_max(&self) -> u32 {
981 *self.row_header.keys().max().unwrap_or(&0)
982 }
983
984 pub fn used_grid_size(&self) -> (u32, u32) {
986 let max = self.data.keys().fold((0, 0), |mut max, (r, c)| {
987 max.0 = u32::max(max.0, *r);
988 max.1 = u32::max(max.1, *c);
989 max
990 });
991
992 (max.0 + 1, max.1 + 1)
993 }
994
995 pub fn set_display(&mut self, display: bool) {
997 self.display = display;
998 }
999
1000 pub fn display(&self) -> bool {
1002 self.display
1003 }
1004
1005 pub fn set_print(&mut self, print: bool) {
1007 self.print = print;
1008 }
1009
1010 pub fn print(&self) -> bool {
1012 self.print
1013 }
1014
1015 pub fn is_empty(&self, row: u32, col: u32) -> bool {
1017 self.data.get(&(row, col)).is_none()
1018 }
1019
1020 pub fn cell(&self, row: u32, col: u32) -> Option<CellContent> {
1022 self.data
1023 .get(&(row, col))
1024 .map(CellData::cloned_cell_content)
1025 }
1026
1027 pub fn cell_ref(&self, row: u32, col: u32) -> Option<CellContentRef<'_>> {
1029 self.data.get(&(row, col)).map(CellData::cell_content_ref)
1030 }
1031
1032 pub fn add_cell(&mut self, row: u32, col: u32, cell: CellContent) {
1034 self.add_cell_data(row, col, cell.into_celldata());
1035 }
1036
1037 pub fn remove_cell(&mut self, row: u32, col: u32) -> Option<CellContent> {
1039 self.data
1040 .remove(&(row, col))
1041 .map(CellData::into_cell_content)
1042 }
1043
1044 pub(crate) fn add_cell_data(&mut self, row: u32, col: u32, cell: CellData) {
1046 self.data.insert((row, col), cell);
1047 }
1048
1049 #[inline]
1051 pub fn set_styled<V: Into<Value>>(
1052 &mut self,
1053 row: u32,
1054 col: u32,
1055 value: V,
1056 style: &CellStyleRef,
1057 ) {
1058 self.set_styled_value(row, col, value, style)
1059 }
1060
1061 pub fn set_styled_value<V: Into<Value>>(
1063 &mut self,
1064 row: u32,
1065 col: u32,
1066 value: V,
1067 style: &CellStyleRef,
1068 ) {
1069 let cell = self.data.entry((row, col)).or_default();
1070 cell.value = value.into();
1071 cell.style = Some(style.clone());
1072 }
1073
1074 pub fn set_value<V: Into<Value>>(&mut self, row: u32, col: u32, value: V) {
1076 let cell = self.data.entry((row, col)).or_default();
1077 cell.value = value.into();
1078 }
1079
1080 pub fn value(&self, row: u32, col: u32) -> &Value {
1082 if let Some(cell) = self.data.get(&(row, col)) {
1083 &cell.value
1084 } else {
1085 &Value::Empty
1086 }
1087 }
1088
1089 pub fn set_formula<V: Into<String>>(&mut self, row: u32, col: u32, formula: V) {
1091 let cell = self.data.entry((row, col)).or_default();
1092 cell.formula = Some(formula.into());
1093 }
1094
1095 pub fn clear_formula(&mut self, row: u32, col: u32) {
1097 if let Some(cell) = self.data.get_mut(&(row, col)) {
1098 cell.formula = None;
1099 }
1100 }
1101
1102 pub fn formula(&self, row: u32, col: u32) -> Option<&String> {
1104 if let Some(c) = self.data.get(&(row, col)) {
1105 c.formula.as_ref()
1106 } else {
1107 None
1108 }
1109 }
1110
1111 pub fn set_cell_repeat(&mut self, row: u32, col: u32, repeat: u32) {
1113 let cell = self.data.entry((row, col)).or_default();
1114 cell.repeat = repeat;
1115 }
1116
1117 pub fn cell_repeat(&self, row: u32, col: u32) -> u32 {
1119 if let Some(c) = self.data.get(&(row, col)) {
1120 c.repeat
1121 } else {
1122 1
1123 }
1124 }
1125
1126 pub fn set_cellstyle(&mut self, row: u32, col: u32, style: &CellStyleRef) {
1128 let cell = self.data.entry((row, col)).or_default();
1129 cell.style = Some(style.clone());
1130 }
1131
1132 pub fn clear_cellstyle(&mut self, row: u32, col: u32) {
1134 if let Some(cell) = self.data.get_mut(&(row, col)) {
1135 cell.style = None;
1136 }
1137 }
1138
1139 pub fn cellstyle(&self, row: u32, col: u32) -> Option<&CellStyleRef> {
1141 if let Some(c) = self.data.get(&(row, col)) {
1142 c.style.as_ref()
1143 } else {
1144 None
1145 }
1146 }
1147
1148 pub fn set_validation(&mut self, row: u32, col: u32, validation: &ValidationRef) {
1150 let cell = self.data.entry((row, col)).or_default();
1151 cell.extra_mut().validation_name = Some(validation.clone());
1152 }
1153
1154 pub fn clear_validation(&mut self, row: u32, col: u32) {
1156 if let Some(cell) = self.data.get_mut(&(row, col)) {
1157 cell.extra_mut().validation_name = None;
1158 }
1159 }
1160
1161 pub fn validation(&self, row: u32, col: u32) -> Option<&ValidationRef> {
1163 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1164 c.validation_name.as_ref()
1165 } else {
1166 None
1167 }
1168 }
1169
1170 pub fn set_row_span(&mut self, row: u32, col: u32, span: u32) {
1172 let cell = self.data.entry((row, col)).or_default();
1173 cell.extra_mut().span.set_row_span(span);
1174 }
1175
1176 pub fn row_span(&self, row: u32, col: u32) -> u32 {
1178 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1179 c.span.row_span()
1180 } else {
1181 1
1182 }
1183 }
1184
1185 pub fn set_col_span(&mut self, row: u32, col: u32, span: u32) {
1187 assert!(span > 0);
1188 let cell = self.data.entry((row, col)).or_default();
1189 cell.extra_mut().span.set_col_span(span);
1190 }
1191
1192 pub fn col_span(&self, row: u32, col: u32) -> u32 {
1194 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1195 c.span.col_span()
1196 } else {
1197 1
1198 }
1199 }
1200
1201 pub fn set_matrix_row_span(&mut self, row: u32, col: u32, span: u32) {
1203 let cell = self.data.entry((row, col)).or_default();
1204 cell.extra_mut().matrix_span.set_row_span(span);
1205 }
1206
1207 pub fn matrix_row_span(&self, row: u32, col: u32) -> u32 {
1209 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1210 c.matrix_span.row_span()
1211 } else {
1212 1
1213 }
1214 }
1215
1216 pub fn set_matrix_col_span(&mut self, row: u32, col: u32, span: u32) {
1218 let cell = self.data.entry((row, col)).or_default();
1219 cell.extra_mut().matrix_span.set_col_span(span);
1220 }
1221
1222 pub fn matrix_col_span(&self, row: u32, col: u32) -> u32 {
1224 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1225 c.matrix_span.col_span()
1226 } else {
1227 1
1228 }
1229 }
1230
1231 pub fn set_annotation(&mut self, row: u32, col: u32, annotation: Annotation) {
1233 let cell = self.data.entry((row, col)).or_default();
1234 cell.extra_mut().annotation = Some(Box::new(annotation));
1235 }
1236
1237 pub fn clear_annotation(&mut self, row: u32, col: u32) {
1239 if let Some(cell) = self.data.get_mut(&(row, col)) {
1240 cell.extra_mut().annotation = None;
1241 }
1242 }
1243
1244 pub fn annotation(&self, row: u32, col: u32) -> Option<&Annotation> {
1246 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1247 c.annotation.as_ref().map(|v| v.as_ref())
1248 } else {
1249 None
1250 }
1251 }
1252
1253 pub fn annotation_mut(&mut self, row: u32, col: u32) -> Option<&mut Annotation> {
1255 if let Some(CellData { extra: Some(c), .. }) = self.data.get_mut(&(row, col)) {
1256 c.annotation.as_mut().map(|v| v.as_mut())
1257 } else {
1258 None
1259 }
1260 }
1261
1262 pub fn add_draw_frame(&mut self, row: u32, col: u32, draw_frame: DrawFrame) {
1264 let cell = self.data.entry((row, col)).or_default();
1265 cell.extra_mut().draw_frames.push(draw_frame);
1266 }
1267
1268 pub fn clear_draw_frames(&mut self, row: u32, col: u32) {
1270 if let Some(cell) = self.data.get_mut(&(row, col)) {
1271 cell.extra_mut().draw_frames = Vec::new();
1272 }
1273 }
1274
1275 pub fn draw_frames(&self, row: u32, col: u32) -> Option<&Vec<DrawFrame>> {
1277 if let Some(CellData { extra: Some(c), .. }) = self.data.get(&(row, col)) {
1278 Some(c.draw_frames.as_ref())
1279 } else {
1280 None
1281 }
1282 }
1283
1284 pub fn draw_frames_mut(&mut self, row: u32, col: u32) -> Option<&mut Vec<DrawFrame>> {
1286 if let Some(CellData { extra: Some(c), .. }) = self.data.get_mut(&(row, col)) {
1287 Some(c.draw_frames.as_mut())
1288 } else {
1289 None
1290 }
1291 }
1292
1293 pub fn set_header_rows(&mut self, row_start: u32, row_end: u32) {
1296 self.header_rows = Some(Header {
1297 from: row_start,
1298 to: row_end,
1299 });
1300 }
1301
1302 pub fn clear_header_rows(&mut self) {
1304 self.header_rows = None;
1305 }
1306
1307 pub fn header_rows(&self) -> Option<Header> {
1310 self.header_rows.map(Into::into)
1311 }
1312
1313 pub fn set_header_cols(&mut self, col_start: u32, col_end: u32) {
1316 self.header_cols = Some(Header {
1317 from: col_start,
1318 to: col_end,
1319 });
1320 }
1321
1322 pub fn clear_header_cols(&mut self) {
1324 self.header_cols = None;
1325 }
1326
1327 pub fn header_cols(&self) -> Option<Header> {
1330 self.header_cols.map(Into::into)
1331 }
1332
1333 pub fn add_print_range(&mut self, range: CellRange) {
1335 self.print_ranges.get_or_insert_with(Vec::new).push(range);
1336 }
1337
1338 pub fn clear_print_ranges(&mut self) {
1340 self.print_ranges = None;
1341 }
1342
1343 pub fn print_ranges(&self) -> Option<&Vec<CellRange>> {
1345 self.print_ranges.as_ref()
1346 }
1347
1348 pub fn split_col_header(&mut self, col: u32) {
1351 self.config_mut().hor_split_mode = SplitMode::Heading;
1352 self.config_mut().hor_split_pos = col + 1;
1353 self.config_mut().position_right = col + 1;
1354 self.config_mut().cursor_x = col + 1;
1355 }
1356
1357 pub fn split_row_header(&mut self, row: u32) {
1360 self.config_mut().vert_split_mode = SplitMode::Heading;
1361 self.config_mut().vert_split_pos = row + 1;
1362 self.config_mut().position_bottom = row + 1;
1363 self.config_mut().cursor_y = row + 1;
1364 }
1365
1366 pub fn split_horizontal(&mut self, col: u32) {
1369 self.config_mut().hor_split_mode = SplitMode::Split;
1370 self.config_mut().hor_split_pos = col;
1371 }
1372
1373 pub fn split_vertical(&mut self, col: u32) {
1376 self.config_mut().vert_split_mode = SplitMode::Split;
1377 self.config_mut().vert_split_pos = col;
1378 }
1379
1380 pub fn add_col_group(&mut self, from: u32, to: u32) {
1387 assert!(from <= to);
1388 let grp = Grouped::new(from, to, true);
1389 for v in &self.group_cols {
1390 assert!(grp.contains(v) || v.contains(&grp) || grp.disjunct(v));
1391 }
1392 self.group_cols.push(grp);
1393 }
1394
1395 pub fn remove_col_group(&mut self, from: u32, to: u32) {
1397 if let Some(idx) = self
1398 .group_cols
1399 .iter()
1400 .position(|v| v.from == from && v.to == to)
1401 {
1402 self.group_cols.remove(idx);
1403 }
1404 }
1405
1406 pub fn set_col_group_displayed(&mut self, from: u32, to: u32, display: bool) {
1410 if let Some(idx) = self
1411 .group_cols
1412 .iter()
1413 .position(|v| v.from == from && v.to == to)
1414 {
1415 self.group_cols[idx].display = display;
1416
1417 for r in from..=to {
1418 self.set_col_visible(
1419 r,
1420 if display {
1421 Visibility::Visible
1422 } else {
1423 Visibility::Collapsed
1424 },
1425 );
1426 }
1427 }
1428 }
1429
1430 pub fn col_group_count(&self) -> usize {
1432 self.group_cols.len()
1433 }
1434
1435 pub fn col_group(&self, idx: usize) -> Option<&Grouped> {
1437 return self.group_cols.get(idx);
1438 }
1439
1440 pub fn col_group_mut(&mut self, idx: usize) -> Option<&mut Grouped> {
1442 return self.group_cols.get_mut(idx);
1443 }
1444
1445 pub fn col_group_iter(&self) -> impl Iterator<Item = &Grouped> {
1447 self.group_cols.iter()
1448 }
1449
1450 pub fn add_row_group(&mut self, from: u32, to: u32) {
1457 assert!(from <= to);
1458 let grp = Grouped::new(from, to, true);
1459 for v in &self.group_rows {
1460 assert!(grp.contains(v) || v.contains(&grp) || grp.disjunct(v));
1461 }
1462 self.group_rows.push(grp);
1463 }
1464
1465 pub fn remove_row_group(&mut self, from: u32, to: u32) {
1467 if let Some(idx) = self
1468 .group_rows
1469 .iter()
1470 .position(|v| v.from == from && v.to == to)
1471 {
1472 self.group_rows.remove(idx);
1473 }
1474 }
1475
1476 pub fn set_row_group_displayed(&mut self, from: u32, to: u32, display: bool) {
1480 if let Some(idx) = self
1481 .group_rows
1482 .iter()
1483 .position(|v| v.from == from && v.to == to)
1484 {
1485 self.group_rows[idx].display = display;
1486
1487 for r in from..=to {
1488 self.set_row_visible(
1489 r,
1490 if display {
1491 Visibility::Visible
1492 } else {
1493 Visibility::Collapsed
1494 },
1495 );
1496 }
1497 }
1498 }
1499
1500 pub fn row_group_count(&self) -> usize {
1502 self.group_rows.len()
1503 }
1504
1505 pub fn row_group(&self, idx: usize) -> Option<&Grouped> {
1507 return self.group_rows.get(idx);
1508 }
1509
1510 pub fn row_group_iter(&self) -> impl Iterator<Item = &Grouped> {
1512 self.group_rows.iter()
1513 }
1514}
1515
1516#[derive(Debug, Copy, Clone, Default, GetSize)]
1518pub struct Header {
1519 pub from: u32,
1520 pub to: u32,
1521}
1522
1523impl From<Header> for (u32, u32) {
1524 fn from(value: Header) -> Self {
1525 (value.from, value.to)
1526 }
1527}
1528
1529#[derive(Debug, PartialEq, Clone, Copy, GetSize)]
1531pub struct Grouped {
1532 pub from: u32,
1534 pub to: u32,
1536 pub display: bool,
1538}
1539
1540impl Grouped {
1541 pub fn new(from: u32, to: u32, display: bool) -> Self {
1543 Self { from, to, display }
1544 }
1545
1546 pub fn from(&self) -> u32 {
1548 self.from
1549 }
1550
1551 pub fn set_from(&mut self, from: u32) {
1553 self.from = from;
1554 }
1555
1556 pub fn to(&self) -> u32 {
1558 self.to
1559 }
1560
1561 pub fn set_to(&mut self, to: u32) {
1563 self.to = to
1564 }
1565
1566 pub fn display(&self) -> bool {
1568 self.display
1569 }
1570
1571 pub fn set_display(&mut self, display: bool) {
1577 self.display = display;
1578 }
1579
1580 pub fn contains(&self, other: &Grouped) -> bool {
1582 self.from <= other.from && self.to >= other.to
1583 }
1584
1585 pub fn disjunct(&self, other: &Grouped) -> bool {
1587 self.from < other.from && self.to < other.from || self.from > other.to && self.to > other.to
1588 }
1589}
1590
1591#[derive(Clone, Copy, Debug, GetSize)]
1595#[allow(missing_docs)]
1596pub enum SplitMode {
1597 None = 0,
1598 Split = 1,
1599 Heading = 2,
1600}
1601
1602impl TryFrom<i16> for SplitMode {
1603 type Error = OdsError;
1604
1605 fn try_from(n: i16) -> Result<Self, Self::Error> {
1606 match n {
1607 0 => Ok(SplitMode::None),
1608 1 => Ok(SplitMode::Split),
1609 2 => Ok(SplitMode::Heading),
1610 _ => Err(OdsError::Ods(format!("Invalid split mode {}", n))),
1611 }
1612 }
1613}
1614
1615#[derive(Clone, Debug, GetSize)]
1617pub struct SheetConfig {
1618 pub cursor_x: u32,
1620 pub cursor_y: u32,
1622 pub hor_split_mode: SplitMode,
1624 pub vert_split_mode: SplitMode,
1626 pub hor_split_pos: u32,
1628 pub vert_split_pos: u32,
1630 pub active_split_range: i16,
1635 pub position_left: u32,
1641 pub position_right: u32,
1646 pub position_top: u32,
1652 pub position_bottom: u32,
1657 pub zoom_type: i16,
1660 pub zoom_value: i32,
1662 pub page_view_zoom_value: i32,
1664 pub show_grid: bool,
1666}
1667
1668impl Default for SheetConfig {
1669 fn default() -> Self {
1670 Self {
1671 cursor_x: 0,
1672 cursor_y: 0,
1673 hor_split_mode: SplitMode::None,
1674 vert_split_mode: SplitMode::None,
1675 hor_split_pos: 0,
1676 vert_split_pos: 0,
1677 active_split_range: 2,
1678 position_left: 0,
1679 position_right: 0,
1680 position_top: 0,
1681 position_bottom: 0,
1682 zoom_type: 0,
1683 zoom_value: 100,
1684 page_view_zoom_value: 60,
1685 show_grid: true,
1686 }
1687 }
1688}
1689
1690pub(crate) fn dedup_colheader(sheet: &mut Sheet) -> Result<(), OdsError> {
1692 fn limited_eq(ch1: &ColHeader, ch2: &ColHeader) -> bool {
1693 ch1.style == ch2.style
1694 && ch1.cellstyle == ch2.cellstyle
1695 && ch1.visible == ch2.visible
1696 && ch1.width == ch2.width
1697 }
1698
1699 let col_header = mem::take(&mut sheet.col_header);
1700
1701 let mut new_col_header = BTreeMap::new();
1702 let mut new = None;
1703 for (col, header) in col_header {
1704 match new.as_mut() {
1705 None => {
1706 new = Some((col, header));
1707 }
1708 Some((new_col, new_header)) => {
1709 if limited_eq(new_header, &header) {
1710 new_header.span += header.span;
1711 } else {
1712 new_col_header
1713 .insert(mem::replace(new_col, col), mem::replace(new_header, header));
1714 }
1715 }
1716 }
1717 }
1718 if let Some((new_col, new_header)) = new {
1719 new_col_header.insert(new_col, new_header);
1720 }
1721
1722 sheet.col_header = new_col_header;
1723
1724 Ok(())
1725}