nss: upgrade to release 3.73
[LibreOffice.git] / sc / source / filter / xml / XMLDDELinksContext.cxx
blobe06992efbc2aa96e7ac6f65270027cd8859878aa
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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/xmlnamespace.hxx>
26 #include <svl/sharedstringpool.hxx>
27 #include <osl/diagnose.h>
28 #include <sal/log.hxx>
30 using namespace com::sun::star;
31 using namespace xmloff::token;
33 ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport ) :
34 ScXMLImportContext( rImport )
36 // here are no attributes
37 rImport.LockSolarMutex();
40 ScXMLDDELinksContext::~ScXMLDDELinksContext()
42 GetScImport().UnlockSolarMutex();
45 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDDELinksContext::createFastChildContext(
46 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& /*xAttrList*/ )
48 SvXMLImportContext *pContext = nullptr;
50 if ( nElement == XML_ELEMENT( TABLE, XML_DDE_LINK) )
51 pContext = new ScXMLDDELinkContext(GetScImport());
53 return pContext;
56 ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport ) :
57 ScXMLImportContext( rImport ),
58 aDDELinkTable(),
59 aDDELinkRow(),
60 sApplication(),
61 sTopic(),
62 sItem(),
63 nPosition(-1),
64 nColumns(0),
65 nRows(0),
66 nMode(SC_DDE_DEFAULT)
68 // here are no attributes
71 ScXMLDDELinkContext::~ScXMLDDELinkContext()
75 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDDELinkContext::createFastChildContext(
76 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
78 SvXMLImportContext *pContext = nullptr;
79 sax_fastparser::FastAttributeList *pAttribList =
80 &sax_fastparser::castToFastAttributeList( xAttrList );
82 switch (nElement)
84 case XML_ELEMENT( OFFICE, XML_DDE_SOURCE ):
85 pContext = new ScXMLDDESourceContext(GetScImport(), pAttribList, this);
86 break;
87 case XML_ELEMENT( TABLE, XML_TABLE ):
88 pContext = new ScXMLDDETableContext(GetScImport(), this);
89 break;
92 return pContext;
95 void ScXMLDDELinkContext::CreateDDELink()
97 if (GetScImport().GetDocument() &&
98 !sApplication.isEmpty() &&
99 !sTopic.isEmpty() &&
100 !sItem.isEmpty())
102 GetScImport().GetDocument()->CreateDdeLink(sApplication, sTopic, sItem, nMode, ScMatrixRef());
103 size_t nPos;
104 if(GetScImport().GetDocument()->FindDdeLink(sApplication, sTopic, sItem, nMode, nPos))
105 nPosition = nPos;
106 else
108 nPosition = -1;
109 SAL_WARN("sc" , "DDE Link not inserted");
114 void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell)
116 aDDELinkRow.push_back(aCell);
119 void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP)
121 for (sal_Int32 i = 0; i < nRowsP; ++i)
122 aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end());
123 aDDELinkRow.clear();
126 void SAL_CALL ScXMLDDELinkContext::endFastElement( sal_Int32 /*nElement*/ )
128 ScDocument* pDoc = GetScImport().GetDocument();
129 if (!(nPosition > -1 && nColumns && nRows))
130 return;
132 bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size());
133 OSL_ENSURE( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count");
134 // Excel writes bad ODF in that it does not write the
135 // table:number-columns-repeated attribute of the
136 // <table:table-column> element, but apparently uses the number of
137 // <table:table-cell> elements within a <table:table-row> element to
138 // determine the column count instead. Be lenient ...
139 if (!bSizeMatch && nColumns == 1)
141 nColumns = aDDELinkTable.size() / nRows;
142 OSL_ENSURE( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(),
143 "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either");
145 ScMatrixRef pMatrix = new ScMatrix(static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows), 0.0);
146 sal_Int32 nCol(0);
147 sal_Int32 nRow(-1);
148 sal_Int32 nIndex(0);
150 svl::SharedStringPool& rPool = pDoc->GetSharedStringPool();
151 for (const auto& rDDELinkCell : aDDELinkTable)
153 if (nIndex % nColumns == 0)
155 ++nRow;
156 nCol = 0;
158 else
159 ++nCol;
161 SCSIZE nScCol( static_cast< SCSIZE >( nCol ) );
162 SCSIZE nScRow( static_cast< SCSIZE >( nRow ) );
163 if( rDDELinkCell.bEmpty )
164 pMatrix->PutEmpty( nScCol, nScRow );
165 else if( rDDELinkCell.bString )
166 pMatrix->PutString(rPool.intern(rDDELinkCell.sValue), nScCol, nScRow);
167 else
168 pMatrix->PutDouble( rDDELinkCell.fValue, nScCol, nScRow );
170 ++nIndex;
173 GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix );
176 ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport,
177 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
178 ScXMLDDELinkContext* pTempDDELink) :
179 ScXMLImportContext( rImport ),
180 pDDELink(pTempDDELink)
182 if ( !rAttrList.is() )
183 return;
185 for (auto &aIter : *rAttrList)
187 switch (aIter.getToken())
189 case XML_ELEMENT( OFFICE, XML_DDE_APPLICATION ):
190 pDDELink->SetApplication(aIter.toString());
191 break;
192 case XML_ELEMENT( OFFICE, XML_DDE_TOPIC ):
193 pDDELink->SetTopic(aIter.toString());
194 break;
195 case XML_ELEMENT( OFFICE, XML_DDE_ITEM ):
196 pDDELink->SetItem(aIter.toString());
197 break;
198 case XML_ELEMENT( TABLE, XML_CONVERSION_MODE ):
199 if (IsXMLToken(aIter, XML_INTO_ENGLISH_NUMBER))
200 pDDELink->SetMode(SC_DDE_ENGLISH);
201 else if (IsXMLToken(aIter, XML_KEEP_TEXT))
202 pDDELink->SetMode(SC_DDE_TEXT);
203 else
204 pDDELink->SetMode(SC_DDE_DEFAULT);
205 break;
210 ScXMLDDESourceContext::~ScXMLDDESourceContext()
214 void SAL_CALL ScXMLDDESourceContext::endFastElement( sal_Int32 /*nElement*/ )
216 pDDELink->CreateDDELink();
219 ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport,
220 ScXMLDDELinkContext* pTempDDELink) :
221 ScXMLImportContext( rImport ),
222 pDDELink(pTempDDELink)
224 // here are no attributes
227 ScXMLDDETableContext::~ScXMLDDETableContext()
231 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDDETableContext::createFastChildContext(
232 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
234 SvXMLImportContext *pContext = nullptr;
235 sax_fastparser::FastAttributeList *pAttribList =
236 &sax_fastparser::castToFastAttributeList( xAttrList );
238 switch (nElement)
240 case XML_ELEMENT( TABLE, XML_TABLE_COLUMN ):
241 pContext = new ScXMLDDEColumnContext(GetScImport(), pAttribList, pDDELink);
242 break;
243 case XML_ELEMENT( TABLE, XML_TABLE_ROW ):
244 pContext = new ScXMLDDERowContext(GetScImport(), pAttribList, pDDELink);
245 break;
248 return pContext;
251 ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport,
252 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
253 ScXMLDDELinkContext* pDDELink) :
254 ScXMLImportContext( rImport )
256 if ( rAttrList.is() )
258 sal_Int32 nCols(1);
259 auto aIter( rAttrList->find( XML_ELEMENT( TABLE, XML_NUMBER_COLUMNS_REPEATED ) ) );
260 if (aIter != rAttrList->end())
261 nCols = aIter.toInt32();
263 pDDELink->AddColumns(nCols);
267 ScXMLDDEColumnContext::~ScXMLDDEColumnContext()
271 ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport,
272 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
273 ScXMLDDELinkContext* pTempDDELink) :
274 ScXMLImportContext( rImport ),
275 pDDELink(pTempDDELink),
276 nRows(1)
278 if ( rAttrList.is() )
280 auto aIter( rAttrList->find( XML_ELEMENT( TABLE, XML_NUMBER_ROWS_REPEATED ) ) );
281 if (aIter != rAttrList->end())
282 nRows = aIter.toInt32();
284 pDDELink->AddRows(nRows);
288 ScXMLDDERowContext::~ScXMLDDERowContext()
292 uno::Reference< xml::sax::XFastContextHandler > SAL_CALL ScXMLDDERowContext::createFastChildContext(
293 sal_Int32 nElement, const uno::Reference< xml::sax::XFastAttributeList >& xAttrList )
295 SvXMLImportContext *pContext = nullptr;
296 sax_fastparser::FastAttributeList *pAttribList =
297 &sax_fastparser::castToFastAttributeList( xAttrList );
299 if (nElement == XML_ELEMENT( TABLE, XML_TABLE_CELL ))
300 pContext = new ScXMLDDECellContext(GetScImport(), pAttribList, pDDELink);
302 return pContext;
305 void SAL_CALL ScXMLDDERowContext::endFastElement( sal_Int32 /*nElement*/ )
307 pDDELink->AddRowsToTable(nRows);
310 ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport,
311 const rtl::Reference<sax_fastparser::FastAttributeList>& rAttrList,
312 ScXMLDDELinkContext* pTempDDELink) :
313 ScXMLImportContext( rImport ),
314 sValue(),
315 fValue(),
316 nCells(1),
317 bString(true),
318 bString2(true),
319 bEmpty(true),
320 pDDELink(pTempDDELink)
322 if ( !rAttrList.is() )
323 return;
325 for (auto &aIter : *rAttrList)
327 switch (aIter.getToken())
329 case XML_ELEMENT( OFFICE, XML_VALUE_TYPE ):
330 if (IsXMLToken(aIter, XML_STRING))
331 bString = true;
332 else
333 bString = false;
334 break;
335 case XML_ELEMENT( OFFICE, XML_STRING_VALUE ):
336 sValue = aIter.toString();
337 bEmpty = false;
338 bString2 = true;
339 break;
340 case XML_ELEMENT( OFFICE, XML_VALUE ):
341 fValue = aIter.toDouble();
342 bEmpty = false;
343 bString2 = false;
344 break;
345 case XML_ELEMENT( TABLE, XML_NUMBER_COLUMNS_REPEATED ):
346 nCells = aIter.toInt32();
347 break;
352 ScXMLDDECellContext::~ScXMLDDECellContext()
356 void SAL_CALL ScXMLDDECellContext::endFastElement( sal_Int32 /*nElement*/ )
358 OSL_ENSURE(bString == bString2, "something wrong with this type");
359 ScDDELinkCell aCell;
360 aCell.sValue = sValue;
361 aCell.fValue = fValue;
362 aCell.bEmpty = bEmpty;
363 aCell.bString = bString2;
364 for(sal_Int32 i = 0; i < nCells; ++i)
365 pDDELink->AddCellToRow(aCell);
368 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */