merge the formfield patch from ooo-build
[ooovba.git] / sc / source / filter / xml / XMLDDELinksContext.cxx
blob2f534a75dc4f8fc3cbd7c59b13eb08446da2cbfd
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: XMLDDELinksContext.cxx,v $
10 * $Revision: 1.18.134.1 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
36 // INCLUDE ---------------------------------------------------------------
37 #include "XMLDDELinksContext.hxx"
38 #include "xmlimprt.hxx"
39 #include "document.hxx"
40 #include "scmatrix.hxx"
41 #include <xmloff/xmltoken.hxx>
42 #include <xmloff/xmlnmspe.hxx>
43 #include <xmloff/nmspmap.hxx>
44 #include <xmloff/xmluconv.hxx>
45 #include <tools/debug.hxx>
47 using namespace com::sun::star;
48 using namespace xmloff::token;
49 using ::rtl::OUString;
51 //------------------------------------------------------------------
53 ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport,
54 USHORT nPrfx,
55 const ::rtl::OUString& rLName,
56 const ::com::sun::star::uno::Reference<
57 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
58 SvXMLImportContext( rImport, nPrfx, rLName )
60 // here are no attributes
61 rImport.LockSolarMutex();
64 ScXMLDDELinksContext::~ScXMLDDELinksContext()
66 GetScImport().UnlockSolarMutex();
69 SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( USHORT nPrefix,
70 const ::rtl::OUString& rLName,
71 const ::com::sun::star::uno::Reference<
72 ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
74 SvXMLImportContext *pContext = 0;
76 if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK))
77 pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList);
79 if( !pContext )
80 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
82 return pContext;
85 void ScXMLDDELinksContext::EndElement()
89 ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport,
90 USHORT nPrfx,
91 const ::rtl::OUString& rLName,
92 const ::com::sun::star::uno::Reference<
93 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) :
94 SvXMLImportContext( rImport, nPrfx, rLName ),
95 aDDELinkTable(),
96 aDDELinkRow(),
97 sApplication(),
98 sTopic(),
99 sItem(),
100 nPosition(-1),
101 nColumns(0),
102 nRows(0),
103 nMode(SC_DDE_DEFAULT)
105 // here are no attributes
108 ScXMLDDELinkContext::~ScXMLDDELinkContext()
112 SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( USHORT nPrefix,
113 const ::rtl::OUString& rLName,
114 const ::com::sun::star::uno::Reference<
115 ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
117 SvXMLImportContext *pContext = 0;
119 if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE))
120 pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this);
121 else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE))
122 pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this);
124 if( !pContext )
125 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
127 return pContext;
130 void ScXMLDDELinkContext::CreateDDELink()
132 if (GetScImport().GetDocument() &&
133 sApplication.getLength() &&
134 sTopic.getLength() &&
135 sItem.getLength())
137 String sAppl(sApplication);
138 String sTop(sTopic);
139 String sIt(sItem);
140 GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode);
141 sal_uInt16 nPos;
142 if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos))
143 nPosition = nPos;
144 else
145 nPosition = -1;
146 DBG_ASSERT(nPosition > -1, "DDE Link not inserted");
150 void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
152 aDDELinkRow.push_back(aCell);
155 void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
157 for (sal_Int32 i = 0; i < nRowsP; ++i)
158 aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
159 aDDELinkRow.clear();
162 void ScXMLDDELinkContext::EndElement()
164 if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument())
166 bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size());
167 DBG_ASSERT( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count");
168 // Excel writes bad ODF in that it does not write the
169 // table:number-columns-repeated attribute of the
170 // <table:table-column> element, but apparently uses the number of
171 // <table:table-cell> elements within a <table:table-row> element to
172 // determine the column count instead. Be lenient ...
173 if (!bSizeMatch && nColumns == 1)
175 nColumns = aDDELinkTable.size() / nRows;
176 DBG_ASSERT( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
177 "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
179 ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) );
180 sal_Int32 nCol(0);
181 sal_Int32 nRow(-1);
182 sal_Int32 nIndex(0);
183 ScDDELinkCells::iterator aItr(aDDELinkTable.begin());
184 ScDDELinkCells::iterator aEndItr(aDDELinkTable.end());
185 while (aItr != aEndItr)
187 if (nIndex % nColumns == 0)
189 ++nRow;
190 nCol = 0;
192 else
193 ++nCol;
195 SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
196 SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
197 if( aItr->bEmpty )
198 pMatrix->PutEmpty( nScCol, nScRow );
199 else if( aItr->bString )
200 pMatrix->PutString( aItr->sValue, nScCol, nScRow );
201 else
202 pMatrix->PutDouble( aItr->fValue, nScCol, nScRow );
204 ++nIndex;
205 ++aItr;
208 GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< USHORT >( nPosition ), pMatrix );
212 ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
213 USHORT nPrfx,
214 const ::rtl::OUString& rLName,
215 const ::com::sun::star::uno::Reference<
216 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
217 ScXMLDDELinkContext* pTempDDELink) :
218 SvXMLImportContext( rImport, nPrfx, rLName ),
219 pDDELink(pTempDDELink)
221 if( !xAttrList.is() ) return;
223 sal_Int16 nAttrCount = xAttrList->getLength();
225 for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
227 const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
228 const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
229 OUString aLocalName;
230 USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
232 if (nPrefix == XML_NAMESPACE_OFFICE)
234 if (IsXMLToken(aLocalName, XML_DDE_APPLICATION))
235 pDDELink->SetApplication(sValue);
236 else if (IsXMLToken(aLocalName, XML_DDE_TOPIC))
237 pDDELink->SetTopic(sValue);
238 else if (IsXMLToken(aLocalName, XML_DDE_ITEM))
239 pDDELink->SetItem(sValue);
241 else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE))
243 if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER))
244 pDDELink->SetMode(SC_DDE_ENGLISH);
245 else if (IsXMLToken(sValue, XML_KEEP_TEXT))
246 pDDELink->SetMode(SC_DDE_TEXT);
247 else
248 pDDELink->SetMode(SC_DDE_DEFAULT);
253 ScXMLDDESourceContext::~ScXMLDDESourceContext()
257 SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( USHORT nPrefix,
258 const ::rtl::OUString& rLName,
259 const ::com::sun::star::uno::Reference<
260 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
262 SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
264 return pContext;
267 void ScXMLDDESourceContext::EndElement()
269 pDDELink->CreateDDELink();
272 ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
273 USHORT nPrfx,
274 const ::rtl::OUString& rLName,
275 const ::com::sun::star::uno::Reference<
276 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */,
277 ScXMLDDELinkContext* pTempDDELink) :
278 SvXMLImportContext( rImport, nPrfx, rLName ),
279 pDDELink(pTempDDELink)
281 // here are no attributes
284 ScXMLDDETableContext::~ScXMLDDETableContext()
288 SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( USHORT nPrefix,
289 const ::rtl::OUString& rLName,
290 const ::com::sun::star::uno::Reference<
291 ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
293 SvXMLImportContext *pContext = NULL;
295 if (nPrefix == XML_NAMESPACE_TABLE)
297 if (IsXMLToken(rLName, XML_TABLE_COLUMN))
298 pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
299 else if (IsXMLToken(rLName, XML_TABLE_ROW))
300 pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
303 if (!pContext)
304 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
306 return pContext;
309 void ScXMLDDETableContext::EndElement()
313 ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
314 USHORT nPrfx,
315 const ::rtl::OUString& rLName,
316 const ::com::sun::star::uno::Reference<
317 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
318 ScXMLDDELinkContext* pTempDDELink) :
319 SvXMLImportContext( rImport, nPrfx, rLName ),
320 pDDELink(pTempDDELink)
322 if( !xAttrList.is() ) return;
323 sal_Int32 nCols(1);
325 sal_Int16 nAttrCount = xAttrList->getLength();
327 for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
329 const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
330 const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
331 OUString aLocalName;
332 USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
334 if (nPrefix == XML_NAMESPACE_TABLE)
335 if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
336 GetScImport().GetMM100UnitConverter().convertNumber(nCols, sValue);
338 pDDELink->AddColumns(nCols);
341 ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
345 SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( USHORT nPrefix,
346 const ::rtl::OUString& rLName,
347 const ::com::sun::star::uno::Reference<
348 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
350 SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
352 return pContext;
355 void ScXMLDDEColumnContext::EndElement()
359 ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
360 USHORT nPrfx,
361 const ::rtl::OUString& rLName,
362 const ::com::sun::star::uno::Reference<
363 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
364 ScXMLDDELinkContext* pTempDDELink) :
365 SvXMLImportContext( rImport, nPrfx, rLName ),
366 pDDELink(pTempDDELink),
367 nRows(1)
369 if( !xAttrList.is() ) return;
371 sal_Int16 nAttrCount = xAttrList->getLength();
373 for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
375 const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
376 const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex ));
377 OUString aLocalName;
378 USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
380 if (nPrefix == XML_NAMESPACE_TABLE)
381 if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED))
382 GetScImport().GetMM100UnitConverter().convertNumber(nRows, sValue);
384 pDDELink->AddRows(nRows);
387 ScXMLDDERowContext::~ScXMLDDERowContext()
391 SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( USHORT nPrefix,
392 const ::rtl::OUString& rLName,
393 const ::com::sun::star::uno::Reference<
394 ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
396 SvXMLImportContext *pContext = NULL;
398 if (nPrefix == XML_NAMESPACE_TABLE)
399 if (IsXMLToken(rLName, XML_TABLE_CELL))
400 pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink);
402 if (!pContext)
403 pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
405 return pContext;
408 void ScXMLDDERowContext::EndElement()
410 pDDELink->AddRowsToTable(nRows);
413 ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
414 USHORT nPrfx,
415 const ::rtl::OUString& rLName,
416 const ::com::sun::star::uno::Reference<
417 ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
418 ScXMLDDELinkContext* pTempDDELink) :
419 SvXMLImportContext( rImport, nPrfx, rLName ),
420 sValue(),
421 fValue(),
422 nCells(1),
423 bString(sal_True),
424 bString2(sal_True),
425 bEmpty(sal_True),
426 pDDELink(pTempDDELink)
428 if( !xAttrList.is() ) return;
430 sal_Int16 nAttrCount = xAttrList->getLength();
432 for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex )
434 const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex ));
435 const rtl::OUString& sTempValue (xAttrList->getValueByIndex( nIndex ));
436 OUString aLocalName;
437 USHORT nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName );
439 if (nPrefix == XML_NAMESPACE_OFFICE)
441 if (IsXMLToken(aLocalName, XML_VALUE_TYPE))
443 if (IsXMLToken(sTempValue, XML_STRING))
444 bString = sal_True;
445 else
446 bString = sal_False;
448 else if (IsXMLToken(aLocalName, XML_STRING_VALUE))
450 sValue = sTempValue;
451 bEmpty = sal_False;
452 bString2 = sal_True;
454 else if (IsXMLToken(aLocalName, XML_VALUE))
456 GetScImport().GetMM100UnitConverter().convertDouble(fValue, sTempValue);
457 bEmpty = sal_False;
458 bString2 = sal_False;
461 else if (nPrefix == XML_NAMESPACE_TABLE)
463 if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED))
464 GetScImport().GetMM100UnitConverter().convertNumber(nCells, sTempValue);
469 ScXMLDDECellContext::~ScXMLDDECellContext()
473 SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( USHORT nPrefix,
474 const ::rtl::OUString& rLName,
475 const ::com::sun::star::uno::Reference<
476 ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ )
478 SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
480 return pContext;
483 void ScXMLDDECellContext::EndElement()
485 DBG_ASSERT(bString == bString2, "something wrong with this type");
486 ScDDELinkCell aCell;
487 aCell.sValue = sValue;
488 aCell.fValue = fValue;
489 aCell.bEmpty = bEmpty;
490 aCell.bString = bString2;
491 for(sal_Int32 i = 0; i < nCells; ++i)
492 pDDELink->AddCellToRow(aCell);