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_context.hpp"
29 : #include "orcus/gnumeric/gnumeric_token_constants.hpp"
30 : #include "orcus/gnumeric/gnumeric_cell_context.hpp"
31 : #include "orcus/global.hpp"
32 : #include "orcus/spreadsheet/import_interface.hpp"
33 :
34 : #include <iostream>
35 : #include <fstream>
36 : #include <algorithm>
37 :
38 : using namespace std;
39 :
40 : namespace orcus {
41 :
42 : using namespace spreadsheet;
43 :
44 : enum gnumeric_celltype
45 : {
46 : celltype_bool,
47 : celltype_value,
48 : celltype_string,
49 : celltype_formula,
50 : celltype_shared_formula,
51 : celltype_unknown
52 : };
53 :
54 :
55 : struct gnumeric_cell_data
56 : {
57 : row_t row;
58 : col_t col;
59 : gnumeric_celltype cell_type;
60 : size_t shared_formula_id;
61 : };
62 :
63 : namespace {
64 :
65 : class cell_attr_parser : public unary_function<xml_token_attr_t, void>
66 : {
67 : public:
68 : cell_attr_parser()
69 : {
70 0 : cell_data.cell_type = celltype_formula;
71 0 : cell_data.shared_formula_id = -1;
72 : }
73 :
74 : cell_attr_parser(const cell_attr_parser& r):
75 0 : cell_data(r.cell_data) {}
76 :
77 0 : void operator() (const xml_token_attr_t& attr)
78 : {
79 0 : switch (attr.name)
80 : {
81 : case XML_Row:
82 0 : cell_data.row = atoi(attr.value.get());
83 0 : break;
84 : case XML_Col:
85 0 : cell_data.col = atoi(attr.value.get());
86 0 : break;
87 : case XML_ValueType:
88 : {
89 : int value_type = atoi(attr.value.get());
90 0 : switch (value_type)
91 : {
92 : case 20:
93 0 : cell_data.cell_type = celltype_bool;
94 0 : break;
95 : case 30:
96 : case 40:
97 0 : cell_data.cell_type = celltype_value;
98 0 : break;
99 : case 60:
100 0 : cell_data.cell_type = celltype_string;
101 : }
102 : }
103 : break;
104 : case XML_ExprID:
105 0 : cell_data.shared_formula_id = atoi(attr.value.get());
106 0 : cell_data.cell_type = celltype_shared_formula;
107 0 : break;
108 : }
109 0 : }
110 :
111 : gnumeric_cell_data get_cell_data() const
112 : {
113 0 : return cell_data;
114 : }
115 :
116 : private:
117 : gnumeric_cell_data cell_data;
118 : };
119 :
120 : }
121 :
122 : // ============================================================================
123 :
124 0 : gnumeric_cell_context::gnumeric_cell_context(const tokens& tokens, spreadsheet::iface::import_factory* factory, spreadsheet::iface::import_sheet* sheet) :
125 : xml_context_base(tokens),
126 : mp_factory(factory),
127 0 : mp_sheet(sheet)
128 : {
129 0 : }
130 :
131 0 : gnumeric_cell_context::~gnumeric_cell_context()
132 : {
133 0 : }
134 :
135 0 : bool gnumeric_cell_context::can_handle_element(xmlns_token_t ns, xml_token_t name) const
136 : {
137 0 : return true;
138 : }
139 :
140 0 : xml_context_base* gnumeric_cell_context::create_child_context(xmlns_token_t ns, xml_token_t name) const
141 : {
142 0 : return NULL;
143 : }
144 :
145 0 : void gnumeric_cell_context::end_child_context(xmlns_token_t ns, xml_token_t name, xml_context_base* child)
146 : {
147 0 : }
148 :
149 0 : void gnumeric_cell_context::start_element(xmlns_token_t ns, xml_token_t name, const xml_attrs_t& attrs)
150 : {
151 0 : push_stack(ns, name);
152 :
153 0 : if (ns == XMLNS_gnm)
154 : {
155 0 : switch (name)
156 : {
157 : case XML_Cell:
158 0 : start_cell(attrs);
159 0 : break;
160 : default:
161 0 : warn_unhandled();
162 : }
163 : }
164 : else
165 0 : warn_unhandled();
166 0 : }
167 :
168 0 : bool gnumeric_cell_context::end_element(xmlns_token_t ns, xml_token_t name)
169 : {
170 0 : if (ns == XMLNS_gnm)
171 : {
172 0 : switch (name)
173 : {
174 : case XML_Cell:
175 0 : end_cell();
176 0 : break;
177 : default:
178 : ;
179 : }
180 : }
181 0 : return pop_stack(ns, name);
182 : }
183 :
184 0 : void gnumeric_cell_context::characters(const pstring& str)
185 : {
186 : chars = str;
187 0 : }
188 :
189 0 : void gnumeric_cell_context::start_cell(const xml_attrs_t& attrs)
190 : {
191 0 : mp_cell_data.reset(new gnumeric_cell_data);
192 0 : cell_attr_parser parser = for_each(attrs.begin(), attrs.end(), cell_attr_parser());
193 0 : *mp_cell_data = parser.get_cell_data();
194 0 : }
195 :
196 0 : void gnumeric_cell_context::end_cell()
197 : {
198 0 : if (!mp_cell_data)
199 0 : return;
200 :
201 0 : col_t col = mp_cell_data->col;
202 0 : row_t row = mp_cell_data->row;
203 0 : gnumeric_celltype cell_type = mp_cell_data->cell_type;
204 0 : switch (cell_type)
205 : {
206 : case celltype_value:
207 : case celltype_string:
208 0 : mp_sheet->set_auto(row, col, chars.get(), chars.size());
209 0 : break;
210 : case celltype_formula:
211 0 : mp_sheet->set_formula(row, col, spreadsheet::gnumeric, chars.get(), chars.size());
212 0 : break;
213 : case celltype_shared_formula:
214 0 : if (chars.empty())
215 0 : mp_sheet->set_shared_formula(row, col, mp_cell_data->shared_formula_id);
216 : else
217 0 : mp_sheet->set_shared_formula(row, col, spreadsheet::gnumeric, mp_cell_data->shared_formula_id, chars.get(), chars.size());
218 : break;
219 : default:
220 : ;
221 : }
222 :
223 0 : mp_cell_data.reset();
224 : }
225 :
226 24 : }
|