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 : #include "svl/sharedstringpool.hxx"
29 :
30 : using namespace com::sun::star;
31 : using namespace xmloff::token;
32 :
33 :
34 0 : ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport,
35 : sal_uInt16 nPrfx,
36 : const OUString& rLName,
37 : const ::com::sun::star::uno::Reference<
38 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
39 0 : SvXMLImportContext( rImport, nPrfx, rLName )
40 : {
41 : // here are no attributes
42 0 : rImport.LockSolarMutex();
43 0 : }
44 :
45 0 : ScXMLDDELinksContext::~ScXMLDDELinksContext()
46 : {
47 0 : GetScImport().UnlockSolarMutex();
48 0 : }
49 :
50 0 : SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( sal_uInt16 nPrefix,
51 : const OUString& rLName,
52 : const ::com::sun::star::uno::Reference<
53 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
54 : {
55 0 : SvXMLImportContext *pContext = 0;
56 :
57 0 : if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK))
58 0 : pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList);
59 :
60 0 : if( !pContext )
61 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
62 :
63 0 : return pContext;
64 : }
65 :
66 0 : void ScXMLDDELinksContext::EndElement()
67 : {
68 0 : }
69 :
70 0 : ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport,
71 : sal_uInt16 nPrfx,
72 : const OUString& rLName,
73 : const ::com::sun::star::uno::Reference<
74 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
75 : SvXMLImportContext( rImport, nPrfx, rLName ),
76 : aDDELinkTable(),
77 : aDDELinkRow(),
78 : sApplication(),
79 : sTopic(),
80 : sItem(),
81 : nPosition(-1),
82 : nColumns(0),
83 : nRows(0),
84 0 : nMode(SC_DDE_DEFAULT)
85 : {
86 : // here are no attributes
87 0 : }
88 :
89 0 : ScXMLDDELinkContext::~ScXMLDDELinkContext()
90 : {
91 0 : }
92 :
93 0 : SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( sal_uInt16 nPrefix,
94 : const OUString& rLName,
95 : const ::com::sun::star::uno::Reference<
96 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
97 : {
98 0 : SvXMLImportContext *pContext = 0;
99 :
100 0 : if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE))
101 0 : pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
102 0 : else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE))
103 0 : pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
104 :
105 0 : if( !pContext )
106 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
107 :
108 0 : return pContext;
109 : }
110 :
111 0 : void ScXMLDDELinkContext::CreateDDELink()
112 : {
113 0 : if (GetScImport().GetDocument() &&
114 0 : !sApplication.isEmpty() &&
115 0 : !sTopic.isEmpty() &&
116 0 : !sItem.isEmpty())
117 : {
118 0 : GetScImport().GetDocument()->CreateDdeLink(sApplication, sTopic, sItem, nMode, ScMatrixRef());
119 : size_t nPos;
120 0 : if(GetScImport().GetDocument()->FindDdeLink(sApplication, sTopic, sItem, nMode, nPos))
121 0 : nPosition = nPos;
122 : else
123 : {
124 0 : nPosition = -1;
125 : SAL_WARN("sc" , "DDE Link not inserted");
126 : }
127 : }
128 0 : }
129 :
130 0 : void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
131 : {
132 0 : aDDELinkRow.push_back(aCell);
133 0 : }
134 :
135 0 : void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
136 : {
137 0 : for (sal_Int32 i = 0; i < nRowsP; ++i)
138 0 : aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
139 0 : aDDELinkRow.clear();
140 0 : }
141 :
142 0 : void ScXMLDDELinkContext::EndElement()
143 : {
144 0 : ScDocument* pDoc = GetScImport().GetDocument();
145 0 : if (nPosition > -1 && nColumns && nRows)
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 :
167 0 : svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
168 0 : while (aItr != aEndItr)
169 : {
170 0 : if (nIndex % nColumns == 0)
171 : {
172 0 : ++nRow;
173 0 : nCol = 0;
174 : }
175 : else
176 0 : ++nCol;
177 :
178 0 : SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
179 0 : SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
180 0 : if( aItr->bEmpty )
181 0 : pMatrix->PutEmpty( nScCol, nScRow );
182 0 : else if( aItr->bString )
183 0 : pMatrix->PutString(rPool.intern(aItr->sValue), nScCol, nScRow);
184 : else
185 0 : pMatrix->PutDouble( aItr->fValue, nScCol, nScRow );
186 :
187 0 : ++nIndex;
188 0 : ++aItr;
189 : }
190 :
191 0 : GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix );
192 : }
193 0 : }
194 :
195 0 : ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
196 : sal_uInt16 nPrfx,
197 : const OUString& rLName,
198 : const ::com::sun::star::uno::Reference<
199 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
200 : ScXMLDDELinkContext* pTempDDELink) :
201 : SvXMLImportContext( rImport, nPrfx, rLName ),
202 0 : pDDELink(pTempDDELink)
203 : {
204 0 : if( !xAttrList.is() ) return;
205 :
206 0 : sal_Int16 nAttrCount = xAttrList->getLength();
207 :
208 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
209 : {
210 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
211 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
212 0 : OUString aLocalName;
213 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
214 :
215 0 : if (nPrefix == XML_NAMESPACE_OFFICE)
216 : {
217 0 : if (IsXMLToken(aLocalName, XML_DDE_APPLICATION))
218 0 : pDDELink->SetApplication(sValue);
219 0 : else if (IsXMLToken(aLocalName, XML_DDE_TOPIC))
220 0 : pDDELink->SetTopic(sValue);
221 0 : else if (IsXMLToken(aLocalName, XML_DDE_ITEM))
222 0 : pDDELink->SetItem(sValue);
223 : }
224 0 : else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE))
225 : {
226 0 : if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER))
227 0 : pDDELink->SetMode(SC_DDE_ENGLISH);
228 0 : else if (IsXMLToken(sValue, XML_KEEP_TEXT))
229 0 : pDDELink->SetMode(SC_DDE_TEXT);
230 : else
231 0 : pDDELink->SetMode(SC_DDE_DEFAULT);
232 : }
233 0 : }
234 : }
235 :
236 0 : ScXMLDDESourceContext::~ScXMLDDESourceContext()
237 : {
238 0 : }
239 :
240 0 : SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( sal_uInt16 nPrefix,
241 : const OUString& rLName,
242 : const ::com::sun::star::uno::Reference<
243 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
244 : {
245 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
246 :
247 0 : return pContext;
248 : }
249 :
250 0 : void ScXMLDDESourceContext::EndElement()
251 : {
252 0 : pDDELink->CreateDDELink();
253 0 : }
254 :
255 0 : ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
256 : sal_uInt16 nPrfx,
257 : const OUString& rLName,
258 : const ::com::sun::star::uno::Reference<
259 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
260 : ScXMLDDELinkContext* pTempDDELink) :
261 : SvXMLImportContext( rImport, nPrfx, rLName ),
262 0 : pDDELink(pTempDDELink)
263 : {
264 : // here are no attributes
265 0 : }
266 :
267 0 : ScXMLDDETableContext::~ScXMLDDETableContext()
268 : {
269 0 : }
270 :
271 0 : SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( sal_uInt16 nPrefix,
272 : const OUString& rLName,
273 : const ::com::sun::star::uno::Reference<
274 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
275 : {
276 0 : SvXMLImportContext *pContext = NULL;
277 :
278 0 : if (nPrefix == XML_NAMESPACE_TABLE)
279 : {
280 0 : if (IsXMLToken(rLName, XML_TABLE_COLUMN))
281 0 : pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
282 0 : else if (IsXMLToken(rLName, XML_TABLE_ROW))
283 0 : pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
284 : }
285 :
286 0 : if (!pContext)
287 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
288 :
289 0 : return pContext;
290 : }
291 :
292 0 : void ScXMLDDETableContext::EndElement()
293 : {
294 0 : }
295 :
296 0 : ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
297 : sal_uInt16 nPrfx,
298 : const OUString& rLName,
299 : const ::com::sun::star::uno::Reference<
300 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
301 : ScXMLDDELinkContext* pTempDDELink) :
302 : SvXMLImportContext( rImport, nPrfx, rLName ),
303 0 : pDDELink(pTempDDELink)
304 : {
305 0 : if( !xAttrList.is() ) return;
306 0 : sal_Int32 nCols(1);
307 :
308 0 : sal_Int16 nAttrCount = xAttrList->getLength();
309 :
310 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
311 : {
312 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
313 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
314 0 : OUString aLocalName;
315 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
316 :
317 0 : if (nPrefix == XML_NAMESPACE_TABLE)
318 0 : if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
319 : {
320 0 : ::sax::Converter::convertNumber(nCols, sValue);
321 : }
322 0 : }
323 0 : pDDELink->AddColumns(nCols);
324 : }
325 :
326 0 : ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
327 : {
328 0 : }
329 :
330 0 : SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( sal_uInt16 nPrefix,
331 : const OUString& rLName,
332 : const ::com::sun::star::uno::Reference<
333 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
334 : {
335 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
336 :
337 0 : return pContext;
338 : }
339 :
340 0 : void ScXMLDDEColumnContext::EndElement()
341 : {
342 0 : }
343 :
344 0 : ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
345 : sal_uInt16 nPrfx,
346 : const OUString& rLName,
347 : const ::com::sun::star::uno::Reference<
348 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
349 : ScXMLDDELinkContext* pTempDDELink) :
350 : SvXMLImportContext( rImport, nPrfx, rLName ),
351 : pDDELink(pTempDDELink),
352 0 : nRows(1)
353 : {
354 0 : if( !xAttrList.is() ) return;
355 :
356 0 : sal_Int16 nAttrCount = xAttrList->getLength();
357 :
358 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
359 : {
360 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
361 0 : const OUString& sValue (xAttrList->getValueByIndex( nIndex ));
362 0 : OUString aLocalName;
363 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
364 :
365 0 : if (nPrefix == XML_NAMESPACE_TABLE)
366 0 : if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED))
367 : {
368 0 : ::sax::Converter::convertNumber(nRows, sValue);
369 : }
370 0 : }
371 0 : pDDELink->AddRows(nRows);
372 : }
373 :
374 0 : ScXMLDDERowContext::~ScXMLDDERowContext()
375 : {
376 0 : }
377 :
378 0 : SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( sal_uInt16 nPrefix,
379 : const OUString& rLName,
380 : const ::com::sun::star::uno::Reference<
381 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
382 : {
383 0 : SvXMLImportContext *pContext = NULL;
384 :
385 0 : if (nPrefix == XML_NAMESPACE_TABLE)
386 0 : if (IsXMLToken(rLName, XML_TABLE_CELL))
387 0 : pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
388 :
389 0 : if (!pContext)
390 0 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
391 :
392 0 : return pContext;
393 : }
394 :
395 0 : void ScXMLDDERowContext::EndElement()
396 : {
397 0 : pDDELink->AddRowsToTable(nRows);
398 0 : }
399 :
400 0 : ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
401 : sal_uInt16 nPrfx,
402 : const OUString& rLName,
403 : const ::com::sun::star::uno::Reference<
404 : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
405 : ScXMLDDELinkContext* pTempDDELink) :
406 : SvXMLImportContext( rImport, nPrfx, rLName ),
407 : sValue(),
408 : fValue(),
409 : nCells(1),
410 : bString(true),
411 : bString2(true),
412 : bEmpty(true),
413 0 : pDDELink(pTempDDELink)
414 : {
415 0 : if( !xAttrList.is() ) return;
416 :
417 0 : sal_Int16 nAttrCount = xAttrList->getLength();
418 :
419 0 : for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
420 : {
421 0 : const OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
422 0 : const OUString& sTempValue (xAttrList->getValueByIndex( nIndex ));
423 0 : OUString aLocalName;
424 0 : sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
425 :
426 0 : if (nPrefix == XML_NAMESPACE_OFFICE)
427 : {
428 0 : if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
429 : {
430 0 : if (IsXMLToken(sTempValue, XML_STRING))
431 0 : bString = true;
432 : else
433 0 : bString = false;
434 : }
435 0 : else if (IsXMLToken(aLocalName, XML_STRING_VALUE))
436 : {
437 0 : sValue = sTempValue;
438 0 : bEmpty = false;
439 0 : bString2 = true;
440 : }
441 0 : else if (IsXMLToken(aLocalName, XML_VALUE))
442 : {
443 0 : ::sax::Converter::convertDouble(fValue, sTempValue);
444 0 : bEmpty = false;
445 0 : bString2 = false;
446 : }
447 : }
448 0 : else if (nPrefix == XML_NAMESPACE_TABLE)
449 : {
450 0 : if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
451 : {
452 0 : ::sax::Converter::convertNumber(nCells, sTempValue);
453 : }
454 : }
455 0 : }
456 : }
457 :
458 0 : ScXMLDDECellContext::~ScXMLDDECellContext()
459 : {
460 0 : }
461 :
462 0 : SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( sal_uInt16 nPrefix,
463 : const OUString& rLName,
464 : const ::com::sun::star::uno::Reference<
465 : ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
466 : {
467 0 : SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
468 :
469 0 : return pContext;
470 : }
471 :
472 0 : void ScXMLDDECellContext::EndElement()
473 : {
474 : OSL_ENSURE(bString == bString2, "something wrong with this type");
475 0 : ScDDELinkCell aCell;
476 0 : aCell.sValue = sValue;
477 0 : aCell.fValue = fValue;
478 0 : aCell.bEmpty = bEmpty;
479 0 : aCell.bString = bString2;
480 0 : for(sal_Int32 i = 0; i < nCells; ++i)
481 0 : pDDELink->AddCellToRow(aCell);
482 0 : }
483 :
484 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|