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

Generated by: LCOV version 1.11