spreadsheet_ods/
workbook_.rs

1//!
2//! Workbook
3//!
4
5use get_size2::GetSize;
6use std::borrow::Borrow;
7use std::fmt;
8use std::fmt::Formatter;
9use std::hash::Hash;
10
11use icu_locale_core::{locale, Locale};
12
13use crate::config::Config;
14use crate::defaultstyles::{DefaultFormat, DefaultStyle};
15use crate::ds::detach::{Detach, Detached};
16use crate::format::ValueFormatTrait;
17use crate::io::read::default_settings;
18use crate::io::NamespaceMap;
19use crate::manifest::Manifest;
20use crate::metadata::Metadata;
21use crate::sheet_::Sheet;
22use crate::style::{
23    ColStyle, ColStyleRef, FontFaceDecl, GraphicStyle, GraphicStyleRef, MasterPage, MasterPageRef,
24    PageStyle, PageStyleRef, ParagraphStyle, ParagraphStyleRef, RowStyle, RowStyleRef, RubyStyle,
25    RubyStyleRef, TableStyle, TableStyleRef, TextStyle, TextStyleRef,
26};
27use crate::validation::{Validation, ValidationRef};
28use crate::value_::ValueType;
29use crate::xlink::{XLinkActuate, XLinkType};
30use crate::xmltree::{XmlContent, XmlTag};
31use crate::{
32    locale, CellStyle, CellStyleRef, HashMap, ValueFormatBoolean, ValueFormatCurrency,
33    ValueFormatDateTime, ValueFormatNumber, ValueFormatPercentage, ValueFormatRef, ValueFormatText,
34    ValueFormatTimeDuration,
35};
36
37/// Book is the main structure for the Spreadsheet.
38#[derive(Clone, GetSize)]
39pub struct WorkBook {
40    /// The data.
41    pub(crate) sheets: Vec<Detach<Sheet>>,
42
43    /// ODS Version
44    pub(crate) version: String,
45
46    /// FontDecl hold the style:font-face elements
47    pub(crate) fonts: HashMap<String, FontFaceDecl>,
48
49    /// Auto-Styles. Maps the prefix to a number.
50    pub(crate) autonum: HashMap<String, u32>,
51
52    /// Scripts
53    pub(crate) scripts: Vec<Script>,
54    pub(crate) event_listener: HashMap<String, EventListener>,
55
56    /// Styles hold the style:style elements.
57    pub(crate) tablestyles: HashMap<TableStyleRef, TableStyle>,
58    pub(crate) rowstyles: HashMap<RowStyleRef, RowStyle>,
59    pub(crate) colstyles: HashMap<ColStyleRef, ColStyle>,
60    pub(crate) cellstyles: HashMap<CellStyleRef, CellStyle>,
61    pub(crate) paragraphstyles: HashMap<ParagraphStyleRef, ParagraphStyle>,
62    pub(crate) textstyles: HashMap<TextStyleRef, TextStyle>,
63    pub(crate) rubystyles: HashMap<RubyStyleRef, RubyStyle>,
64    pub(crate) graphicstyles: HashMap<GraphicStyleRef, GraphicStyle>,
65
66    /// Value-styles are actual formatting instructions for various datatypes.
67    /// Represents the various number:xxx-style elements.
68    pub(crate) formats_boolean: HashMap<String, ValueFormatBoolean>,
69    pub(crate) formats_number: HashMap<String, ValueFormatNumber>,
70    pub(crate) formats_percentage: HashMap<String, ValueFormatPercentage>,
71    pub(crate) formats_currency: HashMap<String, ValueFormatCurrency>,
72    pub(crate) formats_text: HashMap<String, ValueFormatText>,
73    pub(crate) formats_datetime: HashMap<String, ValueFormatDateTime>,
74    pub(crate) formats_timeduration: HashMap<String, ValueFormatTimeDuration>,
75
76    /// Default-styles per Type.
77    /// This is only used when writing the ods file.
78    pub(crate) def_styles: HashMap<ValueType, CellStyleRef>,
79
80    /// Page-layout data.
81    pub(crate) pagestyles: HashMap<PageStyleRef, PageStyle>,
82    pub(crate) masterpages: HashMap<MasterPageRef, MasterPage>,
83
84    /// Validations.
85    pub(crate) validations: HashMap<ValidationRef, Validation>,
86
87    /// Configuration data. Internal cache for all values.
88    /// Mapped into WorkBookConfig, SheetConfig.
89    pub(crate) config: Detach<Config>,
90    /// User modifiable config.
91    pub(crate) workbook_config: WorkBookConfig,
92    /// Keeps all the namespaces.
93    pub(crate) xmlns: HashMap<String, NamespaceMap>,
94
95    /// All extra files contained in the zip manifest are copied here.
96    pub(crate) manifest: HashMap<String, Manifest>,
97
98    /// Metadata
99    pub(crate) metadata: Metadata,
100
101    /// other stuff ...
102    pub(crate) extra: Vec<XmlTag>,
103}
104
105impl fmt::Debug for WorkBook {
106    fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result {
107        writeln!(f, "{:?}", self.version)?;
108        for s in self.sheets.iter() {
109            writeln!(f, "{:?}", s)?;
110        }
111        for s in self.fonts.values() {
112            writeln!(f, "{:?}", s)?;
113        }
114        for s in self.tablestyles.values() {
115            writeln!(f, "{:?}", s)?;
116        }
117        for s in self.rowstyles.values() {
118            writeln!(f, "{:?}", s)?;
119        }
120        for s in self.colstyles.values() {
121            writeln!(f, "{:?}", s)?;
122        }
123        for s in self.cellstyles.values() {
124            writeln!(f, "{:?}", s)?;
125        }
126        for s in self.paragraphstyles.values() {
127            writeln!(f, "{:?}", s)?;
128        }
129        for s in self.textstyles.values() {
130            writeln!(f, "{:?}", s)?;
131        }
132        for s in self.rubystyles.values() {
133            writeln!(f, "{:?}", s)?;
134        }
135        for s in self.graphicstyles.values() {
136            writeln!(f, "{:?}", s)?;
137        }
138        for s in self.formats_boolean.values() {
139            writeln!(f, "{:?}", s)?;
140        }
141        for s in self.formats_number.values() {
142            writeln!(f, "{:?}", s)?;
143        }
144        for s in self.formats_percentage.values() {
145            writeln!(f, "{:?}", s)?;
146        }
147        for s in self.formats_currency.values() {
148            writeln!(f, "{:?}", s)?;
149        }
150        for s in self.formats_text.values() {
151            writeln!(f, "{:?}", s)?;
152        }
153        for s in self.formats_datetime.values() {
154            writeln!(f, "{:?}", s)?;
155        }
156        for s in self.formats_timeduration.values() {
157            writeln!(f, "{:?}", s)?;
158        }
159        for (t, s) in &self.def_styles {
160            writeln!(f, "{:?} -> {:?}", t, s)?;
161        }
162        for s in self.pagestyles.values() {
163            writeln!(f, "{:?}", s)?;
164        }
165        for s in self.masterpages.values() {
166            writeln!(f, "{:?}", s)?;
167        }
168        for s in self.validations.values() {
169            writeln!(f, "{:?}", s)?;
170        }
171        writeln!(f, "{:?}", &self.workbook_config)?;
172        for v in self.manifest.values() {
173            writeln!(f, "extras {:?}", v)?;
174        }
175        writeln!(f, "{:?}", &self.metadata)?;
176        for xtr in &self.extra {
177            writeln!(f, "extras {:?}", xtr)?;
178        }
179        Ok(())
180    }
181}
182
183/// Autogenerate a stylename. Runs a counter with the prefix and
184/// checks for existence.
185fn auto_style_name2<K, V>(
186    autonum: &mut HashMap<String, u32>,
187    prefix: &str,
188    styles: &HashMap<K, V>,
189) -> String
190where
191    K: Borrow<str> + Hash + Eq,
192{
193    let mut cnt = if let Some(n) = autonum.get(prefix) {
194        n + 1
195    } else {
196        0
197    };
198
199    let style_name = loop {
200        let style_name = format!("{}{}", prefix, cnt);
201        if !styles.contains_key(&style_name) {
202            break style_name;
203        }
204        cnt += 1;
205    };
206
207    autonum.insert(prefix.to_string(), cnt);
208
209    style_name
210}
211
212/// Autogenerate a stylename. Runs a counter with the prefix and
213/// checks for existence.
214fn auto_style_name<T>(
215    autonum: &mut HashMap<String, u32>,
216    prefix: &str,
217    styles: &HashMap<String, T>,
218) -> String {
219    let mut cnt = if let Some(n) = autonum.get(prefix) {
220        n + 1
221    } else {
222        0
223    };
224
225    let style_name = loop {
226        let style_name = format!("{}{}", prefix, cnt);
227        if !styles.contains_key(&style_name) {
228            break style_name;
229        }
230        cnt += 1;
231    };
232
233    autonum.insert(prefix.to_string(), cnt);
234
235    style_name
236}
237
238impl Default for WorkBook {
239    fn default() -> Self {
240        WorkBook::new(locale!("en"))
241    }
242}
243
244impl WorkBook {
245    /// Creates a new, completely empty workbook.
246    ///
247    /// WorkBook::locale_settings can be used to initialize default styles.
248    pub fn new_empty() -> Self {
249        WorkBook {
250            sheets: Default::default(),
251            version: "1.3".to_string(),
252            fonts: Default::default(),
253            autonum: Default::default(),
254            scripts: Default::default(),
255            event_listener: Default::default(),
256            tablestyles: Default::default(),
257            rowstyles: Default::default(),
258            colstyles: Default::default(),
259            cellstyles: Default::default(),
260            paragraphstyles: Default::default(),
261            textstyles: Default::default(),
262            rubystyles: Default::default(),
263            graphicstyles: Default::default(),
264            formats_boolean: Default::default(),
265            formats_number: Default::default(),
266            formats_percentage: Default::default(),
267            formats_currency: Default::default(),
268            formats_text: Default::default(),
269            formats_datetime: Default::default(),
270            formats_timeduration: Default::default(),
271            def_styles: Default::default(),
272            pagestyles: Default::default(),
273            masterpages: Default::default(),
274            validations: Default::default(),
275            config: default_settings(),
276            workbook_config: Default::default(),
277            extra: vec![],
278            manifest: Default::default(),
279            metadata: Default::default(),
280            xmlns: Default::default(),
281        }
282    }
283
284    /// Creates a new workbook, and initializes default styles according
285    /// to the given locale.
286    ///
287    /// If the locale is not supported no ValueFormat's are set and all
288    /// depends on the application opening the spreadsheet.
289    ///
290    /// The available locales can be activated via feature-flags.
291    pub fn new(locale: Locale) -> Self {
292        let mut wb = WorkBook::new_empty();
293        wb.locale_settings(locale);
294        wb
295    }
296
297    /// Creates a set of default formats and styles for every value-type.
298    ///
299    /// If the locale is not supported no ValueFormat's are set and all
300    /// depends on the application opening the spreadsheet.
301    ///
302    /// The available locales can be activated via feature-flags.
303    pub fn locale_settings(&mut self, locale: Locale) {
304        if let Some(lf) = locale::localized_format(locale) {
305            self.add_boolean_format(lf.boolean_format());
306            self.add_number_format(lf.number_format());
307            self.add_percentage_format(lf.percentage_format());
308            self.add_currency_format(lf.currency_format());
309            self.add_datetime_format(lf.date_format());
310            self.add_datetime_format(lf.datetime_format());
311            self.add_datetime_format(lf.time_of_day_format());
312            self.add_timeduration_format(lf.time_interval_format());
313        }
314
315        self.add_cellstyle(CellStyle::new(DefaultStyle::bool(), &DefaultFormat::bool()));
316        self.add_cellstyle(CellStyle::new(
317            DefaultStyle::number(),
318            &DefaultFormat::number(),
319        ));
320        self.add_cellstyle(CellStyle::new(
321            DefaultStyle::percent(),
322            &DefaultFormat::percent(),
323        ));
324        self.add_cellstyle(CellStyle::new(
325            DefaultStyle::currency(),
326            &DefaultFormat::currency(),
327        ));
328        self.add_cellstyle(CellStyle::new(DefaultStyle::date(), &DefaultFormat::date()));
329        self.add_cellstyle(CellStyle::new(
330            DefaultStyle::datetime(),
331            &DefaultFormat::datetime(),
332        ));
333        self.add_cellstyle(CellStyle::new(
334            DefaultStyle::time_of_day(),
335            &DefaultFormat::time_of_day(),
336        ));
337        self.add_cellstyle(CellStyle::new(
338            DefaultStyle::time_interval(),
339            &DefaultFormat::time_interval(),
340        ));
341
342        self.add_def_style(ValueType::Boolean, DefaultStyle::bool());
343        self.add_def_style(ValueType::Number, DefaultStyle::number());
344        self.add_def_style(ValueType::Percentage, DefaultStyle::percent());
345        self.add_def_style(ValueType::Currency, DefaultStyle::currency());
346        self.add_def_style(ValueType::DateTime, DefaultStyle::date());
347        self.add_def_style(ValueType::TimeDuration, DefaultStyle::time_interval());
348    }
349
350    /// ODS version. Defaults to 1.3.
351    pub fn version(&self) -> &String {
352        &self.version
353    }
354
355    /// ODS version. Defaults to 1.3.
356    /// It's not advised to set another value.
357    pub fn set_version(&mut self, version: String) {
358        self.version = version;
359    }
360
361    /// Configuration flags.
362    pub fn config(&self) -> &WorkBookConfig {
363        &self.workbook_config
364    }
365
366    /// Configuration flags.
367    pub fn config_mut(&mut self) -> &mut WorkBookConfig {
368        &mut self.workbook_config
369    }
370
371    /// Number of sheets.
372    pub fn num_sheets(&self) -> usize {
373        self.sheets.len()
374    }
375
376    /// Finds the sheet index by the sheet-name.
377    pub fn sheet_idx<S: AsRef<str>>(&self, name: S) -> Option<usize> {
378        for (idx, sheet) in self.sheets.iter().enumerate() {
379            if sheet.name() == name.as_ref() {
380                return Some(idx);
381            }
382        }
383        None
384    }
385
386    /// Detaches a sheet.
387    /// Useful if you have to make mutating calls to the workbook and
388    /// the sheet intermixed.
389    ///
390    /// Warning
391    ///
392    /// The sheet has to be re-attached before saving the workbook.
393    ///
394    /// Panics
395    ///
396    /// Panics if the sheet has already been detached.
397    /// Panics if n is out of bounds.
398    pub fn detach_sheet(&mut self, n: usize) -> Detached<usize, Sheet> {
399        self.sheets[n].detach(n)
400    }
401
402    /// Reattaches the sheet in the place it was before.
403    ///
404    /// Panics
405    ///
406    /// Panics if n is out of bounds.
407    pub fn attach_sheet(&mut self, sheet: Detached<usize, Sheet>) {
408        self.sheets[Detached::key(&sheet)].attach(sheet)
409    }
410
411    /// Returns a certain sheet.
412    ///
413    /// Panics
414    ///
415    /// Panics if n is out of bounds.
416    pub fn sheet(&self, n: usize) -> &Sheet {
417        self.sheets[n].as_ref()
418    }
419
420    /// Returns a certain sheet.
421    ///
422    /// Panics
423    ///
424    /// Panics if n does not exist.
425    pub fn sheet_mut(&mut self, n: usize) -> &mut Sheet {
426        self.sheets[n].as_mut()
427    }
428
429    /// Returns iterator over sheets.
430    pub fn iter_sheets(&self) -> impl Iterator<Item = &Sheet> {
431        self.sheets.iter().map(|sheet| &**sheet)
432    }
433
434    /// Inserts the sheet at the given position.
435    pub fn insert_sheet(&mut self, i: usize, sheet: Sheet) {
436        self.sheets.insert(i, sheet.into());
437    }
438
439    /// Appends a sheet.
440    pub fn push_sheet(&mut self, sheet: Sheet) {
441        self.sheets.push(sheet.into());
442    }
443
444    /// Removes a sheet from the table.
445    ///
446    /// Panics
447    ///
448    /// Panics if the sheet was detached.
449    pub fn remove_sheet(&mut self, n: usize) -> Sheet {
450        self.sheets.remove(n).take()
451    }
452
453    /// Scripts.
454    pub fn add_script(&mut self, v: Script) {
455        self.scripts.push(v);
456    }
457
458    /// Scripts.
459    pub fn iter_scripts(&self) -> impl Iterator<Item = &Script> {
460        self.scripts.iter()
461    }
462
463    /// Scripts
464    pub fn scripts(&self) -> &Vec<Script> {
465        &self.scripts
466    }
467
468    /// Scripts
469    pub fn scripts_mut(&mut self) -> &mut Vec<Script> {
470        &mut self.scripts
471    }
472
473    /// Event-Listener
474    pub fn add_event_listener(&mut self, e: EventListener) {
475        self.event_listener.insert(e.event_name.clone(), e);
476    }
477
478    /// Event-Listener
479    pub fn remove_event_listener(&mut self, event_name: &str) -> Option<EventListener> {
480        self.event_listener.remove(event_name)
481    }
482
483    /// Event-Listener
484    pub fn iter_event_listeners(&self) -> impl Iterator<Item = &EventListener> {
485        self.event_listener.values()
486    }
487
488    /// Event-Listener
489    pub fn event_listener(&self, event_name: &str) -> Option<&EventListener> {
490        self.event_listener.get(event_name)
491    }
492
493    /// Event-Listener
494    pub fn event_listener_mut(&mut self, event_name: &str) -> Option<&mut EventListener> {
495        self.event_listener.get_mut(event_name)
496    }
497
498    /// Adds a default-style for all new values.
499    /// This information is only used when writing the data to the ODS file.
500    pub fn add_def_style(&mut self, value_type: ValueType, style: CellStyleRef) {
501        self.def_styles.insert(value_type, style);
502    }
503
504    /// Returns the default style name.
505    pub fn def_style(&self, value_type: ValueType) -> Option<&CellStyleRef> {
506        self.def_styles.get(&value_type)
507    }
508
509    /// Adds a font.
510    pub fn add_font(&mut self, font: FontFaceDecl) {
511        self.fonts.insert(font.name().to_string(), font);
512    }
513
514    /// Removes a font.
515    pub fn remove_font(&mut self, name: &str) -> Option<FontFaceDecl> {
516        self.fonts.remove(name)
517    }
518
519    /// Iterates the fonts.
520    pub fn iter_fonts(&self) -> impl Iterator<Item = &FontFaceDecl> {
521        self.fonts.values()
522    }
523
524    /// Returns the FontDecl.
525    pub fn font(&self, name: &str) -> Option<&FontFaceDecl> {
526        self.fonts.get(name)
527    }
528
529    /// Returns a mutable FontDecl.
530    pub fn font_mut(&mut self, name: &str) -> Option<&mut FontFaceDecl> {
531        self.fonts.get_mut(name)
532    }
533
534    /// Adds a style.
535    /// Unnamed styles will be assigned an automatic name.
536    pub fn add_tablestyle(&mut self, mut style: TableStyle) -> TableStyleRef {
537        if style.name().is_empty() {
538            style.set_name(auto_style_name2(&mut self.autonum, "ta", &self.tablestyles));
539        }
540        let sref = style.style_ref();
541        self.tablestyles.insert(style.style_ref(), style);
542        sref
543    }
544
545    /// Removes a style.
546    pub fn remove_tablestyle<S: AsRef<str>>(&mut self, name: S) -> Option<TableStyle> {
547        self.tablestyles.remove(name.as_ref())
548    }
549
550    /// Iterates the table-styles.
551    pub fn iter_table_styles(&self) -> impl Iterator<Item = &TableStyle> {
552        self.tablestyles.values()
553    }
554
555    /// Returns the style.
556    pub fn tablestyle<S: AsRef<str>>(&self, name: S) -> Option<&TableStyle> {
557        self.tablestyles.get(name.as_ref())
558    }
559
560    /// Returns the mutable style.
561    pub fn tablestyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut TableStyle> {
562        self.tablestyles.get_mut(name.as_ref())
563    }
564
565    /// Adds a style.
566    /// Unnamed styles will be assigned an automatic name.
567    pub fn add_rowstyle(&mut self, mut style: RowStyle) -> RowStyleRef {
568        if style.name().is_empty() {
569            style.set_name(auto_style_name2(&mut self.autonum, "ro", &self.rowstyles));
570        }
571        let sref = style.style_ref();
572        self.rowstyles.insert(style.style_ref(), style);
573        sref
574    }
575
576    /// Removes a style.
577    pub fn remove_rowstyle<S: AsRef<str>>(&mut self, name: S) -> Option<RowStyle> {
578        self.rowstyles.remove(name.as_ref())
579    }
580
581    /// Returns the style.
582    pub fn rowstyle<S: AsRef<str>>(&self, name: S) -> Option<&RowStyle> {
583        self.rowstyles.get(name.as_ref())
584    }
585
586    /// Returns the mutable style.
587    pub fn rowstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut RowStyle> {
588        self.rowstyles.get_mut(name.as_ref())
589    }
590
591    /// Returns iterator over styles.
592    pub fn iter_rowstyles(&self) -> impl Iterator<Item = &RowStyle> {
593        self.rowstyles.values()
594    }
595
596    /// Adds a style.
597    /// Unnamed styles will be assigned an automatic name.
598    pub fn add_colstyle(&mut self, mut style: ColStyle) -> ColStyleRef {
599        if style.name().is_empty() {
600            style.set_name(auto_style_name2(&mut self.autonum, "co", &self.colstyles));
601        }
602        let sref = style.style_ref();
603        self.colstyles.insert(style.style_ref(), style);
604        sref
605    }
606
607    /// Removes a style.
608    pub fn remove_colstyle<S: AsRef<str>>(&mut self, name: S) -> Option<ColStyle> {
609        self.colstyles.remove(name.as_ref())
610    }
611
612    /// Returns the style.
613    pub fn colstyle<S: AsRef<str>>(&self, name: S) -> Option<&ColStyle> {
614        self.colstyles.get(name.as_ref())
615    }
616
617    /// Returns the mutable style.
618    pub fn colstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut ColStyle> {
619        self.colstyles.get_mut(name.as_ref())
620    }
621
622    /// Returns iterator over styles.
623    pub fn iter_colstyles(&self) -> impl Iterator<Item = &ColStyle> {
624        self.colstyles.values()
625    }
626
627    /// Adds a style.
628    /// Unnamed styles will be assigned an automatic name.
629    pub fn add_cellstyle(&mut self, mut style: CellStyle) -> CellStyleRef {
630        if style.name().is_empty() {
631            style.set_name(auto_style_name2(&mut self.autonum, "ce", &self.cellstyles));
632        }
633        let sref = style.style_ref();
634        self.cellstyles.insert(style.style_ref(), style);
635        sref
636    }
637
638    /// Removes a style.
639    pub fn remove_cellstyle<S: AsRef<str>>(&mut self, name: S) -> Option<CellStyle> {
640        self.cellstyles.remove(name.as_ref())
641    }
642
643    /// Returns iterator over styles.
644    pub fn iter_cellstyles(&self) -> impl Iterator<Item = &CellStyle> {
645        self.cellstyles.values()
646    }
647
648    /// Returns the style.
649    pub fn cellstyle<S: AsRef<str>>(&self, name: S) -> Option<&CellStyle> {
650        self.cellstyles.get(name.as_ref())
651    }
652
653    /// Returns the mutable style.
654    pub fn cellstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut CellStyle> {
655        self.cellstyles.get_mut(name.as_ref())
656    }
657
658    /// Adds a style.
659    /// Unnamed styles will be assigned an automatic name.
660    pub fn add_paragraphstyle(&mut self, mut style: ParagraphStyle) -> ParagraphStyleRef {
661        if style.name().is_empty() {
662            style.set_name(auto_style_name2(
663                &mut self.autonum,
664                "para",
665                &self.paragraphstyles,
666            ));
667        }
668        let sref = style.style_ref();
669        self.paragraphstyles.insert(style.style_ref(), style);
670        sref
671    }
672
673    /// Removes a style.
674    pub fn remove_paragraphstyle<S: AsRef<str>>(&mut self, name: S) -> Option<ParagraphStyle> {
675        self.paragraphstyles.remove(name.as_ref())
676    }
677
678    /// Returns iterator over styles.
679    pub fn iter_paragraphstyles(&self) -> impl Iterator<Item = &ParagraphStyle> {
680        self.paragraphstyles.values()
681    }
682
683    /// Returns the style.
684    pub fn paragraphstyle<S: AsRef<str>>(&self, name: S) -> Option<&ParagraphStyle> {
685        self.paragraphstyles.get(name.as_ref())
686    }
687
688    /// Returns the mutable style.
689    pub fn paragraphstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut ParagraphStyle> {
690        self.paragraphstyles.get_mut(name.as_ref())
691    }
692
693    /// Adds a style.
694    /// Unnamed styles will be assigned an automatic name.
695    pub fn add_textstyle(&mut self, mut style: TextStyle) -> TextStyleRef {
696        if style.name().is_empty() {
697            style.set_name(auto_style_name2(&mut self.autonum, "txt", &self.textstyles));
698        }
699        let sref = style.style_ref();
700        self.textstyles.insert(style.style_ref(), style);
701        sref
702    }
703
704    /// Removes a style.
705    pub fn remove_textstyle<S: AsRef<str>>(&mut self, name: S) -> Option<TextStyle> {
706        self.textstyles.remove(name.as_ref())
707    }
708
709    /// Returns iterator over styles.
710    pub fn iter_textstyles(&self) -> impl Iterator<Item = &TextStyle> {
711        self.textstyles.values()
712    }
713
714    /// Returns the style.
715    pub fn textstyle<S: AsRef<str>>(&self, name: S) -> Option<&TextStyle> {
716        self.textstyles.get(name.as_ref())
717    }
718
719    /// Returns the mutable style.
720    pub fn textstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut TextStyle> {
721        self.textstyles.get_mut(name.as_ref())
722    }
723
724    /// Adds a style.
725    /// Unnamed styles will be assigned an automatic name.
726    pub fn add_rubystyle(&mut self, mut style: RubyStyle) -> RubyStyleRef {
727        if style.name().is_empty() {
728            style.set_name(auto_style_name2(
729                &mut self.autonum,
730                "ruby",
731                &self.rubystyles,
732            ));
733        }
734        let sref = style.style_ref();
735        self.rubystyles.insert(style.style_ref(), style);
736        sref
737    }
738
739    /// Removes a style.
740    pub fn remove_rubystyle<S: AsRef<str>>(&mut self, name: S) -> Option<RubyStyle> {
741        self.rubystyles.remove(name.as_ref())
742    }
743
744    /// Returns iterator over styles.
745    pub fn iter_rubystyles(&self) -> impl Iterator<Item = &RubyStyle> {
746        self.rubystyles.values()
747    }
748
749    /// Returns the style.
750    pub fn rubystyle<S: AsRef<str>>(&self, name: S) -> Option<&RubyStyle> {
751        self.rubystyles.get(name.as_ref())
752    }
753
754    /// Returns the mutable style.
755    pub fn rubystyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut RubyStyle> {
756        self.rubystyles.get_mut(name.as_ref())
757    }
758
759    /// Adds a style.
760    /// Unnamed styles will be assigned an automatic name.
761    pub fn add_graphicstyle(&mut self, mut style: GraphicStyle) -> GraphicStyleRef {
762        if style.name().is_empty() {
763            style.set_name(auto_style_name2(
764                &mut self.autonum,
765                "gr",
766                &self.graphicstyles,
767            ));
768        }
769        let sref = style.style_ref();
770        self.graphicstyles.insert(style.style_ref(), style);
771        sref
772    }
773
774    /// Removes a style.
775    pub fn remove_graphicstyle<S: AsRef<str>>(&mut self, name: S) -> Option<GraphicStyle> {
776        self.graphicstyles.remove(name.as_ref())
777    }
778
779    /// Returns iterator over styles.
780    pub fn iter_graphicstyles(&self) -> impl Iterator<Item = &GraphicStyle> {
781        self.graphicstyles.values()
782    }
783
784    /// Returns the style.
785    pub fn graphicstyle<S: AsRef<str>>(&self, name: S) -> Option<&GraphicStyle> {
786        self.graphicstyles.get(name.as_ref())
787    }
788
789    /// Returns the mutable style.
790    pub fn graphicstyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut GraphicStyle> {
791        self.graphicstyles.get_mut(name.as_ref())
792    }
793
794    /// Adds a value format.
795    /// Unnamed formats will be assigned an automatic name.
796    pub fn add_boolean_format(&mut self, mut vstyle: ValueFormatBoolean) -> ValueFormatRef {
797        if vstyle.name().is_empty() {
798            vstyle.set_name(
799                auto_style_name(&mut self.autonum, "val_boolean", &self.formats_boolean).as_str(),
800            );
801        }
802        let sref = vstyle.format_ref();
803        self.formats_boolean
804            .insert(vstyle.name().to_string(), vstyle);
805        sref
806    }
807
808    /// Removes the format.
809    pub fn remove_boolean_format(&mut self, name: &str) -> Option<ValueFormatBoolean> {
810        self.formats_boolean.remove(name)
811    }
812
813    /// Returns iterator over formats.
814    pub fn iter_boolean_formats(&self) -> impl Iterator<Item = &ValueFormatBoolean> {
815        self.formats_boolean.values()
816    }
817
818    /// Returns the format.
819    pub fn boolean_format(&self, name: &str) -> Option<&ValueFormatBoolean> {
820        self.formats_boolean.get(name)
821    }
822
823    /// Returns the mutable format.
824    pub fn boolean_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatBoolean> {
825        self.formats_boolean.get_mut(name)
826    }
827
828    /// Adds a value format.
829    /// Unnamed formats will be assigned an automatic name.
830    pub fn add_number_format(&mut self, mut vstyle: ValueFormatNumber) -> ValueFormatRef {
831        if vstyle.name().is_empty() {
832            vstyle.set_name(
833                auto_style_name(&mut self.autonum, "val_number", &self.formats_number).as_str(),
834            );
835        }
836        let sref = vstyle.format_ref();
837        self.formats_number
838            .insert(vstyle.name().to_string(), vstyle);
839        sref
840    }
841
842    /// Removes the format.
843    pub fn remove_number_format(&mut self, name: &str) -> Option<ValueFormatNumber> {
844        self.formats_number.remove(name)
845    }
846
847    /// Returns iterator over formats.
848    pub fn iter_number_formats(&self) -> impl Iterator<Item = &ValueFormatNumber> {
849        self.formats_number.values()
850    }
851
852    /// Returns the format.
853    pub fn number_format(&self, name: &str) -> Option<&ValueFormatNumber> {
854        self.formats_number.get(name)
855    }
856
857    /// Returns the mutable format.
858    pub fn number_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatNumber> {
859        self.formats_number.get_mut(name)
860    }
861
862    /// Adds a value format.
863    /// Unnamed formats will be assigned an automatic name.
864    pub fn add_percentage_format(&mut self, mut vstyle: ValueFormatPercentage) -> ValueFormatRef {
865        if vstyle.name().is_empty() {
866            vstyle.set_name(
867                auto_style_name(
868                    &mut self.autonum,
869                    "val_percentage",
870                    &self.formats_percentage,
871                )
872                .as_str(),
873            );
874        }
875        let sref = vstyle.format_ref();
876        self.formats_percentage
877            .insert(vstyle.name().to_string(), vstyle);
878        sref
879    }
880
881    /// Removes the format.
882    pub fn remove_percentage_format(&mut self, name: &str) -> Option<ValueFormatPercentage> {
883        self.formats_percentage.remove(name)
884    }
885
886    /// Returns iterator over formats.
887    pub fn iter_percentage_formats(&self) -> impl Iterator<Item = &ValueFormatPercentage> {
888        self.formats_percentage.values()
889    }
890
891    /// Returns the format.
892    pub fn percentage_format(&self, name: &str) -> Option<&ValueFormatPercentage> {
893        self.formats_percentage.get(name)
894    }
895
896    /// Returns the mutable format.
897    pub fn percentage_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatPercentage> {
898        self.formats_percentage.get_mut(name)
899    }
900
901    /// Adds a value format.
902    /// Unnamed formats will be assigned an automatic name.
903    pub fn add_currency_format(&mut self, mut vstyle: ValueFormatCurrency) -> ValueFormatRef {
904        if vstyle.name().is_empty() {
905            vstyle.set_name(
906                auto_style_name(&mut self.autonum, "val_currency", &self.formats_currency).as_str(),
907            );
908        }
909        let sref = vstyle.format_ref();
910        self.formats_currency
911            .insert(vstyle.name().to_string(), vstyle);
912        sref
913    }
914
915    /// Removes the format.
916    pub fn remove_currency_format(&mut self, name: &str) -> Option<ValueFormatCurrency> {
917        self.formats_currency.remove(name)
918    }
919
920    /// Returns iterator over formats.
921    pub fn iter_currency_formats(&self) -> impl Iterator<Item = &ValueFormatCurrency> {
922        self.formats_currency.values()
923    }
924
925    /// Returns the format.
926    pub fn currency_format(&self, name: &str) -> Option<&ValueFormatCurrency> {
927        self.formats_currency.get(name)
928    }
929
930    /// Returns the mutable format.
931    pub fn currency_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatCurrency> {
932        self.formats_currency.get_mut(name)
933    }
934
935    /// Adds a value format.
936    /// Unnamed formats will be assigned an automatic name.
937    pub fn add_text_format(&mut self, mut vstyle: ValueFormatText) -> ValueFormatRef {
938        if vstyle.name().is_empty() {
939            vstyle.set_name(
940                auto_style_name(&mut self.autonum, "val_text", &self.formats_text).as_str(),
941            );
942        }
943        let sref = vstyle.format_ref();
944        self.formats_text.insert(vstyle.name().to_string(), vstyle);
945        sref
946    }
947
948    /// Removes the format.
949    pub fn remove_text_format(&mut self, name: &str) -> Option<ValueFormatText> {
950        self.formats_text.remove(name)
951    }
952
953    /// Returns iterator over formats.
954    pub fn iter_text_formats(&self) -> impl Iterator<Item = &ValueFormatText> {
955        self.formats_text.values()
956    }
957
958    /// Returns the format.
959    pub fn text_format(&self, name: &str) -> Option<&ValueFormatText> {
960        self.formats_text.get(name)
961    }
962
963    /// Returns the mutable format.
964    pub fn text_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatText> {
965        self.formats_text.get_mut(name)
966    }
967
968    /// Adds a value format.
969    /// Unnamed formats will be assigned an automatic name.
970    pub fn add_datetime_format(&mut self, mut vstyle: ValueFormatDateTime) -> ValueFormatRef {
971        if vstyle.name().is_empty() {
972            vstyle.set_name(
973                auto_style_name(&mut self.autonum, "val_datetime", &self.formats_datetime).as_str(),
974            );
975        }
976        let sref = vstyle.format_ref();
977        self.formats_datetime
978            .insert(vstyle.name().to_string(), vstyle);
979        sref
980    }
981
982    /// Removes the format.
983    pub fn remove_datetime_format(&mut self, name: &str) -> Option<ValueFormatDateTime> {
984        self.formats_datetime.remove(name)
985    }
986
987    /// Returns iterator over formats.
988    pub fn iter_datetime_formats(&self) -> impl Iterator<Item = &ValueFormatDateTime> {
989        self.formats_datetime.values()
990    }
991
992    /// Returns the format.
993    pub fn datetime_format(&self, name: &str) -> Option<&ValueFormatDateTime> {
994        self.formats_datetime.get(name)
995    }
996
997    /// Returns the mutable format.
998    pub fn datetime_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatDateTime> {
999        self.formats_datetime.get_mut(name)
1000    }
1001
1002    /// Adds a value format.
1003    /// Unnamed formats will be assigned an automatic name.
1004    pub fn add_timeduration_format(
1005        &mut self,
1006        mut vstyle: ValueFormatTimeDuration,
1007    ) -> ValueFormatRef {
1008        if vstyle.name().is_empty() {
1009            vstyle.set_name(
1010                auto_style_name(
1011                    &mut self.autonum,
1012                    "val_timeduration",
1013                    &self.formats_timeduration,
1014                )
1015                .as_str(),
1016            );
1017        }
1018        let sref = vstyle.format_ref();
1019        self.formats_timeduration
1020            .insert(vstyle.name().to_string(), vstyle);
1021        sref
1022    }
1023
1024    /// Removes the format.
1025    pub fn remove_timeduration_format(&mut self, name: &str) -> Option<ValueFormatTimeDuration> {
1026        self.formats_timeduration.remove(name)
1027    }
1028
1029    /// Returns iterator over formats.
1030    pub fn iter_timeduration_formats(&self) -> impl Iterator<Item = &ValueFormatTimeDuration> {
1031        self.formats_timeduration.values()
1032    }
1033
1034    /// Returns the format.
1035    pub fn timeduration_format(&self, name: &str) -> Option<&ValueFormatTimeDuration> {
1036        self.formats_timeduration.get(name)
1037    }
1038
1039    /// Returns the mutable format.
1040    pub fn timeduration_format_mut(&mut self, name: &str) -> Option<&mut ValueFormatTimeDuration> {
1041        self.formats_timeduration.get_mut(name)
1042    }
1043
1044    /// Adds a value PageStyle.
1045    /// Unnamed formats will be assigned an automatic name.
1046    pub fn add_pagestyle(&mut self, mut pstyle: PageStyle) -> PageStyleRef {
1047        if pstyle.name().is_empty() {
1048            pstyle.set_name(auto_style_name2(
1049                &mut self.autonum,
1050                "page",
1051                &self.pagestyles,
1052            ));
1053        }
1054        let sref = pstyle.style_ref();
1055        self.pagestyles.insert(pstyle.style_ref(), pstyle);
1056        sref
1057    }
1058
1059    /// Removes the PageStyle.
1060    pub fn remove_pagestyle<S: AsRef<str>>(&mut self, name: S) -> Option<PageStyle> {
1061        self.pagestyles.remove(name.as_ref())
1062    }
1063
1064    /// Returns iterator over formats.
1065    pub fn iter_pagestyles(&self) -> impl Iterator<Item = &PageStyle> {
1066        self.pagestyles.values()
1067    }
1068
1069    /// Returns the PageStyle.
1070    pub fn pagestyle<S: AsRef<str>>(&self, name: S) -> Option<&PageStyle> {
1071        self.pagestyles.get(name.as_ref())
1072    }
1073
1074    /// Returns the mutable PageStyle.
1075    pub fn pagestyle_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut PageStyle> {
1076        self.pagestyles.get_mut(name.as_ref())
1077    }
1078
1079    /// Adds a value MasterPage.
1080    /// Unnamed formats will be assigned an automatic name.
1081    pub fn add_masterpage(&mut self, mut mpage: MasterPage) -> MasterPageRef {
1082        if mpage.name().is_empty() {
1083            mpage.set_name(auto_style_name2(&mut self.autonum, "mp", &self.masterpages));
1084        }
1085        let sref = mpage.masterpage_ref();
1086        self.masterpages.insert(mpage.masterpage_ref(), mpage);
1087        sref
1088    }
1089
1090    /// Removes the MasterPage.
1091    pub fn remove_masterpage<S: AsRef<str>>(&mut self, name: S) -> Option<MasterPage> {
1092        self.masterpages.remove(name.as_ref())
1093    }
1094
1095    /// Returns iterator over formats.
1096    pub fn iter_masterpages(&self) -> impl Iterator<Item = &MasterPage> {
1097        self.masterpages.values()
1098    }
1099
1100    /// Returns the MasterPage.
1101    pub fn masterpage<S: AsRef<str>>(&self, name: S) -> Option<&MasterPage> {
1102        self.masterpages.get(name.as_ref())
1103    }
1104
1105    /// Returns the mutable MasterPage.
1106    pub fn masterpage_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut MasterPage> {
1107        self.masterpages.get_mut(name.as_ref())
1108    }
1109
1110    /// Adds a Validation.
1111    /// Nameless validations will be assigned a name.
1112    pub fn add_validation(&mut self, mut valid: Validation) -> ValidationRef {
1113        if valid.name().is_empty() {
1114            valid.set_name(auto_style_name2(
1115                &mut self.autonum,
1116                "val",
1117                &self.validations,
1118            ));
1119        }
1120        let vref = valid.validation_ref();
1121        self.validations.insert(valid.validation_ref(), valid);
1122        vref
1123    }
1124
1125    /// Removes a Validation.
1126    pub fn remove_validation<S: AsRef<str>>(&mut self, name: S) -> Option<Validation> {
1127        self.validations.remove(name.as_ref())
1128    }
1129
1130    /// Returns iterator over formats.
1131    pub fn iter_validations(&self) -> impl Iterator<Item = &Validation> {
1132        self.validations.values()
1133    }
1134
1135    /// Returns the Validation.
1136    pub fn validation<S: AsRef<str>>(&self, name: S) -> Option<&Validation> {
1137        self.validations.get(name.as_ref())
1138    }
1139
1140    /// Returns a mutable Validation.
1141    pub fn validation_mut<S: AsRef<str>>(&mut self, name: S) -> Option<&mut Validation> {
1142        self.validations.get_mut(name.as_ref())
1143    }
1144
1145    /// Adds a manifest entry, replaces an existing one with the same name.
1146    pub fn add_manifest(&mut self, manifest: Manifest) {
1147        self.manifest.insert(manifest.full_path.clone(), manifest);
1148    }
1149
1150    /// Removes a manifest entry.
1151    pub fn remove_manifest(&mut self, path: &str) -> Option<Manifest> {
1152        self.manifest.remove(path)
1153    }
1154
1155    /// Iterates the manifest.
1156    pub fn iter_manifest(&self) -> impl Iterator<Item = &Manifest> {
1157        self.manifest.values()
1158    }
1159
1160    /// Returns the manifest entry for the path
1161    pub fn manifest(&self, path: &str) -> Option<&Manifest> {
1162        self.manifest.get(path)
1163    }
1164
1165    /// Returns the manifest entry for the path
1166    pub fn manifest_mut(&mut self, path: &str) -> Option<&mut Manifest> {
1167        self.manifest.get_mut(path)
1168    }
1169
1170    /// Gives access to meta-data.
1171    pub fn metadata(&self) -> &Metadata {
1172        &self.metadata
1173    }
1174
1175    /// Gives access to meta-data.
1176    pub fn metadata_mut(&mut self) -> &mut Metadata {
1177        &mut self.metadata
1178    }
1179}
1180
1181/// Subset of the Workbook wide configurations.
1182#[derive(Clone, Debug, GetSize)]
1183pub struct WorkBookConfig {
1184    /// Which table is active when opening.    
1185    pub active_table: String,
1186    /// Show grid in general. Per sheet definition take priority.
1187    pub show_grid: bool,
1188    /// Show page-breaks.
1189    pub show_page_breaks: bool,
1190    /// Are the sheet-tabs shown or not.
1191    pub has_sheet_tabs: bool,
1192}
1193
1194impl Default for WorkBookConfig {
1195    fn default() -> Self {
1196        Self {
1197            active_table: "".to_string(),
1198            show_grid: true,
1199            show_page_breaks: false,
1200            has_sheet_tabs: true,
1201        }
1202    }
1203}
1204
1205/// Script.
1206#[derive(Debug, Default, Clone, GetSize)]
1207pub struct Script {
1208    pub(crate) script_lang: String,
1209    pub(crate) script: Vec<XmlContent>,
1210}
1211
1212impl Script {
1213    /// Script
1214    pub fn new() -> Self {
1215        Self {
1216            script_lang: "".to_string(),
1217            script: Default::default(),
1218        }
1219    }
1220
1221    /// Script language
1222    pub fn script_lang(&self) -> &str {
1223        &self.script_lang
1224    }
1225
1226    /// Script language
1227    pub fn set_script_lang(&mut self, script_lang: String) {
1228        self.script_lang = script_lang
1229    }
1230
1231    /// Script
1232    pub fn script(&self) -> &Vec<XmlContent> {
1233        &self.script
1234    }
1235
1236    /// Script
1237    pub fn set_script(&mut self, script: Vec<XmlContent>) {
1238        self.script = script
1239    }
1240}
1241
1242/// Event-Listener.
1243#[derive(Debug, Clone, GetSize)]
1244pub struct EventListener {
1245    pub(crate) event_name: String,
1246    pub(crate) script_lang: String,
1247    pub(crate) macro_name: String,
1248    pub(crate) actuate: XLinkActuate,
1249    pub(crate) href: String,
1250    pub(crate) link_type: XLinkType,
1251}
1252
1253impl EventListener {
1254    /// EventListener
1255    pub fn new() -> Self {
1256        Self {
1257            event_name: Default::default(),
1258            script_lang: Default::default(),
1259            macro_name: Default::default(),
1260            actuate: XLinkActuate::OnLoad,
1261            href: Default::default(),
1262            link_type: Default::default(),
1263        }
1264    }
1265
1266    /// Name
1267    pub fn event_name(&self) -> &str {
1268        &self.event_name
1269    }
1270
1271    /// Name
1272    pub fn set_event_name(&mut self, name: String) {
1273        self.event_name = name;
1274    }
1275
1276    /// Script language
1277    pub fn script_lang(&self) -> &str {
1278        &self.script_lang
1279    }
1280
1281    /// Script language
1282    pub fn set_script_lang(&mut self, lang: String) {
1283        self.script_lang = lang
1284    }
1285
1286    /// Macro name
1287    pub fn macro_name(&self) -> &str {
1288        &self.macro_name
1289    }
1290
1291    /// Macro name
1292    pub fn set_macro_name(&mut self, name: String) {
1293        self.macro_name = name
1294    }
1295
1296    /// Actuate
1297    pub fn actuate(&self) -> XLinkActuate {
1298        self.actuate
1299    }
1300
1301    /// Actuate
1302    pub fn set_actuate(&mut self, actuate: XLinkActuate) {
1303        self.actuate = actuate;
1304    }
1305
1306    /// HRef
1307    pub fn href(&self) -> &str {
1308        &self.href
1309    }
1310
1311    /// HRef
1312    pub fn set_href(&mut self, href: String) {
1313        self.href = href;
1314    }
1315
1316    /// Link type
1317    pub fn link_type(&self) -> XLinkType {
1318        self.link_type
1319    }
1320
1321    /// Link type
1322    pub fn set_link_type(&mut self, link_type: XLinkType) {
1323        self.link_type = link_type
1324    }
1325}
1326
1327impl Default for EventListener {
1328    fn default() -> Self {
1329        Self {
1330            event_name: Default::default(),
1331            script_lang: Default::default(),
1332            macro_name: Default::default(),
1333            actuate: XLinkActuate::OnRequest,
1334            href: Default::default(),
1335            link_type: Default::default(),
1336        }
1337    }
1338}