blob: 301128f2bba6df91cc47b11dbcb5594c3648dcda [file] [log] [blame]
/**************************************************************
*
* 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);
}