spreadsheet_ods/style/
masterpage.rs

1use crate::style::pagestyle::PageStyleRef;
2use crate::style::AnyStyleRef;
3use crate::text::TextTag;
4use get_size::GetSize;
5use get_size_derive::GetSize;
6use std::borrow::Borrow;
7
8style_ref2!(MasterPageRef);
9
10/// Defines the structure and content for a page.
11/// Refers to a PageStyle for layout information.
12/// It must be attached to a Sheet to be used.
13///
14/// ```
15/// use spreadsheet_ods::{pt, Length, WorkBook, Sheet};
16/// use spreadsheet_ods::style::{PageStyle, MasterPage, TableStyle};
17/// use spreadsheet_ods::style::units::Border;
18/// use spreadsheet_ods::xmltree::XmlVec;
19/// use spreadsheet_ods::color::Rgb;
20/// use icu_locid::locale;
21///
22/// let mut wb = WorkBook::new(locale!("en_US"));
23///
24/// let mut ps = PageStyle::new("ps1");
25/// ps.set_border(pt!(0.5), Border::Groove, Rgb::new(128,128,128));
26/// ps.headerstyle_mut().set_background_color(Rgb::new(92,92,92));
27/// let ps_ref = wb.add_pagestyle(ps);
28///
29/// let mut mp1 = MasterPage::new("mp1");
30/// mp1.set_pagestyle(&ps_ref);
31/// mp1.header_mut().center_mut().add_text("center");
32/// mp1.footer_mut().right_mut().add_text("right");
33/// let mp1_ref = wb.add_masterpage(mp1);
34///
35/// let mut ts = TableStyle::new("ts1");
36/// ts.set_master_page(&mp1_ref);
37/// let ts_ref = wb.add_tablestyle(ts);
38///
39/// let mut sheet = Sheet::new("sheet 1");
40/// sheet.set_style(&ts_ref);
41/// ```
42#[derive(Clone, Debug, Default, GetSize)]
43pub struct MasterPage {
44    name: String,
45    display_name: String,
46    pagestyle: Option<PageStyleRef>,
47    next_style_name: Option<MasterPageRef>,
48
49    header: HeaderFooter,
50    header_first: HeaderFooter,
51    header_left: HeaderFooter,
52
53    footer: HeaderFooter,
54    footer_first: HeaderFooter,
55    footer_left: HeaderFooter,
56}
57
58impl MasterPage {
59    /// Empty.
60    pub fn new_empty() -> Self {
61        Self {
62            name: Default::default(),
63            display_name: Default::default(),
64            pagestyle: Default::default(),
65            next_style_name: Default::default(),
66            header: Default::default(),
67            header_first: Default::default(),
68            header_left: Default::default(),
69            footer: Default::default(),
70            footer_first: Default::default(),
71            footer_left: Default::default(),
72        }
73    }
74
75    /// New MasterPage
76    pub fn new<S: AsRef<str>>(name: S) -> Self {
77        Self {
78            name: name.as_ref().to_string(),
79            display_name: Default::default(),
80            pagestyle: Default::default(),
81            next_style_name: Default::default(),
82            header: Default::default(),
83            header_first: Default::default(),
84            header_left: Default::default(),
85            footer: Default::default(),
86            footer_first: Default::default(),
87            footer_left: Default::default(),
88        }
89    }
90
91    /// Style reference.
92    pub fn masterpage_ref(&self) -> MasterPageRef {
93        MasterPageRef::from(self.name())
94    }
95
96    /// Name.
97    pub fn set_name(&mut self, name: String) {
98        self.name = name;
99    }
100
101    /// Name.
102    pub fn name(&self) -> &String {
103        &self.name
104    }
105
106    /// Name.
107    pub fn set_display_name(&mut self, display_name: String) {
108        self.display_name = display_name;
109    }
110
111    /// Name.
112    pub fn display_name(&self) -> &String {
113        &self.display_name
114    }
115
116    /// Reference to a page-style.
117    pub fn set_pagestyle(&mut self, name: &PageStyleRef) {
118        self.pagestyle = Some(name.clone());
119    }
120
121    /// Reference to a page-style.
122    pub fn pagestyle(&self) -> Option<&PageStyleRef> {
123        self.pagestyle.as_ref()
124    }
125
126    /// The style:next-style-name attribute specifies the name of the master page that is used for
127    /// the next page if the current page is entirely filled. If the next style name is not specified, the
128    /// current master page is used for the next page. The value of this attribute shall be the name of a
129    /// <style:master-page> element.
130    pub fn set_next_masterpage(&mut self, master: &MasterPageRef) {
131        self.next_style_name = Some(master.clone());
132    }
133
134    ///
135    pub fn next_masterpage(&self) -> Option<&MasterPageRef> {
136        self.next_style_name.as_ref()
137    }
138
139    /// Left side header.
140    pub fn set_header(&mut self, header: HeaderFooter) {
141        self.header = header;
142    }
143
144    /// Left side header.
145    pub fn header(&self) -> &HeaderFooter {
146        &self.header
147    }
148
149    /// Header.
150    pub fn header_mut(&mut self) -> &mut HeaderFooter {
151        &mut self.header
152    }
153
154    /// First page header.
155    pub fn set_header_first(&mut self, header: HeaderFooter) {
156        self.header_first = header;
157    }
158
159    /// First page header.
160    pub fn header_first(&self) -> &HeaderFooter {
161        &self.header_first
162    }
163
164    /// First page header.
165    pub fn header_first_mut(&mut self) -> &mut HeaderFooter {
166        &mut self.header_first
167    }
168
169    /// Left side header.
170    pub fn set_header_left(&mut self, header: HeaderFooter) {
171        self.header_left = header;
172    }
173
174    /// Left side header.
175    pub fn header_left(&self) -> &HeaderFooter {
176        &self.header_left
177    }
178
179    /// Left side header.
180    pub fn header_left_mut(&mut self) -> &mut HeaderFooter {
181        &mut self.header_left
182    }
183
184    /// Footer.
185    pub fn set_footer(&mut self, footer: HeaderFooter) {
186        self.footer = footer;
187    }
188
189    /// Footer.
190    pub fn footer(&self) -> &HeaderFooter {
191        &self.footer
192    }
193
194    /// Footer.
195    pub fn footer_mut(&mut self) -> &mut HeaderFooter {
196        &mut self.footer
197    }
198
199    /// First page footer.
200    pub fn set_footer_first(&mut self, footer: HeaderFooter) {
201        self.footer_first = footer;
202    }
203
204    /// First page footer.
205    pub fn footer_first(&self) -> &HeaderFooter {
206        &self.footer_first
207    }
208
209    /// First page footer.
210    pub fn footer_first_mut(&mut self) -> &mut HeaderFooter {
211        &mut self.footer_first
212    }
213
214    /// Left side footer.
215    pub fn set_footer_left(&mut self, footer: HeaderFooter) {
216        self.footer_left = footer;
217    }
218
219    /// Left side footer.
220    pub fn footer_left(&self) -> &HeaderFooter {
221        &self.footer_left
222    }
223
224    /// Left side footer.
225    pub fn footer_left_mut(&mut self) -> &mut HeaderFooter {
226        &mut self.footer_left
227    }
228}
229
230/// Header/Footer data.
231/// Can be seen as three regions left/center/right or as one region.
232/// In the first case region* contains the data, in the second it's content.
233/// Each is a TextTag of parsed XML-tags.
234#[derive(Clone, Debug, Default, GetSize)]
235pub struct HeaderFooter {
236    display: bool,
237
238    region_left: Vec<TextTag>,
239    region_center: Vec<TextTag>,
240    region_right: Vec<TextTag>,
241
242    content: Vec<TextTag>,
243}
244
245impl HeaderFooter {
246    /// Create
247    pub fn new() -> Self {
248        Self {
249            display: true,
250            region_left: Default::default(),
251            region_center: Default::default(),
252            region_right: Default::default(),
253            content: Default::default(),
254        }
255    }
256
257    /// Is the header displayed. Used to deactivate left side headers.
258    pub fn set_display(&mut self, display: bool) {
259        self.display = display;
260    }
261
262    /// Display
263    pub fn display(&self) -> bool {
264        self.display
265    }
266
267    /// true if all regions of the header/footer are empty.
268    pub fn is_empty(&self) -> bool {
269        self.region_left.is_empty()
270            && self.region_center.is_empty()
271            && self.region_right.is_empty()
272            && self.content.is_empty()
273    }
274
275    /// Set the content of the left region of the header.
276    ///
277    /// Attention:
278    /// This tag must be a text:p otherwise its ignored.
279    pub fn set_left(&mut self, txt: Vec<TextTag>) {
280        self.region_left = txt;
281    }
282
283    /// Adds to the content of the left region of the header.
284    ///
285    /// Attention:
286    /// This tag must be a text:p otherwise its ignored.
287    pub fn add_left(&mut self, txt: TextTag) {
288        self.region_left.push(txt);
289    }
290
291    /// Clear left region.
292    pub fn clear_left(&mut self) {
293        self.region_left = Vec::new();
294    }
295
296    /// Left region.
297    pub fn left(&self) -> &Vec<TextTag> {
298        self.region_left.as_ref()
299    }
300
301    /// Left region.
302    pub fn left_mut(&mut self) -> &mut Vec<TextTag> {
303        self.region_left.as_mut()
304    }
305
306    /// Set the content of the center region of the header.
307    ///
308    /// Attention:
309    /// This tag must be a text:p otherwise its ignored.
310    pub fn set_center(&mut self, txt: Vec<TextTag>) {
311        self.region_center = txt;
312    }
313
314    /// Adds to the content of the center region of the header.
315    ///
316    /// Attention:
317    /// This tag must be a text:p otherwise its ignored.
318    pub fn add_center(&mut self, txt: TextTag) {
319        self.region_center.push(txt);
320    }
321
322    /// Center region.
323    pub fn clear_center(&mut self) {
324        self.region_center = Vec::new();
325    }
326
327    /// Center region.
328    pub fn center(&self) -> &Vec<TextTag> {
329        self.region_center.as_ref()
330    }
331
332    /// Center region.
333    pub fn center_mut(&mut self) -> &mut Vec<TextTag> {
334        self.region_center.as_mut()
335    }
336
337    /// Set the content of the right region of the header.
338    ///
339    /// Attention:
340    /// This tag must be a text:p otherwise its ignored.
341    pub fn set_right(&mut self, txt: Vec<TextTag>) {
342        self.region_right = txt;
343    }
344
345    /// Adds to the content of the right region of the header.
346    ///
347    /// Attention:
348    /// This tag must be a text:p otherwise its ignored.
349    pub fn add_right(&mut self, txt: TextTag) {
350        self.region_right.push(txt);
351    }
352
353    /// Right region.
354    pub fn clear_right(&mut self) {
355        self.region_right = Vec::new();
356    }
357
358    /// Right region.
359    pub fn right(&self) -> &Vec<TextTag> {
360        self.region_right.as_ref()
361    }
362
363    /// Right region.
364    pub fn right_mut(&mut self) -> &mut Vec<TextTag> {
365        self.region_right.as_mut()
366    }
367
368    /// Header content, if there are no regions.
369    pub fn set_content(&mut self, txt: Vec<TextTag>) {
370        self.content = txt;
371    }
372
373    /// Adds header content, if there are no regions.
374    pub fn add_content(&mut self, txt: TextTag) {
375        self.content.push(txt);
376    }
377
378    /// Header content, if there are no regions.
379    pub fn content(&self) -> &Vec<TextTag> {
380        &self.content
381    }
382
383    /// Header content, if there are no regions.
384    pub fn content_mut(&mut self) -> &mut Vec<TextTag> {
385        &mut self.content
386    }
387}