1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
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 #include <osl/diagnose.h>
31 using namespace com::sun::star
;
32 using namespace xmloff::token
;
34 ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport
& rImport
,
36 const OUString
& rLName
,
37 const ::com::sun::star::uno::Reference
<
38 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */ ) :
39 SvXMLImportContext( rImport
, nPrfx
, rLName
)
41 // here are no attributes
42 rImport
.LockSolarMutex();
45 ScXMLDDELinksContext::~ScXMLDDELinksContext()
47 GetScImport().UnlockSolarMutex();
50 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
)
55 SvXMLImportContext
*pContext
= 0;
57 if ((nPrefix
== XML_NAMESPACE_TABLE
) && IsXMLToken(rLName
, XML_DDE_LINK
))
58 pContext
= new ScXMLDDELinkContext(GetScImport(), nPrefix
, rLName
, xAttrList
);
61 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
66 void ScXMLDDELinksContext::EndElement()
70 ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport
& rImport
,
72 const OUString
& rLName
,
73 const ::com::sun::star::uno::Reference
<
74 ::com::sun::star::xml::sax::XAttributeList
>& /* xAttrList */ ) :
75 SvXMLImportContext( rImport
, nPrfx
, rLName
),
86 // here are no attributes
89 ScXMLDDELinkContext::~ScXMLDDELinkContext()
93 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
)
98 SvXMLImportContext
*pContext
= 0;
100 if ((nPrefix
== XML_NAMESPACE_OFFICE
) && IsXMLToken(rLName
, XML_DDE_SOURCE
))
101 pContext
= new ScXMLDDESourceContext(GetScImport(), nPrefix
, rLName
, xAttrList
, this);
102 else if ((nPrefix
== XML_NAMESPACE_TABLE
) && IsXMLToken(rLName
, XML_TABLE
))
103 pContext
= new ScXMLDDETableContext(GetScImport(), nPrefix
, rLName
, xAttrList
, this);
106 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
111 void ScXMLDDELinkContext::CreateDDELink()
113 if (GetScImport().GetDocument() &&
114 !sApplication
.isEmpty() &&
118 GetScImport().GetDocument()->CreateDdeLink(sApplication
, sTopic
, sItem
, nMode
, ScMatrixRef());
120 if(GetScImport().GetDocument()->FindDdeLink(sApplication
, sTopic
, sItem
, nMode
, nPos
))
125 SAL_WARN("sc" , "DDE Link not inserted");
130 void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell
& aCell
)
132 aDDELinkRow
.push_back(aCell
);
135 void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP
)
137 for (sal_Int32 i
= 0; i
< nRowsP
; ++i
)
138 aDDELinkTable
.insert(aDDELinkTable
.end(), aDDELinkRow
.begin(), aDDELinkRow
.end());
142 void ScXMLDDELinkContext::EndElement()
144 ScDocument
* pDoc
= GetScImport().GetDocument();
145 if (nPosition
> -1 && nColumns
&& nRows
)
147 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 if (!bSizeMatch
&& nColumns
== 1)
156 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");
160 ScMatrixRef pMatrix
= new ScMatrix(static_cast<SCSIZE
>(nColumns
), static_cast<SCSIZE
>(nRows
), 0.0);
164 ScDDELinkCells::iterator
aItr(aDDELinkTable
.begin());
165 ScDDELinkCells::iterator
aEndItr(aDDELinkTable
.end());
167 svl::SharedStringPool
& rPool
= pDoc
->GetSharedStringPool();
168 while (aItr
!= aEndItr
)
170 if (nIndex
% nColumns
== 0)
178 SCSIZE
nScCol( static_cast< SCSIZE
>( nCol
) );
179 SCSIZE
nScRow( static_cast< SCSIZE
>( nRow
) );
181 pMatrix
->PutEmpty( nScCol
, nScRow
);
182 else if( aItr
->bString
)
183 pMatrix
->PutString(rPool
.intern(aItr
->sValue
), nScCol
, nScRow
);
185 pMatrix
->PutDouble( aItr
->fValue
, nScCol
, nScRow
);
191 GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16
>( nPosition
), pMatrix
);
195 ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport
& rImport
,
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 pDDELink(pTempDDELink
)
204 if( !xAttrList
.is() ) return;
206 sal_Int16 nAttrCount
= xAttrList
->getLength();
208 for( sal_Int16 nIndex
= 0; nIndex
< nAttrCount
; ++nIndex
)
210 const OUString
& sAttrName (xAttrList
->getNameByIndex( nIndex
));
211 const OUString
& sValue (xAttrList
->getValueByIndex( nIndex
));
213 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
215 if (nPrefix
== XML_NAMESPACE_OFFICE
)
217 if (IsXMLToken(aLocalName
, XML_DDE_APPLICATION
))
218 pDDELink
->SetApplication(sValue
);
219 else if (IsXMLToken(aLocalName
, XML_DDE_TOPIC
))
220 pDDELink
->SetTopic(sValue
);
221 else if (IsXMLToken(aLocalName
, XML_DDE_ITEM
))
222 pDDELink
->SetItem(sValue
);
224 else if ((nPrefix
== XML_NAMESPACE_TABLE
) && IsXMLToken(aLocalName
, XML_CONVERSION_MODE
))
226 if (IsXMLToken(sValue
, XML_INTO_ENGLISH_NUMBER
))
227 pDDELink
->SetMode(SC_DDE_ENGLISH
);
228 else if (IsXMLToken(sValue
, XML_KEEP_TEXT
))
229 pDDELink
->SetMode(SC_DDE_TEXT
);
231 pDDELink
->SetMode(SC_DDE_DEFAULT
);
236 ScXMLDDESourceContext::~ScXMLDDESourceContext()
240 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 */ )
245 SvXMLImportContext
*pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
250 void ScXMLDDESourceContext::EndElement()
252 pDDELink
->CreateDDELink();
255 ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport
& rImport
,
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 pDDELink(pTempDDELink
)
264 // here are no attributes
267 ScXMLDDETableContext::~ScXMLDDETableContext()
271 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
)
276 SvXMLImportContext
*pContext
= NULL
;
278 if (nPrefix
== XML_NAMESPACE_TABLE
)
280 if (IsXMLToken(rLName
, XML_TABLE_COLUMN
))
281 pContext
= new ScXMLDDEColumnContext(GetScImport(), nPrefix
, rLName
, xAttrList
, pDDELink
);
282 else if (IsXMLToken(rLName
, XML_TABLE_ROW
))
283 pContext
= new ScXMLDDERowContext(GetScImport(), nPrefix
, rLName
, xAttrList
, pDDELink
);
287 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
292 void ScXMLDDETableContext::EndElement()
296 ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport
& rImport
,
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 pDDELink(pTempDDELink
)
305 if( !xAttrList
.is() ) return;
308 sal_Int16 nAttrCount
= xAttrList
->getLength();
310 for( sal_Int16 nIndex
= 0; nIndex
< nAttrCount
; ++nIndex
)
312 const OUString
& sAttrName (xAttrList
->getNameByIndex( nIndex
));
313 const OUString
& sValue (xAttrList
->getValueByIndex( nIndex
));
315 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
317 if (nPrefix
== XML_NAMESPACE_TABLE
)
318 if (IsXMLToken(aLocalName
, XML_NUMBER_COLUMNS_REPEATED
))
320 ::sax::Converter::convertNumber(nCols
, sValue
);
323 pDDELink
->AddColumns(nCols
);
326 ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
330 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 */ )
335 SvXMLImportContext
*pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
340 void ScXMLDDEColumnContext::EndElement()
344 ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport
& rImport
,
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
),
354 if( !xAttrList
.is() ) return;
356 sal_Int16 nAttrCount
= xAttrList
->getLength();
358 for( sal_Int16 nIndex
= 0; nIndex
< nAttrCount
; ++nIndex
)
360 const OUString
& sAttrName (xAttrList
->getNameByIndex( nIndex
));
361 const OUString
& sValue (xAttrList
->getValueByIndex( nIndex
));
363 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
365 if (nPrefix
== XML_NAMESPACE_TABLE
)
366 if (IsXMLToken(aLocalName
, XML_NUMBER_ROWS_REPEATED
))
368 ::sax::Converter::convertNumber(nRows
, sValue
);
371 pDDELink
->AddRows(nRows
);
374 ScXMLDDERowContext::~ScXMLDDERowContext()
378 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
)
383 SvXMLImportContext
*pContext
= NULL
;
385 if (nPrefix
== XML_NAMESPACE_TABLE
)
386 if (IsXMLToken(rLName
, XML_TABLE_CELL
))
387 pContext
= new ScXMLDDECellContext(GetScImport(), nPrefix
, rLName
, xAttrList
, pDDELink
);
390 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
395 void ScXMLDDERowContext::EndElement()
397 pDDELink
->AddRowsToTable(nRows
);
400 ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport
& rImport
,
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
),
413 pDDELink(pTempDDELink
)
415 if( !xAttrList
.is() ) return;
417 sal_Int16 nAttrCount
= xAttrList
->getLength();
419 for( sal_Int16 nIndex
= 0; nIndex
< nAttrCount
; ++nIndex
)
421 const OUString
& sAttrName (xAttrList
->getNameByIndex( nIndex
));
422 const OUString
& sTempValue (xAttrList
->getValueByIndex( nIndex
));
424 sal_uInt16 nPrefix
= GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName
, &aLocalName
);
426 if (nPrefix
== XML_NAMESPACE_OFFICE
)
428 if (IsXMLToken(aLocalName
, XML_VALUE_TYPE
))
430 if (IsXMLToken(sTempValue
, XML_STRING
))
435 else if (IsXMLToken(aLocalName
, XML_STRING_VALUE
))
441 else if (IsXMLToken(aLocalName
, XML_VALUE
))
443 ::sax::Converter::convertDouble(fValue
, sTempValue
);
448 else if (nPrefix
== XML_NAMESPACE_TABLE
)
450 if (IsXMLToken(aLocalName
, XML_NUMBER_COLUMNS_REPEATED
))
452 ::sax::Converter::convertNumber(nCells
, sTempValue
);
458 ScXMLDDECellContext::~ScXMLDDECellContext()
462 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 */ )
467 SvXMLImportContext
*pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
472 void ScXMLDDECellContext::EndElement()
474 OSL_ENSURE(bString
== bString2
, "something wrong with this type");
476 aCell
.sValue
= sValue
;
477 aCell
.fValue
= fValue
;
478 aCell
.bEmpty
= bEmpty
;
479 aCell
.bString
= bString2
;
480 for(sal_Int32 i
= 0; i
< nCells
; ++i
)
481 pDDELink
->AddCellToRow(aCell
);
484 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */