| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sc.hxx" |
| |
| |
| |
| // INCLUDE --------------------------------------------------------------- |
| #include "XMLDDELinksContext.hxx" |
| #include "xmlimprt.hxx" |
| #include "document.hxx" |
| #include "scmatrix.hxx" |
| #include <xmloff/xmltoken.hxx> |
| #include <xmloff/xmlnmspe.hxx> |
| #include <xmloff/nmspmap.hxx> |
| #include <xmloff/xmluconv.hxx> |
| #include <tools/debug.hxx> |
| |
| using namespace com::sun::star; |
| using namespace xmloff::token; |
| using ::rtl::OUString; |
| |
| //------------------------------------------------------------------ |
| |
| ScXMLDDELinksContext::ScXMLDDELinksContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : |
| SvXMLImportContext( rImport, nPrfx, rLName ) |
| { |
| // here are no attributes |
| rImport.LockSolarMutex(); |
| } |
| |
| ScXMLDDELinksContext::~ScXMLDDELinksContext() |
| { |
| GetScImport().UnlockSolarMutex(); |
| } |
| |
| SvXMLImportContext *ScXMLDDELinksContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) |
| { |
| SvXMLImportContext *pContext = 0; |
| |
| if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_DDE_LINK)) |
| pContext = new ScXMLDDELinkContext(GetScImport(), nPrefix, rLName, xAttrList); |
| |
| if( !pContext ) |
| pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDELinksContext::EndElement() |
| { |
| } |
| |
| ScXMLDDELinkContext::ScXMLDDELinkContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| aDDELinkTable(), |
| aDDELinkRow(), |
| sApplication(), |
| sTopic(), |
| sItem(), |
| nPosition(-1), |
| nColumns(0), |
| nRows(0), |
| nMode(SC_DDE_DEFAULT) |
| { |
| // here are no attributes |
| } |
| |
| ScXMLDDELinkContext::~ScXMLDDELinkContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDELinkContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) |
| { |
| SvXMLImportContext *pContext = 0; |
| |
| if ((nPrefix == XML_NAMESPACE_OFFICE) && IsXMLToken(rLName, XML_DDE_SOURCE)) |
| pContext = new ScXMLDDESourceContext(GetScImport(), nPrefix, rLName, xAttrList, this); |
| else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(rLName, XML_TABLE)) |
| pContext = new ScXMLDDETableContext(GetScImport(), nPrefix, rLName, xAttrList, this); |
| |
| if( !pContext ) |
| pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDELinkContext::CreateDDELink() |
| { |
| if (GetScImport().GetDocument() && |
| sApplication.getLength() && |
| sTopic.getLength() && |
| sItem.getLength()) |
| { |
| String sAppl(sApplication); |
| String sTop(sTopic); |
| String sIt(sItem); |
| GetScImport().GetDocument()->CreateDdeLink(sAppl, sTop, sIt, nMode); |
| sal_uInt16 nPos; |
| if(GetScImport().GetDocument()->FindDdeLink(sAppl, sTop, sIt, nMode, nPos)) |
| nPosition = nPos; |
| else |
| nPosition = -1; |
| DBG_ASSERT(nPosition > -1, "DDE Link not inserted"); |
| } |
| } |
| |
| void ScXMLDDELinkContext::AddCellToRow(const ScDDELinkCell& aCell) |
| { |
| aDDELinkRow.push_back(aCell); |
| } |
| |
| void ScXMLDDELinkContext::AddRowsToTable(const sal_Int32 nRowsP) |
| { |
| for (sal_Int32 i = 0; i < nRowsP; ++i) |
| aDDELinkTable.insert(aDDELinkTable.end(), aDDELinkRow.begin(), aDDELinkRow.end()); |
| aDDELinkRow.clear(); |
| } |
| |
| void ScXMLDDELinkContext::EndElement() |
| { |
| if (nPosition > -1 && nColumns && nRows && GetScImport().GetDocument()) |
| { |
| bool bSizeMatch = (static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size()); |
| DBG_ASSERT( bSizeMatch, "ScXMLDDELinkContext::EndElement: matrix dimension doesn't match cells count"); |
| // Excel writes bad ODF in that it does not write the |
| // table:number-columns-repeated attribute of the |
| // <table:table-column> element, but apparently uses the number of |
| // <table:table-cell> elements within a <table:table-row> element to |
| // determine the column count instead. Be lenient ... |
| if (!bSizeMatch && nColumns == 1) |
| { |
| nColumns = aDDELinkTable.size() / nRows; |
| DBG_ASSERT( static_cast<size_t>(nColumns * nRows) == aDDELinkTable.size(), |
| "ScXMLDDELinkContext::EndElement: adapted matrix dimension doesn't match either"); |
| } |
| ScMatrixRef pMatrix = new ScMatrix( static_cast<SCSIZE>(nColumns), static_cast<SCSIZE>(nRows) ); |
| sal_Int32 nCol(0); |
| sal_Int32 nRow(-1); |
| sal_Int32 nIndex(0); |
| ScDDELinkCells::iterator aItr(aDDELinkTable.begin()); |
| ScDDELinkCells::iterator aEndItr(aDDELinkTable.end()); |
| while (aItr != aEndItr) |
| { |
| if (nIndex % nColumns == 0) |
| { |
| ++nRow; |
| nCol = 0; |
| } |
| else |
| ++nCol; |
| |
| SCSIZE nScCol( static_cast< SCSIZE >( nCol ) ); |
| SCSIZE nScRow( static_cast< SCSIZE >( nRow ) ); |
| if( aItr->bEmpty ) |
| pMatrix->PutEmpty( nScCol, nScRow ); |
| else if( aItr->bString ) |
| pMatrix->PutString( aItr->sValue, nScCol, nScRow ); |
| else |
| pMatrix->PutDouble( aItr->fValue, nScCol, nScRow ); |
| |
| ++nIndex; |
| ++aItr; |
| } |
| |
| GetScImport().GetDocument()->SetDdeLinkResultMatrix( static_cast< sal_uInt16 >( nPosition ), pMatrix ); |
| } |
| } |
| |
| ScXMLDDESourceContext::ScXMLDDESourceContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList, |
| ScXMLDDELinkContext* pTempDDELink) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| pDDELink(pTempDDELink) |
| { |
| if( !xAttrList.is() ) return; |
| |
| sal_Int16 nAttrCount = xAttrList->getLength(); |
| |
| for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) |
| { |
| const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); |
| const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| |
| if (nPrefix == XML_NAMESPACE_OFFICE) |
| { |
| if (IsXMLToken(aLocalName, XML_DDE_APPLICATION)) |
| pDDELink->SetApplication(sValue); |
| else if (IsXMLToken(aLocalName, XML_DDE_TOPIC)) |
| pDDELink->SetTopic(sValue); |
| else if (IsXMLToken(aLocalName, XML_DDE_ITEM)) |
| pDDELink->SetItem(sValue); |
| } |
| else if ((nPrefix == XML_NAMESPACE_TABLE) && IsXMLToken(aLocalName, XML_CONVERSION_MODE)) |
| { |
| if (IsXMLToken(sValue, XML_INTO_ENGLISH_NUMBER)) |
| pDDELink->SetMode(SC_DDE_ENGLISH); |
| else if (IsXMLToken(sValue, XML_KEEP_TEXT)) |
| pDDELink->SetMode(SC_DDE_TEXT); |
| else |
| pDDELink->SetMode(SC_DDE_DEFAULT); |
| } |
| } |
| } |
| |
| ScXMLDDESourceContext::~ScXMLDDESourceContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDESourceContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) |
| { |
| SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDESourceContext::EndElement() |
| { |
| pDDELink->CreateDDELink(); |
| } |
| |
| ScXMLDDETableContext::ScXMLDDETableContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */, |
| ScXMLDDELinkContext* pTempDDELink) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| pDDELink(pTempDDELink) |
| { |
| // here are no attributes |
| } |
| |
| ScXMLDDETableContext::~ScXMLDDETableContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDETableContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) |
| { |
| SvXMLImportContext *pContext = NULL; |
| |
| if (nPrefix == XML_NAMESPACE_TABLE) |
| { |
| if (IsXMLToken(rLName, XML_TABLE_COLUMN)) |
| pContext = new ScXMLDDEColumnContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); |
| else if (IsXMLToken(rLName, XML_TABLE_ROW)) |
| pContext = new ScXMLDDERowContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); |
| } |
| |
| if (!pContext) |
| pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDETableContext::EndElement() |
| { |
| } |
| |
| ScXMLDDEColumnContext::ScXMLDDEColumnContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList, |
| ScXMLDDELinkContext* pTempDDELink) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| pDDELink(pTempDDELink) |
| { |
| if( !xAttrList.is() ) return; |
| sal_Int32 nCols(1); |
| |
| sal_Int16 nAttrCount = xAttrList->getLength(); |
| |
| for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) |
| { |
| const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); |
| const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| |
| if (nPrefix == XML_NAMESPACE_TABLE) |
| if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED)) |
| GetScImport().GetMM100UnitConverter().convertNumber(nCols, sValue); |
| } |
| pDDELink->AddColumns(nCols); |
| } |
| |
| ScXMLDDEColumnContext::~ScXMLDDEColumnContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDEColumnContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) |
| { |
| SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDEColumnContext::EndElement() |
| { |
| } |
| |
| ScXMLDDERowContext::ScXMLDDERowContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList, |
| ScXMLDDELinkContext* pTempDDELink) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| pDDELink(pTempDDELink), |
| nRows(1) |
| { |
| if( !xAttrList.is() ) return; |
| |
| sal_Int16 nAttrCount = xAttrList->getLength(); |
| |
| for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) |
| { |
| const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); |
| const rtl::OUString& sValue (xAttrList->getValueByIndex( nIndex )); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| |
| if (nPrefix == XML_NAMESPACE_TABLE) |
| if (IsXMLToken(aLocalName, XML_NUMBER_ROWS_REPEATED)) |
| GetScImport().GetMM100UnitConverter().convertNumber(nRows, sValue); |
| } |
| pDDELink->AddRows(nRows); |
| } |
| |
| ScXMLDDERowContext::~ScXMLDDERowContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDERowContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList ) |
| { |
| SvXMLImportContext *pContext = NULL; |
| |
| if (nPrefix == XML_NAMESPACE_TABLE) |
| if (IsXMLToken(rLName, XML_TABLE_CELL)) |
| pContext = new ScXMLDDECellContext(GetScImport(), nPrefix, rLName, xAttrList, pDDELink); |
| |
| if (!pContext) |
| pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDERowContext::EndElement() |
| { |
| pDDELink->AddRowsToTable(nRows); |
| } |
| |
| ScXMLDDECellContext::ScXMLDDECellContext( ScXMLImport& rImport, |
| sal_uInt16 nPrfx, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& xAttrList, |
| ScXMLDDELinkContext* pTempDDELink) : |
| SvXMLImportContext( rImport, nPrfx, rLName ), |
| sValue(), |
| fValue(), |
| nCells(1), |
| bString(sal_True), |
| bString2(sal_True), |
| bEmpty(sal_True), |
| pDDELink(pTempDDELink) |
| { |
| if( !xAttrList.is() ) return; |
| |
| sal_Int16 nAttrCount = xAttrList->getLength(); |
| |
| for( sal_Int16 nIndex = 0; nIndex < nAttrCount; ++nIndex ) |
| { |
| const rtl::OUString& sAttrName (xAttrList->getNameByIndex( nIndex )); |
| const rtl::OUString& sTempValue (xAttrList->getValueByIndex( nIndex )); |
| OUString aLocalName; |
| sal_uInt16 nPrefix = GetScImport().GetNamespaceMap().GetKeyByAttrName( sAttrName, &aLocalName ); |
| |
| if (nPrefix == XML_NAMESPACE_OFFICE) |
| { |
| if (IsXMLToken(aLocalName, XML_VALUE_TYPE)) |
| { |
| if (IsXMLToken(sTempValue, XML_STRING)) |
| bString = sal_True; |
| else |
| bString = sal_False; |
| } |
| else if (IsXMLToken(aLocalName, XML_STRING_VALUE)) |
| { |
| sValue = sTempValue; |
| bEmpty = sal_False; |
| bString2 = sal_True; |
| } |
| else if (IsXMLToken(aLocalName, XML_VALUE)) |
| { |
| GetScImport().GetMM100UnitConverter().convertDouble(fValue, sTempValue); |
| bEmpty = sal_False; |
| bString2 = sal_False; |
| } |
| } |
| else if (nPrefix == XML_NAMESPACE_TABLE) |
| { |
| if (IsXMLToken(aLocalName, XML_NUMBER_COLUMNS_REPEATED)) |
| GetScImport().GetMM100UnitConverter().convertNumber(nCells, sTempValue); |
| } |
| } |
| } |
| |
| ScXMLDDECellContext::~ScXMLDDECellContext() |
| { |
| } |
| |
| SvXMLImportContext *ScXMLDDECellContext::CreateChildContext( sal_uInt16 nPrefix, |
| const ::rtl::OUString& rLName, |
| const ::com::sun::star::uno::Reference< |
| ::com::sun::star::xml::sax::XAttributeList>& /* xAttrList */ ) |
| { |
| SvXMLImportContext *pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName ); |
| |
| return pContext; |
| } |
| |
| void ScXMLDDECellContext::EndElement() |
| { |
| DBG_ASSERT(bString == bString2, "something wrong with this type"); |
| ScDDELinkCell aCell; |
| aCell.sValue = sValue; |
| aCell.fValue = fValue; |
| aCell.bEmpty = bEmpty; |
| aCell.bString = bString2; |
| for(sal_Int32 i = 0; i < nCells; ++i) |
| pDDELink->AddCellToRow(aCell); |
| } |