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