LCOV - code coverage report
Current view: top level - libreoffice/sc/source/filter/xml - xmlexternaltabi.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 178 0.0 %
Date: 2012-12-27 Functions: 0 28 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       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/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      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 .
      18             :  */
      19             : 
      20             : #include "xmlexternaltabi.hxx"
      21             : #include "xmlimprt.hxx"
      22             : #include "xmltabi.hxx"
      23             : #include "xmlstyli.hxx"
      24             : 
      25             : #include "token.hxx"
      26             : #include "document.hxx"
      27             : 
      28             : #include <xmloff/nmspmap.hxx>
      29             : #include <xmloff/xmlnmspe.hxx>
      30             : #include <xmloff/xmltoken.hxx>
      31             : #include <xmloff/xmluconv.hxx>
      32             : 
      33             : #include <sax/tools/converter.hxx>
      34             : 
      35             : #include <com/sun/star/util/NumberFormat.hpp>
      36             : 
      37             : using namespace ::com::sun::star;
      38             : 
      39             : using ::rtl::OUString;
      40             : using ::com::sun::star::uno::Reference;
      41             : using ::com::sun::star::xml::sax::XAttributeList;
      42             : 
      43             : // ============================================================================
      44             : 
      45           0 : ScXMLExternalRefTabSourceContext::ScXMLExternalRefTabSourceContext(
      46             :     ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
      47             :     const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
      48             :     SvXMLImportContext( rImport, nPrefix, rLName ),
      49             :     mrScImport(rImport),
      50           0 :     mrExternalRefInfo(rRefInfo)
      51             : {
      52             :     using namespace ::xmloff::token;
      53             : 
      54           0 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
      55           0 :     for (sal_Int16 i = 0; i < nAttrCount; ++i)
      56             :     {
      57           0 :         const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
      58           0 :         rtl::OUString aLocalName;
      59           0 :         sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
      60           0 :         const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
      61           0 :         if (nAttrPrefix == XML_NAMESPACE_XLINK)
      62             :         {
      63           0 :             if (IsXMLToken(aLocalName, XML_HREF))
      64           0 :                 maRelativeUrl = sValue;
      65             :         }
      66           0 :         else if (nAttrPrefix == XML_NAMESPACE_TABLE)
      67             :         {
      68           0 :             if (IsXMLToken(aLocalName, XML_TABLE_NAME))
      69           0 :                 maTableName = sValue;
      70           0 :             else if (IsXMLToken(aLocalName, XML_FILTER_NAME))
      71           0 :                 maFilterName = sValue;
      72           0 :             else if (IsXMLToken(aLocalName, XML_FILTER_OPTIONS))
      73           0 :                 maFilterOptions = sValue;
      74             :         }
      75           0 :     }
      76           0 : }
      77             : 
      78           0 : ScXMLExternalRefTabSourceContext::~ScXMLExternalRefTabSourceContext()
      79             : {
      80           0 : }
      81             : 
      82           0 : SvXMLImportContext* ScXMLExternalRefTabSourceContext::CreateChildContext(
      83             :     sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
      84             : {
      85           0 :     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
      86             : }
      87             : 
      88             : /**
      89             :  * Make sure the URL is a valid relative URL, mainly to avoid storing
      90             :  * absolute URL as relative URL by accident.  For now, we only check the first
      91             :  * three characters which are assumed to be always '../', because the relative
      92             :  * URL for an external document is always in reference to the content.xml
      93             :  * fragment of the original document.
      94             :  */
      95           0 : static bool lcl_isValidRelativeURL(const OUString& rUrl)
      96             : {
      97           0 :     sal_Int32 n = ::std::min( rUrl.getLength(), static_cast<sal_Int32>(3));
      98           0 :     if (n < 3)
      99           0 :         return false;
     100           0 :     const sal_Unicode* p = rUrl.getStr();
     101           0 :     for (sal_Int32 i = 0; i < n; ++i)
     102             :     {
     103           0 :         sal_Unicode c = p[i];
     104           0 :         if (i < 2 && c != '.')
     105             :             // the path must begin with '..'
     106           0 :             return false;
     107           0 :         else if (i == 2 && c != '/')
     108             :             // a '/' path separator must follow
     109           0 :             return false;
     110             :     }
     111           0 :     return true;
     112             : }
     113             : 
     114           0 : void ScXMLExternalRefTabSourceContext::EndElement()
     115             : {
     116           0 :     ScDocument* pDoc = mrScImport.GetDocument();
     117           0 :     if (!pDoc)
     118           0 :         return;
     119             : 
     120           0 :     ScExternalRefManager* pRefMgr = pDoc->GetExternalRefManager();
     121           0 :     if (lcl_isValidRelativeURL(maRelativeUrl))
     122           0 :         pRefMgr->setRelativeFileName(mrExternalRefInfo.mnFileId, maRelativeUrl);
     123           0 :     pRefMgr->setFilterData(mrExternalRefInfo.mnFileId, maFilterName, maFilterOptions);
     124             : }
     125             : 
     126             : // ============================================================================
     127             : 
     128           0 : ScXMLExternalRefRowsContext::ScXMLExternalRefRowsContext(
     129             :     ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
     130             :     const Reference<XAttributeList>& /* xAttrList */, ScXMLExternalTabData& rRefInfo ) :
     131             :     SvXMLImportContext( rImport, nPrefix, rLName ),
     132             :     mrScImport(rImport),
     133           0 :     mrExternalRefInfo(rRefInfo)
     134             : {
     135           0 : }
     136             : 
     137           0 : ScXMLExternalRefRowsContext::~ScXMLExternalRefRowsContext()
     138             : {
     139           0 : }
     140             : 
     141           0 : SvXMLImportContext* ScXMLExternalRefRowsContext::CreateChildContext(
     142             :     sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
     143             : {
     144             :     // #i101319# row elements inside group, rows or header-rows
     145             :     // are treated like row elements directly in the table element
     146             : 
     147           0 :     const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowsElemTokenMap();
     148           0 :     sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
     149           0 :     switch (nToken)
     150             :     {
     151             :         case XML_TOK_TABLE_ROWS_ROW_GROUP:
     152             :         case XML_TOK_TABLE_ROWS_HEADER_ROWS:
     153             :         case XML_TOK_TABLE_ROWS_ROWS:
     154             :             return new ScXMLExternalRefRowsContext(
     155           0 :                 mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
     156             :         case XML_TOK_TABLE_ROWS_ROW:
     157             :             return new ScXMLExternalRefRowContext(
     158           0 :                 mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
     159             :         default:
     160             :             ;
     161             :     }
     162           0 :     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
     163             : }
     164             : 
     165           0 : void ScXMLExternalRefRowsContext::EndElement()
     166             : {
     167           0 : }
     168             : 
     169             : // ============================================================================
     170             : 
     171           0 : ScXMLExternalRefRowContext::ScXMLExternalRefRowContext(
     172             :     ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
     173             :     const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
     174             :     SvXMLImportContext( rImport, nPrefix, rLName ),
     175             :     mrScImport(rImport),
     176             :     mrExternalRefInfo(rRefInfo),
     177           0 :     mnRepeatRowCount(1)
     178             : {
     179           0 :     mrExternalRefInfo.mnCol = 0;
     180             : 
     181           0 :     sal_Int16 nAttrCount(xAttrList.is() ? xAttrList->getLength() : 0);
     182           0 :     const SvXMLTokenMap& rAttrTokenMap = mrScImport.GetTableRowAttrTokenMap();
     183           0 :     for( sal_Int16 i=0; i < nAttrCount; ++i )
     184             :     {
     185           0 :         const rtl::OUString& sAttrName = xAttrList->getNameByIndex(i);
     186           0 :         rtl::OUString aLocalName;
     187           0 :         sal_uInt16 nAttrPrefix = mrScImport.GetNamespaceMap().GetKeyByAttrName(sAttrName, &aLocalName);
     188           0 :         const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
     189             : 
     190           0 :         switch (rAttrTokenMap.Get(nAttrPrefix, aLocalName))
     191             :         {
     192             :             case XML_TOK_TABLE_ROW_ATTR_REPEATED:
     193             :             {
     194           0 :                 mnRepeatRowCount = std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
     195             :             }
     196           0 :             break;
     197             :         }
     198           0 :     }
     199           0 : }
     200             : 
     201           0 : ScXMLExternalRefRowContext::~ScXMLExternalRefRowContext()
     202             : {
     203           0 : }
     204             : 
     205           0 : SvXMLImportContext* ScXMLExternalRefRowContext::CreateChildContext(
     206             :     sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
     207             : {
     208           0 :     const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowElemTokenMap();
     209           0 :     sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
     210           0 :     if (nToken == XML_TOK_TABLE_ROW_CELL || nToken == XML_TOK_TABLE_ROW_COVERED_CELL)
     211           0 :         return new ScXMLExternalRefCellContext(mrScImport, nPrefix, rLocalName, xAttrList, mrExternalRefInfo);
     212             : 
     213           0 :     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
     214             : }
     215             : 
     216           0 : void ScXMLExternalRefRowContext::EndElement()
     217             : {
     218           0 :     ScExternalRefCache::TableTypeRef pTab = mrExternalRefInfo.mpCacheTable;
     219             : 
     220           0 :     for (sal_Int32 i = 1; i < mnRepeatRowCount; ++i)
     221             :     {
     222             :         // Performance: duplicates of a non-existent row will still not exist.
     223             :         // Don't find that out for every cell.
     224             :         // External references often are a sparse matrix.
     225           0 :         if (i == 1 && !pTab->hasRow( mrExternalRefInfo.mnRow))
     226             :         {
     227           0 :             mrExternalRefInfo.mnRow += mnRepeatRowCount;
     228           0 :             return;
     229             :         }
     230             : 
     231           0 :         for (sal_Int32 j = 0; j < mrExternalRefInfo.mnCol; ++j)
     232             :         {
     233             :             ScExternalRefCache::TokenRef pToken = pTab->getCell(
     234           0 :                 static_cast<SCCOL>(j), static_cast<SCROW>(mrExternalRefInfo.mnRow));
     235             : 
     236           0 :             if (pToken.get())
     237             :             {
     238             :                 pTab->setCell(static_cast<SCCOL>(j),
     239           0 :                               static_cast<SCROW>(mrExternalRefInfo.mnRow+i), pToken);
     240             :             }
     241           0 :         }
     242             :     }
     243           0 :     mrExternalRefInfo.mnRow += mnRepeatRowCount;
     244             : }
     245             : 
     246             : // ============================================================================
     247             : 
     248           0 : ScXMLExternalRefCellContext::ScXMLExternalRefCellContext(
     249             :     ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
     250             :     const Reference<XAttributeList>& xAttrList, ScXMLExternalTabData& rRefInfo ) :
     251             :     SvXMLImportContext( rImport, nPrefix, rLName ),
     252             :     mrScImport(rImport),
     253             :     mrExternalRefInfo(rRefInfo),
     254             :     mfCellValue(0.0),
     255             :     mnRepeatCount(1),
     256             :     mnNumberFormat(-1),
     257             :     mnCellType(::com::sun::star::util::NumberFormat::UNDEFINED),
     258             :     mbIsNumeric(false),
     259           0 :     mbIsEmpty(true)
     260             : {
     261             :     using namespace ::xmloff::token;
     262             : 
     263           0 :     sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     264           0 :     const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
     265           0 :     for (sal_Int16 i = 0; i < nAttrCount; ++i)
     266             :     {
     267           0 :         OUString aLocalName;
     268           0 :         sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
     269           0 :             xAttrList->getNameByIndex(i), &aLocalName);
     270             : 
     271           0 :         const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
     272           0 :         sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
     273             : 
     274           0 :         switch (nToken)
     275             :         {
     276             :             case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
     277             :             {
     278           0 :                 XMLTableStylesContext* pStyles = static_cast<XMLTableStylesContext*>(mrScImport.GetAutoStyles());
     279             :                 const XMLTableStyleContext* pStyle = static_cast<const XMLTableStyleContext*>(
     280           0 :                     pStyles->FindStyleChildContext(XML_STYLE_FAMILY_TABLE_CELL, sValue, true));
     281           0 :                 if (pStyle)
     282           0 :                     mnNumberFormat = const_cast<XMLTableStyleContext*>(pStyle)->GetNumberFormat();
     283             :             }
     284           0 :             break;
     285             :             case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
     286             :             {
     287           0 :                 mnRepeatCount = ::std::max(sValue.toInt32(), static_cast<sal_Int32>(1));
     288             :             }
     289           0 :             break;
     290             :             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
     291             :             {
     292           0 :                 mnCellType = mrScImport.GetCellType(sValue);
     293             :             }
     294           0 :             break;
     295             :             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
     296             :             {
     297           0 :                 if (!sValue.isEmpty())
     298             :                 {
     299           0 :                     ::sax::Converter::convertDouble(mfCellValue, sValue);
     300           0 :                     mbIsNumeric = true;
     301           0 :                     mbIsEmpty = false;
     302             :                 }
     303             :             }
     304           0 :             break;
     305             :             case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
     306             :             {
     307           0 :                 if (!sValue.isEmpty() && mrScImport.SetNullDateOnUnitConverter())
     308             :                 {
     309           0 :                     mrScImport.GetMM100UnitConverter().convertDateTime(mfCellValue, sValue);
     310           0 :                     mbIsNumeric = true;
     311           0 :                     mbIsEmpty = false;
     312             :                 }
     313             :             }
     314           0 :             break;
     315             :             case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
     316             :             {
     317           0 :                 if (!sValue.isEmpty())
     318             :                 {
     319           0 :                     ::sax::Converter::convertDuration(mfCellValue, sValue);
     320           0 :                     mbIsNumeric = true;
     321           0 :                     mbIsEmpty = false;
     322             :                 }
     323             :             }
     324           0 :             break;
     325             :             case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
     326             :             {
     327           0 :                 if (!sValue.isEmpty())
     328             :                 {
     329           0 :                     maCellString = sValue;
     330           0 :                     mbIsNumeric = false;
     331           0 :                     mbIsEmpty = false;
     332             :                 }
     333             :             }
     334           0 :             break;
     335             :             case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
     336             :             {
     337           0 :                 if (!sValue.isEmpty())
     338             :                 {
     339           0 :                     mfCellValue = IsXMLToken(sValue, XML_TRUE) ? 1.0 : 0.0;
     340           0 :                     mbIsNumeric = true;
     341           0 :                     mbIsEmpty = false;
     342             :                 }
     343             :             }
     344           0 :             break;
     345             :             default:
     346             :                 ;
     347             :         }
     348           0 :     }
     349           0 : }
     350             : 
     351           0 : ScXMLExternalRefCellContext::~ScXMLExternalRefCellContext()
     352             : {
     353           0 : }
     354             : 
     355           0 : SvXMLImportContext* ScXMLExternalRefCellContext::CreateChildContext(
     356             :     sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& xAttrList )
     357             : {
     358           0 :     const SvXMLTokenMap& rTokenMap = mrScImport.GetTableRowCellElemTokenMap();
     359           0 :     sal_uInt16 nToken = rTokenMap.Get(nPrefix, rLocalName);
     360           0 :     if (nToken == XML_TOK_TABLE_ROW_CELL_P)
     361           0 :         return new ScXMLExternalRefCellTextContext(mrScImport, nPrefix, rLocalName, xAttrList, *this);
     362             : 
     363           0 :     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
     364             : }
     365             : 
     366           0 : void ScXMLExternalRefCellContext::EndElement()
     367             : {
     368           0 :     if (!maCellString.isEmpty())
     369           0 :         mbIsEmpty = false;
     370             : 
     371           0 :     for (sal_Int32 i = 0; i < mnRepeatCount; ++i, ++mrExternalRefInfo.mnCol)
     372             :     {
     373           0 :         if (mbIsEmpty)
     374           0 :             continue;
     375             : 
     376           0 :         ScExternalRefCache::TokenRef aToken;
     377           0 :         if (mbIsNumeric)
     378           0 :             aToken.reset(new formula::FormulaDoubleToken(mfCellValue));
     379             :         else
     380           0 :             aToken.reset(new formula::FormulaStringToken(maCellString));
     381             : 
     382           0 :         sal_uInt32 nNumFmt = mnNumberFormat >= 0 ? static_cast<sal_uInt32>(mnNumberFormat) : 0;
     383             :         mrExternalRefInfo.mpCacheTable->setCell(
     384             :             static_cast<SCCOL>(mrExternalRefInfo.mnCol),
     385             :             static_cast<SCROW>(mrExternalRefInfo.mnRow),
     386           0 :             aToken, nNumFmt);
     387           0 :     }
     388           0 : }
     389             : 
     390           0 : void ScXMLExternalRefCellContext::SetCellString(const OUString& rStr)
     391             : {
     392           0 :     maCellString = rStr;
     393           0 : }
     394             : 
     395             : // ============================================================================
     396             : 
     397           0 : ScXMLExternalRefCellTextContext::ScXMLExternalRefCellTextContext(
     398             :     ScXMLImport& rImport, sal_uInt16 nPrefix, const OUString& rLName,
     399             :     const Reference<XAttributeList>& /*xAttrList*/,
     400             :     ScXMLExternalRefCellContext& rParent ) :
     401             :     SvXMLImportContext( rImport, nPrefix, rLName ),
     402           0 :     mrParent(rParent)
     403             : {
     404           0 : }
     405             : 
     406           0 : ScXMLExternalRefCellTextContext::~ScXMLExternalRefCellTextContext()
     407             : {
     408           0 : }
     409             : 
     410           0 : SvXMLImportContext* ScXMLExternalRefCellTextContext::CreateChildContext(
     411             :     sal_uInt16 nPrefix, const OUString& rLocalName, const Reference<XAttributeList>& /*xAttrList*/ )
     412             : {
     413           0 :     return new SvXMLImportContext(GetImport(), nPrefix, rLocalName);
     414             : }
     415             : 
     416           0 : void ScXMLExternalRefCellTextContext::Characters(const OUString& rChar)
     417             : {
     418           0 :     maCellStrBuf.append(rChar);
     419           0 : }
     420             : 
     421           0 : void ScXMLExternalRefCellTextContext::EndElement()
     422             : {
     423           0 :     mrParent.SetCellString(maCellStrBuf.makeStringAndClear());
     424           0 : }
     425             : 
     426             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10