1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
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
,
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
);
80 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
85 void ScXMLDDELinksContext::EndElement()
89 ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport
& rImport
,
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
),
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);
125 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
130 void ScXMLDDELinkContext::CreateDDELink()
132 if (GetScImport().GetDocument() &&
133 sApplication
.getLength() &&
134 sTopic
.getLength() &&
137 String
sAppl(sApplication
);
140 GetScImport().GetDocument()->CreateDdeLink(sAppl
, sTop
, sIt
, nMode
);
142 if(GetScImport().GetDocument()->FindDdeLink(sAppl
, sTop
, sIt
, nMode
, nPos
))
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());
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
) );
183 ScDDELinkCells::iterator
aItr(aDDELinkTable
.begin());
184 ScDDELinkCells::iterator
aEndItr(aDDELinkTable
.end());
185 while (aItr
!= aEndItr
)
187 if (nIndex
% nColumns
== 0)
195 SCSIZE
nScCol( static_cast< SCSIZE
>( nCol
) );
196 SCSIZE
nScRow( static_cast< SCSIZE
>( nRow
) );
198 pMatrix
->PutEmpty( nScCol
, nScRow
);
199 else if( aItr
->bString
)
200 pMatrix
->PutString( aItr
->sValue
, nScCol
, nScRow
);
202 pMatrix
->PutDouble( aItr
->fValue
, nScCol
, nScRow
);
208 GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< USHORT
>( nPosition
), pMatrix
);
212 ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport
& rImport
,
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
));
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
);
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
);
267 void ScXMLDDESourceContext::EndElement()
269 pDDELink
->CreateDDELink();
272 ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport
& rImport
,
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
);
304 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
309 void ScXMLDDETableContext::EndElement()
313 ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport
& rImport
,
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;
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
));
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
);
355 void ScXMLDDEColumnContext::EndElement()
359 ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport
& rImport
,
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
),
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
));
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
);
403 pContext
= new SvXMLImportContext( GetImport(), nPrefix
, rLName
);
408 void ScXMLDDERowContext::EndElement()
410 pDDELink
->AddRowsToTable(nRows
);
413 ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport
& rImport
,
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
),
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
));
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
))
448 else if (IsXMLToken(aLocalName
, XML_STRING_VALUE
))
454 else if (IsXMLToken(aLocalName
, XML_VALUE
))
456 GetScImport().GetMM100UnitConverter().convertDouble(fValue
, sTempValue
);
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
);
483 void ScXMLDDECellContext::EndElement()
485 DBG_ASSERT(bString
== bString2
, "something wrong with this type");
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
);