Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "XMLDDELinksContext.hxx"
21 : #include "xmlimprt.hxx"
22 : #include "document.hxx"
23 : #include "scmatrix.hxx"
24 : #include <xmloff/xmltoken.hxx>
25 : #include <xmloff/xmlnmspe.hxx>
26 : #include <xmloff/nmspmap.hxx>
27 : #include <sax/tools/converter.hxx>
28 :
29 : using namespace com::sun::star;
30 : using namespace xmloff::token;
31 :
32 :
33 : //------------------------------------------------------------------
34 :
35 0 : ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport,
36 : sal_uInt16 nPrfx,
37 : const OUString& rLName,
38 : const ::com::sun::star::uno::Reference<
39 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
40 0 : SvXMLImportContext( rImport, nPrfx, rLName )
41 : {
42 : // here are no attributes
43 0 : rImport.LockSolarMutex();
44 0 : }
45 :
46 0 : ScXMLDDELinksContext::~ScXMLDDELinksContext()
47 : {
48 0 : GetScImport().UnlockSolarMutex();
49 0 : }
50 :
51 0 : SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( sal_uInt16 nPrefix,
52 : const OUString& rLName,
53 : const ::com::sun::star::uno::Reference<
54 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
55 : {
56 0 : SvXMLImportContext *pContext = 0;
57 :
58 0 : if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK))
59 0 : pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList);
60 :
61 0 : if( !pContext )
62 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
63 :
64 0 : return pContext;
65 : }
66 :
67 0 : void ScXMLDDELinksContext::EndElement()
68 : {
69 0 : }
70 :
71 0 : ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport,
72 : sal_uInt16 nPrfx,
73 : const OUString& rLName,
74 : const ::com::sun::star::uno::Reference<
75 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
76 : SvXMLImportContext( rImport, nPrfx, rLName ),
77 : aDDELinkTable(),
78 : aDDELinkRow(),
79 : sApplication(),
80 : sTopic(),
81 : sItem(),
82 : nPosition(-1),
83 : nColumns(0),
84 : nRows(0),
85 0 : nMode(SC_DDE_DEFAULT)
86 : {
87 : // here are no attributes
88 0 : }
89 :
90 0 : ScXMLDDELinkContext::~ScXMLDDELinkContext()
91 : {
92 0 : }
93 :
94 0 : SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( sal_uInt16 nPrefix,
95 : const OUString& rLName,
96 : const ::com::sun::star::uno::Reference<
97 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
98 : {
99 0 : SvXMLImportContext *pContext = 0;
100 :
101 0 : if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE))
102 0 : pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
103 0 : else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE))
104 0 : pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
105 :
106 0 : if( !pContext )
107 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
108 :
109 0 : return pContext;
110 : }
111 :
112 0 : void ScXMLDDELinkContext::CreateDDELink()
113 : {
114 0 : if (GetScImport().GetDocument() &&
115 0 : !sApplication.isEmpty() &&
116 0 : !sTopic.isEmpty() &&
117 0 : !sItem.isEmpty())
118 : {
119 0 : GetScImport().GetDocument()->CreateDdeLink(sApplication, sTopic, sItem, nMode, ScMatrixRef());
120 : size_t nPos;
121 0 : if(GetScImport().GetDocument()->FindDdeLink(sApplication, sTopic, sItem, nMode, nPos))
122 0 : nPosition = nPos;
123 : else
124 : {
125 0 : nPosition = -1;
126 : SAL_WARN("sc" , "DDE Link not inserted");
127 : }
128 : }
129 0 : }
130 :
131 0 : void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
132 : {
133 0 : aDDELinkRow.push_back(aCell);
134 0 : }
135 :
136 0 : void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
137 : {
138 0 : for (sal_Int32 i = 0; i < nRowsP; ++i)
139 0 : aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
140 0 : aDDELinkRow.clear();
141 0 : }
142 :
143 0 : void ScXMLDDELinkContext::EndElement()
144 : {
145 0 : if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument())
146 : {
147 0 : bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size());
148 : OSL_ENSURE( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count");
149 : // Excel writes bad ODF in that it does not write the
150 : // table:number-columns-repeated attribute of the
151 : // <table:table-column> element, but apparently uses the number of
152 : // <table:table-cell> elements within a <table:table-row> element to
153 : // determine the column count instead. Be lenient ...
154 0 : if (!bSizeMatch && nColumns == 1)
155 : {
156 0 : nColumns = aDDELinkTable.size() / nRows;
157 : OSL_ENSURE( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
158 : "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
159 : }
160 0 : ScMatrixRef pMatrix = new ScMatrix(static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows), 0.0);
161 0 : sal_Int32 nCol(0);
162 0 : sal_Int32 nRow(-1);
163 0 : sal_Int32 nIndex(0);
164 0 : ScDDELinkCells::iterator aItr(aDDELinkTable.begin());
165 0 : ScDDELinkCells::iterator aEndItr(aDDELinkTable.end());
166 0 : while (aItr != aEndItr)
167 : {
168 0 : if (nIndex % nColumns == 0)
169 : {
170 0 : ++nRow;
171 0 : nCol = 0;
172 : }
173 : else
174 0 : ++nCol;
175 :
176 0 : SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
177 0 : SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
178 0 : if( aItr->bEmpty )
179 0 : pMatrix->PutEmpty( nScCol, nScRow );
180 0 : else if( aItr->bString )
181 0 : pMatrix->PutString( aItr->sValue, nScCol, nScRow );
182 : else
183 0 : pMatrix->PutDouble( aItr->fValue, nScCol, nScRow );
184 :
185 0 : ++nIndex;
186 0 : ++aItr;
187 : }
188 :
189 0 : GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix );
190 : }
191 0 : }
192 :
193 0 : ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
194 : sal_uInt16 nPrfx,
195 : const OUString& rLName,
196 : const ::com::sun::star::uno::Reference<
197 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
198 : ScXMLDDELinkContext* pTempDDELink) :
199 : SvXMLImportContext( rImport, nPrfx, rLName ),
200 0 : pDDELink(pTempDDELink)
201 : {
202 0 : if( !xAttrList.is() ) return;
203 :
204 0 : sal_Int16 nAttrCount = xAttrList->getLength();
205 :
206 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
207 : {
208 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
209 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
210 0 : OUString aLocalName;
211 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
212 :
213 0 : if (nPrefix == XML_NAMESPACE_OFFICE)
214 : {
215 0 : if (IsXMLToken(aLocalName, XML_DDE_APPLICATION))
216 0 : pDDELink->SetApplication(sValue);
217 0 : else if (IsXMLToken(aLocalName, XML_DDE_TOPIC))
218 0 : pDDELink->SetTopic(sValue);
219 0 : else if (IsXMLToken(aLocalName, XML_DDE_ITEM))
220 0 : pDDELink->SetItem(sValue);
221 : }
222 0 : else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE))
223 : {
224 0 : if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER))
225 0 : pDDELink->SetMode(SC_DDE_ENGLISH);
226 0 : else if (IsXMLToken(sValue, XML_KEEP_TEXT))
227 0 : pDDELink->SetMode(SC_DDE_TEXT);
228 : else
229 0 : pDDELink->SetMode(SC_DDE_DEFAULT);
230 : }
231 0 : }
232 : }
233 :
234 0 : ScXMLDDESourceContext::~ScXMLDDESourceContext()
235 : {
236 0 : }
237 :
238 0 : SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( sal_uInt16 nPrefix,
239 : const OUString& rLName,
240 : const ::com::sun::star::uno::Reference<
241 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
242 : {
243 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
244 :
245 0 : return pContext;
246 : }
247 :
248 0 : void ScXMLDDESourceContext::EndElement()
249 : {
250 0 : pDDELink->CreateDDELink();
251 0 : }
252 :
253 0 : ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
254 : sal_uInt16 nPrfx,
255 : const OUString& rLName,
256 : const ::com::sun::star::uno::Reference<
257 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
258 : ScXMLDDELinkContext* pTempDDELink) :
259 : SvXMLImportContext( rImport, nPrfx, rLName ),
260 0 : pDDELink(pTempDDELink)
261 : {
262 : // here are no attributes
263 0 : }
264 :
265 0 : ScXMLDDETableContext::~ScXMLDDETableContext()
266 : {
267 0 : }
268 :
269 0 : SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( sal_uInt16 nPrefix,
270 : const OUString& rLName,
271 : const ::com::sun::star::uno::Reference<
272 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
273 : {
274 0 : SvXMLImportContext *pContext = NULL;
275 :
276 0 : if (nPrefix == XML_NAMESPACE_TABLE)
277 : {
278 0 : if (IsXMLToken(rLName, XML_TABLE_COLUMN))
279 0 : pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
280 0 : else if (IsXMLToken(rLName, XML_TABLE_ROW))
281 0 : pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
282 : }
283 :
284 0 : if (!pContext)
285 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
286 :
287 0 : return pContext;
288 : }
289 :
290 0 : void ScXMLDDETableContext::EndElement()
291 : {
292 0 : }
293 :
294 0 : ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
295 : sal_uInt16 nPrfx,
296 : const OUString& rLName,
297 : const ::com::sun::star::uno::Reference<
298 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
299 : ScXMLDDELinkContext* pTempDDELink) :
300 : SvXMLImportContext( rImport, nPrfx, rLName ),
301 0 : pDDELink(pTempDDELink)
302 : {
303 0 : if( !xAttrList.is() ) return;
304 0 : sal_Int32 nCols(1);
305 :
306 0 : sal_Int16 nAttrCount = xAttrList->getLength();
307 :
308 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
309 : {
310 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
311 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
312 0 : OUString aLocalName;
313 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
314 :
315 0 : if (nPrefix == XML_NAMESPACE_TABLE)
316 0 : if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
317 : {
318 0 : ::sax::Converter::convertNumber(nCols, sValue);
319 : }
320 0 : }
321 0 : pDDELink->AddColumns(nCols);
322 : }
323 :
324 0 : ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
325 : {
326 0 : }
327 :
328 0 : SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( sal_uInt16 nPrefix,
329 : const OUString& rLName,
330 : const ::com::sun::star::uno::Reference<
331 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
332 : {
333 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
334 :
335 0 : return pContext;
336 : }
337 :
338 0 : void ScXMLDDEColumnContext::EndElement()
339 : {
340 0 : }
341 :
342 0 : ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
343 : sal_uInt16 nPrfx,
344 : const OUString& rLName,
345 : const ::com::sun::star::uno::Reference<
346 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
347 : ScXMLDDELinkContext* pTempDDELink) :
348 : SvXMLImportContext( rImport, nPrfx, rLName ),
349 : pDDELink(pTempDDELink),
350 0 : nRows(1)
351 : {
352 0 : if( !xAttrList.is() ) return;
353 :
354 0 : sal_Int16 nAttrCount = xAttrList->getLength();
355 :
356 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
357 : {
358 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
359 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
360 0 : OUString aLocalName;
361 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
362 :
363 0 : if (nPrefix == XML_NAMESPACE_TABLE)
364 0 : if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED))
365 : {
366 0 : ::sax::Converter::convertNumber(nRows, sValue);
367 : }
368 0 : }
369 0 : pDDELink->AddRows(nRows);
370 : }
371 :
372 0 : ScXMLDDERowContext::~ScXMLDDERowContext()
373 : {
374 0 : }
375 :
376 0 : SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( sal_uInt16 nPrefix,
377 : const OUString& rLName,
378 : const ::com::sun::star::uno::Reference<
379 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
380 : {
381 0 : SvXMLImportContext *pContext = NULL;
382 :
383 0 : if (nPrefix == XML_NAMESPACE_TABLE)
384 0 : if (IsXMLToken(rLName, XML_TABLE_CELL))
385 0 : pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
386 :
387 0 : if (!pContext)
388 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
389 :
390 0 : return pContext;
391 : }
392 :
393 0 : void ScXMLDDERowContext::EndElement()
394 : {
395 0 : pDDELink->AddRowsToTable(nRows);
396 0 : }
397 :
398 0 : ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
399 : sal_uInt16 nPrfx,
400 : const OUString& rLName,
401 : const ::com::sun::star::uno::Reference<
402 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
403 : ScXMLDDELinkContext* pTempDDELink) :
404 : SvXMLImportContext( rImport, nPrfx, rLName ),
405 : sValue(),
406 : fValue(),
407 : nCells(1),
408 : bString(true),
409 : bString2(true),
410 : bEmpty(true),
411 0 : pDDELink(pTempDDELink)
412 : {
413 0 : if( !xAttrList.is() ) return;
414 :
415 0 : sal_Int16 nAttrCount = xAttrList->getLength();
416 :
417 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
418 : {
419 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
420 0 : const OUString& sTempValue (xAttrList->getValueByIndex( nIndex ));
421 0 : OUString aLocalName;
422 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
423 :
424 0 : if (nPrefix == XML_NAMESPACE_OFFICE)
425 : {
426 0 : if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
427 : {
428 0 : if (IsXMLToken(sTempValue, XML_STRING))
429 0 : bString = true;
430 : else
431 0 : bString = false;
432 : }
433 0 : else if (IsXMLToken(aLocalName, XML_STRING_VALUE))
434 : {
435 0 : sValue = sTempValue;
436 0 : bEmpty = false;
437 0 : bString2 = true;
438 : }
439 0 : else if (IsXMLToken(aLocalName, XML_VALUE))
440 : {
441 0 : ::sax::Converter::convertDouble(fValue, sTempValue);
442 0 : bEmpty = false;
443 0 : bString2 = false;
444 : }
445 : }
446 0 : else if (nPrefix == XML_NAMESPACE_TABLE)
447 : {
448 0 : if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
449 : {
450 0 : ::sax::Converter::convertNumber(nCells, sTempValue);
451 : }
452 : }
453 0 : }
454 : }
455 :
456 0 : ScXMLDDECellContext::~ScXMLDDECellContext()
457 : {
458 0 : }
459 :
460 0 : SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( sal_uInt16 nPrefix,
461 : const OUString& rLName,
462 : const ::com::sun::star::uno::Reference<
463 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
464 : {
465 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
466 :
467 0 : return pContext;
468 : }
469 :
470 0 : void ScXMLDDECellContext::EndElement()
471 : {
472 : OSL_ENSURE(bString == bString2, "something wrong with this type");
473 0 : ScDDELinkCell aCell;
474 0 : aCell.sValue = sValue;
475 0 : aCell.fValue = fValue;
476 0 : aCell.bEmpty = bEmpty;
477 0 : aCell.bString = bString2;
478 0 : for(sal_Int32 i = 0; i < nCells; ++i)
479 0 : pDDELink->AddCellToRow(aCell);
480 0 : }
481 :
482 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|