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

Generated by: LCOV version 1.10