Line data Source code
1 : /*************************************************************************
2 : *
3 : * Copyright (c) 2010, 2011 Kohei Yoshida
4 : *
5 : * Permission is hereby granted, free of charge, to any person
6 : * obtaining a copy of this software and associated documentation
7 : * files (the "Software"), to deal in the Software without
8 : * restriction, including without limitation the rights to use,
9 : * copy, modify, merge, publish, distribute, sublicense, and/or sell
10 : * copies of the Software, and to permit persons to whom the
11 : * Software is furnished to do so, subject to the following
12 : * conditions:
13 : *
14 : * The above copyright notice and this permission notice shall be
15 : * included in all copies or substantial portions of the Software.
16 : *
17 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18 : * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19 : * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20 : * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21 : * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22 : * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23 : * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24 : * OTHER DEALINGS IN THE SOFTWARE.
25 : *
26 : ************************************************************************/
27 :
28 : #include "orcus/gnumeric/gnumeric_sheet_context.hpp"
29 : #include "orcus/gnumeric/gnumeric_cell_context.hpp"
30 : #include "orcus/gnumeric/gnumeric_token_constants.hpp"
31 : #include "orcus/gnumeric/gnumeric_helper.hpp"
32 : #include "orcus/global.hpp"
33 : #include "orcus/spreadsheet/import_interface.hpp"
34 : #include "orcus/gnumeric/gnumeric_helper.hpp"
35 :
36 : namespace orcus {
37 :
38 : namespace {
39 :
40 : class gnumeric_style_region_attr_parser : public std::unary_function<xml_token_attr_t, void>
41 : {
42 : public:
43 : gnumeric_style_region_attr_parser(gnumeric_style_region& style_region_data):
44 0 : m_style_region_data(style_region_data) {}
45 :
46 0 : void operator() (const xml_token_attr_t& attr)
47 : {
48 0 : switch(attr.name)
49 : {
50 : case XML_startCol:
51 : {
52 : size_t n = atoi(attr.value.get());
53 0 : m_style_region_data.start_col = n;
54 : }
55 0 : break;
56 : case XML_startRow:
57 : {
58 : size_t n = atoi(attr.value.get());
59 0 : m_style_region_data.start_row = n;
60 : }
61 0 : break;
62 : case XML_endCol:
63 : {
64 : size_t n = atoi(attr.value.get());
65 0 : m_style_region_data.end_col = n;
66 : }
67 0 : break;
68 : case XML_endRow:
69 : {
70 : size_t n = atoi(attr.value.get());
71 0 : m_style_region_data.end_row = n;
72 : }
73 0 : break;
74 : default:
75 : ;
76 : }
77 0 : }
78 :
79 : private:
80 : gnumeric_style_region& m_style_region_data;
81 : };
82 :
83 : class gnumeric_font_attr_parser : public std::unary_function<xml_token_attr_t, void>
84 : {
85 : public:
86 : gnumeric_font_attr_parser(spreadsheet::iface::import_styles& styles) :
87 0 : m_styles(styles) {}
88 :
89 0 : void operator() (const xml_token_attr_t& attr)
90 : {
91 0 : switch(attr.name)
92 : {
93 : case XML_Unit:
94 : {
95 0 : double n = atoi(attr.value.get());
96 0 : m_styles.set_font_size(n);
97 : }
98 0 : break;
99 : case XML_Bold:
100 : {
101 0 : bool b = atoi(attr.value.get()) != 0;
102 0 : m_styles.set_font_bold(b);
103 : }
104 0 : break;
105 : case XML_Italic:
106 : {
107 0 : bool b = atoi(attr.value.get()) != 0;
108 0 : m_styles.set_font_italic(b);
109 : }
110 0 : break;
111 : case XML_Underline:
112 : {
113 : int n = atoi(attr.value.get());
114 0 : switch (n)
115 : {
116 : case 0:
117 0 : m_styles.set_font_underline(spreadsheet::underline_none);
118 0 : break;
119 : case 1:
120 0 : m_styles.set_font_underline(spreadsheet::underline_single);
121 0 : break;
122 : case 2:
123 0 : m_styles.set_font_underline(spreadsheet::underline_double);
124 0 : break;
125 : default:
126 : ;
127 : }
128 : }
129 : break;
130 : }
131 0 : }
132 :
133 : private:
134 : spreadsheet::iface::import_styles& m_styles;
135 : };
136 :
137 : class gnumeric_style_attr_parser : public std::unary_function<xml_token_attr_t, void>
138 : {
139 : public:
140 : gnumeric_style_attr_parser(spreadsheet::iface::import_styles& styles) :
141 0 : m_styles(styles) {}
142 :
143 0 : void operator() (const xml_token_attr_t& attr)
144 : {
145 0 : switch(attr.name)
146 : {
147 : case XML_Fore:
148 : {
149 : spreadsheet::color_elem_t red, green, blue;
150 0 : gnumeric_helper::parse_RGB_color_attribute(red, green, blue, attr.value);
151 0 : m_styles.set_fill_fg_color(0, red, green, blue);
152 : }
153 0 : break;
154 : case XML_Back:
155 : {
156 : spreadsheet::color_elem_t red, green, blue;
157 0 : gnumeric_helper::parse_RGB_color_attribute(red, green, blue, attr.value);
158 0 : m_styles.set_fill_bg_color(0, red, green, blue);
159 : }
160 0 : break;
161 : case XML_Hidden:
162 : {
163 0 : bool b = atoi(attr.value.get());
164 0 : m_styles.set_cell_hidden(b);
165 : }
166 0 : break;
167 : case XML_Locked:
168 : {
169 0 : bool b = atoi(attr.value.get());
170 0 : m_styles.set_cell_locked(b);
171 : }
172 0 : break;
173 : }
174 0 : }
175 :
176 : private:
177 : spreadsheet::iface::import_styles& m_styles;
178 : };
179 :
180 : }
181 :
182 :
183 0 : gnumeric_sheet_context::gnumeric_sheet_context(
184 : const tokens& tokens, spreadsheet::iface::import_factory* factory) :
185 : xml_context_base(tokens),
186 0 : mp_factory(factory)
187 : {
188 0 : }
189 :
190 0 : gnumeric_sheet_context::~gnumeric_sheet_context()
191 : {
192 0 : }
193 :
194 0 : bool gnumeric_sheet_context::can_handle_element(xmlns_token_t ns, xml_token_t name) const
195 : {
196 0 : if (ns == XMLNS_gnm && name == XML_Cells)
197 : return false;
198 :
199 0 : return true;
200 : }
201 :
202 0 : xml_context_base* gnumeric_sheet_context::create_child_context(xmlns_token_t ns, xml_token_t name) const
203 : {
204 0 : if (ns == XMLNS_gnm && name == XML_Cells)
205 0 : return new gnumeric_cell_context(get_tokens(), mp_factory, mp_sheet);
206 :
207 : return NULL;
208 : }
209 :
210 0 : void gnumeric_sheet_context::end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child)
211 : {
212 0 : }
213 :
214 0 : void gnumeric_sheet_context::start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs)
215 : {
216 0 : push_stack(ns, name);
217 0 : if (ns == XMLNS_gnm)
218 : {
219 0 : switch (name)
220 : {
221 : case XML_Font:
222 0 : start_font(attrs);
223 0 : break;
224 : case XML_Style:
225 0 : start_style(attrs);
226 0 : break;
227 : case XML_StyleRegion:
228 0 : start_style_region(attrs);
229 0 : break;
230 : default:
231 : ;
232 : }
233 : }
234 0 : }
235 :
236 0 : bool gnumeric_sheet_context::end_element(xmlns_token_t ns, xml_token_t name)
237 : {
238 0 : if (ns == XMLNS_gnm)
239 : {
240 0 : switch(name)
241 : {
242 : case XML_Name:
243 : {
244 0 : xml_token_pair_t parent = get_parent_element();
245 0 : if(parent.first == XMLNS_gnm && parent.second == XML_Sheet)
246 : end_table();
247 : else
248 0 : warn_unhandled();
249 : }
250 : break;
251 : case XML_Font:
252 0 : end_font();
253 0 : break;
254 : case XML_Style:
255 0 : end_style();
256 0 : break;
257 : default:
258 : ;
259 : }
260 : }
261 :
262 0 : return pop_stack(ns, name);
263 : }
264 :
265 0 : void gnumeric_sheet_context::characters(const pstring& str)
266 : {
267 : chars = str;
268 0 : }
269 :
270 0 : void gnumeric_sheet_context::start_font(const xml_attrs_t& attrs)
271 : {
272 0 : for_each(attrs.begin(), attrs.end(), gnumeric_font_attr_parser(*mp_factory->get_styles()));
273 0 : }
274 :
275 0 : void gnumeric_sheet_context::start_style(const xml_attrs_t& attrs)
276 : {
277 0 : for_each(attrs.begin(), attrs.end(), gnumeric_style_attr_parser(*mp_factory->get_styles()));
278 0 : }
279 :
280 0 : void gnumeric_sheet_context::start_style_region(const xml_attrs_t& attrs)
281 : {
282 0 : mp_region_data.reset(new gnumeric_style_region());
283 0 : for_each(attrs.begin(), attrs.end(), gnumeric_style_region_attr_parser(*mp_region_data));
284 0 : }
285 :
286 0 : void gnumeric_sheet_context::end_table()
287 : {
288 0 : mp_sheet = mp_factory->append_sheet(chars.get(), chars.size());
289 0 : }
290 :
291 0 : void gnumeric_sheet_context::end_font()
292 : {
293 0 : spreadsheet::iface::import_styles& styles = *mp_factory->get_styles();
294 0 : styles.set_font_name(chars.get(), chars.size());
295 0 : size_t font_id = styles.commit_font();
296 0 : styles.set_xf_font(font_id);
297 0 : }
298 :
299 0 : void gnumeric_sheet_context::end_style()
300 : {
301 0 : spreadsheet::iface::import_styles& styles = *mp_factory->get_styles();
302 0 : size_t fill_id = styles.commit_fill();
303 0 : styles.set_xf_fill(fill_id);
304 0 : size_t id = styles.commit_cell_xf();
305 0 : mp_region_data->xf_id = id;
306 0 : }
307 :
308 0 : void gnumeric_sheet_context::end_style_region()
309 : {
310 0 : for (spreadsheet::col_t col = mp_region_data->start_col;
311 0 : col <= mp_region_data->end_col; ++col)
312 : {
313 0 : for (spreadsheet::row_t row = mp_region_data->start_row;
314 0 : row <= mp_region_data->end_row; ++row)
315 : {
316 0 : mp_sheet->set_format(row, col, mp_region_data->xf_id);
317 : }
318 : }
319 0 : mp_region_data.reset();
320 0 : }
321 :
322 24 : }
|