Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
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 : : #include "docsh.hxx"
42 : : #include "cellform.hxx"
43 : : #include "validat.hxx"
44 : : #include "patattr.hxx"
45 : : #include "scitems.hxx"
46 : : #include "docpool.hxx"
47 : :
48 : : #include "XMLTableShapeImportHelper.hxx"
49 : : #include "XMLTextPContext.hxx"
50 : : #include "XMLStylesImportHelper.hxx"
51 : :
52 : : #include "arealink.hxx"
53 : : #include <sfx2/linkmgr.hxx>
54 : : #include "convuno.hxx"
55 : : #include "XMLConverter.hxx"
56 : : #include "scerrors.hxx"
57 : : #include "editutil.hxx"
58 : : #include "cell.hxx"
59 : :
60 : :
61 : : #include <xmloff/xmltkmap.hxx>
62 : : #include <xmloff/xmltoken.hxx>
63 : : #include <xmloff/nmspmap.hxx>
64 : : #include <xmloff/xmluconv.hxx>
65 : : #include <xmloff/families.hxx>
66 : : #include <xmloff/numehelp.hxx>
67 : : #include <xmloff/xmlnmspe.hxx>
68 : : #include <svl/zforlist.hxx>
69 : : #include <svx/svdocapt.hxx>
70 : : #include <editeng/outlobj.hxx>
71 : : #include <editeng/editobj.hxx>
72 : : #include <svx/unoapi.hxx>
73 : : #include <svl/languageoptions.hxx>
74 : : #include <sax/tools/converter.hxx>
75 : :
76 : : #include <com/sun/star/frame/XModel.hpp>
77 : : #include <com/sun/star/text/XText.hpp>
78 : : #include <com/sun/star/sheet/XSpreadsheets.hpp>
79 : : #include <com/sun/star/sheet/XSpreadsheet.hpp>
80 : : #include <com/sun/star/sheet/XCellRangeAddressable.hpp>
81 : :
82 : : #include <com/sun/star/util/XMergeable.hpp>
83 : : #include <com/sun/star/sheet/XSheetCondition.hpp>
84 : : #include <com/sun/star/table/XCellRange.hpp>
85 : : #include <com/sun/star/table/CellAddress.hpp>
86 : : #include <com/sun/star/util/NumberFormat.hpp>
87 : : #include <com/sun/star/util/XNumberFormatsSupplier.hpp>
88 : : #include <com/sun/star/util/XNumberFormatTypes.hpp>
89 : : #include <com/sun/star/util/Date.hpp>
90 : : #include <com/sun/star/lang/Locale.hpp>
91 : : #include <com/sun/star/text/ControlCharacter.hpp>
92 : :
93 : : #include <com/sun/star/sheet/ValidationType.hpp>
94 : : #include <com/sun/star/sheet/ValidationAlertStyle.hpp>
95 : : #include <com/sun/star/sheet/ConditionOperator.hpp>
96 : :
97 : : #include <rtl/ustrbuf.hxx>
98 : : #include <tools/date.hxx>
99 : : #include <i18npool/lang.h>
100 : : #include <comphelper/extract.hxx>
101 : : #include <tools/string.hxx>
102 : :
103 : : using namespace com::sun::star;
104 : : using namespace xmloff::token;
105 : :
106 : : using rtl::OUString;
107 : :
108 : : //------------------------------------------------------------------
109 : :
110 : 10481 : ScXMLTableRowCellContext::ScXMLTableRowCellContext( ScXMLImport& rImport,
111 : : sal_uInt16 nPrfx,
112 : : const ::rtl::OUString& rLName,
113 : : const ::com::sun::star::uno::Reference<
114 : : ::com::sun::star::xml::sax::XAttributeList>& xAttrList,
115 : : const bool bTempIsCovered,
116 : : const sal_Int32 nTempRepeatedRows ) :
117 : : SvXMLImportContext( rImport, nPrfx, rLName ),
118 : : pContentValidationName(NULL),
119 : : pDetectiveObjVec(NULL),
120 : : pCellRangeSource(NULL),
121 : : fValue(0.0),
122 : : nMergedRows(1),
123 : : nRepeatedRows(nTempRepeatedRows),
124 : : nMergedCols(1),
125 : : nColsRepeated(1),
126 : : rXMLImport((ScXMLImport&)rImport),
127 : : eGrammar( formula::FormulaGrammar::GRAM_STORAGE_DEFAULT),
128 : : nCellType(util::NumberFormat::TEXT),
129 : : bIsMerged(false),
130 : : bIsMatrix(false),
131 : : bIsCovered(bTempIsCovered),
132 : : bIsEmpty(true),
133 : : bHasTextImport(false),
134 : : bIsFirstTextImport(false),
135 : : bSolarMutexLocked(false),
136 [ + - ][ + - ]: 10481 : bFormulaTextResult(false)
[ + - ]
137 : : {
138 : 10481 : rXMLImport.SetRemoveLastChar(false);
139 [ + - ]: 10481 : rXMLImport.GetTables().AddColumn(bTempIsCovered);
140 [ + - ][ + - ]: 10481 : const sal_Int16 nAttrCount = xAttrList.is() ? xAttrList->getLength() : 0;
[ + - ]
141 : 10481 : rtl::OUString aLocalName;
142 : 10481 : rtl::OUString* pStyleName = NULL;
143 : 10481 : rtl::OUString* pCurrencySymbol = NULL;
144 [ + - ]: 10481 : const SvXMLTokenMap& rTokenMap = rImport.GetTableRowCellAttrTokenMap();
145 [ + + ]: 24439 : for (sal_Int16 i = 0; i < nAttrCount; ++i)
146 : : {
147 : 13958 : sal_uInt16 nAttrPrefix = rImport.GetNamespaceMap().GetKeyByAttrName(
148 [ + - ]: 27916 : xAttrList->getNameByIndex(i), &aLocalName);
[ + - + - ]
149 : :
150 [ + - ][ + - ]: 13958 : const rtl::OUString& sValue = xAttrList->getValueByIndex(i);
151 [ + - ]: 13958 : sal_uInt16 nToken = rTokenMap.Get(nAttrPrefix, aLocalName);
152 [ + + + + : 13958 : switch (nToken)
+ + + + +
+ + + + +
+ - ]
153 : : {
154 : : case XML_TOK_TABLE_ROW_CELL_ATTR_STYLE_NAME:
155 [ + - ]: 581 : pStyleName = new rtl::OUString(sValue);
156 : 581 : break;
157 : : case XML_TOK_TABLE_ROW_CELL_ATTR_CONTENT_VALIDATION_NAME:
158 : : OSL_ENSURE(!pContentValidationName, "here should be only one Validation Name");
159 [ + - ]: 42 : pContentValidationName = new rtl::OUString(sValue);
160 : 42 : break;
161 : : case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_ROWS:
162 : 15 : bIsMerged = true;
163 : 15 : nMergedRows = static_cast<SCROW>(sValue.toInt32());
164 : 15 : break;
165 : : case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_COLS:
166 : 15 : bIsMerged = true;
167 : 15 : nMergedCols = static_cast<SCCOL>(sValue.toInt32());
168 : 15 : break;
169 : : case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_COLS:
170 : 75 : bIsMatrix = true;
171 : 75 : nMatrixCols = static_cast<SCCOL>(sValue.toInt32());
172 : 75 : break;
173 : : case XML_TOK_TABLE_ROW_CELL_ATTR_SPANNED_MATRIX_ROWS:
174 : 75 : bIsMatrix = true;
175 : 75 : nMatrixRows = static_cast<SCROW>(sValue.toInt32());
176 : 75 : break;
177 : : case XML_TOK_TABLE_ROW_CELL_ATTR_REPEATED:
178 [ + - ]: 1072 : nColsRepeated = static_cast<SCCOL>(std::max( sValue.toInt32(), static_cast<sal_Int32>(1) ));
179 : 1072 : break;
180 : : case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE_TYPE:
181 [ + - ]: 5872 : nCellType = GetScImport().GetCellType(sValue);
182 : 5872 : bIsEmpty = false;
183 : 5872 : break;
184 : : case XML_TOK_TABLE_ROW_CELL_ATTR_VALUE:
185 : : {
186 [ + - ]: 4617 : if (!sValue.isEmpty())
187 : : {
188 [ + - ]: 4617 : ::sax::Converter::convertDouble(fValue, sValue);
189 : 4617 : bIsEmpty = false;
190 : :
191 : : //if office:value="0", let's get the text:p in case this is
192 : : //a special case in HasSpecialCaseFormulaText(). If it
193 : : //turns out not to be a special case, we'll use the 0 value.
194 [ + + ]: 4617 : if(fValue == 0.0)
195 : 144 : bFormulaTextResult = true;
196 : : }
197 : : }
198 : 4617 : break;
199 : : case XML_TOK_TABLE_ROW_CELL_ATTR_DATE_VALUE:
200 : : {
201 [ + - ][ + - ]: 6 : if (!sValue.isEmpty() && rXMLImport.SetNullDateOnUnitConverter())
[ + - ][ + - ]
202 : : {
203 [ + - ]: 6 : rXMLImport.GetMM100UnitConverter().convertDateTime(fValue, sValue);
204 : 6 : bIsEmpty = false;
205 : : }
206 : : }
207 : 6 : break;
208 : : case XML_TOK_TABLE_ROW_CELL_ATTR_TIME_VALUE:
209 : : {
210 [ + - ]: 3 : if (!sValue.isEmpty())
211 : : {
212 [ + - ]: 3 : ::sax::Converter::convertDuration(fValue, sValue);
213 : 3 : bIsEmpty = false;
214 : : }
215 : : }
216 : 3 : break;
217 : : case XML_TOK_TABLE_ROW_CELL_ATTR_STRING_VALUE:
218 : : {
219 [ + - ]: 92 : if (!sValue.isEmpty())
220 : : {
221 : : OSL_ENSURE(!pOUTextValue, "here should be only one string value");
222 [ + - ]: 92 : pOUTextValue.reset(sValue);
223 : 92 : bIsEmpty = false;
224 : : }
225 : : }
226 : 92 : break;
227 : : case XML_TOK_TABLE_ROW_CELL_ATTR_BOOLEAN_VALUE:
228 : : {
229 [ + - ]: 420 : if (!sValue.isEmpty())
230 : : {
231 [ + - ][ + + ]: 420 : if ( IsXMLToken(sValue, XML_TRUE) )
232 : 195 : fValue = 1.0;
233 [ + - ][ + - ]: 225 : else if ( IsXMLToken(sValue, XML_FALSE) )
234 : 225 : fValue = 0.0;
235 : : else
236 [ # # ]: 0 : ::sax::Converter::convertDouble(fValue, sValue);
237 : 420 : bIsEmpty = false;
238 : : }
239 : : }
240 : 420 : break;
241 : : case XML_TOK_TABLE_ROW_CELL_ATTR_FORMULA:
242 : : {
243 [ + - ]: 1067 : if (!sValue.isEmpty())
244 : : {
245 : : OSL_ENSURE(!pOUFormula, "here should be only one formula");
246 : 1067 : rtl::OUString aFormula, aFormulaNmsp;
247 [ + - ]: 1067 : rXMLImport.ExtractFormulaNamespaceGrammar( aFormula, aFormulaNmsp, eGrammar, sValue );
248 [ + - ]: 1067 : pOUFormula.reset( FormulaWithNamespace( aFormula, aFormulaNmsp ) );
249 : : }
250 : : }
251 : 1067 : break;
252 : : case XML_TOK_TABLE_ROW_CELL_ATTR_CURRENCY:
253 [ + - ]: 6 : pCurrencySymbol = new rtl::OUString(sValue);
254 : 6 : break;
255 : : default:
256 : : ;
257 : : }
258 : 13958 : }
259 [ + - ][ + + ]: 10481 : if (pOUFormula)
260 : : {
261 [ + + ]: 1067 : if (nCellType == util::NumberFormat::TEXT)
262 : 92 : bFormulaTextResult = true;
263 [ + + ]: 1067 : if(nCellType == util::NumberFormat::DATETIME)
264 : 6 : nCellType = util::NumberFormat::UNDEFINED;
265 : : //if bIsEmpty is true at this point, then there is no office value.
266 : : //we must get the text:p (even if it is empty) in case this a special
267 : : //case in HasSpecialCaseFormulaText().
268 [ - + ]: 1067 : if(bIsEmpty)
269 : 0 : bFormulaTextResult = true;
270 : : }
271 [ + - ]: 10481 : rXMLImport.GetStylesImportHelper()->SetAttributes(pStyleName, pCurrencySymbol, nCellType);
272 : 10481 : }
273 : :
274 [ + - ][ + - ]: 10481 : ScXMLTableRowCellContext::~ScXMLTableRowCellContext()
[ + - ][ + - ]
275 : : {
276 [ + + ]: 10481 : if (pContentValidationName)
277 [ + - ]: 42 : delete pContentValidationName;
278 [ - + ]: 10481 : if (pDetectiveObjVec)
279 [ # # ]: 0 : delete pDetectiveObjVec;
280 [ - + ]: 10481 : if (pCellRangeSource)
281 [ # # ]: 0 : delete pCellRangeSource;
282 [ - + ]: 20962 : }
283 : :
284 : 8 : void ScXMLTableRowCellContext::LockSolarMutex()
285 : : {
286 [ + - ]: 8 : if (!bSolarMutexLocked)
287 : : {
288 : 8 : GetScImport().LockSolarMutex();
289 : 8 : bSolarMutexLocked = true;
290 : : }
291 : 8 : }
292 : :
293 : 10481 : void ScXMLTableRowCellContext::UnlockSolarMutex()
294 : : {
295 [ + + ]: 10481 : if (bSolarMutexLocked)
296 : : {
297 : 8 : GetScImport().UnlockSolarMutex();
298 : 8 : bSolarMutexLocked = false;
299 : : }
300 : 10481 : }
301 : :
302 : : namespace {
303 : :
304 : 31622 : bool cellExists( const ScAddress& rCellPos )
305 : : {
306 : 63244 : return( rCellPos.Col() >= 0 && rCellPos.Row() >= 0 &&
307 [ + - ][ + - ]: 63244 : rCellPos.Col() <= MAXCOL && rCellPos.Row() <= MAXROW );
[ + - + - ]
308 : : }
309 : :
310 : : }
311 : :
312 : 6 : void ScXMLTableRowCellContext::SetCursorOnTextImport(const rtl::OUString& rOUTempText)
313 : : {
314 : 6 : ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
315 [ + - ]: 6 : if (cellExists(aCellPos))
316 : : {
317 : 6 : sal_Int32 nCol = static_cast<sal_Int32>( aCellPos.Col() );
318 : 6 : sal_Int32 nRow = static_cast<sal_Int32>( aCellPos.Row() );
319 [ + - ]: 6 : uno::Reference<table::XCellRange> xCellRange(rXMLImport.GetTables().GetCurrentXCellRange());
320 [ + - ]: 6 : if (xCellRange.is())
321 : : {
322 [ + - ][ + - ]: 6 : xBaseCell.set( xCellRange->getCellByPosition(nCol, nRow) );
[ + - ]
323 [ + - ]: 6 : if (xBaseCell.is())
324 : : {
325 [ + - ]: 6 : xLockable.set(xBaseCell, uno::UNO_QUERY);
326 [ + - ]: 6 : if (xLockable.is())
327 [ + - ][ + - ]: 6 : xLockable->addActionLock();
328 [ + - ]: 6 : uno::Reference<text::XText> xText(xBaseCell, uno::UNO_QUERY);
329 [ + - ]: 6 : if (xText.is())
330 : : {
331 [ + - ][ + - ]: 6 : uno::Reference<text::XTextCursor> xTextCursor(xText->createTextCursor());
332 [ + - ]: 6 : if (xTextCursor.is())
333 : : {
334 [ + - ][ + - ]: 6 : xTextCursor->setString(rOUTempText);
335 [ + - ][ + - ]: 6 : xTextCursor->gotoEnd(false);
336 [ + - ][ + - ]: 6 : rXMLImport.GetTextImport()->SetCursor(xTextCursor);
[ + - ][ + - ]
337 : 6 : }
338 : 6 : }
339 : : }
340 : 6 : }
341 : : }
342 : : else
343 : : {
344 : : OSL_FAIL("this method should only be called for a existing cell");
345 : : }
346 : 6 : }
347 : :
348 : 5940 : SvXMLImportContext *ScXMLTableRowCellContext::CreateChildContext( sal_uInt16 nPrefix,
349 : : const ::rtl::OUString& rLName,
350 : : const ::com::sun::star::uno::Reference<
351 : : ::com::sun::star::xml::sax::XAttributeList>& xAttrList )
352 : : {
353 : 5940 : SvXMLImportContext *pContext = 0;
354 : :
355 : 5940 : const SvXMLTokenMap& rTokenMap = rXMLImport.GetTableRowCellElemTokenMap();
356 : 5940 : bool bTextP(false);
357 [ + - + - : 5940 : switch( rTokenMap.Get( nPrefix, rLName ) )
- + ]
358 : : {
359 : : case XML_TOK_TABLE_ROW_CELL_P:
360 : : {
361 : 5880 : bIsEmpty = false;
362 : 5880 : bTextP = true;
363 : :
364 : 5880 : ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
365 : :
366 [ + + ][ + + ]: 5880 : if( ((nCellType == util::NumberFormat::TEXT) || bFormulaTextResult) )
367 : : {
368 [ + + ]: 978 : if (!bHasTextImport)
369 : : {
370 : 975 : bIsFirstTextImport = true;
371 : 975 : bHasTextImport = true;
372 [ + - ][ + - ]: 975 : pContext = new ScXMLTextPContext(rXMLImport, nPrefix, rLName, xAttrList, this);
373 : : }
374 : : else
375 : : {
376 [ + - ]: 3 : if (cellExists(aCellPos))
377 : : {
378 [ + - ][ + - ]: 3 : if (bIsFirstTextImport && !rXMLImport.GetRemoveLastChar())
[ + - ]
379 : : {
380 [ + - ][ + - ]: 3 : if (pOUTextContent)
381 : : {
382 [ + - ][ + - ]: 3 : SetCursorOnTextImport(*pOUTextContent);
383 [ + - ]: 3 : pOUTextContent.reset();
384 : : }
385 : : else
386 [ # # ]: 0 : SetCursorOnTextImport(rtl::OUString());
387 : 3 : rXMLImport.SetRemoveLastChar(true);
388 [ + - ][ + - ]: 3 : uno::Reference < text::XTextCursor > xTextCursor(rXMLImport.GetTextImport()->GetCursor());
[ + - ][ + - ]
389 [ + - ]: 3 : if (xTextCursor.is())
390 : : {
391 [ + - ][ + - ]: 3 : uno::Reference < text::XText > xText (xTextCursor->getText());
392 [ + - ]: 3 : uno::Reference < text::XTextRange > xTextRange (xTextCursor, uno::UNO_QUERY);
393 [ + - ][ + - ]: 3 : if (xText.is() && xTextRange.is())
[ + - ]
394 [ + - ][ + - ]: 3 : xText->insertControlCharacter(xTextRange, text::ControlCharacter::PARAGRAPH_BREAK, false);
395 : 3 : }
396 : : }
397 : : pContext = rXMLImport.GetTextImport()->CreateTextChildContext(
398 [ + - ][ + - ]: 3 : rXMLImport, nPrefix, rLName, xAttrList);
[ + - ][ + - ]
399 : 3 : bIsFirstTextImport = false;
400 : : }
401 : : }
402 : : }
403 : : }
404 : 5880 : break;
405 : : case XML_TOK_TABLE_ROW_CELL_TABLE:
406 : : {
407 : : SAL_WARN("sc", "ScXMLTableRowCellContext::CreateChildContext: subtables are not supported");
408 : : }
409 : 0 : break;
410 : : case XML_TOK_TABLE_ROW_CELL_ANNOTATION:
411 : : {
412 : 8 : bIsEmpty = false;
413 : : OSL_ENSURE( !mxAnnotationData.get(), "ScXMLTableRowCellContext::CreateChildContext - multiple annotations in one cell" );
414 [ + - ]: 8 : mxAnnotationData.reset( new ScXMLAnnotationData );
415 : : pContext = new ScXMLAnnotationContext( rXMLImport, nPrefix, rLName,
416 [ + - ]: 8 : xAttrList, *mxAnnotationData, this);
417 : : }
418 : 8 : break;
419 : : case XML_TOK_TABLE_ROW_CELL_DETECTIVE:
420 : : {
421 : 0 : bIsEmpty = false;
422 [ # # ]: 0 : if (!pDetectiveObjVec)
423 [ # # ]: 0 : pDetectiveObjVec = new ScMyImpDetectiveObjVec();
424 : : pContext = new ScXMLDetectiveContext(
425 [ # # ]: 0 : rXMLImport, nPrefix, rLName, pDetectiveObjVec );
426 : : }
427 : 0 : break;
428 : : case XML_TOK_TABLE_ROW_CELL_CELL_RANGE_SOURCE:
429 : : {
430 : 0 : bIsEmpty = false;
431 [ # # ]: 0 : if (!pCellRangeSource)
432 [ # # ]: 0 : pCellRangeSource = new ScMyImpCellRangeSource();
433 : : pContext = new ScXMLCellRangeSourceContext(
434 [ # # ]: 0 : rXMLImport, nPrefix, rLName, xAttrList, pCellRangeSource );
435 : : }
436 : 0 : break;
437 : : }
438 : :
439 [ + + ][ + + ]: 5940 : if (!pContext && !bTextP)
440 : : {
441 : 52 : ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
442 [ + - ]: 52 : uno::Reference<drawing::XShapes> xShapes (rXMLImport.GetTables().GetCurrentXShapes());
443 [ + - ]: 52 : if (xShapes.is())
444 : : {
445 [ - + ]: 52 : if (aCellPos.Col() > MAXCOL)
446 : 0 : aCellPos.SetCol(MAXCOL);
447 [ - + ]: 52 : if (aCellPos.Row() > MAXROW)
448 : 0 : aCellPos.SetRow(MAXROW);
449 : : XMLTableShapeImportHelper* pTableShapeImport =
450 [ + - ][ + - ]: 52 : static_cast< XMLTableShapeImportHelper* >( rXMLImport.GetShapeImport().get() );
451 : 52 : pTableShapeImport->SetOnTable(false);
452 : 52 : com::sun::star::table::CellAddress aCellAddress;
453 : 52 : ScUnoConversion::FillApiAddress( aCellAddress, aCellPos );
454 : 52 : pTableShapeImport->SetCell(aCellAddress);
455 : : pContext = rXMLImport.GetShapeImport()->CreateGroupChildContext(
456 [ + - ][ + - ]: 52 : rXMLImport, nPrefix, rLName, xAttrList, xShapes);
[ + - ]
457 [ + - ]: 52 : if (pContext)
458 : : {
459 : 52 : bIsEmpty = false;
460 [ + - ]: 52 : rXMLImport.ProgressBarIncrement(false);
461 : : }
462 : 52 : }
463 : : }
464 : :
465 [ + + ]: 5940 : if( !pContext )
466 [ + - ]: 4902 : pContext = new SvXMLImportContext( GetImport(), nPrefix, rLName );
467 : :
468 : 5940 : return pContext;
469 : : }
470 : :
471 : 15 : void ScXMLTableRowCellContext::DoMerge( const ScAddress& rScAddress, const SCCOL nCols, const SCROW nRows )
472 : : {
473 : 15 : SCCOL mergeToCol = rScAddress.Col() + nCols;
474 : 15 : SCROW mergeToRow = rScAddress.Row() + nRows;
475 : 30 : bool bInBounds = rScAddress.Col() <= MAXCOL && rScAddress.Row() <= MAXROW &&
476 [ + - ][ + - ]: 30 : mergeToCol <= MAXCOL && mergeToRow <= MAXROW;
[ + - + - ]
477 [ + - ]: 15 : if( bInBounds )
478 : : {
479 : 15 : rXMLImport.GetDocument()->DoMerge( rScAddress.Tab(),
480 : 30 : rScAddress.Col(), rScAddress.Row(), mergeToCol, mergeToRow );
481 : : }
482 : 15 : }
483 : :
484 : : namespace {
485 : :
486 : 42 : ScValidationMode validationTypeToMode( const sheet::ValidationType eVType )
487 : : {
488 : : ScValidationMode eMode;
489 [ + + - - : 42 : switch( eVType )
- - - - ]
490 : : {
491 : 30 : case sheet::ValidationType_WHOLE: eMode = SC_VALID_WHOLE; break;
492 : 12 : case sheet::ValidationType_DECIMAL: eMode = SC_VALID_DECIMAL; break;
493 : 0 : case sheet::ValidationType_DATE: eMode = SC_VALID_DATE; break;
494 : 0 : case sheet::ValidationType_TIME: eMode = SC_VALID_TIME; break;
495 : 0 : case sheet::ValidationType_TEXT_LEN: eMode = SC_VALID_TEXTLEN; break;
496 : 0 : case sheet::ValidationType_LIST: eMode = SC_VALID_LIST; break;
497 : 0 : case sheet::ValidationType_CUSTOM: eMode = SC_VALID_CUSTOM; break;
498 : 0 : default: eMode = SC_VALID_ANY; break;
499 : : }
500 : 42 : return eMode;
501 : : }
502 : :
503 : 42 : ScValidErrorStyle validAlertToValidError( const sheet::ValidationAlertStyle eVAlertStyle )
504 : : {
505 : : ScValidErrorStyle eVErrStyle;
506 [ + + - - ]: 42 : switch( eVAlertStyle )
507 : : {
508 : 30 : case sheet::ValidationAlertStyle_STOP: eVErrStyle = SC_VALERR_STOP; break;
509 : 12 : case sheet::ValidationAlertStyle_WARNING: eVErrStyle = SC_VALERR_WARNING; break;
510 : 0 : case sheet::ValidationAlertStyle_MACRO: eVErrStyle = SC_VALERR_MACRO; break;
511 : 0 : default: eVErrStyle = SC_VALERR_INFO; break;
512 : : //should INFO be the default? seems to be the most unobtrusive choice.
513 : : }
514 : 42 : return eVErrStyle;
515 : : }
516 : :
517 : 42 : ScConditionMode conditionOpToMode( const sheet::ConditionOperator eOp )
518 : : {
519 : : ScConditionMode eMode;
520 [ - - + - : 42 : switch( eOp )
- - + - -
- ]
521 : : {
522 : 0 : case sheet::ConditionOperator_EQUAL: eMode = SC_COND_EQUAL; break;
523 : 0 : case sheet::ConditionOperator_NOT_EQUAL: eMode = SC_COND_NOTEQUAL; break;
524 : 12 : case sheet::ConditionOperator_GREATER: eMode = SC_COND_GREATER; break;
525 : 0 : case sheet::ConditionOperator_GREATER_EQUAL: eMode = SC_COND_EQGREATER; break;
526 : 0 : case sheet::ConditionOperator_LESS: eMode = SC_COND_LESS; break;
527 : 0 : case sheet::ConditionOperator_LESS_EQUAL: eMode = SC_COND_EQLESS; break;
528 : 30 : case sheet::ConditionOperator_BETWEEN: eMode = SC_COND_BETWEEN; break;
529 : 0 : case sheet::ConditionOperator_NOT_BETWEEN: eMode = SC_COND_NOTBETWEEN; break;
530 : 0 : case sheet::ConditionOperator_FORMULA: eMode = SC_COND_DIRECT; break;
531 : 0 : default: eMode = SC_COND_NONE; break;
532 : : }
533 : 42 : return eMode;
534 : : }
535 : :
536 : : }
537 : :
538 : 10481 : void ScXMLTableRowCellContext::SetContentValidation( const ScRange& rScRange )
539 : : {
540 [ + + ][ + - ]: 10481 : if( pContentValidationName && !pContentValidationName->isEmpty() )
[ + + ]
541 : : {
542 : 42 : ScDocument* pDoc = rXMLImport.GetDocument();
543 : 42 : ScMyImportValidation aValidation;
544 : 42 : aValidation.eGrammar1 = aValidation.eGrammar2 = pDoc->GetStorageGrammar();
545 [ + - ][ + - ]: 42 : if( rXMLImport.GetValidation(*pContentValidationName, aValidation) )
546 : : {
547 : : ScValidationData aScValidationData(
548 : : validationTypeToMode(aValidation.aValidationType),
549 : : conditionOpToMode(aValidation.aOperator),
550 : : aValidation.sFormula1, aValidation.sFormula2, pDoc, ScAddress(),
551 : : aValidation.sFormulaNmsp1, aValidation.sFormulaNmsp2,
552 : : aValidation.eGrammar1, aValidation.eGrammar2
553 [ + - ][ + - ]: 42 : );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
554 : :
555 [ + - ]: 42 : aScValidationData.SetIgnoreBlank( aValidation.bIgnoreBlanks );
556 : 42 : aScValidationData.SetListType( aValidation.nShowList );
557 : :
558 : : // set strings for error / input even if disabled (and disable afterwards)
559 [ + - ][ + - ]: 42 : aScValidationData.SetInput( aValidation.sImputTitle, aValidation.sImputMessage );
[ + - ][ + - ]
[ + - ]
560 [ + - ]: 42 : if( !aValidation.bShowImputMessage )
561 [ + - ]: 42 : aScValidationData.ResetInput();
562 [ + - ][ + - ]: 42 : aScValidationData.SetError( aValidation.sErrorTitle, aValidation.sErrorMessage, validAlertToValidError(aValidation.aAlertStyle) );
[ + - ][ + - ]
[ + - ]
563 [ - + ]: 42 : if( !aValidation.bShowErrorMessage )
564 [ # # ]: 0 : aScValidationData.ResetError();
565 : :
566 [ + - ]: 42 : if( !aValidation.sBaseCellAddress.isEmpty() )
567 [ + - ][ + - ]: 42 : aScValidationData.SetSrcString( aValidation.sBaseCellAddress );
[ + - ]
568 : :
569 [ + - ]: 42 : sal_uLong nIndex = pDoc->AddValidationEntry( aScValidationData );
570 : :
571 [ + - ][ + - ]: 42 : ScPatternAttr aPattern( pDoc->GetPool() );
572 [ + - ][ + - ]: 42 : aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_VALIDDATA, nIndex ) );
[ + - ]
573 [ + + ]: 42 : if( rScRange.aStart == rScRange.aEnd ) //for a single cell
574 : : {
575 : 27 : pDoc->ApplyPattern( rScRange.aStart.Col(), rScRange.aStart.Row(),
576 [ + - ]: 54 : rScRange.aStart.Tab(), aPattern );
577 : : }
578 : : else //for repeating cells
579 : : {
580 : 15 : pDoc->ApplyPatternAreaTab( rScRange.aStart.Col(), rScRange.aStart.Row(),
581 : 15 : rScRange.aEnd.Col(), rScRange.aEnd.Row(),
582 [ + - ]: 45 : rScRange.aStart.Tab(), aPattern );
583 : : }
584 : :
585 : : // is the below still needed?
586 : : // For now, any sheet with validity is blocked from stream-copying.
587 : : // Later, the validation names could be stored along with the style names.
588 [ + - ][ + - ]: 42 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(GetImport().GetModel())->GetSheetSaveData();
589 [ + - ][ + - ]: 42 : pSheetData->BlockSheet( GetScImport().GetTables().GetCurrentSheet() );
[ + - ]
590 : 42 : }
591 : : }
592 : 10481 : }
593 : :
594 : 9391 : void ScXMLTableRowCellContext::SetContentValidation( const ScAddress& rCellPos )
595 : : {
596 [ + - ]: 9391 : SetContentValidation( ScRange(rCellPos, rCellPos) );
597 : 9391 : }
598 : :
599 : 5972 : void ScXMLTableRowCellContext::SetAnnotation(const ScAddress& rPos)
600 : : {
601 : 5972 : ScDocument* pDoc = rXMLImport.GetDocument();
602 [ + + ][ + + ]: 5972 : if( !pDoc || !mxAnnotationData.get() )
[ + - ]
603 : 5972 : return;
604 : :
605 [ + - ]: 8 : LockSolarMutex();
606 : :
607 : 8 : ScPostIt* pNote = 0;
608 : :
609 [ + - ]: 8 : uno::Reference< drawing::XShapes > xShapes = rXMLImport.GetTables().GetCurrentXShapes();
610 [ + - ]: 8 : uno::Reference< container::XIndexAccess > xShapesIA( xShapes, uno::UNO_QUERY );
611 [ + - ][ + - ]: 8 : sal_Int32 nOldShapeCount = xShapesIA.is() ? xShapesIA->getCount() : 0;
[ + - ]
612 : :
613 : : OSL_ENSURE( !mxAnnotationData->mxShape.is() || mxAnnotationData->mxShapes.is(),
614 : : "ScXMLTableRowCellContext::SetAnnotation - shape without drawing page" );
615 [ + - ][ + - ]: 8 : if( mxAnnotationData->mxShape.is() && mxAnnotationData->mxShapes.is() )
[ + - ]
616 : : {
617 : : OSL_ENSURE( mxAnnotationData->mxShapes.get() == xShapes.get(), "ScXMLTableRowCellContext::SetAnnotation - diffenet drawing pages" );
618 : 8 : SdrObject* pObject = ::GetSdrObjectFromXShape( mxAnnotationData->mxShape );
619 : : OSL_ENSURE( pObject, "ScXMLTableRowCellContext::SetAnnotation - cannot get SdrObject from shape" );
620 : :
621 : : /* Try to reuse the drawing object already created (but only if the
622 : : note is visible, and the object is a caption object). */
623 [ - + ][ - + ]: 8 : if( mxAnnotationData->mbShown && mxAnnotationData->mbUseShapePos )
[ + + ]
624 : : {
625 [ # # ][ # # ]: 0 : if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
626 : : {
627 : : OSL_ENSURE( !pCaption->GetLogicRect().IsEmpty(), "ScXMLTableRowCellContext::SetAnnotation - invalid caption rectangle" );
628 : : // create the cell note with the caption object
629 [ # # ]: 0 : pNote = ScNoteUtil::CreateNoteFromCaption( *pDoc, rPos, *pCaption, true );
630 : : // forget pointer to object (do not create note again below)
631 : 0 : pObject = 0;
632 : : }
633 : : }
634 : :
635 : : // drawing object has not been used to create a note -> use shape data
636 [ + - ]: 8 : if( pObject )
637 : : {
638 : : // rescue settings from drawing object before the shape is removed
639 [ + - ][ + - ]: 8 : ::std::auto_ptr< SfxItemSet > xItemSet( new SfxItemSet( pObject->GetMergedItemSet() ) );
[ + - ]
640 : 8 : ::std::auto_ptr< OutlinerParaObject > xOutlinerObj;
641 [ + - ][ + - ]: 8 : if( OutlinerParaObject* pOutlinerObj = pObject->GetOutlinerParaObject() )
642 [ + - ][ + - ]: 8 : xOutlinerObj.reset( new OutlinerParaObject( *pOutlinerObj ) );
643 [ + - ]: 8 : Rectangle aCaptionRect;
644 [ + + ]: 8 : if( mxAnnotationData->mbUseShapePos )
645 [ + - ]: 3 : aCaptionRect = pObject->GetLogicRect();
646 : : // remove the shape from the drawing page, this invalidates pObject
647 [ + - ][ + - ]: 8 : mxAnnotationData->mxShapes->remove( mxAnnotationData->mxShape );
648 : 8 : pObject = 0;
649 : : // update current number of existing objects
650 [ + - ]: 8 : if( xShapesIA.is() )
651 [ + - ][ + - ]: 8 : nOldShapeCount = xShapesIA->getCount();
652 : :
653 : : // an outliner object is required (empty note captions not allowed)
654 [ + - ]: 8 : if( xOutlinerObj.get() )
655 : : {
656 : : // create cell note with all data from drawing object
657 : : pNote = ScNoteUtil::CreateNoteFromObjectData( *pDoc, rPos,
658 : : xItemSet.release(), xOutlinerObj.release(),
659 [ + - ]: 8 : aCaptionRect, mxAnnotationData->mbShown, false );
660 [ + - ][ + - ]: 8 : }
661 : : }
662 : : }
663 [ # # ]: 0 : else if( !mxAnnotationData->maSimpleText.isEmpty() )
664 : : {
665 : : // create note from simple text
666 : : pNote = ScNoteUtil::CreateNoteFromString( *pDoc, rPos,
667 [ # # ]: 0 : mxAnnotationData->maSimpleText, mxAnnotationData->mbShown, false );
668 : : }
669 : :
670 : : // set author and date
671 [ + - ]: 8 : if( pNote )
672 : : {
673 : : double fDate;
674 [ + - ]: 8 : rXMLImport.GetMM100UnitConverter().convertDateTime( fDate, mxAnnotationData->maCreateDate );
675 [ + - ]: 8 : SvNumberFormatter* pNumForm = pDoc->GetFormatTable();
676 [ + - ]: 8 : sal_uInt32 nfIndex = pNumForm->GetFormatIndex( NF_DATE_SYS_DDMMYYYY, LANGUAGE_SYSTEM );
677 [ + - ]: 8 : String aDate;
678 : 8 : Color* pColor = 0;
679 : 8 : Color** ppColor = &pColor;
680 [ + - ]: 8 : pNumForm->GetOutputString( fDate, nfIndex, aDate, ppColor );
681 [ + - ]: 8 : pNote->SetDate( aDate );
682 [ + - ]: 8 : pNote->SetAuthor( mxAnnotationData->maAuthor );
683 : : }
684 : :
685 : : // register a shape that has been newly created in the ScNoteUtil functions
686 [ + - ][ + - ]: 8 : if( xShapesIA.is() && (nOldShapeCount < xShapesIA->getCount()) )
[ + - ][ + + ]
[ + + ]
687 : : {
688 : 5 : uno::Reference< drawing::XShape > xShape;
689 [ + - ][ + - ]: 5 : rXMLImport.GetShapeImport()->shapeWithZIndexAdded( xShape, xShapesIA->getCount() );
[ + - ][ + - ]
[ + - ]
690 : : }
691 : :
692 : : // store the style names for stream copying
693 [ + - ][ + - ]: 8 : ScSheetSaveData* pSheetData = ScModelObj::getImplementation(rXMLImport.GetModel())->GetSheetSaveData();
694 [ + - ]: 8 : pSheetData->HandleNoteStyles( mxAnnotationData->maStyleName, mxAnnotationData->maTextStyle, rPos );
695 : :
696 [ + - ]: 8 : std::vector<ScXMLAnnotationStyleEntry>::const_iterator aIter = mxAnnotationData->maContentStyles.begin();
697 [ + - ]: 8 : std::vector<ScXMLAnnotationStyleEntry>::const_iterator aEnd = mxAnnotationData->maContentStyles.end();
698 [ + - ][ + + ]: 11 : while (aIter != aEnd)
699 : : {
700 [ + - ]: 3 : pSheetData->AddNoteContentStyle( aIter->mnFamily, aIter->maName, rPos, aIter->maSelection );
701 : 3 : ++aIter;
702 : 5972 : }
703 : : }
704 : :
705 : : // core implementation
706 : 5972 : void ScXMLTableRowCellContext::SetDetectiveObj( const ScAddress& rPosition )
707 : : {
708 [ + - ][ - + ]: 5972 : if( cellExists(rPosition) && pDetectiveObjVec && pDetectiveObjVec->size() )
[ # # ][ - + ]
709 : : {
710 [ # # ]: 0 : LockSolarMutex();
711 : 0 : ScDetectiveFunc aDetFunc( rXMLImport.GetDocument(), rPosition.Tab() );
712 [ # # ][ # # ]: 0 : uno::Reference<container::XIndexAccess> xShapesIndex (rXMLImport.GetTables().GetCurrentXShapes(), uno::UNO_QUERY); // make draw page
713 : 0 : ScMyImpDetectiveObjVec::iterator aItr(pDetectiveObjVec->begin());
714 : 0 : ScMyImpDetectiveObjVec::iterator aEndItr(pDetectiveObjVec->end());
715 [ # # ][ # # ]: 0 : while(aItr != aEndItr)
716 : : {
717 [ # # ]: 0 : aDetFunc.InsertObject( aItr->eObjType, rPosition, aItr->aSourceRange, aItr->bHasError );
718 [ # # ]: 0 : if (xShapesIndex.is())
719 : : {
720 [ # # ][ # # ]: 0 : sal_Int32 nShapes = xShapesIndex->getCount();
721 : 0 : uno::Reference < drawing::XShape > xShape;
722 [ # # ][ # # ]: 0 : rXMLImport.GetShapeImport()->shapeWithZIndexAdded(xShape, nShapes);
[ # # ]
723 : : }
724 : 0 : ++aItr;
725 : 0 : }
726 : : }
727 : 5972 : }
728 : :
729 : : // core implementation
730 : 5972 : void ScXMLTableRowCellContext::SetCellRangeSource( const ScAddress& rPosition )
731 : : {
732 [ + - ][ - + ]: 5972 : if( cellExists(rPosition) && pCellRangeSource && !pCellRangeSource->sSourceStr.isEmpty() &&
[ # # # #
# # ][ - + ]
733 : 0 : !pCellRangeSource->sFilterName.isEmpty() && !pCellRangeSource->sURL.isEmpty() )
734 : : {
735 : 0 : ScDocument* pDoc = rXMLImport.GetDocument();
736 [ # # ]: 0 : if (pDoc)
737 : : {
738 [ # # ]: 0 : LockSolarMutex();
739 : 0 : ScRange aDestRange( rPosition.Col(), rPosition.Row(), rPosition.Tab(),
740 : 0 : rPosition.Col() + static_cast<SCCOL>(pCellRangeSource->nColumns - 1),
741 : 0 : rPosition.Row() + static_cast<SCROW>(pCellRangeSource->nRows - 1), rPosition.Tab() );
742 [ # # ]: 0 : String sFilterName( pCellRangeSource->sFilterName );
743 [ # # ]: 0 : String sSourceStr( pCellRangeSource->sSourceStr );
744 : : ScAreaLink* pLink = new ScAreaLink( pDoc->GetDocumentShell(), pCellRangeSource->sURL,
745 [ # # ][ # # ]: 0 : sFilterName, pCellRangeSource->sFilterOptions, sSourceStr, aDestRange, pCellRangeSource->nRefresh );
[ # # ][ # # ]
[ # # ][ # # ]
746 [ # # ]: 0 : sfx2::LinkManager* pLinkManager = pDoc->GetLinkManager();
747 [ # # ][ # # ]: 0 : pLinkManager->InsertFileLink( *pLink, OBJECT_CLIENT_FILE, pCellRangeSource->sURL, &sFilterName, &sSourceStr );
[ # # ][ # # ]
[ # # ]
748 : : }
749 : : }
750 : 5972 : }
751 : :
752 : 1172 : void ScXMLTableRowCellContext::SetFormulaCell(ScFormulaCell* pFCell) const
753 : : {
754 [ + - ]: 1172 : if(pFCell)
755 : : {
756 [ + + ][ + + ]: 1172 : if( bFormulaTextResult && pOUTextValue )
[ + + ]
757 : 148 : pFCell->SetHybridString( *pOUTextValue );
758 : : else
759 : 1024 : pFCell->SetHybridDouble( fValue );
760 : 1172 : pFCell->ResetDirty();
761 : : }
762 : 1172 : }
763 : :
764 : 841 : void ScXMLTableRowCellContext::PutTextCell( const ScAddress& rCurrentPos,
765 : : const SCCOL nCurrentCol, const ::boost::optional< rtl::OUString >& pOUText )
766 : : {
767 : 841 : bool bDoIncrement = true;
768 : : //matrix reference cells that contain text formula results;
769 : : //cell was already put in document, just need to set text here.
770 [ + + ]: 841 : if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
771 : : {
772 : 30 : ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
773 [ + - ][ + - ]: 30 : bDoIncrement = ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA );
774 [ + - ]: 30 : if ( bDoIncrement )
775 : : {
776 [ + - ]: 30 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
777 [ + - ][ + + ]: 30 : if (pOUTextValue && !pOUTextValue->isEmpty())
[ + + ]
778 : 24 : pFCell->SetHybridString( *pOUTextValue );
779 [ + - ][ - + ]: 6 : else if (pOUTextContent && !pOUTextContent->isEmpty())
[ - + ]
780 : 0 : pFCell->SetHybridString( *pOUTextContent );
781 [ - + ][ # # ]: 6 : else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
[ # # ][ - + ]
782 : 0 : pFCell->SetHybridString( *pOUText );
783 : : else
784 : 6 : bDoIncrement = false;
785 : 30 : pFCell->ResetDirty();
786 : : }
787 : : }
788 : : else //regular text cells
789 : : {
790 : 811 : ScBaseCell* pNewCell = NULL;
791 : 811 : ScDocument* pDoc = rXMLImport.GetDocument();
792 [ # # ][ - + ]: 811 : if (pOUTextValue && !pOUTextValue->isEmpty())
[ - + ]
793 : 0 : pNewCell = ScBaseCell::CreateTextCell( *pOUTextValue, pDoc );
794 [ + + ][ + - ]: 811 : else if (pOUTextContent && !pOUTextContent->isEmpty())
[ + + ]
795 : 748 : pNewCell = ScBaseCell::CreateTextCell( *pOUTextContent, pDoc );
796 [ + + ][ + - ]: 63 : else if ( nCurrentCol > 0 && pOUText && !pOUText->isEmpty() )
[ - + ][ - + ]
797 : 0 : pNewCell = ScBaseCell::CreateTextCell( *pOUText, pDoc );
798 : :
799 : 811 : bDoIncrement = pNewCell != NULL;
800 [ + + ]: 811 : if ( bDoIncrement )
801 : 748 : pDoc->PutCell( rCurrentPos, pNewCell );
802 : : }
803 : : // #i56027# This is about setting simple text, not edit cells,
804 : : // so ProgressBarIncrement must be called with bEditCell = FALSE.
805 : : // Formatted text that is put into the cell by the child context
806 : : // is handled in AddCellsToTable() (bIsEmpty is true then).
807 [ + + ][ + + ]: 841 : if (bDoIncrement || bHasTextImport)
808 : 778 : rXMLImport.ProgressBarIncrement(false);
809 : 841 : }
810 : :
811 : 4064 : void ScXMLTableRowCellContext::PutValueCell( const ScAddress& rCurrentPos )
812 : : {
813 : : //matrix reference cells that contain value formula results;
814 : : //cell was already put in document, just need to set value here.
815 [ + + ]: 4064 : if( rXMLImport.GetTables().IsPartOfMatrix(rCurrentPos) )
816 : : {
817 : 105 : ScBaseCell* pCell = rXMLImport.GetDocument()->GetCell( rCurrentPos );
818 [ + - ][ + - ]: 105 : if ( pCell && pCell->GetCellType() == CELLTYPE_FORMULA )
[ + - ]
819 : : {
820 [ + - ]: 105 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
821 : 105 : SetFormulaCell(pFCell);
822 : : }
823 : : }
824 : : else //regular value cell
825 : : {
826 : : // #i62435# Initialize the value cell's script type
827 : : // if the default style's number format is latin-only.
828 : : // If the cell uses a different format, the script type
829 : : // will be reset when the style is applied.
830 : :
831 [ + - ]: 3959 : ScBaseCell* pNewCell = new ScValueCell(fValue);
832 [ + - ]: 3959 : if ( rXMLImport.IsLatinDefaultStyle() )
833 : 3959 : pNewCell->SetScriptType( SCRIPTTYPE_LATIN );
834 : : rXMLImport.GetDocument()->PutCell(
835 : 3959 : rCurrentPos.Col(), rCurrentPos.Row(),
836 : 7918 : rCurrentPos.Tab(), pNewCell );
837 : : }
838 : 4064 : rXMLImport.ProgressBarIncrement(false);
839 : 4064 : }
840 : :
841 : : namespace {
842 : :
843 : 0 : bool isEmptyOrNote( ScDocument* pDoc, const ScAddress& rCurrentPos )
844 : : {
845 : 0 : ScBaseCell* pCell = pDoc->GetCell( rCurrentPos );
846 [ # # ][ # # ]: 0 : return ( !pCell || pCell->GetCellType() == CELLTYPE_NOTE );
847 : : }
848 : :
849 : : }
850 : :
851 : 9414 : void ScXMLTableRowCellContext::AddTextAndValueCells( const ScAddress& rCellPos,
852 : : const ::boost::optional< rtl::OUString >& pOUText, ScAddress& rCurrentPos )
853 : : {
854 : 9414 : ScMyTables& rTables = rXMLImport.GetTables();
855 : 9414 : bool bWasEmpty = bIsEmpty;
856 [ + + ]: 26776 : for (SCCOL i = 0; i < nColsRepeated; ++i)
857 : : {
858 : 17362 : rCurrentPos.SetCol( rCellPos.Col() + i );
859 [ + + ]: 17362 : if (i > 0)
860 : 7948 : rTables.AddColumn(false);
861 [ + + ]: 17362 : if (!bIsEmpty)
862 : : {
863 [ + + ]: 9792 : for (SCROW j = 0; j < nRepeatedRows; ++j)
864 : : {
865 : 4905 : rCurrentPos.SetRow( rCellPos.Row() + j );
866 [ - + ][ - + ]: 4905 : if( (rCurrentPos.Col() == 0) && (j > 0) )
[ + + ]
867 : : {
868 : 0 : rTables.AddRow();
869 : 0 : rTables.AddColumn(false);
870 : : }
871 [ + - ]: 4905 : if( cellExists(rCurrentPos) )
872 : : {
873 [ - + ][ # # ]: 4905 : if( ( !(bIsCovered) || isEmptyOrNote(rXMLImport.GetDocument(), rCurrentPos) ) )
[ + - ]
874 : : {
875 [ + + - ]: 4905 : switch (nCellType)
876 : : {
877 : : case util::NumberFormat::TEXT:
878 : : {
879 : 841 : PutTextCell( rCurrentPos, i, pOUText );
880 : : }
881 : 841 : break;
882 : : case util::NumberFormat::NUMBER:
883 : : case util::NumberFormat::PERCENT:
884 : : case util::NumberFormat::CURRENCY:
885 : : case util::NumberFormat::TIME:
886 : : case util::NumberFormat::DATETIME:
887 : : case util::NumberFormat::LOGICAL:
888 : : {
889 : 4064 : PutValueCell( rCurrentPos );
890 : : }
891 : 4064 : break;
892 : : default:
893 : : {
894 : : OSL_FAIL("no cell type given");
895 : : }
896 : 4905 : break;
897 : : }
898 : : }
899 : :
900 : 4905 : SetAnnotation( rCurrentPos );
901 : 4905 : SetDetectiveObj( rCurrentPos );
902 : 4905 : SetCellRangeSource( rCurrentPos );
903 : : }
904 : : else
905 : : {
906 [ # # ][ # # ]: 0 : if (!bWasEmpty || mxAnnotationData.get())
[ # # ]
907 : : {
908 [ # # ]: 0 : if (rCurrentPos.Row() > MAXROW)
909 : 0 : rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
910 : : else
911 : 0 : rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
912 : : }
913 : : }
914 : : }
915 : : }
916 : : else
917 : : {
918 : : // #i56027# If the child context put formatted text into the cell,
919 : : // bIsEmpty is true and ProgressBarIncrement has to be called
920 : : // with bEditCell = TRUE.
921 [ + + ]: 12475 : if (bHasTextImport)
922 : 6 : rXMLImport.ProgressBarIncrement(true);
923 [ + + ][ + + ]: 12475 : if ((i == 0) && (rCellPos.Col() == 0))
[ + + ]
924 : : {
925 [ + + ]: 6292279 : for (sal_Int32 j = 1; j < nRepeatedRows; ++j)
926 : : {
927 : 6291687 : rTables.AddRow();
928 : 6291687 : rTables.AddColumn(false);
929 : : }
930 : : }
931 : : }
932 : : }
933 : 9414 : }
934 : :
935 : 9414 : bool ScXMLTableRowCellContext::HasSpecialContent() const
936 : : {
937 : 42 : return ( (pContentValidationName && !pContentValidationName->isEmpty()) ||
938 [ + + - + ]: 9456 : mxAnnotationData.get() || pDetectiveObjVec || pCellRangeSource );
[ + + ][ + - ]
[ - + ]
939 : : }
940 : :
941 : 14787 : bool ScXMLTableRowCellContext::CellsAreRepeated() const
942 : : {
943 [ + + ][ + + ]: 14787 : return ( (nColsRepeated > 1) || (nRepeatedRows > 1) );
944 : : }
945 : :
946 : : namespace {
947 : :
948 : : // from ScCellObj::GetOutputString_Imp(). all of it may not be necessary.
949 : 1079 : rtl::OUString getOutputString(ScDocument* pDoc, const ScAddress& aCellPos)
950 : : {
951 : 1079 : rtl::OUString aVal;
952 [ + - ]: 1079 : if ( pDoc )
953 : : {
954 [ + - ]: 1079 : ScBaseCell* pCell = pDoc->GetCell( aCellPos );
955 [ - + ][ # # ]: 1079 : if ( pCell && pCell->GetCellType() != CELLTYPE_NOTE )
[ - + ]
956 : : {
957 [ # # ]: 0 : if ( pCell->GetCellType() == CELLTYPE_EDIT )
958 : : {
959 : : // GetString an der EditCell macht Leerzeichen aus Umbruechen,
960 : : // hier werden die Umbrueche aber gebraucht
961 : 0 : const EditTextObject* pData = ( static_cast< ScEditCell* >(pCell) )->GetData();
962 [ # # ]: 0 : if (pData)
963 : : {
964 [ # # ]: 0 : EditEngine& rEngine = pDoc->GetEditEngine();
965 [ # # ]: 0 : rEngine.SetText( *pData );
966 [ # # ][ # # ]: 0 : aVal = rEngine.GetText( LINEEND_LF );
[ # # ]
967 : : }
968 : : // Edit-Zellen auch nicht per NumberFormatter formatieren
969 : : // (passend zur Ausgabe)
970 : : }
971 : : else
972 : : {
973 : : // wie in GetString am Dokument (column)
974 : : Color* pColor;
975 [ # # ]: 0 : sal_uLong nNumFmt = pDoc->GetNumberFormat( aCellPos );
976 [ # # ][ # # ]: 0 : ScCellFormat::GetString( pCell, nNumFmt, aVal, &pColor, *pDoc->GetFormatTable() );
977 : : }
978 : : }
979 : : }
980 : 1079 : return aVal;
981 : : }
982 : :
983 : : }
984 : :
985 : 9414 : void ScXMLTableRowCellContext::AddNonFormulaCells( const ScAddress& rCellPos )
986 : : {
987 [ + - ]: 9414 : ::boost::optional< rtl::OUString > pOUText;
988 : :
989 [ + + ]: 9414 : if( nCellType == util::NumberFormat::TEXT )
990 : : {
991 [ + - ][ + + ]: 5373 : if( cellExists(rCellPos) && CellsAreRepeated() )
[ + + ]
992 [ + - ][ + - ]: 1079 : pOUText.reset( getOutputString(rXMLImport.GetDocument(), rCellPos) );
993 : :
994 [ + - ][ + + ]: 5373 : if( !pOUTextContent && !pOUText && !pOUTextValue )
[ + - ][ + + ]
[ + - ][ + - ]
[ + + ]
995 : 3534 : bIsEmpty = true;
996 : : }
997 : :
998 : 9414 : ScAddress aCurrentPos( rCellPos );
999 [ + + ]: 9414 : if( HasSpecialContent() )
1000 : 50 : bIsEmpty = false;
1001 : :
1002 [ + - ]: 9414 : AddTextAndValueCells( rCellPos, pOUText, aCurrentPos );
1003 : :
1004 [ + + ]: 9414 : if( CellsAreRepeated() )
1005 : : {
1006 [ + - ]: 1090 : SCCOL nStartCol( rCellPos.Col() < MAXCOL ? rCellPos.Col() : MAXCOL );
1007 [ + + ]: 1090 : SCROW nStartRow( rCellPos.Row() < MAXROW ? rCellPos.Row() : MAXROW );
1008 [ + - ]: 1090 : SCCOL nEndCol( rCellPos.Col() + nColsRepeated - 1 < MAXCOL ? rCellPos.Col() + nColsRepeated - 1 : MAXCOL );
1009 [ + + ]: 1090 : SCROW nEndRow( rCellPos.Row() + nRepeatedRows - 1 < MAXROW ? rCellPos.Row() + nRepeatedRows - 1 : MAXROW );
1010 : 1090 : ScRange aScRange( nStartCol, nStartRow, rCellPos.Tab(), nEndCol, nEndRow, rCellPos.Tab() );
1011 [ + - ]: 1090 : SetContentValidation( aScRange );
1012 [ + - ]: 1090 : rXMLImport.GetStylesImportHelper()->AddRange( aScRange );
1013 : : }
1014 [ + - ]: 8324 : else if( cellExists(rCellPos) )
1015 : : {
1016 [ + - ]: 8324 : rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
1017 [ + - ]: 8324 : SetContentValidation( rCellPos );
1018 [ + - ]: 9414 : }
1019 : 9414 : }
1020 : :
1021 : 992 : void ScXMLTableRowCellContext::PutFormulaCell( const ScAddress& rCellPos )
1022 : : {
1023 : 992 : ScDocument* pDoc = rXMLImport.GetDocument();
1024 : :
1025 [ + - ]: 992 : rtl::OUString aText = pOUFormula->first;
1026 [ + - ]: 992 : rtl::OUString aFormulaNmsp = pOUFormula->second;
1027 : :
1028 : 992 : ::boost::scoped_ptr<ScExternalRefManager::ApiGuard> pExtRefGuard;
1029 [ + - ][ + - ]: 992 : pExtRefGuard.reset(new ScExternalRefManager::ApiGuard(pDoc));
[ + - ]
1030 : :
1031 : 992 : ScBaseCell* pNewCell = NULL;
1032 : :
1033 [ + - ]: 992 : if ( !aText.isEmpty() )
1034 : : {
1035 [ + - ][ + - ]: 992 : if ( aText[0] == '=' && aText.getLength() > 1 )
[ + - ]
1036 : : {
1037 : : // temporary formula string as string tokens
1038 [ + - ][ + - ]: 992 : ScTokenArray* pCode = new ScTokenArray;
1039 [ + - ][ + - ]: 992 : pCode->AddStringXML( aText );
[ + - ]
1040 [ - + ][ # # ]: 992 : if( (eGrammar == formula::FormulaGrammar::GRAM_EXTERNAL) && !aFormulaNmsp.isEmpty() )
[ - + ]
1041 [ # # ][ # # ]: 0 : pCode->AddStringXML( aFormulaNmsp );
[ # # ]
1042 : :
1043 : 992 : pDoc->IncXMLImportedFormulaCount( aText.getLength() );
1044 [ + - ][ + - ]: 992 : pNewCell = new ScFormulaCell( pDoc, rCellPos, pCode, eGrammar, MM_NONE );
[ + - ]
1045 [ + - ][ + - ]: 992 : delete pCode;
1046 : :
1047 [ + - ]: 992 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pNewCell);
1048 [ + - ]: 992 : SetFormulaCell(pFCell);
1049 : : }
1050 [ # # ][ # # ]: 0 : else if ( aText[0] == '\'' && aText.getLength() > 1 )
[ # # ]
1051 : : {
1052 : : // for bEnglish, "'" at the beginning is always interpreted as text
1053 : : // marker and stripped
1054 [ # # ]: 0 : pNewCell = ScBaseCell::CreateTextCell( aText.copy( 1 ), pDoc );
1055 : : }
1056 : : else
1057 : : {
1058 [ # # ]: 0 : SvNumberFormatter* pFormatter = pDoc->GetFormatTable();
1059 [ # # ]: 0 : sal_uInt32 nEnglish = pFormatter->GetStandardIndex(LANGUAGE_ENGLISH_US);
1060 : : double fVal;
1061 [ # # ][ # # ]: 0 : if ( pFormatter->IsNumberFormat( aText, nEnglish, fVal ) )
[ # # ][ # # ]
1062 [ # # ][ # # ]: 0 : pNewCell = new ScValueCell( fVal );
1063 : : //the (english) number format will not be set
1064 : : //search matching local format and apply it
1065 : : else
1066 [ # # ]: 0 : pNewCell = ScBaseCell::CreateTextCell( aText, pDoc );
1067 : : }
1068 [ + - ]: 992 : pDoc->PutCell( rCellPos, pNewCell );
1069 [ + - ]: 992 : }
1070 : 992 : }
1071 : :
1072 : 1067 : void ScXMLTableRowCellContext::AddFormulaCell( const ScAddress& rCellPos )
1073 : : {
1074 [ + - ]: 1067 : if( cellExists(rCellPos) )
1075 : : {
1076 : 1067 : SetContentValidation( rCellPos );
1077 : : OSL_ENSURE(((nColsRepeated == 1) && (nRepeatedRows == 1)), "repeated cells with formula not possible now");
1078 : 1067 : rXMLImport.GetStylesImportHelper()->AddCell(rCellPos);
1079 : :
1080 : : //add matrix
1081 [ + + ]: 1067 : if(bIsMatrix)
1082 : : {
1083 [ + - ][ + - ]: 75 : if (nMatrixCols > 0 && nMatrixRows > 0)
1084 : : {
1085 : : //matrix cells are put in the document, but we must set the
1086 : : //value/text of each matrix cell later
1087 : 75 : rXMLImport.GetTables().AddMatrixRange(
1088 : 75 : rCellPos.Col(), rCellPos.Row(),
1089 : 75 : rCellPos.Col() + nMatrixCols - 1,
1090 : 75 : rCellPos.Row() + nMatrixRows - 1,
1091 : 225 : pOUFormula->first, pOUFormula->second, eGrammar);
1092 : :
1093 : : //set the value/text of the first matrix position (top-left).
1094 : : //the value/text of the matrix reference cells will be set later.
1095 : : ScFormulaCell* pFCell =
1096 [ + - ]: 75 : static_cast<ScFormulaCell*>( rXMLImport.GetDocument()->GetCell(rCellPos) );
1097 : 75 : SetFormulaCell(pFCell);
1098 : : }
1099 : : }
1100 : : else
1101 : 992 : PutFormulaCell( rCellPos );
1102 : :
1103 : 1067 : SetAnnotation( rCellPos );
1104 : 1067 : SetDetectiveObj( rCellPos );
1105 : 1067 : SetCellRangeSource( rCellPos );
1106 : 1067 : rXMLImport.ProgressBarIncrement(false);
1107 : : }
1108 : : else
1109 : : {
1110 [ # # ]: 0 : if (rCellPos.Row() > MAXROW)
1111 : 0 : rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_ROW_OVERFLOW);
1112 : : else
1113 : 0 : rXMLImport.SetRangeOverflowType(SCWARN_IMPORT_COLUMN_OVERFLOW);
1114 : : }
1115 : 1067 : }
1116 : :
1117 : : //There are cases where a formula cell is exported with an office:value of 0 or
1118 : : //no office:value at all, but the formula cell will have a text:p value which
1119 : : //contains the intended formula result.
1120 : : //These cases include when a formula result:
1121 : : // - is blank
1122 : : // - has a constant error value beginning with "#" (such as "#VALUE!" or "#N/A")
1123 : : // - has an "Err:[###]" (where "[###]" is an error number)
1124 : 236 : bool ScXMLTableRowCellContext::HasSpecialCaseFormulaText() const
1125 : : {
1126 [ + + ][ + - : 908 : if( pOUTextContent &&
+ + + + +
+ ]
1127 : 466 : ( pOUTextContent->isEmpty() || (pOUTextContent->indexOf("#") > -1) ||
1128 : 442 : (pOUTextContent->indexOf("Err:") > -1) )
1129 : : )
1130 : 86 : return true;
1131 : 236 : return false;
1132 : : }
1133 : :
1134 : :
1135 : 10481 : void ScXMLTableRowCellContext::EndElement()
1136 : : {
1137 [ + + ][ + + ]: 10481 : if( bHasTextImport && rXMLImport.GetRemoveLastChar() )
[ + + ]
1138 : : {
1139 [ + - ]: 6 : UniReference< XMLTextImportHelper > aTextImport = rXMLImport.GetTextImport();
1140 [ + - ][ + - ]: 6 : if( aTextImport->GetCursor().is() )
[ + - ]
1141 : : {
1142 [ + - ][ + - ]: 6 : if( aTextImport->GetCursor()->goLeft(1, true) )
[ + - ][ + - ]
[ + - ]
1143 : : {
1144 [ + - ][ + - ]: 6 : aTextImport->GetText()->insertString(
[ + - ]
1145 [ + - ][ + - ]: 6 : aTextImport->GetCursorAsRange(), rtl::OUString(), true );
[ + - ]
1146 : : }
1147 [ + - ][ + - ]: 6 : aTextImport->ResetCursor();
1148 [ + - ]: 6 : }
1149 : : }
1150 : :
1151 [ + + ][ + - ]: 10481 : if( bFormulaTextResult && HasSpecialCaseFormulaText() )
[ + + ][ + + ]
1152 : : {
1153 [ + - ][ + - ]: 86 : pOUTextValue.reset(*pOUTextContent);
1154 : 86 : nCellType = util::NumberFormat::TEXT;
1155 : : }
1156 : :
1157 : 10481 : ScAddress aCellPos = rXMLImport.GetTables().GetCurrentCellPos();
1158 [ + + ][ + + ]: 10481 : if( aCellPos.Col() > 0 && nRepeatedRows > 1 )
[ + + ]
1159 : 27 : aCellPos.SetRow( aCellPos.Row() - (nRepeatedRows - 1) );
1160 [ + + ]: 10481 : if( bIsMerged )
1161 [ + - ]: 15 : DoMerge( aCellPos, nMergedCols - 1, nMergedRows - 1 );
1162 [ + - ][ + + ]: 10481 : if( !pOUFormula )
1163 [ + - ]: 9414 : AddNonFormulaCells( aCellPos );
1164 : : else // if ( pOUFormula )
1165 [ + - ]: 1067 : AddFormulaCell( aCellPos );
1166 : :
1167 [ + - ]: 10481 : UnlockSolarMutex(); //if LockSolarMutex got used, we presumably need to ensure an UnlockSolarMutex
1168 : :
1169 : 10481 : bIsMerged = false;
1170 : 10481 : nMergedCols = 1;
1171 : 10481 : nMergedRows = 1;
1172 : 10481 : nColsRepeated = 1;
1173 : 10481 : }
1174 : :
1175 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|