LCOV - code coverage report
Current view: top level - usr/local/src/libreoffice/sc/source/filter/xml - xmlcelli.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 547 693 78.9 %
Date: 2013-07-09 Functions: 41 42 97.6 %
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 "xmlcelli.hxx"
      21             : #include "xmlimprt.hxx"
      22             : #include "xmltabi.hxx"
      23             : #include "xmlstyli.hxx"
      24             : #include "xmlannoi.hxx"
      25             : #include "global.hxx"
      26             : #include "document.hxx"
      27             : #include "cellsuno.hxx"
      28             : #include "docuno.hxx"
      29             : #include "unonames.hxx"
      30             : #include "postit.hxx"
      31             : #include "sheetdata.hxx"
      32             : #include "docsh.hxx"
      33             : #include "cellform.hxx"
      34             : #include "validat.hxx"
      35             : #include "patattr.hxx"
      36             : #include "scitems.hxx"
      37             : #include "docpool.hxx"
      38             : 
      39             : #include "XMLTableShapeImportHelper.hxx"
      40             : #include "XMLStylesImportHelper.hxx"
      41             : #include "celltextparacontext.hxx"
      42             : 
      43             : #include "arealink.hxx"
      44             : #include <sfx2/linkmgr.hxx>
      45             : #include "convuno.hxx"
      46             : #include "XMLConverter.hxx"
      47             : #include "scerrors.hxx"
      48             : #include "editutil.hxx"
      49             : #include "formulacell.hxx"
      50             : #include "editattributemap.hxx"
      51             : #include "stringutil.hxx"
      52             : #include "tokenarray.hxx"
      53             : #include "scmatrix.hxx"
      54             : 
      55             : #include <xmloff/xmltkmap.hxx>
      56             : #include <xmloff/xmltoken.hxx>
      57             : #include <xmloff/nmspmap.hxx>
      58             : #include <xmloff/xmluconv.hxx>
      59             : #include <xmloff/families.hxx>
      60             : #include <xmloff/numehelp.hxx>
      61             : #include <xmloff/xmlnmspe.hxx>
      62             : #include "xmloff/prstylei.hxx"
      63             : #include <svl/zforlist.hxx>
      64             : #include <svx/svdocapt.hxx>
      65             : #include <editeng/outlobj.hxx>
      66             : #include <editeng/editobj.hxx>
      67             : #include "editeng/wghtitem.hxx"
      68             : #include "editeng/colritem.hxx"
      69             : #include "editeng/fhgtitem.hxx"
      70             : #include "editeng/postitem.hxx"
      71             : #include "editeng/fontitem.hxx"
      72             : #include "editeng/udlnitem.hxx"
      73             : #include "editeng/wrlmitem.hxx"
      74             : #include "editeng/crossedoutitem.hxx"
      75             : #include "editeng/charreliefitem.hxx"
      76             : #include "editeng/charscaleitem.hxx"
      77             : #include "editeng/contouritem.hxx"
      78             : #include "editeng/shdditem.hxx"
      79             : #include "editeng/kernitem.hxx"
      80             : #include "editeng/autokernitem.hxx"
      81             : #include "editeng/escapementitem.hxx"
      82             : #include "editeng/emphasismarkitem.hxx"
      83             : #include "editeng/langitem.hxx"
      84             : #include <svx/unoapi.hxx>
      85             : #include <svl/languageoptions.hxx>
      86             : #include <sax/tools/converter.hxx>
      87             : 
      88             : #include <com/sun/star/frame/XModel.hpp>
      89             : #include <com/sun/star/text/XText.hpp>
      90             : #include <com/sun/star/sheet/XSpreadsheets.hpp>
      91             : #include <com/sun/star/sheet/XSpreadsheet.hpp>
      92             : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
      93             : 
      94             : #include <com/sun/star/sheet/XSheetCondition.hpp>
      95             : #include <com/sun/star/table/XCellRange.hpp>
      96             : #include <com/sun/star/table/CellAddress.hpp>
      97             : #include <com/sun/star/util/NumberFormat.hpp>
      98             : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
      99             : #include <com/sun/star/util/XNumberFormatTypes.hpp>
     100             : #include <com/sun/star/util/Date.hpp>
     101             : #include <com/sun/star/lang/Locale.hpp>
     102             : #include <com/sun/star/text/ControlCharacter.hpp>
     103             : #include <com/sun/star/table/XCell.hpp>
     104             : #include <com/sun/star/document/XActionLockable.hpp>
     105             : 
     106             : #include <com/sun/star/sheet/ValidationType.hpp>
     107             : #include <com/sun/star/sheet/ValidationAlertStyle.hpp>
     108             : #include <com/sun/star/sheet/ConditionOperator.hpp>
     109             : 
     110             : #include <rtl/ustrbuf.hxx>
     111             : #include <tools/date.hxx>
     112             : #include <i18nlangtag/lang.h>
     113             : #include <comphelper/extract.hxx>
     114             : #include <tools/string.hxx>
     115             : 
     116             : using namespace com::sun::star;
     117             : using namespace xmloff::token;
     118             : 
     119          16 : ScXMLTableRowCellContext::ParaFormat::ParaFormat(ScEditEngineDefaulter& rEditEngine) :
     120          16 :     maItemSet(rEditEngine.GetEmptyItemSet()) {}
     121             : 
     122           9 : ScXMLTableRowCellContext::Field::Field(SvxFieldData* pData) : mpData(pData) {}
     123             : 
     124          18 : ScXMLTableRowCellContext::Field::~Field()
     125             : {
     126           9 :     delete mpData;
     127           9 : }
     128             : 
     129        5652 : ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
     130             :                                       sal_uInt16 nPrfx,
     131             :                                       const OUString& rLName,
     132             :                                       const ::com::sun::star::uno::Reference<
     133             :                                       ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
     134             :                                       const bool bTempIsCovered,
     135             :                                       const sal_Int32 nTempRepeatedRows ) :
     136             :     ScXMLImportContext(rImport, nPrfx, rLName),
     137        5652 :     mpEditEngine(GetScImport().GetEditEngine()),
     138             :     mnCurParagraph(0),
     139             :     pDetectiveObjVec(NULL),
     140             :     pCellRangeSource(NULL),
     141             :     fValue(0.0),
     142             :     nMergedRows(1),
     143             :     nRepeatedRows(nTempRepeatedRows),
     144             :     nMergedCols(1),
     145             :     nColsRepeated(1),
     146             :     rXMLImport((ScXMLImport&)rImport),
     147             :     eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
     148             :     nCellType(util::NumberFormat::TEXT),
     149             :     bIsMerged(false),
     150             :     bIsMatrix(false),
     151             :     bIsCovered(bTempIsCovered),
     152             :     bIsEmpty(true),
     153             :     mbNewValueType(false),
     154             :     mbErrorValue(false),
     155             :     bIsFirstTextImport(false),
     156             :     bSolarMutexLocked(false),
     157             :     bFormulaTextResult(false),
     158             :     mbPossibleErrorCell(false),
     159             :     mbCheckWithCompilerForError(false),
     160       11304 :     mbEditEngineHasText(false)
     161             : {
     162        5652 :     rtl::math::setNan(&fValue); // NaN by default
     163        5652 :     mpEditEngine->Clear();
     164             : 
     165        5652 :     rXMLImport.SetRemoveLastChar(false);
     166        5652 :     rXMLImport.GetTables().AddColumn(bTempIsCovered);
     167        5652 :     const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
     168        5652 :     OUString aLocalName;
     169        5652 :     OUString* pStyleName = NULL;
     170        5652 :     OUString* pCurrencySymbol = NULL;
     171        5652 :     const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
     172       13451 :     for (sal_Int16 i = 0; i < nAttrCount; ++i)
     173             :     {
     174        7799 :         sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
     175       15598 :             xAttrList->getNameByIndex(i), &aLocalName);
     176             : 
     177        7799 :         const OUString& sValue = xAttrList->getValueByIndex(i);
     178        7799 :         sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
     179        7799 :         switch (nToken)
     180             :         {
     181             :             case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
     182         809 :                 pStyleName = new OUString(sValue);
     183         809 :             break;
     184             :             case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
     185             :                 OSL_ENSURE(!maContentValidationName, "here should be only one Validation Name");
     186          14 :                 if (!sValue.isEmpty())
     187          14 :                     maContentValidationName.reset(sValue);
     188          14 :             break;
     189             :             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
     190           5 :                 bIsMerged = true;
     191           5 :                 nMergedRows = static_cast<SCROW>(sValue.toInt32());
     192           5 :             break;
     193             :             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
     194           5 :                 bIsMerged = true;
     195           5 :                 nMergedCols = static_cast<SCCOL>(sValue.toInt32());
     196           5 :             break;
     197             :             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
     198          31 :                 bIsMatrix = true;
     199          31 :                 nMatrixCols = static_cast<SCCOL>(sValue.toInt32());
     200          31 :             break;
     201             :             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
     202          31 :                 bIsMatrix = true;
     203          31 :                 nMatrixRows = static_cast<SCROW>(sValue.toInt32());
     204          31 :             break;
     205             :             case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
     206             :                 nColsRepeated = static_cast<SCCOL>(std::min<sal_Int32>( MAXCOLCOUNT,
     207         561 :                             std::max( sValue.toInt32(), static_cast<sal_Int32>(1) ) ));
     208         561 :             break;
     209             :             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
     210        3101 :                 nCellType = GetScImport().GetCellType(sValue);
     211        3101 :                 bIsEmpty = false;
     212        3101 :             break;
     213             :             case XML_TOK_TABLE_ROW_CELL_ATTR_NEW_VALUE_TYPE:
     214         228 :                 if(sValue == "error")
     215           0 :                     mbErrorValue = true;
     216             :                 else
     217         228 :                     nCellType = GetScImport().GetCellType(sValue);
     218         228 :                 bIsEmpty = false;
     219         228 :                 mbNewValueType = true;
     220         228 :             break;
     221             :             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
     222             :             {
     223        2430 :                 if (!sValue.isEmpty())
     224             :                 {
     225        2430 :                     ::sax::Converter::convertDouble(fValue, sValue);
     226        2430 :                     bIsEmpty = false;
     227             : 
     228             :                     //if office:value="0", let's get the text:p in case this is
     229             :                     //a special case in HasSpecialCaseFormulaText(). If it
     230             :                     //turns out not to be a special case, we'll use the 0 value.
     231        2430 :                     if(fValue == 0.0)
     232          64 :                         bFormulaTextResult = true;
     233             :                 }
     234             :             }
     235        2430 :             break;
     236             :             case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
     237             :             {
     238           8 :                 if (!sValue.isEmpty() && rXMLImport.SetNullDateOnUnitConverter())
     239             :                 {
     240           8 :                     rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
     241           8 :                     bIsEmpty = false;
     242             :                 }
     243             :             }
     244           8 :             break;
     245             :             case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
     246             :             {
     247           3 :                 if (!sValue.isEmpty())
     248             :                 {
     249           3 :                     ::sax::Converter::convertDuration(fValue, sValue);
     250           3 :                     bIsEmpty = false;
     251             :                 }
     252             :             }
     253           3 :             break;
     254             :             case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
     255             :             {
     256          32 :                 if (!sValue.isEmpty())
     257             :                 {
     258             :                     OSL_ENSURE(!maStringValue, "here should be only one string value");
     259          32 :                     maStringValue.reset(sValue);
     260          32 :                     bIsEmpty = false;
     261             :                 }
     262             :             }
     263          32 :             break;
     264             :             case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
     265             :             {
     266         142 :                 if (!sValue.isEmpty())
     267             :                 {
     268         142 :                     if ( IsXMLToken(sValue, XML_TRUE) )
     269          65 :                         fValue = 1.0;
     270          77 :                     else if ( IsXMLToken(sValue, XML_FALSE) )
     271          75 :                         fValue = 0.0;
     272             :                     else
     273           2 :                         ::sax::Converter::convertDouble(fValue, sValue);
     274         142 :                     bIsEmpty = false;
     275             :                 }
     276             :             }
     277         142 :             break;
     278             :             case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
     279             :             {
     280         395 :                 if (!sValue.isEmpty())
     281             :                 {
     282             :                     OSL_ENSURE(!maFormula, "here should be only one formula");
     283         790 :                     OUString aFormula, aFormulaNmsp;
     284         395 :                     rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
     285         790 :                     maFormula.reset( FormulaWithNamespace(aFormula, aFormulaNmsp) );
     286             :                 }
     287             :             }
     288         395 :             break;
     289             :             case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
     290           4 :                 pCurrencySymbol = new OUString(sValue);
     291           4 :             break;
     292             :             default:
     293             :                 ;
     294             :         }
     295        7799 :     }
     296        5652 :     if (maFormula)
     297             :     {
     298         395 :         if (nCellType == util::NumberFormat::TEXT)
     299          32 :             bFormulaTextResult = true;
     300         395 :         if(nCellType == util::NumberFormat::DATETIME)
     301           6 :             nCellType = util::NumberFormat::UNDEFINED;
     302             :         //if bIsEmpty is true at this point, then there is no office value.
     303             :         //we must get the text:p (even if it is empty) in case this a special
     304             :         //case in HasSpecialCaseFormulaText().
     305         395 :         if(bIsEmpty)
     306           0 :             bFormulaTextResult = true;
     307             :     }
     308        5652 :     rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
     309        5652 : }
     310             : 
     311       16956 : ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
     312             : {
     313        5652 :     delete pDetectiveObjVec;
     314        5652 :     delete pCellRangeSource;
     315       11304 : }
     316             : 
     317           8 : void ScXMLTableRowCellContext::LockSolarMutex()
     318             : {
     319           8 :     if (!bSolarMutexLocked)
     320             :     {
     321           8 :         GetScImport().LockSolarMutex();
     322           8 :         bSolarMutexLocked = true;
     323             :     }
     324           8 : }
     325             : 
     326        5652 : void ScXMLTableRowCellContext::UnlockSolarMutex()
     327             : {
     328        5652 :     if (bSolarMutexLocked)
     329             :     {
     330           8 :         GetScImport().UnlockSolarMutex();
     331           8 :         bSolarMutexLocked = false;
     332             :     }
     333        5652 : }
     334             : 
     335             : namespace {
     336             : 
     337       17103 : bool cellExists( const ScAddress& rCellPos )
     338             : {
     339       51309 :     return( rCellPos.Col() >= 0 && rCellPos.Row() >= 0 &&
     340       51309 :             rCellPos.Col() <= MAXCOL && rCellPos.Row() <= MAXROW );
     341             : }
     342             : 
     343             : }
     344             : 
     345        3127 : void ScXMLTableRowCellContext::PushParagraphSpan(const OUString& rSpan, const OUString& rStyleName)
     346             : {
     347        3127 :     sal_Int32 nBegin = maParagraph.getLength();
     348        3127 :     sal_Int32 nEnd = nBegin + rSpan.getLength();
     349        3127 :     maParagraph.append(rSpan);
     350             : 
     351        3127 :     PushFormat(nBegin, nEnd, rStyleName);
     352        3127 : }
     353             : 
     354           9 : void ScXMLTableRowCellContext::PushParagraphField(SvxFieldData* pData, const OUString& rStyleName)
     355             : {
     356           9 :     maFields.push_back(new Field(pData));
     357           9 :     Field& rField = maFields.back();
     358             : 
     359           9 :     sal_Int32 nPos = maParagraph.getLength();
     360           9 :     maParagraph.append(sal_Unicode('\1')); // Placeholder text for inserted field item.
     361           9 :     rField.maSelection.nStartPara = mnCurParagraph;
     362           9 :     rField.maSelection.nEndPara = mnCurParagraph;
     363           9 :     rField.maSelection.nStartPos = nPos;
     364           9 :     rField.maSelection.nEndPos = nPos+1;
     365             : 
     366           9 :     PushFormat(nPos, nPos+1, rStyleName);
     367           9 : }
     368             : 
     369        3136 : void ScXMLTableRowCellContext::PushFormat(sal_Int32 nBegin, sal_Int32 nEnd, const OUString& rStyleName)
     370             : {
     371        3136 :     if (rStyleName.isEmpty())
     372        6240 :         return;
     373             : 
     374             :     // Get the style information from xmloff.
     375          16 :     UniReference<XMLPropertySetMapper> xMapper = GetImport().GetTextImport()->GetTextImportPropertySetMapper()->getPropertySetMapper();
     376          16 :     if (!xMapper.is())
     377             :         // We can't do anything without the mapper.
     378           0 :         return;
     379             : 
     380          16 :     sal_Int32 nEntryCount = xMapper->GetEntryCount();
     381             : 
     382          16 :     SvXMLStylesContext* pAutoStyles = GetImport().GetAutoStyles();
     383             : 
     384             :     // Style name for text span corresponds with the name of an automatic style.
     385             :     const XMLPropStyleContext* pStyle = dynamic_cast<const XMLPropStyleContext*>(
     386          16 :         pAutoStyles->FindStyleChildContext(XML_STYLE_FAMILY_TEXT_TEXT, rStyleName));
     387             : 
     388          16 :     if (!pStyle)
     389             :         // No style by that name found.
     390           0 :         return;
     391             : 
     392          16 :     const std::vector<XMLPropertyState>& rProps = pStyle->GetProperties();
     393          16 :     if (rProps.empty())
     394           0 :         return;
     395             : 
     396          16 :     const ScXMLEditAttributeMap& rEditAttrMap = GetScImport().GetEditAttributeMap();
     397             : 
     398          16 :     maFormats.push_back(new ParaFormat(*mpEditEngine));
     399          16 :     ParaFormat& rFmt = maFormats.back();
     400          16 :     rFmt.maSelection.nStartPara = rFmt.maSelection.nEndPara = mnCurParagraph;
     401          16 :     rFmt.maSelection.nStartPos = nBegin;
     402          16 :     rFmt.maSelection.nEndPos = nEnd;
     403             : 
     404          32 :     boost::scoped_ptr<SfxPoolItem> pPoolItem;
     405          16 :     sal_uInt16 nLastItemID = EE_CHAR_END + 1;
     406             : 
     407          16 :     std::vector<XMLPropertyState>::const_iterator it = rProps.begin(), itEnd = rProps.end();
     408         148 :     for (; it != itEnd; ++it)
     409             :     {
     410         132 :         if (it->mnIndex == -1 || it->mnIndex >= nEntryCount)
     411           0 :             continue;
     412             : 
     413         132 :         const OUString& rName = xMapper->GetEntryAPIName(it->mnIndex);
     414         132 :         const ScXMLEditAttributeMap::Entry* pEntry = rEditAttrMap.getEntry(rName);
     415         132 :         if (!pEntry)
     416           6 :             continue;
     417             : 
     418         126 :         if (nLastItemID != pEntry->mnItemID && pPoolItem)
     419             :         {
     420             :             // Flush the last item when the item ID changes.
     421          41 :             rFmt.maItemSet.Put(*pPoolItem);
     422          41 :             pPoolItem.reset();
     423             :         }
     424             : 
     425         126 :         switch (pEntry->mnItemID)
     426             :         {
     427             :             case EE_CHAR_FONTINFO:
     428             :             case EE_CHAR_FONTINFO_CJK:
     429             :             case EE_CHAR_FONTINFO_CTL:
     430             :             {
     431             :                 // Font properties need to be consolidated into a single item.
     432          84 :                 if (!pPoolItem)
     433          18 :                     pPoolItem.reset(new SvxFontItem(pEntry->mnItemID));
     434             : 
     435          84 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     436             :             }
     437          84 :             break;
     438             :             case EE_CHAR_WEIGHT:
     439             :             case EE_CHAR_WEIGHT_CJK:
     440             :             case EE_CHAR_WEIGHT_CTL:
     441             :             {
     442          15 :                 if (!pPoolItem)
     443          15 :                     pPoolItem.reset(new SvxWeightItem(WEIGHT_NORMAL, pEntry->mnItemID));
     444             : 
     445          15 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     446             :             }
     447          15 :             break;
     448             :             case EE_CHAR_FONTHEIGHT:
     449             :             case EE_CHAR_FONTHEIGHT_CJK:
     450             :             case EE_CHAR_FONTHEIGHT_CTL:
     451             :             {
     452           6 :                 if (!pPoolItem)
     453           6 :                     pPoolItem.reset(new SvxFontHeightItem(240, 100, pEntry->mnItemID));
     454             : 
     455           6 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     456             :             }
     457           6 :             break;
     458             :             case EE_CHAR_ITALIC:
     459             :             case EE_CHAR_ITALIC_CJK:
     460             :             case EE_CHAR_ITALIC_CTL:
     461             :             {
     462          12 :                 if (!pPoolItem)
     463          12 :                     pPoolItem.reset(new SvxPostureItem(ITALIC_NONE, pEntry->mnItemID));
     464             : 
     465          12 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     466             :             }
     467          12 :             break;
     468             :             case EE_CHAR_UNDERLINE:
     469             :             {
     470           6 :                 if (!pPoolItem)
     471           3 :                     pPoolItem.reset(new SvxUnderlineItem(UNDERLINE_NONE, pEntry->mnItemID));
     472             : 
     473           6 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     474             :             }
     475           6 :             break;
     476             :             case EE_CHAR_OVERLINE:
     477             :             {
     478           0 :                 if (!pPoolItem)
     479           0 :                     pPoolItem.reset(new SvxOverlineItem(UNDERLINE_NONE, pEntry->mnItemID));
     480             : 
     481           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     482             :             }
     483           0 :             break;
     484             :             case EE_CHAR_COLOR:
     485             :             {
     486           2 :                 if (!pPoolItem)
     487           2 :                     pPoolItem.reset(new SvxColorItem(pEntry->mnItemID));
     488             : 
     489           2 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     490             :             }
     491           2 :             break;
     492             :             case EE_CHAR_WLM:
     493             :             {
     494           0 :                 if (!pPoolItem)
     495           0 :                     pPoolItem.reset(new SvxWordLineModeItem(false, pEntry->mnItemID));
     496             : 
     497           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     498             :             }
     499           0 :             break;
     500             :             case EE_CHAR_STRIKEOUT:
     501             :             {
     502           1 :                 if (!pPoolItem)
     503           1 :                     pPoolItem.reset(new SvxCrossedOutItem(STRIKEOUT_NONE, pEntry->mnItemID));
     504             : 
     505           1 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     506             :             }
     507           1 :             break;
     508             :             case EE_CHAR_RELIEF:
     509             :             {
     510           0 :                 if (!pPoolItem)
     511           0 :                     pPoolItem.reset(new SvxCharReliefItem(RELIEF_NONE, pEntry->mnItemID));
     512             : 
     513           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     514             :             }
     515           0 :             break;
     516             :             case EE_CHAR_OUTLINE:
     517             :             {
     518           0 :                 if (!pPoolItem)
     519           0 :                     pPoolItem.reset(new SvxContourItem(false, pEntry->mnItemID));
     520             : 
     521           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     522             :             }
     523           0 :             break;
     524             :             case EE_CHAR_SHADOW:
     525             :             {
     526           0 :                 if (!pPoolItem)
     527           0 :                     pPoolItem.reset(new SvxShadowedItem(false, pEntry->mnItemID));
     528             : 
     529           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     530             :             }
     531           0 :             break;
     532             :             case EE_CHAR_KERNING:
     533             :             {
     534           0 :                 if (!pPoolItem)
     535           0 :                     pPoolItem.reset(new SvxKerningItem(0, pEntry->mnItemID));
     536             : 
     537           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     538             :             }
     539           0 :             break;
     540             :             case EE_CHAR_PAIRKERNING:
     541             :             {
     542           0 :                 if (!pPoolItem)
     543           0 :                     pPoolItem.reset(new SvxAutoKernItem(false, pEntry->mnItemID));
     544             : 
     545           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     546             :             }
     547           0 :             break;
     548             :             case EE_CHAR_FONTWIDTH:
     549             :             {
     550           0 :                 if (!pPoolItem)
     551           0 :                     pPoolItem.reset(new SvxCharScaleWidthItem(100, pEntry->mnItemID));
     552             : 
     553           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     554             :             }
     555           0 :             break;
     556             :             case EE_CHAR_ESCAPEMENT:
     557             :             {
     558           0 :                 if (!pPoolItem)
     559           0 :                     pPoolItem.reset(new SvxEscapementItem(pEntry->mnItemID));
     560             : 
     561           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     562             :             }
     563           0 :             break;
     564             :             case EE_CHAR_EMPHASISMARK:
     565             :             {
     566           0 :                 if (!pPoolItem)
     567           0 :                     pPoolItem.reset(new SvxEmphasisMarkItem(EMPHASISMARK_NONE, pEntry->mnItemID));
     568             : 
     569           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     570             :             }
     571           0 :             break;
     572             :             case EE_CHAR_LANGUAGE:
     573             :             case EE_CHAR_LANGUAGE_CJK:
     574             :             case EE_CHAR_LANGUAGE_CTL:
     575             :             {
     576           0 :                 if (!pPoolItem)
     577           0 :                     pPoolItem.reset(new SvxLanguageItem(LANGUAGE_DONTKNOW, pEntry->mnItemID));
     578             : 
     579           0 :                 pPoolItem->PutValue(it->maValue, pEntry->mnFlag);
     580             :             }
     581           0 :             break;
     582             :             default:
     583             :                 ;
     584             :         }
     585             : 
     586         126 :         nLastItemID = pEntry->mnItemID;
     587             :     }
     588             : 
     589          16 :     if (pPoolItem)
     590          32 :         rFmt.maItemSet.Put(*pPoolItem);
     591             : }
     592             : 
     593           2 : void ScXMLTableRowCellContext::PushParagraphFieldDate(const OUString& rStyleName)
     594             : {
     595           2 :     PushParagraphField(new SvxDateField, rStyleName);
     596           2 : }
     597             : 
     598           2 : void ScXMLTableRowCellContext::PushParagraphFieldSheetName(const OUString& rStyleName)
     599             : {
     600           2 :     SCTAB nTab = GetScImport().GetTables().GetCurrentCellPos().Tab();
     601           2 :     PushParagraphField(new SvxTableField(nTab), rStyleName);
     602           2 : }
     603             : 
     604           2 : void ScXMLTableRowCellContext::PushParagraphFieldDocTitle(const OUString& rStyleName)
     605             : {
     606           2 :     PushParagraphField(new SvxFileField, rStyleName);
     607           2 : }
     608             : 
     609           3 : void ScXMLTableRowCellContext::PushParagraphFieldURL(
     610             :     const OUString& rURL, const OUString& rRep, const OUString& rStyleName)
     611             : {
     612           3 :     OUString aAbsURL = GetScImport().GetAbsoluteReference(rURL);
     613           3 :     PushParagraphField(new SvxURLField(aAbsURL, rRep, SVXURLFORMAT_REPR), rStyleName);
     614           3 : }
     615             : 
     616        3119 : void ScXMLTableRowCellContext::PushParagraphEnd()
     617             : {
     618             :     // EditEngine always has at least one paragraph even when its content is empty.
     619             : 
     620        3119 :     if (mbEditEngineHasText)
     621          13 :         mpEditEngine->InsertParagraph(mpEditEngine->GetParagraphCount(), maParagraph.makeStringAndClear());
     622             :     else
     623             :     {
     624        3106 :         mpEditEngine->SetText(maParagraph.makeStringAndClear());
     625        3106 :         mbEditEngineHasText = true;
     626             :     }
     627             : 
     628        3119 :     ++mnCurParagraph;
     629        3119 : }
     630             : 
     631        3179 : SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix,
     632             :                                             const OUString& rLName,
     633             :                                             const ::com::sun::star::uno::Reference<
     634             :                                           ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
     635             : {
     636        3179 :     SvXMLImportContext *pContext = 0;
     637             : 
     638        3179 :     const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap();
     639        3179 :     bool bTextP(false);
     640        3179 :     switch( rTokenMap.Get( nPrefix, rLName ) )
     641             :     {
     642             :         case XML_TOK_TABLE_ROW_CELL_P:
     643             :         {
     644        3119 :             bIsEmpty = false;
     645        3119 :             bTextP = true;
     646             : 
     647        3119 :             pContext = new ScXMLCellTextParaContext(rXMLImport, nPrefix, rLName, *this);
     648             :         }
     649        3119 :         break;
     650             :         case XML_TOK_TABLE_ROW_CELL_TABLE:
     651             :         {
     652             :             SAL_WARN("sc", "ScXMLTableRowCellContext::CreateChildContext: subtables are not supported");
     653             :         }
     654           0 :         break;
     655             :         case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
     656             :         {
     657           8 :             bIsEmpty = false;
     658             :             OSL_ENSURE( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
     659           8 :             mxAnnotationData.reset( new ScXMLAnnotationData );
     660             :             pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
     661           8 :                                                     xAttrList, *mxAnnotationData, this);
     662             :         }
     663           8 :         break;
     664             :         case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
     665             :         {
     666           0 :             bIsEmpty = false;
     667           0 :             if (!pDetectiveObjVec)
     668           0 :                 pDetectiveObjVec = new ScMyImpDetectiveObjVec();
     669             :             pContext = new ScXMLDetectiveContext(
     670           0 :                 rXMLImport, nPrefix, rLName, pDetectiveObjVec );
     671             :         }
     672           0 :         break;
     673             :         case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE:
     674             :         {
     675           0 :             bIsEmpty = false;
     676           0 :             if (!pCellRangeSource)
     677           0 :                 pCellRangeSource = new ScMyImpCellRangeSource();
     678             :             pContext = new ScXMLCellRangeSourceContext(
     679           0 :                 rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource );
     680             :         }
     681           0 :         break;
     682             :     }
     683             : 
     684        3179 :     if (!pContext && !bTextP)
     685             :     {
     686          52 :         ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
     687          52 :         uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
     688          52 :         if (xShapes.is())
     689             :         {
     690          52 :             if (aCellPos.Col() > MAXCOL)
     691           0 :                 aCellPos.SetCol(MAXCOL);
     692          52 :             if (aCellPos.Row() > MAXROW)
     693           0 :                 aCellPos.SetRow(MAXROW);
     694             :             XMLTableShapeImportHelper* pTableShapeImport =
     695          52 :                     static_cast< XMLTableShapeImportHelper* >( rXMLImport.GetShapeImport().get() );
     696          52 :             pTableShapeImport->SetOnTable(false);
     697          52 :             com::sun::star::table::CellAddress aCellAddress;
     698          52 :             ScUnoConversion::FillApiAddress( aCellAddress, aCellPos );
     699          52 :             pTableShapeImport->SetCell(aCellAddress);
     700             :             pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
     701          52 :                 rXMLImport, nPrefix, rLName, xAttrList, xShapes);
     702          52 :             if (pContext)
     703             :             {
     704          52 :                 bIsEmpty = false;
     705          52 :                 rXMLImport.ProgressBarIncrement(false);
     706             :             }
     707          52 :         }
     708             :     }
     709             : 
     710        3179 :     if( !pContext )
     711           0 :         pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
     712             : 
     713        3179 :     return pContext;
     714             : }
     715             : 
     716           5 : void ScXMLTableRowCellContext::DoMerge( const ScAddress& rScAddress, const SCCOL nCols, const SCROW nRows )
     717             : {
     718           5 :     SCCOL mergeToCol = rScAddress.Col() + nCols;
     719           5 :     SCROW mergeToRow = rScAddress.Row() + nRows;
     720          10 :     bool bInBounds = rScAddress.Col() <= MAXCOL && rScAddress.Row() <= MAXROW &&
     721          10 :                        mergeToCol <= MAXCOL && mergeToRow <= MAXROW;
     722           5 :     if( bInBounds )
     723             :     {
     724           5 :         rXMLImport.GetDocument()->DoMerge( rScAddress.Tab(),
     725          10 :             rScAddress.Col(), rScAddress.Row(), mergeToCol, mergeToRow );
     726             :     }
     727           5 : }
     728             : 
     729             : namespace {
     730             : 
     731          14 : ScValidationMode validationTypeToMode( const sheet::ValidationType eVType )
     732             : {
     733             :     ScValidationMode eMode;
     734          14 :     switch( eVType )
     735             :     {
     736          10 :         case sheet::ValidationType_WHOLE:               eMode = SC_VALID_WHOLE;     break;
     737           4 :         case sheet::ValidationType_DECIMAL:             eMode = SC_VALID_DECIMAL;   break;
     738           0 :         case sheet::ValidationType_DATE:                eMode = SC_VALID_DATE;      break;
     739           0 :         case sheet::ValidationType_TIME:                eMode = SC_VALID_TIME;      break;
     740           0 :         case sheet::ValidationType_TEXT_LEN:            eMode = SC_VALID_TEXTLEN;   break;
     741           0 :         case sheet::ValidationType_LIST:                eMode = SC_VALID_LIST;      break;
     742           0 :         case sheet::ValidationType_CUSTOM:              eMode = SC_VALID_CUSTOM;    break;
     743           0 :         default:                                        eMode = SC_VALID_ANY;       break;
     744             :     }
     745          14 :     return eMode;
     746             : }
     747             : 
     748          14 : ScValidErrorStyle validAlertToValidError( const sheet::ValidationAlertStyle eVAlertStyle )
     749             : {
     750             :     ScValidErrorStyle eVErrStyle;
     751          14 :     switch( eVAlertStyle )
     752             :     {
     753          10 :         case sheet::ValidationAlertStyle_STOP:          eVErrStyle = SC_VALERR_STOP;      break;
     754           4 :         case sheet::ValidationAlertStyle_WARNING:       eVErrStyle = SC_VALERR_WARNING;   break;
     755           0 :         case sheet::ValidationAlertStyle_MACRO:         eVErrStyle = SC_VALERR_MACRO;     break;
     756           0 :         default:                                        eVErrStyle = SC_VALERR_INFO;      break;
     757             :         //should INFO be the default?  seems to be the most unobtrusive choice.
     758             :     }
     759          14 :     return eVErrStyle;
     760             : }
     761             : 
     762             : }
     763             : 
     764        5652 : void ScXMLTableRowCellContext::SetContentValidation( const ScRange& rScRange )
     765             : {
     766        5652 :     if (maContentValidationName)
     767             :     {
     768          14 :         ScDocument* pDoc = rXMLImport.GetDocument();
     769          14 :         ScMyImportValidation aValidation;
     770          14 :         aValidation.eGrammar1 = aValidation.eGrammar2 = pDoc->GetStorageGrammar();
     771          14 :         if( rXMLImport.GetValidation(*maContentValidationName, aValidation) )
     772             :         {
     773             :             ScValidationData aScValidationData(
     774             :                 validationTypeToMode(aValidation.aValidationType),
     775             :                 ScConditionEntry::GetModeFromApi(static_cast<sal_Int32>(aValidation.aOperator)),
     776             :                 aValidation.sFormula1, aValidation.sFormula2, pDoc, ScAddress(),
     777             :                 aValidation.sFormulaNmsp1, aValidation.sFormulaNmsp2,
     778             :                 aValidation.eGrammar1, aValidation.eGrammar2
     779          14 :             );
     780             : 
     781          14 :             aScValidationData.SetIgnoreBlank( aValidation.bIgnoreBlanks );
     782          14 :             aScValidationData.SetListType( aValidation.nShowList );
     783             : 
     784             :             // set strings for error / input even if disabled (and disable afterwards)
     785          14 :             aScValidationData.SetInput( aValidation.sImputTitle, aValidation.sImputMessage );
     786          14 :             if( !aValidation.bShowImputMessage )
     787          14 :                 aScValidationData.ResetInput();
     788          14 :             aScValidationData.SetError( aValidation.sErrorTitle, aValidation.sErrorMessage, validAlertToValidError(aValidation.aAlertStyle) );
     789          14 :             if( !aValidation.bShowErrorMessage )
     790           0 :                 aScValidationData.ResetError();
     791             : 
     792          14 :             if( !aValidation.sBaseCellAddress.isEmpty() )
     793          14 :                 aScValidationData.SetSrcString( aValidation.sBaseCellAddress );
     794             : 
     795          14 :             sal_uLong nIndex = pDoc->AddValidationEntry( aScValidationData );
     796             : 
     797          28 :             ScPatternAttr aPattern( pDoc->GetPool() );
     798          14 :             aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) );
     799          14 :             if( rScRange.aStart == rScRange.aEnd )  //for a single cell
     800             :             {
     801           9 :                 pDoc->ApplyPattern( rScRange.aStart.Col(), rScRange.aStart.Row(),
     802          18 :                                     rScRange.aStart.Tab(), aPattern );
     803             :             }
     804             :             else  //for repeating cells
     805             :             {
     806           5 :                 pDoc->ApplyPatternAreaTab( rScRange.aStart.Col(), rScRange.aStart.Row(),
     807           5 :                                        rScRange.aEnd.Col(), rScRange.aEnd.Row(),
     808          15 :                                        rScRange.aStart.Tab(), aPattern );
     809             :             }
     810             : 
     811             :             // is the below still needed?
     812             :             // For now, any sheet with validity is blocked from stream-copying.
     813             :             // Later, the validation names could be stored along with the style names.
     814          14 :             ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
     815          28 :             pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
     816          14 :         }
     817             :     }
     818        5652 : }
     819             : 
     820        5073 : void ScXMLTableRowCellContext::SetContentValidation( const ScAddress& rCellPos )
     821             : {
     822        5073 :     SetContentValidation( ScRange(rCellPos, rCellPos) );
     823        5073 : }
     824             : 
     825        3124 : void ScXMLTableRowCellContext::SetAnnotation(const ScAddress& rPos)
     826             : {
     827        3124 :     ScDocument* pDoc = rXMLImport.GetDocument();
     828        3124 :     if( !pDoc || !mxAnnotationData.get() )
     829        6240 :         return;
     830             : 
     831           8 :     LockSolarMutex();
     832             : 
     833           8 :     ScPostIt* pNote = 0;
     834             : 
     835           8 :     uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
     836          16 :     uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
     837           8 :     sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
     838             : 
     839             :     OSL_ENSURE( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
     840             :         "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
     841           8 :     if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
     842             :     {
     843             :         OSL_ENSURE( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
     844           8 :         SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
     845             :         OSL_ENSURE( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
     846             : 
     847             :         /*  Try to reuse the drawing object already created (but only if the
     848             :             note is visible, and the object is a caption object). */
     849           8 :         if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
     850             :         {
     851           2 :             if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
     852             :             {
     853             :                 OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
     854             :                 // create the cell note with the caption object
     855           2 :                 pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, rPos, *pCaption, true );
     856             :                 // forget pointer to object (do not create note again below)
     857           2 :                 pObject = 0;
     858             :             }
     859             :         }
     860             : 
     861             :         // drawing object has not been used to create a note -> use shape data
     862           8 :         if( pObject )
     863             :         {
     864             :             // rescue settings from drawing object before the shape is removed
     865           6 :             ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
     866          12 :             ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
     867           6 :             if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
     868           6 :                 xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
     869           6 :             Rectangle aCaptionRect;
     870           6 :             if( mxAnnotationData->mbUseShapePos )
     871           1 :                 aCaptionRect = pObject->GetLogicRect();
     872             :             // remove the shape from the drawing page, this invalidates pObject
     873           6 :             mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
     874           6 :             pObject = 0;
     875             :             // update current number of existing objects
     876           6 :             if( xShapesIA.is() )
     877           6 :                 nOldShapeCount = xShapesIA->getCount();
     878             : 
     879             :             // an outliner object is required (empty note captions not allowed)
     880           6 :             if( xOutlinerObj.get() )
     881             :             {
     882             :                 // create cell note with all data from drawing object
     883             :                 pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, rPos,
     884             :                     xItemSet.release(), xOutlinerObj.release(),
     885           6 :                     aCaptionRect, mxAnnotationData->mbShown, false );
     886           6 :             }
     887             :         }
     888             :     }
     889           0 :     else if( !mxAnnotationData->maSimpleText.isEmpty() )
     890             :     {
     891             :         // create note from simple text
     892             :         pNote = ScNoteUtil::CreateNoteFromString( *pDoc, rPos,
     893           0 :             mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
     894             :     }
     895             : 
     896             :     // set author and date
     897           8 :     if( pNote )
     898             :     {
     899             :         double fDate;
     900           8 :         rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
     901           8 :         SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
     902           8 :         sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
     903           8 :         OUString aDate;
     904           8 :         Color* pColor = 0;
     905           8 :         Color** ppColor = &pColor;
     906           8 :         pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
     907           8 :         pNote->SetDate( aDate );
     908           8 :         pNote->SetAuthor( mxAnnotationData->maAuthor );
     909             :     }
     910             : 
     911             :     // register a shape that has been newly created in the ScNoteUtil functions
     912           8 :     if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
     913             :     {
     914           5 :         uno::Reference< drawing::XShape > xShape;
     915           5 :         rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
     916             :     }
     917             : 
     918             :     // store the style names for stream copying
     919           8 :     ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
     920           8 :     pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, rPos );
     921             : 
     922           8 :     std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
     923           8 :     std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
     924          23 :     while (aIter != aEnd)
     925             :     {
     926           7 :         pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, rPos, aIter->maSelection );
     927           7 :         ++aIter;
     928           8 :     }
     929             : }
     930             : 
     931             : // core implementation
     932        3124 : void ScXMLTableRowCellContext::SetDetectiveObj( const ScAddress& rPosition )
     933             : {
     934        3124 :     if( cellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() )
     935             :     {
     936           0 :         LockSolarMutex();
     937           0 :         ScDetectiveFunc aDetFunc( rXMLImport.GetDocument(), rPosition.Tab() );
     938           0 :         uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
     939           0 :         ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin());
     940           0 :         ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end());
     941           0 :         while(aItr != aEndItr)
     942             :         {
     943           0 :             aDetFunc.InsertObject( aItr->eObjType, rPosition, aItr->aSourceRange, aItr->bHasError );
     944           0 :             if (xShapesIndex.is())
     945             :             {
     946           0 :                 sal_Int32 nShapes = xShapesIndex->getCount();
     947           0 :                 uno::Reference < drawing::XShape > xShape;
     948           0 :                 rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
     949             :             }
     950           0 :             ++aItr;
     951           0 :         }
     952             :     }
     953        3124 : }
     954             : 
     955             : // core implementation
     956        3124 : void ScXMLTableRowCellContext::SetCellRangeSource( const ScAddress& rPosition )
     957             : {
     958        9372 :     if( cellExists(rPosition) && pCellRangeSource  && !pCellRangeSource->sSourceStr.isEmpty() &&
     959        3124 :         !pCellRangeSource->sFilterName.isEmpty() && !pCellRangeSource->sURL.isEmpty() )
     960             :     {
     961           0 :         ScDocument* pDoc = rXMLImport.GetDocument();
     962           0 :         if (pDoc)
     963             :         {
     964           0 :             LockSolarMutex();
     965           0 :             ScRange aDestRange( rPosition.Col(), rPosition.Row(), rPosition.Tab(),
     966           0 :                 rPosition.Col() + static_cast<SCCOL>(pCellRangeSource->nColumns - 1),
     967           0 :                 rPosition.Row() + static_cast<SCROW>(pCellRangeSource->nRows - 1), rPosition.Tab() );
     968           0 :             String sFilterName( pCellRangeSource->sFilterName );
     969           0 :             String sSourceStr( pCellRangeSource->sSourceStr );
     970             :             ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
     971           0 :                 sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
     972           0 :             sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
     973           0 :             pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr );
     974             :         }
     975             :     }
     976        3124 : }
     977             : 
     978         401 : void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
     979             : {
     980         401 :     if(pFCell)
     981             :     {
     982         401 :         if(mbErrorValue)
     983             :         {
     984             :             // don't do anything here
     985             :             // we need to recalc anyway
     986             :         }
     987         401 :         else if( bFormulaTextResult && maStringValue )
     988             :         {
     989          49 :             if( !IsPossibleErrorString() )
     990             :             {
     991          26 :                 pFCell->SetHybridString( *maStringValue );
     992          26 :                 pFCell->ResetDirty();
     993             :             }
     994             :         }
     995         352 :         else if (!rtl::math::isNan(fValue))
     996             :         {
     997         352 :             pFCell->SetHybridDouble(fValue);
     998         352 :             pFCell->ResetDirty();
     999             :         }
    1000         401 :         pFCell->StartListeningTo(rXMLImport.GetDocument());
    1001             :     }
    1002         401 : }
    1003             : 
    1004         515 : void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
    1005             :         const SCCOL nCurrentCol, const ::boost::optional< OUString >& pOUText )
    1006             : {
    1007         515 :     bool bDoIncrement = true;
    1008             :     //matrix reference cells that contain text formula results;
    1009             :     //cell was already put in document, just need to set text here.
    1010         515 :     if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
    1011             :     {
    1012          16 :         bDoIncrement = rXMLImport.GetDocument()->GetCellType(rCurrentPos) == CELLTYPE_FORMULA;
    1013          16 :         if ( bDoIncrement )
    1014             :         {
    1015          16 :             ScFormulaCell* pFCell = rXMLImport.GetDocument()->GetFormulaCell(rCurrentPos);
    1016          16 :             OUString aCellString;
    1017          16 :             if (maStringValue)
    1018          16 :                 aCellString = *maStringValue;
    1019           0 :             else if (mbEditEngineHasText)
    1020           0 :                 aCellString = mpEditEngine->GetText(0);
    1021           0 :             else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
    1022           0 :                 aCellString = *pOUText;
    1023             :             else
    1024           0 :                 bDoIncrement = false;
    1025             : 
    1026          16 :             if(mbErrorValue)
    1027           0 :                 bDoIncrement = false;
    1028             : 
    1029          16 :             if(!aCellString.isEmpty())
    1030             :             {
    1031          12 :                 if (bDoIncrement && !IsPossibleErrorString())
    1032             :                 {
    1033           0 :                     pFCell->SetHybridString( aCellString );
    1034           0 :                     pFCell->ResetDirty();
    1035             :                 }
    1036             :                 else
    1037             :                 {
    1038          12 :                     ScAddress aTopLeftMatrixCell;
    1039          12 :                     if(pFCell->GetMatrixOrigin(aTopLeftMatrixCell))
    1040             :                     {
    1041          12 :                         ScFormulaCell* pMatrixCell = rXMLImport.GetDocument()->GetFormulaCell(aTopLeftMatrixCell);
    1042          12 :                         pMatrixCell->SetDirty();
    1043             :                     }
    1044             :                     else
    1045             :                         SAL_WARN("sc", "matrix cell without matrix");
    1046             :                 }
    1047             :             }
    1048          16 :             pFCell->StartListeningTo(rXMLImport.GetDocument());
    1049             :         }
    1050             :     }
    1051             :     else //regular text cells
    1052             :     {
    1053         499 :         ScDocument* pDoc = rXMLImport.GetDocument();
    1054         499 :         if (maStringValue)
    1055             :         {
    1056           0 :             pDoc->SetTextCell(rCurrentPos, *maStringValue);
    1057           0 :             bDoIncrement = true;
    1058             :         }
    1059         499 :         else if (mbEditEngineHasText)
    1060             :         {
    1061         496 :             if (maFields.empty() && maFormats.empty() && mpEditEngine->GetParagraphCount() == 1)
    1062             :             {
    1063             :                 // This is a normal text without format runs.
    1064         478 :                 ScSetStringParam aParam;
    1065         478 :                 aParam.setTextInput();
    1066         478 :                 pDoc->SetString(rCurrentPos, mpEditEngine->GetText(), &aParam);
    1067             :             }
    1068             :             else
    1069             :             {
    1070             :                 // This text either has format runs, has field(s), or consists of multiple lines.
    1071             :                 {
    1072          18 :                     ParaFormatsType::const_iterator it = maFormats.begin(), itEnd = maFormats.end();
    1073          34 :                     for (; it != itEnd; ++it)
    1074          16 :                         mpEditEngine->QuickSetAttribs(it->maItemSet, it->maSelection);
    1075             :                 }
    1076             : 
    1077             :                 {
    1078          18 :                     FieldsType::const_iterator it = maFields.begin(), itEnd = maFields.end();
    1079          27 :                     for (; it != itEnd; ++it)
    1080           9 :                         mpEditEngine->QuickInsertField(SvxFieldItem(*it->mpData, EE_FEATURE_FIELD), it->maSelection);
    1081             :                 }
    1082             : 
    1083             :                 // This edit engine uses the SfxItemPool instance returned
    1084             :                 // from pDoc->GetEditPool() to create the text object, which
    1085             :                 // is a prerequisite for using this constructor of ScEditCell.
    1086          18 :                 pDoc->SetEditText(rCurrentPos, mpEditEngine->CreateTextObject());
    1087             :             }
    1088         496 :             bDoIncrement = true;
    1089             :         }
    1090           3 :         else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
    1091             :         {
    1092           0 :             pDoc->SetTextCell(rCurrentPos, *pOUText);
    1093           0 :             bDoIncrement = true;
    1094             :         }
    1095             :         else
    1096           3 :             bDoIncrement = false;
    1097             :     }
    1098             : 
    1099             :     // #i56027# This is about setting simple text, not edit cells,
    1100             :     // so ProgressBarIncrement must be called with bEditCell = FALSE.
    1101             :     // Formatted text that is put into the cell by the child context
    1102             :     // is handled in AddCellsToTable() (bIsEmpty is true then).
    1103         515 :     if (bDoIncrement)
    1104         512 :         rXMLImport.ProgressBarIncrement(false);
    1105         515 : }
    1106             : 
    1107        2214 : void ScXMLTableRowCellContext::PutValueCell( const ScAddress& rCurrentPos )
    1108             : {
    1109             :     //matrix reference cells that contain value formula results;
    1110             :     //cell was already put in document, just need to set value here.
    1111        2214 :     if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
    1112             :     {
    1113          37 :         if (rXMLImport.GetDocument()->GetCellType(rCurrentPos) == CELLTYPE_FORMULA)
    1114             :         {
    1115          37 :             ScFormulaCell* pFCell = rXMLImport.GetDocument()->GetFormulaCell(rCurrentPos);
    1116          37 :             SetFormulaCell(pFCell);
    1117          37 :             pFCell->SetNeedNumberFormat( true );
    1118             :         }
    1119             :     }
    1120             :     else  //regular value cell
    1121             :     {
    1122             :         // #i62435# Initialize the value cell's script type if the default
    1123             :         // style's number format is latin-only. If the cell uses a different
    1124             :         // format, the script type will be reset when the style is applied.
    1125             : 
    1126        2177 :         ScDocument* pDoc = rXMLImport.GetDocument();
    1127        2177 :         pDoc->SetValue(rCurrentPos, fValue);
    1128        2177 :         if ( rXMLImport.IsLatinDefaultStyle() )
    1129        2177 :             pDoc->SetScriptType(rCurrentPos, SCRIPTTYPE_LATIN);
    1130             :     }
    1131        2214 :     rXMLImport.ProgressBarIncrement(false);
    1132        2214 : }
    1133             : 
    1134             : namespace {
    1135             : 
    1136           0 : bool isEmptyOrNote( ScDocument* pDoc, const ScAddress& rCurrentPos )
    1137             : {
    1138           0 :     CellType eType = pDoc->GetCellType(rCurrentPos);
    1139           0 :     return (eType == CELLTYPE_NONE);
    1140             : }
    1141             : 
    1142             : }
    1143             : 
    1144        5257 : void ScXMLTableRowCellContext::AddTextAndValueCell( const ScAddress& rCellPos,
    1145             :         const ::boost::optional< OUString >& pOUText, ScAddress& rCurrentPos )
    1146             : {
    1147        5257 :     ScMyTables& rTables = rXMLImport.GetTables();
    1148        5257 :     bool bWasEmpty = bIsEmpty;
    1149       35232 :     for (SCCOL i = 0; i < nColsRepeated; ++i)
    1150             :     {
    1151       29975 :         rCurrentPos.SetCol( rCellPos.Col() + i );
    1152             : 
    1153             :         // it makes no sense to import data after the last supported column
    1154             :         // fdo#58539 & gnome#627150
    1155       29975 :         if(rCurrentPos.Col() > MAXCOL)
    1156           0 :             break;
    1157             : 
    1158       29975 :         if (i > 0)
    1159       24718 :             rTables.AddColumn(false);
    1160       29975 :         if (!bIsEmpty)
    1161             :         {
    1162        5458 :             for (SCROW j = 0; j < nRepeatedRows; ++j)
    1163             :             {
    1164        2729 :                 rCurrentPos.SetRow( rCellPos.Row() + j );
    1165             : 
    1166             :                 // it makes no sense to import data after last supported row
    1167             :                 // fdo#58539 & gnome#627150
    1168        2729 :                 if(rCurrentPos.Row() > MAXROW)
    1169           0 :                     break;
    1170             : 
    1171        2729 :                 if( (rCurrentPos.Col() == 0) && (j > 0) )
    1172             :                 {
    1173           0 :                     rTables.AddRow();
    1174           0 :                     rTables.AddColumn(false);
    1175             :                 }
    1176        2729 :                 if( cellExists(rCurrentPos) )
    1177             :                 {
    1178        2729 :                     if(  ( !(bIsCovered) || isEmptyOrNote(rXMLImport.GetDocument(), rCurrentPos) )  )
    1179             :                     {
    1180        2729 :                         switch (nCellType)
    1181             :                         {
    1182             :                             case util::NumberFormat::TEXT:
    1183             :                             {
    1184         515 :                                 PutTextCell( rCurrentPos, i, pOUText );
    1185             :                             }
    1186         515 :                             break;
    1187             :                             case util::NumberFormat::NUMBER:
    1188             :                             case util::NumberFormat::PERCENT:
    1189             :                             case util::NumberFormat::CURRENCY:
    1190             :                             case util::NumberFormat::TIME:
    1191             :                             case util::NumberFormat::DATETIME:
    1192             :                             case util::NumberFormat::LOGICAL:
    1193             :                             {
    1194        2214 :                                 PutValueCell( rCurrentPos );
    1195             :                             }
    1196        2214 :                             break;
    1197             :                             default:
    1198             :                             {
    1199             :                                 OSL_FAIL("no cell type given");
    1200             :                             }
    1201           0 :                             break;
    1202             :                         }
    1203             :                     }
    1204             : 
    1205        2729 :                     SetAnnotation( rCurrentPos );
    1206        2729 :                     SetDetectiveObj( rCurrentPos );
    1207        2729 :                     SetCellRangeSource( rCurrentPos );
    1208             :                 }
    1209             :                 else
    1210             :                 {
    1211           0 :                     if (!bWasEmpty || mxAnnotationData.get())
    1212             :                     {
    1213           0 :                         if (rCurrentPos.Row() > MAXROW)
    1214           0 :                             rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
    1215             :                         else
    1216           0 :                             rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
    1217             :                     }
    1218             :                 }
    1219             :             }
    1220             :         }
    1221             :         else
    1222             :         {
    1223       27246 :             if ((i == 0) && (rCellPos.Col() == 0))
    1224             :             {
    1225    19922693 :                 for (sal_Int32 j = 1; j < nRepeatedRows; ++j)
    1226             :                 {
    1227    19922183 :                     rTables.AddRow();
    1228    19922183 :                     rTables.AddColumn(false);
    1229             :                 }
    1230             :             }
    1231             :         }
    1232             :     }
    1233        5257 : }
    1234             : 
    1235        5257 : bool ScXMLTableRowCellContext::HasSpecialContent() const
    1236             : {
    1237        5257 :     return (mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource);
    1238             : }
    1239             : 
    1240        8310 : bool ScXMLTableRowCellContext::CellsAreRepeated() const
    1241             : {
    1242        8310 :     return ( (nColsRepeated > 1) || (nRepeatedRows > 1) );
    1243             : }
    1244             : 
    1245             : namespace {
    1246             : 
    1247             : // from ScCellObj::GetOutputString_Imp().  all of it may not be necessary.
    1248         573 : OUString getOutputString( ScDocument* pDoc, const ScAddress& aCellPos )
    1249             : {
    1250         573 :     if (!pDoc)
    1251           0 :         return EMPTY_OUSTRING;
    1252             : 
    1253         573 :     CellType eType = pDoc->GetCellType(aCellPos);
    1254         573 :     switch (eType)
    1255             :     {
    1256             :         case CELLTYPE_NONE:
    1257         573 :             return EMPTY_OUSTRING;
    1258             :         case CELLTYPE_EDIT:
    1259             :         {
    1260             :             //  GetString an der EditCell macht Leerzeichen aus Umbruechen,
    1261             :             //  hier werden die Umbrueche aber gebraucht
    1262           0 :             const EditTextObject* pData = pDoc->GetEditText(aCellPos);
    1263           0 :             if (pData)
    1264             :             {
    1265           0 :                 EditEngine& rEngine = pDoc->GetEditEngine();
    1266           0 :                 rEngine.SetText(*pData);
    1267           0 :                 return rEngine.GetText(LINEEND_LF);
    1268             :             }
    1269             :             //  Edit-Zellen auch nicht per NumberFormatter formatieren
    1270             :             //  (passend zur Ausgabe)
    1271             :         }
    1272           0 :         break;
    1273             :         default:
    1274             :         {
    1275             :             //  wie in GetString am Dokument (column)
    1276             :             Color* pColor;
    1277           0 :             sal_uLong nNumFmt = pDoc->GetNumberFormat(aCellPos);
    1278             :             return ScCellFormat::GetString(
    1279           0 :                 *pDoc, aCellPos, nNumFmt, &pColor, *pDoc->GetFormatTable());
    1280             :         }
    1281             :     }
    1282             : 
    1283           0 :     return EMPTY_OUSTRING;
    1284             : }
    1285             : 
    1286             : }
    1287             : 
    1288        5257 : void ScXMLTableRowCellContext::AddNonFormulaCell( const ScAddress& rCellPos )
    1289             : {
    1290        5257 :     ::boost::optional< OUString > pOUText;
    1291             : 
    1292        5257 :     if( nCellType == util::NumberFormat::TEXT )
    1293             :     {
    1294        3053 :         if( cellExists(rCellPos) && CellsAreRepeated() )
    1295         573 :             pOUText.reset( getOutputString(rXMLImport.GetDocument(), rCellPos) );
    1296             : 
    1297        3053 :         if (!mbEditEngineHasText && !pOUText && !maStringValue)
    1298        1974 :             bIsEmpty = true;
    1299             :     }
    1300             : 
    1301        5257 :     ScAddress aCurrentPos( rCellPos );
    1302        5257 :     if( HasSpecialContent() )
    1303           8 :         bIsEmpty = false;
    1304             : 
    1305        5257 :     AddTextAndValueCell( rCellPos, pOUText, aCurrentPos );
    1306             : 
    1307        5257 :     if( CellsAreRepeated() )
    1308             :     {
    1309         579 :         SCCOL nStartCol( rCellPos.Col() < MAXCOL ? rCellPos.Col() : MAXCOL );
    1310         579 :         SCROW nStartRow( rCellPos.Row() < MAXROW ? rCellPos.Row() : MAXROW );
    1311         579 :         SCCOL nEndCol( rCellPos.Col() + nColsRepeated - 1 < MAXCOL ? rCellPos.Col() + nColsRepeated - 1 : MAXCOL );
    1312         579 :         SCROW nEndRow( rCellPos.Row() + nRepeatedRows - 1 < MAXROW ? rCellPos.Row() + nRepeatedRows - 1 : MAXROW );
    1313         579 :         ScRange aScRange( nStartCol, nStartRow, rCellPos.Tab(), nEndCol, nEndRow, rCellPos.Tab() );
    1314         579 :         SetContentValidation( aScRange );
    1315         579 :         rXMLImport.GetStylesImportHelper()->AddRange( aScRange );
    1316             :     }
    1317        4678 :     else if( cellExists(rCellPos) )
    1318             :     {
    1319        4678 :         rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
    1320        4678 :         SetContentValidation( rCellPos );
    1321        5257 :     }
    1322        5257 : }
    1323             : 
    1324         364 : void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
    1325             : {
    1326         364 :     ScDocument* pDoc = rXMLImport.GetDocument();
    1327             : 
    1328         364 :     OUString aText = maFormula->first;
    1329         728 :     OUString aFormulaNmsp = maFormula->second;
    1330             : 
    1331             :     ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard (
    1332         728 :             new ScExternalRefManager::ApiGuard(pDoc));
    1333             : 
    1334             : 
    1335         364 :     if ( !aText.isEmpty() )
    1336             :     {
    1337         364 :         if ( aText[0] == '=' && aText.getLength() > 1 )
    1338             :         {
    1339             :             // temporary formula string as string tokens
    1340         364 :             boost::scoped_ptr<ScTokenArray> pCode(new ScTokenArray);
    1341         364 :             pCode->AddStringXML( aText );
    1342         364 :             if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && !aFormulaNmsp.isEmpty() )
    1343           0 :                 pCode->AddStringXML( aFormulaNmsp );
    1344             : 
    1345         364 :             pDoc->IncXMLImportedFormulaCount( aText.getLength() );
    1346         364 :             ScFormulaCell* pNewCell = new ScFormulaCell(pDoc, rCellPos, pCode.get(), eGrammar, MM_NONE);
    1347         364 :             SetFormulaCell(pNewCell);
    1348         364 :             pNewCell = pDoc->SetFormulaCell(rCellPos, pNewCell);
    1349         364 :             if (pNewCell)
    1350         364 :                 pNewCell->SetNeedNumberFormat( true );
    1351             :         }
    1352           0 :         else if ( aText[0] == '\'' && aText.getLength() > 1 )
    1353             :         {
    1354             :             //  for bEnglish, "'" at the beginning is always interpreted as text
    1355             :             //  marker and stripped
    1356           0 :             pDoc->SetTextCell(rCellPos, aText.copy(1));
    1357             :         }
    1358             :         else
    1359             :         {
    1360           0 :             SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
    1361           0 :             sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
    1362             :             double fVal;
    1363           0 :             if ( pFormatter->IsNumberFormat( aText, nEnglish, fVal ) )
    1364           0 :                 pDoc->SetValue(rCellPos, fVal);
    1365             :             //the (english) number format will not be set
    1366             :             //search matching local format and apply it
    1367             :             else
    1368           0 :                 pDoc->SetTextCell(rCellPos, aText);
    1369             :         }
    1370         364 :     }
    1371         364 : }
    1372             : 
    1373         395 : void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
    1374             : {
    1375         395 :     if( cellExists(rCellPos) )
    1376             :     {
    1377         395 :         SetContentValidation( rCellPos );
    1378             :         SAL_WARN_IF((nColsRepeated != 1) || (nRepeatedRows != 1), "sc", "repeated cells with formula not possible now");
    1379         395 :         rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
    1380             : 
    1381             :         //add matrix
    1382         395 :         if(bIsMatrix)
    1383             :         {
    1384          31 :             if (nMatrixCols > 0 && nMatrixRows > 0)
    1385             :             {
    1386             :                 //matrix cells are put in the document, but we must set the
    1387             :                 //value/text of each matrix cell later
    1388          31 :                 rXMLImport.GetTables().AddMatrixRange(
    1389          31 :                         rCellPos.Col(), rCellPos.Row(),
    1390          62 :                         std::min<SCCOL>(rCellPos.Col() + nMatrixCols - 1, MAXCOL),
    1391          62 :                         std::min<SCROW>(rCellPos.Row() + nMatrixRows - 1, MAXROW),
    1392         155 :                         maFormula->first, maFormula->second, eGrammar);
    1393             : 
    1394             :                 // Set the value/text of the top-left matrix position in its
    1395             :                 // cached result.  For import, we only need to set the correct
    1396             :                 // matrix geometry and the value type of the top-left element.
    1397             : 
    1398          31 :                 ScFormulaCell* pFCell = rXMLImport.GetDocument()->GetFormulaCell(rCellPos);
    1399             : 
    1400          31 :                 ScMatrixRef pMat(new ScMatrix(nMatrixCols, nMatrixRows));
    1401          31 :                 if (bFormulaTextResult && maStringValue)
    1402             :                 {
    1403          12 :                     if (!IsPossibleErrorString())
    1404             :                     {
    1405             :                         pFCell->SetResultMatrix(
    1406           6 :                             nMatrixCols, nMatrixRows, pMat, new formula::FormulaStringToken(*maStringValue));
    1407           6 :                         pFCell->ResetDirty();
    1408             :                     }
    1409             :                 }
    1410          19 :                 else if (!rtl::math::isNan(fValue))
    1411             :                 {
    1412             :                     pFCell->SetResultMatrix(
    1413          19 :                         nMatrixCols, nMatrixRows, pMat, new formula::FormulaDoubleToken(fValue));
    1414          19 :                     pFCell->ResetDirty();
    1415             :                 }
    1416          31 :                 pFCell->StartListeningTo(rXMLImport.GetDocument());
    1417             :             }
    1418             :         }
    1419             :         else
    1420         364 :             PutFormulaCell( rCellPos );
    1421             : 
    1422         395 :         SetAnnotation( rCellPos );
    1423         395 :         SetDetectiveObj( rCellPos );
    1424         395 :         SetCellRangeSource( rCellPos );
    1425         395 :         rXMLImport.ProgressBarIncrement(false);
    1426             :     }
    1427             :     else
    1428             :     {
    1429           0 :         if (rCellPos.Row() > MAXROW)
    1430           0 :             rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
    1431             :         else
    1432           0 :             rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
    1433             :     }
    1434         395 : }
    1435             : 
    1436             : //There are cases where a formula cell is exported with an office:value of 0 or
    1437             : //no office:value at all, but the formula cell will have a text:p value which
    1438             : //contains the intended formula result.
    1439             : //These cases include when a formula result:
    1440             : // - is blank
    1441             : // - has a constant error value beginning with "#" (such as "#VALUE!" or "#N/A")
    1442             : // - has an "Err:[###]" (where "[###]" is an error number)
    1443             : // Libreoffice 4.1+ with ODF1.2 extended write however calcext:value-type="error" in that case
    1444        5652 : void ScXMLTableRowCellContext::HasSpecialCaseFormulaText()
    1445             : {
    1446        5652 :     if (!mbEditEngineHasText || mbNewValueType)
    1447        8426 :         return;
    1448             : 
    1449        2878 :     OUString aStr = mpEditEngine->GetText(0);
    1450        2878 :     if (aStr.isEmpty() || aStr.startsWith("Err:"))
    1451          27 :         mbPossibleErrorCell = true;
    1452        2851 :     else if (aStr.startsWith("#"))
    1453          18 :         mbCheckWithCompilerForError = true;
    1454             : }
    1455             : 
    1456          73 : bool ScXMLTableRowCellContext::IsPossibleErrorString() const
    1457             : {
    1458          73 :     if(mbNewValueType && !mbErrorValue)
    1459           0 :         return false;
    1460          73 :     else if(mbNewValueType && mbErrorValue)
    1461           0 :         return true;
    1462          73 :     return mbPossibleErrorCell || ( mbCheckWithCompilerForError && GetScImport().IsFormulaErrorConstant(*maStringValue) );
    1463             : }
    1464             : 
    1465             : 
    1466        5652 : void ScXMLTableRowCellContext::EndElement()
    1467             : {
    1468        5652 :     HasSpecialCaseFormulaText();
    1469        5652 :     if( bFormulaTextResult && (mbPossibleErrorCell || mbCheckWithCompilerForError) )
    1470             :     {
    1471          45 :         maStringValue.reset(mpEditEngine->GetText(0));
    1472          45 :         nCellType = util::NumberFormat::TEXT;
    1473             :     }
    1474             : 
    1475        5652 :     ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
    1476        5652 :     if( aCellPos.Col() > 0 && nRepeatedRows > 1 )
    1477           9 :         aCellPos.SetRow( aCellPos.Row() - (nRepeatedRows - 1) );
    1478        5652 :     if( bIsMerged )
    1479           5 :         DoMerge( aCellPos, nMergedCols - 1, nMergedRows - 1 );
    1480             : 
    1481        5652 :     if (maFormula)
    1482         395 :         AddFormulaCell(aCellPos);
    1483             :     else
    1484        5257 :         AddNonFormulaCell(aCellPos);
    1485             : 
    1486        5652 :     UnlockSolarMutex(); //if LockSolarMutex got used, we presumably need to ensure an UnlockSolarMutex
    1487             : 
    1488        5652 :     bIsMerged = false;
    1489        5652 :     nMergedCols = 1;
    1490        5652 :     nMergedRows = 1;
    1491        5652 :     nColsRepeated = 1;
    1492        5745 : }
    1493             : 
    1494             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10