xref: /aoo4110/main/sc/source/filter/xml/xmlcelli.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 
27 // INCLUDE ---------------------------------------------------------------
28 
29 #include "xmlcelli.hxx"
30 #include "xmlimprt.hxx"
31 #include "xmltabi.hxx"
32 #include "xmlstyli.hxx"
33 #include "xmlannoi.hxx"
34 #include "global.hxx"
35 #include "document.hxx"
36 #include "cellsuno.hxx"
37 #include "docuno.hxx"
38 #include "unonames.hxx"
39 #include "postit.hxx"
40 #include "sheetdata.hxx"
41 
42 #include "XMLTableShapeImportHelper.hxx"
43 #include "XMLTextPContext.hxx"
44 #include "XMLStylesImportHelper.hxx"
45 
46 #include "arealink.hxx"
47 #include <sfx2/linkmgr.hxx>
48 #include "convuno.hxx"
49 #include "XMLConverter.hxx"
50 #include "scerrors.hxx"
51 #include "editutil.hxx"
52 #include "cell.hxx"
53 
54 #include <xmloff/xmltkmap.hxx>
55 #include <xmloff/xmltoken.hxx>
56 #include <xmloff/nmspmap.hxx>
57 #include <xmloff/xmluconv.hxx>
58 #include <xmloff/families.hxx>
59 #include <xmloff/numehelp.hxx>
60 #include <xmloff/xmlnmspe.hxx>
61 #include <svl/zforlist.hxx>
62 #include <svx/svdocapt.hxx>
63 #include <editeng/outlobj.hxx>
64 #include <editeng/editobj.hxx>
65 #include <svx/unoapi.hxx>
66 #include <svl/languageoptions.hxx>
67 
68 #include <com/sun/star/frame/XModel.hpp>
69 #include <com/sun/star/text/XText.hpp>
70 #include <com/sun/star/sheet/XSpreadsheets.hpp>
71 #include <com/sun/star/sheet/XSpreadsheet.hpp>
72 #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
73 
74 #include <com/sun/star/util/XMergeable.hpp>
75 #include <com/sun/star/sheet/XSheetCondition.hpp>
76 #include <com/sun/star/table/XCellRange.hpp>
77 #include <com/sun/star/table/CellAddress.hpp>
78 #include <com/sun/star/util/NumberFormat.hpp>
79 #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
80 #include <com/sun/star/util/XNumberFormatTypes.hpp>
81 #include <com/sun/star/util/Date.hpp>
82 #include <com/sun/star/lang/Locale.hpp>
83 #include <com/sun/star/text/ControlCharacter.hpp>
84 
85 #include <rtl/ustrbuf.hxx>
86 #include <tools/date.hxx>
87 #include <i18npool/lang.h>
88 #include <comphelper/extract.hxx>
89 
90 #define SC_CURRENCYSYMBOL	"CurrencySymbol"
91 
92 using namespace com::sun::star;
93 using namespace xmloff::token;
94 
95 //------------------------------------------------------------------
96 
ScXMLTableRowCellContext(ScXMLImport & rImport,sal_uInt16 nPrfx,const::rtl::OUString & rLName,const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> & xAttrList,const sal_Bool bTempIsCovered,const sal_Int32 nTempRepeatedRows)97 ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
98 									  sal_uInt16 nPrfx,
99 									  const ::rtl::OUString& rLName,
100 									  const ::com::sun::star::uno::Reference<
101 									  ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
102 									  const sal_Bool bTempIsCovered,
103 									  const sal_Int32 nTempRepeatedRows ) :
104 	SvXMLImportContext( rImport, nPrfx, rLName ),
105 	pContentValidationName(NULL),
106 	pDetectiveObjVec(NULL),
107 	pCellRangeSource(NULL),
108 	fValue(0.0),
109 	nMergedRows(1),
110 	nMergedCols(1),
111 	nRepeatedRows(nTempRepeatedRows),
112 	nCellsRepeated(1),
113 	rXMLImport((ScXMLImport&)rImport),
114     eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
115 	nCellType(util::NumberFormat::TEXT),
116 	bIsMerged(sal_False),
117 	bIsMatrix(sal_False),
118 	bHasSubTable(sal_False),
119 	bIsCovered(bTempIsCovered),
120 	bIsEmpty(sal_True),
121 	bHasTextImport(sal_False),
122 	bIsFirstTextImport(sal_False),
123 	bSolarMutexLocked(sal_False),
124 	bFormulaTextResult(sal_False)
125 {
126 	rXMLImport.SetRemoveLastChar(sal_False);
127 	rXMLImport.GetTables().AddColumn(bTempIsCovered);
128 	const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
129 	rtl::OUString aLocalName;
130 	rtl::OUString* pStyleName = NULL;
131 	rtl::OUString* pCurrencySymbol = NULL;
132     const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
133 	for (sal_Int16 i = 0; i < nAttrCount; ++i)
134 	{
135         sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
136             xAttrList->getNameByIndex(i), &aLocalName);
137 
138         const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
139         sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
140         switch (nToken)
141         {
142             case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
143                 pStyleName = new rtl::OUString(sValue);
144             break;
145             case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
146                 DBG_ASSERT(!pContentValidationName, "here should be only one Validation Name");
147                 pContentValidationName = new rtl::OUString(sValue);
148             break;
149             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
150                 bIsMerged = sal_True;
151                 nMergedRows = sValue.toInt32();
152             break;
153             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
154                 bIsMerged = sal_True;
155                 nMergedCols = sValue.toInt32();
156             break;
157             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
158                 bIsMatrix = sal_True;
159                 nMatrixCols = sValue.toInt32();
160             break;
161             case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
162                 bIsMatrix = sal_True;
163                 nMatrixRows = sValue.toInt32();
164             break;
165             case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
166                 nCellsRepeated = std::max( sValue.toInt32(), (sal_Int32) 1 );
167             break;
168             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
169                 nCellType = GetScImport().GetCellType(sValue);
170                 bIsEmpty = sal_False;
171             break;
172             case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
173             {
174                 if (sValue.getLength())
175                 {
176                     rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
177                     bIsEmpty = sal_False;
178                 }
179             }
180             break;
181             case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
182             {
183                 if (sValue.getLength() && rXMLImport.SetNullDateOnUnitConverter())
184                 {
185                     rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
186                     bIsEmpty = sal_False;
187                 }
188             }
189             break;
190             case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
191             {
192                 if (sValue.getLength())
193                 {
194                     rXMLImport.GetMM100UnitConverter().convertTime(fValue, sValue);
195                     bIsEmpty = sal_False;
196                 }
197             }
198             break;
199             case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
200             {
201                 if (sValue.getLength())
202                 {
203                     DBG_ASSERT(!pOUTextValue, "here should be only one string value");
204 				    pOUTextValue.reset(sValue);
205                     bIsEmpty = sal_False;
206                 }
207             }
208             break;
209             case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
210             {
211                 if (sValue.getLength())
212                 {
213                     if ( IsXMLToken(sValue, XML_TRUE) )
214                         fValue = 1.0;
215                     else if ( IsXMLToken(sValue, XML_FALSE) )
216                         fValue = 0.0;
217                     else
218                         rXMLImport.GetMM100UnitConverter().convertDouble(fValue, sValue);
219                     bIsEmpty = sal_False;
220                 }
221             }
222             break;
223             case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
224             {
225                 if (sValue.getLength())
226                 {
227                     DBG_ASSERT(!pOUFormula, "here should be only one formula");
228                     rtl::OUString aFormula, aFormulaNmsp;
229                     rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
230                     pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
231                 }
232             }
233             break;
234             case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
235                 pCurrencySymbol = new rtl::OUString(sValue);
236             break;
237             default:
238                 ;
239         }
240 	}
241 	if (pOUFormula)
242 	{
243 		if (nCellType == util::NumberFormat::TEXT)
244 			bFormulaTextResult = sal_True;
245 		nCellType = util::NumberFormat::UNDEFINED;
246 	}
247 	rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
248 }
249 
~ScXMLTableRowCellContext()250 ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
251 {
252 	if (pContentValidationName)
253 		delete pContentValidationName;
254 	if (pDetectiveObjVec)
255 		delete pDetectiveObjVec;
256 	if (pCellRangeSource)
257 		delete pCellRangeSource;
258 }
259 
LockSolarMutex()260 void ScXMLTableRowCellContext::LockSolarMutex()
261 {
262 	if (!bSolarMutexLocked)
263 	{
264 		GetScImport().LockSolarMutex();
265 		bSolarMutexLocked = sal_True;
266 	}
267 }
268 
UnlockSolarMutex()269 void ScXMLTableRowCellContext::UnlockSolarMutex()
270 {
271 	if (bSolarMutexLocked)
272 	{
273 		GetScImport().UnlockSolarMutex();
274 		bSolarMutexLocked = sal_False;
275 	}
276 }
277 
SetCursorOnTextImport(const rtl::OUString & rOUTempText)278 void ScXMLTableRowCellContext::SetCursorOnTextImport(const rtl::OUString& rOUTempText)
279 {
280 	com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
281     if (CellExists(aCellPos))
282     {
283 	    uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
284 	    if (xCellRange.is())
285 	    {
286 		    xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
287 		    if (xBaseCell.is())
288 		    {
289 			    xLockable.set(xBaseCell, uno::UNO_QUERY);
290 			    if (xLockable.is())
291 				    xLockable->addActionLock();
292 			    uno::Reference<text::XText> xText(xBaseCell, uno::UNO_QUERY);
293 			    if (xText.is())
294 			    {
295 				    uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
296 				    if (xTextCursor.is())
297 				    {
298 					    xTextCursor->setString(rOUTempText);
299 					    xTextCursor->gotoEnd(sal_False);
300 					    rXMLImport.GetTextImport()->SetCursor(xTextCursor);
301 				    }
302 			    }
303 		    }
304 	    }
305     }
306     else
307     {
308         DBG_ERRORFILE("this method should only be called for a existing cell");
309     }
310 }
311 
CreateChildContext(sal_uInt16 nPrefix,const::rtl::OUString & rLName,const::com::sun::star::uno::Reference<::com::sun::star::xml::sax::XAttributeList> & xAttrList)312 SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix,
313 											const ::rtl::OUString& rLName,
314 											const ::com::sun::star::uno::Reference<
315 									  	::com::sun::star::xml::sax::XAttributeList>& xAttrList )
316 {
317 	SvXMLImportContext *pContext = 0;
318 
319 	const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap();
320 	sal_Bool bTextP(sal_False);
321 	switch( rTokenMap.Get( nPrefix, rLName ) )
322 	{
323 	case XML_TOK_TABLE_ROW_CELL_P:
324 		{
325 			bIsEmpty = sal_False;
326 			bTextP = sal_True;
327             com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
328 			if (((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) &&
329                 !rXMLImport.GetTables().IsPartOfMatrix(aCellPos.Column, aCellPos.Row))
330 			{
331 				if (!bHasTextImport)
332 				{
333 					bIsFirstTextImport = sal_True;
334 					bHasTextImport = sal_True;
335 					pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
336 				}
337 				else
338 				{
339                     // com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
340                     if (CellExists(aCellPos))
341                     {
342 					    if (bIsFirstTextImport && !rXMLImport.GetRemoveLastChar())
343 					    {
344 						    if (pOUTextContent)
345 						    {
346 							    SetCursorOnTextImport(*pOUTextContent);
347 							    pOUTextContent.reset();
348 						    }
349 						    else
350 							    SetCursorOnTextImport(rtl::OUString());
351 						    rXMLImport.SetRemoveLastChar(sal_True);
352                             uno::Reference < text::XTextCursor > xTextCursor(rXMLImport.GetTextImport()->GetCursor());
353                             if (xTextCursor.is())
354                             {
355     						    uno::Reference < text::XText > xText (xTextCursor->getText());
356 		    				    uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
357 	    					    if (xText.is() && xTextRange.is())
358 			    				    xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, sal_False);
359                             }
360 					    }
361 					    pContext = rXMLImport.GetTextImport()->CreateTextChildContext(
362 						    rXMLImport, nPrefix, rLName, xAttrList);
363 					    bIsFirstTextImport = sal_False;
364                     }
365 				}
366 			}
367 		}
368 		break;
369 	case XML_TOK_TABLE_ROW_CELL_TABLE:
370 		{
371 	        const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
372 	        rtl::OUString aLocalName;
373 	        for( sal_Int16 i=0; i < nAttrCount; i++ )
374 	        {
375 		        sal_uInt16 nAttrPrefix = rXMLImport.GetNamespaceMap().GetKeyByAttrName(
376 											        xAttrList->getNameByIndex( i ), &aLocalName );
377 		        if (    nAttrPrefix == XML_NAMESPACE_TABLE
378                     &&  IsXMLToken(aLocalName, XML_IS_SUB_TABLE))
379 		        {
380                     bHasSubTable = IsXMLToken(xAttrList->getValueByIndex( i ), XML_TRUE);
381                 }
382             }
383             DBG_ASSERT(bHasSubTable, "it should be a subtable");
384 			pContext = new ScXMLTableContext( rXMLImport , nPrefix,
385 														rLName, xAttrList,
386 														sal_True, nMergedCols);
387 			nMergedCols = 1;
388 			bIsMerged = sal_False;
389 		}
390 		break;
391 	case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
392 		{
393 			bIsEmpty = sal_False;
394             DBG_ASSERT( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
395             mxAnnotationData.reset( new ScXMLAnnotationData );
396 			pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
397                                                     xAttrList, *mxAnnotationData, this);
398 		}
399 		break;
400 	case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
401 		{
402 			bIsEmpty = sal_False;
403 			if (!pDetectiveObjVec)
404 				pDetectiveObjVec = new ScMyImpDetectiveObjVec();
405 			pContext = new ScXMLDetectiveContext(
406 				rXMLImport, nPrefix, rLName, pDetectiveObjVec );
407 		}
408 		break;
409 	case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE:
410 		{
411 			bIsEmpty = sal_False;
412 			if (!pCellRangeSource)
413 				pCellRangeSource = new ScMyImpCellRangeSource();
414 			pContext = new ScXMLCellRangeSourceContext(
415 				rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource );
416 		}
417 		break;
418 	}
419 
420 	if (!pContext && !bTextP)
421 	{
422 		com::sun::star::table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
423 		uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
424 		if (xShapes.is())
425 		{
426 			if (aCellPos.Column > MAXCOL)
427 				aCellPos.Column = MAXCOL;
428 			if (aCellPos.Row > MAXROW)
429 				aCellPos.Row = MAXROW;
430 			XMLTableShapeImportHelper* pTableShapeImport = (XMLTableShapeImportHelper*)rXMLImport.GetShapeImport().get();
431 			pTableShapeImport->SetOnTable(sal_False);
432 			pTableShapeImport->SetCell(aCellPos);
433 			pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
434 				rXMLImport, nPrefix, rLName, xAttrList, xShapes);
435 			if (pContext)
436 			{
437 				bIsEmpty = sal_False;
438 				rXMLImport.ProgressBarIncrement(sal_False);
439 			}
440 		}
441 	}
442 
443 	if( !pContext )
444 		pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
445 
446 	return pContext;
447 }
448 
IsMerged(const uno::Reference<table::XCellRange> & xCellRange,const sal_Int32 nCol,const sal_Int32 nRow,table::CellRangeAddress & aCellAddress) const449 sal_Bool ScXMLTableRowCellContext::IsMerged (const uno::Reference <table::XCellRange>& xCellRange, const sal_Int32 nCol, const sal_Int32 nRow,
450 							table::CellRangeAddress& aCellAddress) const
451 {
452     table::CellAddress aCell; // don't need to set the sheet, because every sheet can contain the same count of cells.
453     aCell.Column = nCol;
454     aCell.Row = nRow;
455     if (CellExists(aCell))
456     {
457 		uno::Reference<sheet::XSheetCellRange> xMergeSheetCellRange (xCellRange->getCellRangeByPosition(nCol,nRow,nCol,nRow), uno::UNO_QUERY);
458 		uno::Reference<sheet::XSpreadsheet> xTable (xMergeSheetCellRange->getSpreadsheet());
459 		uno::Reference<sheet::XSheetCellCursor> xMergeSheetCursor (xTable->createCursorByRange(xMergeSheetCellRange));
460 		if (xMergeSheetCursor.is())
461 		{
462 			xMergeSheetCursor->collapseToMergedArea();
463 			uno::Reference<sheet::XCellRangeAddressable> xMergeCellAddress (xMergeSheetCursor, uno::UNO_QUERY);
464 			if (xMergeCellAddress.is())
465 			{
466 				aCellAddress = xMergeCellAddress->getRangeAddress();
467 				if (aCellAddress.StartColumn == nCol && aCellAddress.EndColumn == nCol &&
468 					aCellAddress.StartRow == nRow && aCellAddress.EndRow == nRow)
469 					return sal_False;
470 				else
471 					return sal_True;
472 			}
473 		}
474     }
475 	return sal_False;
476 }
477 
DoMerge(const com::sun::star::table::CellAddress & aCellPos,const sal_Int32 nCols,const sal_Int32 nRows)478 void ScXMLTableRowCellContext::DoMerge(const com::sun::star::table::CellAddress& aCellPos,
479 	 			const sal_Int32 nCols, const sal_Int32 nRows)
480 {
481     if (CellExists(aCellPos))
482     {
483 	    uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
484 	    if ( xCellRange.is() )
485 	    {
486             // Stored merge range may actually be of a larger extend than what
487             // we support, in which case getCellRangeByPosition() throws
488             // IndexOutOfBoundsException. Do nothing then.
489             try
490             {
491                 table::CellRangeAddress aCellAddress;
492                 if (IsMerged(xCellRange, aCellPos.Column, aCellPos.Row, aCellAddress))
493                 {
494                     //unmerge
495                     uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
496                                 aCellAddress.EndColumn, aCellAddress.EndRow), uno::UNO_QUERY);
497                     if (xMergeable.is())
498                         xMergeable->merge(sal_False);
499                 }
500 
501                 //merge
502                 uno::Reference <util::XMergeable> xMergeable (xCellRange->getCellRangeByPosition(aCellAddress.StartColumn, aCellAddress.StartRow,
503                             aCellAddress.EndColumn + nCols, aCellAddress.EndRow + nRows), uno::UNO_QUERY);
504                 if (xMergeable.is())
505                     xMergeable->merge(sal_True);
506             }
507             catch ( lang::IndexOutOfBoundsException & )
508             {
509                 DBG_ERRORFILE("ScXMLTableRowCellContext::DoMerge: range to be merged larger than what we support");
510             }
511 	    }
512     }
513 }
514 
SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet> & xPropSet)515 void ScXMLTableRowCellContext::SetContentValidation(com::sun::star::uno::Reference<com::sun::star::beans::XPropertySet>& xPropSet)
516 {
517 	if (pContentValidationName)
518 	{
519 		ScMyImportValidation aValidation;
520         aValidation.eGrammar1 = aValidation.eGrammar2 = GetScImport().GetDocument()->GetStorageGrammar();
521 		if (rXMLImport.GetValidation(*pContentValidationName, aValidation))
522 		{
523             uno::Reference<beans::XPropertySet> xPropertySet(xPropSet->getPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML))), uno::UNO_QUERY);
524 			if (xPropertySet.is())
525 			{
526 				if (aValidation.sErrorMessage.getLength())
527                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRMESS)), uno::makeAny(aValidation.sErrorMessage));
528 				if (aValidation.sErrorTitle.getLength())
529 					xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRTITLE)), uno::makeAny(aValidation.sErrorTitle));
530 				if (aValidation.sImputMessage.getLength())
531 					xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPMESS)), uno::makeAny(aValidation.sImputMessage));
532 				if (aValidation.sImputTitle.getLength())
533 					xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_INPTITLE)), uno::makeAny(aValidation.sImputTitle));
534 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWERR)), uno::makeAny(aValidation.bShowErrorMessage));
535 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWINP)), uno::makeAny(aValidation.bShowImputMessage));
536 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_TYPE)), uno::makeAny(aValidation.aValidationType));
537 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_IGNOREBL)), uno::makeAny(aValidation.bIgnoreBlanks));
538 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SHOWLIST)), uno::makeAny(aValidation.nShowList));
539 				xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_ERRALSTY)), uno::makeAny(aValidation.aAlertStyle));
540 				uno::Reference<sheet::XSheetCondition> xCondition(xPropertySet, uno::UNO_QUERY);
541 				if (xCondition.is())
542 				{
543                     xCondition->setFormula1(aValidation.sFormula1);
544                     xCondition->setFormula2(aValidation.sFormula2);
545                     xCondition->setOperator(aValidation.aOperator);
546                     // #b4974740# source position must be set as string, because it may
547                     // refer to a sheet that hasn't been loaded yet.
548                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_SOURCESTR)), uno::makeAny(aValidation.sBaseCellAddress));
549                     // Transport grammar and formula namespace
550                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP1)), uno::makeAny(aValidation.sFormulaNmsp1));
551                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_FORMULANMSP2)), uno::makeAny(aValidation.sFormulaNmsp2));
552                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR1)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar1)));
553                     xPropertySet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_GRAMMAR2)), uno::makeAny(static_cast<sal_Int32>(aValidation.eGrammar2)));
554 				}
555 			}
556 			xPropSet->setPropertyValue(rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(SC_UNONAME_VALIXML)), uno::makeAny(xPropertySet));
557 
558             // For now, any sheet with validity is blocked from stream-copying.
559             // Later, the validation names could be stored along with the style names.
560             ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
561             pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
562 		}
563 	}
564 }
565 
SetCellProperties(const uno::Reference<table::XCellRange> & xCellRange,const table::CellAddress & aCellAddress)566 void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCellRange>& xCellRange,
567 												const table::CellAddress& aCellAddress)
568 {
569 	if (CellExists(aCellAddress) && pContentValidationName && pContentValidationName->getLength())
570 	{
571 		sal_Int32 nBottom = aCellAddress.Row + nRepeatedRows - 1;
572 		sal_Int32 nRight = aCellAddress.Column + nCellsRepeated - 1;
573 		if (nBottom > MAXROW)
574 			nBottom = MAXROW;
575 		if (nRight > MAXCOL)
576 			nRight = MAXCOL;
577 		uno::Reference <beans::XPropertySet> xProperties (xCellRange->getCellRangeByPosition(aCellAddress.Column, aCellAddress.Row,
578 			                                                nRight, nBottom), uno::UNO_QUERY);
579 		if (xProperties.is())
580 			SetContentValidation(xProperties);
581 	}
582 }
583 
SetCellProperties(const uno::Reference<table::XCell> & xCell)584 void ScXMLTableRowCellContext::SetCellProperties(const uno::Reference<table::XCell>& xCell)
585 {
586 	if (pContentValidationName && pContentValidationName->getLength())
587 	{
588 		uno::Reference <beans::XPropertySet> xProperties (xCell, uno::UNO_QUERY);
589 		if (xProperties.is())
590 			SetContentValidation(xProperties);
591 	}
592 }
593 
SetAnnotation(const table::CellAddress & aCellAddress)594 void ScXMLTableRowCellContext::SetAnnotation(const table::CellAddress& aCellAddress)
595 {
596     ScDocument* pDoc = rXMLImport.GetDocument();
597     if( !pDoc || !mxAnnotationData.get() )
598         return;
599 
600     LockSolarMutex();
601 
602     ScAddress aPos;
603     ScUnoConversion::FillScAddress( aPos, aCellAddress );
604     ScPostIt* pNote = 0;
605 
606     uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
607     uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
608     sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
609 
610     DBG_ASSERT( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
611         "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
612     if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
613     {
614         DBG_ASSERT( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
615         SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
616         DBG_ASSERT( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
617 
618         /*  Try to reuse the drawing object already created (but only if the
619             note is visible, and the object is a caption object). */
620         if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
621         {
622             if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
623             {
624                 OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
625                 // create the cell note with the caption object
626                 pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, aPos, *pCaption, true );
627                 // forget pointer to object (do not create note again below)
628                 pObject = 0;
629             }
630         }
631 
632         // drawing object has not been used to create a note -> use shape data
633         if( pObject )
634         {
635             // rescue settings from drawing object before the shape is removed
636             ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
637             ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
638             if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
639                 xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
640             Rectangle aCaptionRect;
641             if( mxAnnotationData->mbUseShapePos )
642                 aCaptionRect = pObject->GetLogicRect();
643             // remove the shape from the drawing page, this invalidates pObject
644             mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
645             pObject = 0;
646             // update current number of existing objects
647             if( xShapesIA.is() )
648                 nOldShapeCount = xShapesIA->getCount();
649 
650             // an outliner object is required (empty note captions not allowed)
651             if( xOutlinerObj.get() )
652             {
653                 // create cell note with all data from drawing object
654                 pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, aPos,
655                     xItemSet.release(), xOutlinerObj.release(),
656                     aCaptionRect, mxAnnotationData->mbShown, false );
657             }
658         }
659     }
660     else if( mxAnnotationData->maSimpleText.getLength() > 0 )
661     {
662         // create note from simple text
663         pNote = ScNoteUtil::CreateNoteFromString( *pDoc, aPos,
664             mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
665     }
666 
667     // set author and date
668     if( pNote )
669     {
670         double fDate;
671         rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
672         SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
673         sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
674         String aDate;
675         Color* pColor = 0;
676         Color** ppColor = &pColor;
677         pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
678         pNote->SetDate( aDate );
679         pNote->SetAuthor( mxAnnotationData->maAuthor );
680     }
681 
682     // register a shape that has been newly created in the ScNoteUtil functions
683     if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
684     {
685         uno::Reference< drawing::XShape > xShape;
686         rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
687     }
688 
689     // store the style names for stream copying
690     ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
691     pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, aPos );
692 
693     std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
694     std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
695     while (aIter != aEnd)
696     {
697         pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, aPos, aIter->maSelection );
698         ++aIter;
699     }
700 }
701 
702 // core implementation
SetDetectiveObj(const table::CellAddress & rPosition)703 void ScXMLTableRowCellContext::SetDetectiveObj( const table::CellAddress& rPosition )
704 {
705 	if( CellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() )
706 	{
707 		LockSolarMutex();
708 		ScDetectiveFunc	aDetFunc( rXMLImport.GetDocument(), rPosition.Sheet );
709 		uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
710         ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin());
711         ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end());
712 		while(aItr != aEndItr)
713 		{
714 			ScAddress aScAddress;
715 			ScUnoConversion::FillScAddress( aScAddress, rPosition );
716 			aDetFunc.InsertObject( aItr->eObjType, aScAddress, aItr->aSourceRange, aItr->bHasError );
717 			if (xShapesIndex.is())
718 			{
719 				sal_Int32 nShapes = xShapesIndex->getCount();
720 				uno::Reference < drawing::XShape > xShape;
721 				rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
722 			}
723             ++aItr;
724 		}
725 	}
726 }
727 
728 // core implementation
SetCellRangeSource(const table::CellAddress & rPosition)729 void ScXMLTableRowCellContext::SetCellRangeSource( const table::CellAddress& rPosition )
730 {
731 	if( CellExists(rPosition) && pCellRangeSource  && pCellRangeSource->sSourceStr.getLength() &&
732 		pCellRangeSource->sFilterName.getLength() && pCellRangeSource->sURL.getLength() )
733 	{
734 		ScDocument* pDoc = rXMLImport.GetDocument();
735 		if (pDoc)
736 		{
737 			LockSolarMutex();
738 			ScRange aDestRange( static_cast<SCCOL>(rPosition.Column), static_cast<SCROW>(rPosition.Row), rPosition.Sheet,
739 				static_cast<SCCOL>(rPosition.Column + pCellRangeSource->nColumns - 1),
740 				static_cast<SCROW>(rPosition.Row + pCellRangeSource->nRows - 1), rPosition.Sheet );
741 			String sFilterName( pCellRangeSource->sFilterName );
742 			String sSourceStr( pCellRangeSource->sSourceStr );
743 			ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
744 				sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
745 			sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
746 			pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr );
747 		}
748 	}
749 }
750 
lcl_IsEmptyOrNote(ScDocument * pDoc,const table::CellAddress & rCurrentPos)751 bool lcl_IsEmptyOrNote( ScDocument* pDoc, const table::CellAddress& rCurrentPos )
752 {
753     ScAddress aScAddress;
754     ScUnoConversion::FillScAddress( aScAddress, rCurrentPos );
755     ScBaseCell* pCell = pDoc->GetCell( aScAddress );
756     return ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE );
757 }
758 
EndElement()759 void ScXMLTableRowCellContext::EndElement()
760 {
761 	if (!bHasSubTable)
762 	{
763 		if (bHasTextImport && rXMLImport.GetRemoveLastChar())
764 		{
765 			if (rXMLImport.GetTextImport()->GetCursor().is())
766 			{
767 				//GetImport().GetTextImport()->GetCursor()->gotoEnd(sal_False);
768 				if( GetImport().GetTextImport()->GetCursor()->goLeft( 1, sal_True ) )
769 				{
770 					GetImport().GetTextImport()->GetText()->insertString(
771 						GetImport().GetTextImport()->GetCursorAsRange(), rtl::OUString(),
772 						sal_True );
773 				}
774 				rXMLImport.GetTextImport()->ResetCursor();
775 			}
776 		}
777 		table::CellAddress aCellPos = rXMLImport.GetTables().GetRealCellPos();
778 		if (aCellPos.Column > 0 && nRepeatedRows > 1)
779 			aCellPos.Row -= (nRepeatedRows - 1);
780 		uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
781 		if (xCellRange.is())
782 		{
783 			if (bIsMerged)
784 				DoMerge(aCellPos, nMergedCols - 1, nMergedRows - 1);
785 			if ( !pOUFormula )
786 			{
787                 ::boost::optional< rtl::OUString > pOUText;
788 
789 				if(nCellType == util::NumberFormat::TEXT)
790 				{
791 					if (xLockable.is())
792 						xLockable->removeActionLock();
793 
794                     // #i61702# The formatted text content of xBaseCell / xLockable is invalidated,
795                     // so it can't be used after calling removeActionLock (getString always uses the document).
796 
797 					if (CellExists(aCellPos) && ((nCellsRepeated > 1) || (nRepeatedRows > 1)))
798 					{
799 						if (!xBaseCell.is())
800                         {
801                             try
802                             {
803     							xBaseCell.set(xCellRange->getCellByPosition(aCellPos.Column, aCellPos.Row));
804                             }
805                             catch (lang::IndexOutOfBoundsException&)
806                             {
807                                 DBG_ERRORFILE("It seems here are to many columns or rows");
808                             }
809                         }
810 						uno::Reference <text::XText> xTempText (xBaseCell, uno::UNO_QUERY);
811 						if (xTempText.is())
812 						{
813 							pOUText.reset(xTempText->getString());
814 						}
815 					}
816 					if (     (!pOUTextContent && !pOUText && !pOUTextValue)
817                         && ( (pOUTextContent && !pOUTextContent->getLength()) || !pOUTextContent )
818                         && ( (pOUText && !pOUText->getLength()) || !pOUText )
819                         && ( (pOUTextValue && !pOUTextValue->getLength()) || !pOUTextValue ))
820 							bIsEmpty = sal_True;
821 				}
822                 sal_Bool bWasEmpty = bIsEmpty;
823 //				uno::Reference <table::XCell> xCell;
824 				table::CellAddress aCurrentPos( aCellPos );
825 				if ((pContentValidationName && pContentValidationName->getLength()) ||
826                     mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource)
827 					bIsEmpty = sal_False;
828 
829                 ScMyTables& rTables = rXMLImport.GetTables();
830 				for (sal_Int32 i = 0; i < nCellsRepeated; ++i)
831 				{
832 					aCurrentPos.Column = aCellPos.Column + i;
833 					if (i > 0)
834 						rTables.AddColumn(sal_False);
835 					if (!bIsEmpty)
836 					{
837 						for (sal_Int32 j = 0; j < nRepeatedRows; ++j)
838 						{
839 							aCurrentPos.Row = aCellPos.Row + j;
840 							if ((aCurrentPos.Column == 0) && (j > 0))
841                             {
842 								rTables.AddRow();
843                                 rTables.AddColumn(sal_False);
844                             }
845                             if (CellExists(aCurrentPos))
846                             {
847                                 // test - bypass the API
848 							    // if (xBaseCell.is() && (aCurrentPos == aCellPos))
849 								//     xCell.set(xBaseCell);
850 							    // else
851                                 // {
852                                 //     try
853                                 //     {
854     							// 	    xCell.set(xCellRange->getCellByPosition(aCurrentPos.Column, aCurrentPos.Row));
855                                 //     }
856                                 //     catch (lang::IndexOutOfBoundsException&)
857                                 //     {
858                                 //         DBG_ERRORFILE("It seems here are to many columns or rows");
859                                 //     }
860                                 // }
861 
862                                 // test - bypass the API
863                                 // if ((!(bIsCovered) || (xCell->getType() == table::CellContentType_EMPTY)))
864                                 if ((!(bIsCovered) || lcl_IsEmptyOrNote( rXMLImport.GetDocument(), aCurrentPos )))
865 							    {
866 								    switch (nCellType)
867 								    {
868 								    case util::NumberFormat::TEXT:
869 									    {
870 										    sal_Bool bDoIncrement = sal_True;
871                                             if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
872                                             {
873 						                        LockSolarMutex();
874                                                 // test - bypass the API
875                                                 // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
876                                                 // if (pCellObj)
877                                                 // {
878                                                 //     if(pOUTextValue && pOUTextValue->getLength())
879                                                 //         pCellObj->SetFormulaResultString(*pOUTextValue);
880                                                 //     else if (pOUTextContent && pOUTextContent->getLength())
881                                                 //         pCellObj->SetFormulaResultString(*pOUTextContent);
882                                                 //     else if ( i > 0 && pOUText && pOUText->getLength() )
883                                                 //     {
884                                                 //         pCellObj->SetFormulaResultString(*pOUText);
885                                                 //     }
886                                                 //     else
887                                                 //         bDoIncrement = sal_False;
888                                                 // }
889                                                 // else
890                                                 //     bDoIncrement = sal_False;
891                                                 ScAddress aScAddress;
892                                                 ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
893                                                 ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
894                                                 bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA );
895                                                 if ( bDoIncrement )
896                                                 {
897                                                     ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
898                                                     if (pOUTextValue && pOUTextValue->getLength())
899                                                         pFCell->SetHybridString( *pOUTextValue );
900                                                     else if (pOUTextContent && pOUTextContent->getLength())
901                                                         pFCell->SetHybridString( *pOUTextContent );
902                                                     else if ( i > 0 && pOUText && pOUText->getLength() )
903                                                         pFCell->SetHybridString( *pOUText );
904                                                     else
905                                                         bDoIncrement = sal_False;
906                                                 }
907                                             }
908                                             else
909                                             {
910                                                 // test - bypass the API
911                                                 // uno::Reference <text::XText> xText (xCell, uno::UNO_QUERY);
912                                                 // if (xText.is())
913                                                 // {
914                                                 //     if(pOUTextValue && pOUTextValue->getLength())
915                                                 //         xText->setString(*pOUTextValue);
916                                                 //     else if (pOUTextContent && pOUTextContent->getLength())
917                                                 //         xText->setString(*pOUTextContent);
918                                                 //     else if ( i > 0 && pOUText && pOUText->getLength() )
919                                                 //     {
920                                                 //         xText->setString(*pOUText);
921                                                 //     }
922                                                 //     else
923                                                 //         bDoIncrement = sal_False;
924                                                 // }
925                                                 LockSolarMutex();
926                                                 ScBaseCell* pNewCell = NULL;
927                                                 ScDocument* pDoc = rXMLImport.GetDocument();
928                                                 if (pOUTextValue && pOUTextValue->getLength())
929                                                     pNewCell = ScBaseCell::CreateTextCell( *pOUTextValue, pDoc );
930                                                 else if (pOUTextContent && pOUTextContent->getLength())
931                                                     pNewCell = ScBaseCell::CreateTextCell( *pOUTextContent, pDoc );
932                                                 else if ( i > 0 && pOUText && pOUText->getLength() )
933                                                     pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc );
934 
935                                                 bDoIncrement = pNewCell != NULL;
936                                                 if ( bDoIncrement )
937                                                 {
938                                                     ScAddress aScAddress;
939                                                     ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
940                                                     pDoc->PutCell( aScAddress, pNewCell );
941                                                 }
942                                             }
943                                             // #i56027# This is about setting simple text, not edit cells,
944                                             // so ProgressBarIncrement must be called with bEditCell = FALSE.
945                                             // Formatted text that is put into the cell by the child context
946                                             // is handled below (bIsEmpty is sal_True then).
947 										    if (bDoIncrement || bHasTextImport)
948 											    rXMLImport.ProgressBarIncrement(sal_False);
949 									    }
950 									    break;
951 								    case util::NumberFormat::NUMBER:
952 								    case util::NumberFormat::PERCENT:
953 								    case util::NumberFormat::CURRENCY:
954 								    case util::NumberFormat::TIME:
955 								    case util::NumberFormat::DATETIME:
956 								    case util::NumberFormat::LOGICAL:
957 									    {
958                                             if (rTables.IsPartOfMatrix(aCurrentPos.Column, aCurrentPos.Row))
959                                             {
960 						                        LockSolarMutex();
961                                                 // test - bypass the API
962                                                 // ScCellObj* pCellObj = (ScCellObj*)ScCellRangesBase::getImplementation(xCell);
963                                                 // if (pCellObj)
964                                                 //     pCellObj->SetFormulaResultDouble(fValue);
965                                                 ScAddress aScAddress;
966                                                 ScUnoConversion::FillScAddress( aScAddress, aCurrentPos );
967                                                 ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( aScAddress );
968                                                 if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
969                                                     static_cast<ScFormulaCell*>(pCell)->SetHybridDouble( fValue );
970                                             }
971                                             else
972                                             {
973                                                 // test - bypass the API
974                                                 // xCell->setValue(fValue);
975                                                 LockSolarMutex();
976 
977                                                 // #i62435# Initialize the value cell's script type
978                                                 // if the default style's number format is latin-only.
979                                                 // If the cell uses a different format, the script type
980                                                 // will be reset when the style is applied.
981 
982                                                 ScBaseCell* pNewCell = new ScValueCell(fValue);
983                                                 if ( rXMLImport.IsLatinDefaultStyle() )
984                                                     pNewCell->SetScriptType( SCRIPTTYPE_LATIN );
985                                                 rXMLImport.GetDocument()->PutCell(
986                                                     sal::static_int_cast<SCCOL>( aCurrentPos.Column ),
987                                                     sal::static_int_cast<SCROW>( aCurrentPos.Row ),
988                                                     sal::static_int_cast<SCTAB>( aCurrentPos.Sheet ),
989                                                     pNewCell );
990                                             }
991 										    rXMLImport.ProgressBarIncrement(sal_False);
992 									    }
993 									    break;
994 								    default:
995 									    {
996 										    DBG_ERROR("no cell type given");
997 									    }
998 									    break;
999 								    }
1000 							    }
1001 
1002                                 SetAnnotation(aCurrentPos);
1003 							    SetDetectiveObj( aCurrentPos );
1004 							    SetCellRangeSource( aCurrentPos );
1005                             }
1006                             else
1007                             {
1008                                 if (!bWasEmpty || mxAnnotationData.get())
1009                                 {
1010                                     if (aCurrentPos.Row > MAXROW)
1011                                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
1012                                     else
1013                                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
1014                                 }
1015                             }
1016 						}
1017 					}
1018 					else
1019 					{
1020                         // #i56027# If the child context put formatted text into the cell,
1021                         // bIsEmpty is sal_True and ProgressBarIncrement has to be called
1022                         // with bEditCell = TRUE.
1023 						if (bHasTextImport)
1024 							rXMLImport.ProgressBarIncrement(sal_True);
1025 						if ((i == 0) && (aCellPos.Column == 0))
1026 							for (sal_Int32 j = 1; j < nRepeatedRows; ++j)
1027 							{
1028 								rTables.AddRow();
1029 								rTables.AddColumn(sal_False);
1030 							}
1031 					}
1032 				}
1033 				if (nCellsRepeated > 1 || nRepeatedRows > 1)
1034 				{
1035 					SetCellProperties(xCellRange, aCellPos); // set now only the validation for the complete range with the given cell as start cell
1036 					//SetType(xCellRange, aCellPos);
1037                     SCCOL nStartCol(aCellPos.Column < MAXCOL ? static_cast<SCCOL>(aCellPos.Column) : MAXCOL);
1038                     SCROW nStartRow(aCellPos.Row < MAXROW ? static_cast<SCROW>(aCellPos.Row) : MAXROW);
1039                     SCCOL nEndCol(aCellPos.Column + nCellsRepeated - 1 < MAXCOL ? static_cast<SCCOL>(aCellPos.Column + nCellsRepeated - 1) : MAXCOL);
1040                     SCROW nEndRow(aCellPos.Row + nRepeatedRows - 1 < MAXROW ? static_cast<SCROW>(aCellPos.Row + nRepeatedRows - 1) : MAXROW);
1041 					ScRange aScRange( nStartCol, nStartRow, aCellPos.Sheet,
1042 						nEndCol, nEndRow, aCellPos.Sheet );
1043 					rXMLImport.GetStylesImportHelper()->AddRange(aScRange);
1044 				}
1045 				else if (CellExists(aCellPos))
1046 				{
1047 					rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
1048 
1049                     // test - bypass the API
1050                     // SetCellProperties(xCell); // set now only the validation
1051                     SetCellProperties(xCellRange, aCellPos);
1052 
1053 					//SetType(xTempCell);
1054 				}
1055 			}
1056             else // if ( !pOUFormula )
1057 			{
1058                 if (CellExists(aCellPos))
1059                 {
1060                     uno::Reference <table::XCell> xCell;
1061                     try
1062                     {
1063     				    xCell.set(xCellRange->getCellByPosition(aCellPos.Column , aCellPos.Row));
1064                     }
1065                     catch (lang::IndexOutOfBoundsException&)
1066                     {
1067                         DBG_ERRORFILE("It seems here are to many columns or rows");
1068                     }
1069                     if (xCell.is())
1070                     {
1071 				        SetCellProperties(xCell); // set now only the validation
1072 				        DBG_ASSERT(((nCellsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
1073 				        rXMLImport.GetStylesImportHelper()->AddCell(aCellPos);
1074 				        if (!bIsMatrix)
1075 				        {
1076                             LockSolarMutex();
1077                             ScCellObj* pCellObj =
1078                                 static_cast<ScCellObj*>(ScCellRangesBase::getImplementation(
1079                                             xCell));
1080                             if (pCellObj)
1081                             {
1082                                 pCellObj->SetFormulaWithGrammar( pOUFormula->first, pOUFormula->second, eGrammar);
1083                                 if (bFormulaTextResult && pOUTextValue && pOUTextValue->getLength())
1084                                     pCellObj->SetFormulaResultString( *pOUTextValue);
1085                                 else if (fValue != 0.0)
1086                                     pCellObj->SetFormulaResultDouble( fValue);
1087 					        }
1088 				        }
1089 				        else
1090 				        {
1091 					        if (nMatrixCols > 0 && nMatrixRows > 0)
1092 					        {
1093                                 rXMLImport.GetTables().AddMatrixRange(
1094                                         aCellPos.Column, aCellPos.Row,
1095                                         aCellPos.Column + nMatrixCols - 1,
1096                                         aCellPos.Row + nMatrixRows - 1,
1097                                         pOUFormula->first, pOUFormula->second, eGrammar);
1098 					        }
1099 				        }
1100 				        SetAnnotation( aCellPos );
1101 				        SetDetectiveObj( aCellPos );
1102 				        SetCellRangeSource( aCellPos );
1103 				        rXMLImport.ProgressBarIncrement(sal_False);
1104                     }
1105                 }
1106                 else
1107                 {
1108                     if (aCellPos.Row > MAXROW)
1109                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
1110                     else
1111                         rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
1112                 }
1113 
1114             } // if ( !pOUFormula )
1115 		}
1116 		UnlockSolarMutex();
1117 	}
1118 	bIsMerged = sal_False;
1119 	bHasSubTable = sal_False;
1120 	nMergedCols = 1;
1121 	nMergedRows = 1;
1122 	nCellsRepeated = 1;
1123 }
1124