Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "condformatbuffer.hxx"
21 :
22 : #include <com/sun/star/sheet/ConditionOperator2.hpp>
23 : #include <com/sun/star/table/CellAddress.hpp>
24 : #include <com/sun/star/table/CellRangeAddress.hpp>
25 : #include <rtl/ustrbuf.hxx>
26 : #include <osl/diagnose.h>
27 : #include <svl/intitem.hxx>
28 : #include <svl/sharedstringpool.hxx>
29 : #include <oox/helper/attributelist.hxx>
30 : #include <oox/helper/containerhelper.hxx>
31 : #include <oox/helper/propertyset.hxx>
32 : #include <oox/token/properties.hxx>
33 : #include "addressconverter.hxx"
34 : #include "biffinputstream.hxx"
35 : #include "stylesbuffer.hxx"
36 : #include "themebuffer.hxx"
37 :
38 : #include "colorscale.hxx"
39 : #include "conditio.hxx"
40 : #include "document.hxx"
41 : #include "convuno.hxx"
42 : #include "docfunc.hxx"
43 : #include "tokenarray.hxx"
44 : #include "tokenuno.hxx"
45 :
46 : namespace oox {
47 : namespace xls {
48 :
49 : using namespace ::com::sun::star::sheet;
50 : using namespace ::com::sun::star::style;
51 : using namespace ::com::sun::star::table;
52 : using namespace ::com::sun::star::uno;
53 :
54 : namespace {
55 :
56 : const sal_Int32 BIFF12_CFRULE_TYPE_CELLIS = 1;
57 : const sal_Int32 BIFF12_CFRULE_TYPE_EXPRESSION = 2;
58 : const sal_Int32 BIFF12_CFRULE_TYPE_COLORSCALE = 3;
59 : const sal_Int32 BIFF12_CFRULE_TYPE_DATABAR = 4;
60 : const sal_Int32 BIFF12_CFRULE_TYPE_TOPTEN = 5;
61 : const sal_Int32 BIFF12_CFRULE_TYPE_ICONSET = 6;
62 :
63 : const sal_Int32 BIFF12_CFRULE_SUB_CELLIS = 0;
64 : const sal_Int32 BIFF12_CFRULE_SUB_EXPRESSION = 1;
65 : const sal_Int32 BIFF12_CFRULE_SUB_COLORSCALE = 2;
66 : const sal_Int32 BIFF12_CFRULE_SUB_DATABAR = 3;
67 : const sal_Int32 BIFF12_CFRULE_SUB_ICONSET = 4;
68 : const sal_Int32 BIFF12_CFRULE_SUB_TOPTEN = 5;
69 : const sal_Int32 BIFF12_CFRULE_SUB_UNIQUE = 7;
70 : const sal_Int32 BIFF12_CFRULE_SUB_TEXT = 8;
71 : const sal_Int32 BIFF12_CFRULE_SUB_BLANK = 9;
72 : const sal_Int32 BIFF12_CFRULE_SUB_NOTBLANK = 10;
73 : const sal_Int32 BIFF12_CFRULE_SUB_ERROR = 11;
74 : const sal_Int32 BIFF12_CFRULE_SUB_NOTERROR = 12;
75 : const sal_Int32 BIFF12_CFRULE_SUB_TODAY = 15;
76 : const sal_Int32 BIFF12_CFRULE_SUB_TOMORROW = 16;
77 : const sal_Int32 BIFF12_CFRULE_SUB_YESTERDAY = 17;
78 : const sal_Int32 BIFF12_CFRULE_SUB_LAST7DAYS = 18;
79 : const sal_Int32 BIFF12_CFRULE_SUB_LASTMONTH = 19;
80 : const sal_Int32 BIFF12_CFRULE_SUB_NEXTMONTH = 20;
81 : const sal_Int32 BIFF12_CFRULE_SUB_THISWEEK = 21;
82 : const sal_Int32 BIFF12_CFRULE_SUB_NEXTWEEK = 22;
83 : const sal_Int32 BIFF12_CFRULE_SUB_LASTWEEK = 23;
84 : const sal_Int32 BIFF12_CFRULE_SUB_THISMONTH = 24;
85 : const sal_Int32 BIFF12_CFRULE_SUB_ABOVEAVERAGE = 25;
86 : const sal_Int32 BIFF12_CFRULE_SUB_BELOWAVERAGE = 26;
87 : const sal_Int32 BIFF12_CFRULE_SUB_DUPLICATE = 27;
88 : const sal_Int32 BIFF12_CFRULE_SUB_EQABOVEAVERAGE = 29;
89 : const sal_Int32 BIFF12_CFRULE_SUB_EQBELOWAVERAGE = 30;
90 :
91 : const sal_Int32 BIFF12_CFRULE_TIMEOP_TODAY = 0;
92 : const sal_Int32 BIFF12_CFRULE_TIMEOP_YESTERDAY = 1;
93 : const sal_Int32 BIFF12_CFRULE_TIMEOP_LAST7DAYS = 2;
94 : const sal_Int32 BIFF12_CFRULE_TIMEOP_THISWEEK = 3;
95 : const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTWEEK = 4;
96 : const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTMONTH = 5;
97 : const sal_Int32 BIFF12_CFRULE_TIMEOP_TOMORROW = 6;
98 : const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTWEEK = 7;
99 : const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTMONTH = 8;
100 : const sal_Int32 BIFF12_CFRULE_TIMEOP_THISMONTH = 9;
101 :
102 : const sal_uInt16 BIFF12_CFRULE_STOPIFTRUE = 0x0002;
103 : const sal_uInt16 BIFF12_CFRULE_ABOVEAVERAGE = 0x0004;
104 : const sal_uInt16 BIFF12_CFRULE_BOTTOM = 0x0008;
105 : const sal_uInt16 BIFF12_CFRULE_PERCENT = 0x0010;
106 :
107 100 : void SetCfvoData( ColorScaleRuleModelEntry* pEntry, const AttributeList& rAttribs )
108 : {
109 100 : OUString aType = rAttribs.getString( XML_type, OUString() );
110 :
111 100 : if( aType == "formula" )
112 : {
113 9 : OUString aFormula = rAttribs.getString( XML_val, OUString() );
114 9 : pEntry->maFormula = aFormula;
115 : }
116 : else
117 : {
118 91 : double nVal = rAttribs.getDouble( XML_val, 0.0 );
119 91 : pEntry->mnVal = nVal;
120 : }
121 :
122 100 : if (aType == "num")
123 : {
124 15 : pEntry->mbNum = true;
125 : }
126 85 : else if( aType == "min" )
127 : {
128 18 : pEntry->mbMin = true;
129 : }
130 67 : else if( aType == "max" )
131 : {
132 18 : pEntry->mbMax = true;
133 : }
134 49 : else if( aType == "percent" )
135 : {
136 28 : pEntry->mbPercent = true;
137 : }
138 21 : else if( aType == "percentile" )
139 : {
140 12 : pEntry->mbPercentile = true;
141 100 : }
142 100 : }
143 :
144 : }
145 :
146 19 : ColorScaleRule::ColorScaleRule( const CondFormat& rFormat ):
147 : WorksheetHelper( rFormat ),
148 : mnCfvo(0),
149 19 : mnCol(0)
150 : {
151 19 : }
152 :
153 47 : void ColorScaleRule::importCfvo( const AttributeList& rAttribs )
154 : {
155 47 : if(mnCfvo >= maColorScaleRuleEntries.size())
156 47 : maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry());
157 :
158 47 : SetCfvoData( &maColorScaleRuleEntries[mnCfvo], rAttribs );
159 :
160 47 : ++mnCfvo;
161 47 : }
162 :
163 : namespace {
164 :
165 93 : ::Color ARgbToARgbComponents( sal_uInt32& nRgb )
166 : {
167 : // sal_Int32 ornA = 255 - ((nRgb >> 24) & 0xFF);
168 : //
169 93 : sal_Int32 ornR = (nRgb >> 16) & 0xFF;
170 93 : sal_Int32 ornG = (nRgb >> 8) & 0xFF;
171 93 : sal_Int32 ornB = nRgb & 0xFF;
172 :
173 93 : return ::Color(/*ornA*/ 0, ornR, ornG, ornB);
174 : }
175 :
176 81 : ::Color importOOXColor(const AttributeList& rAttribs, ThemeBuffer& rThemeBuffer, GraphicHelper& rGraphicHelper)
177 : {
178 81 : sal_uInt32 nColor = 0;
179 81 : if( rAttribs.hasAttribute( XML_rgb ) )
180 77 : nColor = rAttribs.getUnsignedHex( XML_rgb, UNSIGNED_RGB_TRANSPARENT );
181 4 : else if( rAttribs.hasAttribute( XML_theme ) )
182 : {
183 4 : sal_uInt32 nThemeIndex = rAttribs.getUnsigned( XML_theme, 0 );
184 :
185 : // looks like an Excel bug
186 4 : if (nThemeIndex == 0)
187 1 : nThemeIndex = 1;
188 3 : else if (nThemeIndex == 1)
189 0 : nThemeIndex = 0;
190 :
191 4 : nColor = rThemeBuffer.getColorByIndex( nThemeIndex );
192 :
193 : }
194 :
195 81 : ::Color aColor;
196 81 : double nTint = rAttribs.getDouble(XML_tint, 0.0);
197 81 : if (nTint != 0.0)
198 : {
199 4 : oox::drawingml::Color aDMColor;
200 4 : aDMColor.setSrgbClr(nColor);
201 4 : aDMColor.addExcelTintTransformation(nTint);
202 4 : nColor = aDMColor.getColor(rGraphicHelper);
203 4 : aColor = ::Color(nColor);
204 : }
205 : else
206 77 : aColor = ARgbToARgbComponents( nColor );
207 :
208 81 : return aColor;
209 : }
210 :
211 : }
212 :
213 47 : void ColorScaleRule::importColor( const AttributeList& rAttribs )
214 : {
215 47 : ThemeBuffer& rThemeBuffer = getTheme();
216 47 : GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
217 47 : ::Color aColor = importOOXColor(rAttribs, rThemeBuffer, rGraphicHelper);
218 :
219 47 : if(mnCol >= maColorScaleRuleEntries.size())
220 0 : maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry());
221 :
222 47 : maColorScaleRuleEntries[mnCol].maColor = aColor;
223 47 : ++mnCol;
224 47 : }
225 :
226 : namespace {
227 :
228 100 : ScColorScaleEntry* ConvertToModel( const ColorScaleRuleModelEntry& rEntry, ScDocument* pDoc, const ScAddress& rAddr )
229 : {
230 100 : ScColorScaleEntry* pEntry = new ScColorScaleEntry(rEntry.mnVal, rEntry.maColor);
231 :
232 100 : if(rEntry.mbMin)
233 18 : pEntry->SetType(COLORSCALE_MIN);
234 100 : if(rEntry.mbMax)
235 18 : pEntry->SetType(COLORSCALE_MAX);
236 100 : if(rEntry.mbPercent)
237 28 : pEntry->SetType(COLORSCALE_PERCENT);
238 100 : if(rEntry.mbPercentile)
239 12 : pEntry->SetType(COLORSCALE_PERCENTILE);
240 100 : if (rEntry.mbNum)
241 15 : pEntry->SetType(COLORSCALE_VALUE);
242 :
243 100 : if(!rEntry.maFormula.isEmpty())
244 : {
245 9 : pEntry->SetType(COLORSCALE_FORMULA);
246 9 : pEntry->SetFormula(rEntry.maFormula, pDoc, rAddr, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
247 : }
248 :
249 100 : return pEntry;
250 : }
251 :
252 : }
253 :
254 19 : void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
255 : {
256 66 : for(size_t i = 0; i < maColorScaleRuleEntries.size(); ++i)
257 : {
258 47 : const ColorScaleRuleModelEntry& rEntry = maColorScaleRuleEntries[i];
259 :
260 47 : ScColorScaleEntry* pEntry = ConvertToModel( rEntry, pDoc, rAddr );
261 :
262 47 : pFormat->AddEntry( pEntry );
263 : }
264 19 : }
265 :
266 17 : DataBarRule::DataBarRule( const CondFormat& rFormat ):
267 : WorksheetHelper( rFormat ),
268 17 : mxFormat(new ScDataBarFormatData)
269 : {
270 17 : mxFormat->meAxisPosition = databar::NONE;
271 17 : }
272 :
273 17 : void DataBarRule::importColor( const AttributeList& rAttribs )
274 : {
275 17 : sal_uInt32 nColor = 0;
276 17 : if( rAttribs.hasAttribute( XML_rgb ) )
277 16 : nColor = rAttribs.getUnsignedHex( XML_rgb, UNSIGNED_RGB_TRANSPARENT );
278 1 : else if( rAttribs.hasAttribute( XML_theme ) )
279 : {
280 1 : sal_uInt32 nThemeIndex = rAttribs.getUnsigned( XML_theme, 0 );
281 1 : nColor = getTheme().getColorByIndex( nThemeIndex );
282 : }
283 :
284 17 : ::Color aColor;
285 17 : double nTint = rAttribs.getDouble(XML_tint, 0.0);
286 17 : if (nTint != 0.0)
287 : {
288 1 : oox::drawingml::Color aDMColor;
289 1 : aDMColor.setSrgbClr(nColor);
290 1 : aDMColor.addExcelTintTransformation(nTint);
291 1 : nColor = aDMColor.getColor(getBaseFilter().getGraphicHelper());
292 1 : aColor = ::Color(nColor);
293 : }
294 : else
295 16 : aColor = ARgbToARgbComponents( nColor );
296 :
297 17 : mxFormat->maPositiveColor = aColor;
298 17 : }
299 :
300 34 : void DataBarRule::importCfvo( const AttributeList& rAttribs )
301 : {
302 : ColorScaleRuleModelEntry* pEntry;
303 34 : if(!mpLowerLimit)
304 : {
305 17 : mpLowerLimit.reset(new ColorScaleRuleModelEntry);
306 17 : pEntry = mpLowerLimit.get();
307 : }
308 : else
309 : {
310 17 : mpUpperLimit.reset(new ColorScaleRuleModelEntry);
311 17 : pEntry = mpUpperLimit.get();
312 : }
313 :
314 34 : SetCfvoData( pEntry, rAttribs );
315 34 : }
316 :
317 17 : void DataBarRule::importAttribs( const AttributeList& rAttribs )
318 : {
319 17 : mxFormat->mbOnlyBar = !rAttribs.getBool( XML_showValue, true );
320 17 : mxFormat->mnMinLength = rAttribs.getUnsigned( XML_minLength, 10);
321 17 : mxFormat->mnMaxLength = rAttribs.getUnsigned( XML_maxLength, 90);
322 17 : }
323 :
324 17 : void DataBarRule::SetData( ScDataBarFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
325 : {
326 17 : ScColorScaleEntry* pUpperEntry = ConvertToModel( *mpUpperLimit.get(), pDoc, rAddr);
327 17 : ScColorScaleEntry* pLowerEntry = ConvertToModel( *mpLowerLimit.get(), pDoc, rAddr);
328 :
329 17 : mxFormat->mpUpperLimit.reset( pUpperEntry );
330 17 : mxFormat->mpLowerLimit.reset( pLowerEntry );
331 17 : pFormat->SetDataBarData(mxFormat.release());
332 17 : }
333 :
334 5 : IconSetRule::IconSetRule( const WorksheetHelper& rParent ):
335 : WorksheetHelper( rParent ),
336 5 : mxFormatData( new ScIconSetFormatData ),
337 10 : mbCustom(false)
338 : {
339 5 : }
340 :
341 19 : void IconSetRule::importCfvo( const AttributeList& rAttribs )
342 : {
343 19 : ColorScaleRuleModelEntry aNewEntry;
344 19 : SetCfvoData(&aNewEntry, rAttribs);
345 :
346 19 : maEntries.push_back(aNewEntry);
347 19 : }
348 :
349 5 : void IconSetRule::importAttribs( const AttributeList& rAttribs )
350 : {
351 5 : maIconSetType = rAttribs.getString( XML_iconSet, OUString("3TrafficLights1") );
352 5 : mxFormatData->mbShowValue = rAttribs.getBool( XML_showValue, true );
353 5 : mxFormatData->mbReverse = rAttribs.getBool( XML_reverse, false );
354 5 : mbCustom = rAttribs.getBool(XML_custom, false);
355 5 : }
356 :
357 19 : void IconSetRule::importFormula(const OUString& rFormula)
358 : {
359 19 : ColorScaleRuleModelEntry& rEntry = maEntries.back();
360 19 : if (rEntry.mbNum ||
361 0 : rEntry.mbPercent ||
362 : rEntry.mbPercentile)
363 : {
364 19 : double nVal = rFormula.toDouble();
365 19 : rEntry.mnVal = nVal;
366 : }
367 0 : else if (!rFormula.isEmpty())
368 0 : rEntry.maFormula = rFormula;
369 19 : }
370 :
371 : namespace {
372 :
373 13 : ScIconSetType getType(const OUString& rName)
374 : {
375 13 : ScIconSetType eIconSetType = IconSet_3TrafficLights1;
376 13 : ScIconSetMap* pIconSetMap = ScIconSetFormat::getIconSetMap();
377 138 : for(size_t i = 0; pIconSetMap[i].pName; ++i)
378 : {
379 136 : if(OUString::createFromAscii(pIconSetMap[i].pName) == rName)
380 : {
381 11 : eIconSetType = pIconSetMap[i].eType;
382 11 : break;
383 : }
384 : }
385 :
386 13 : return eIconSetType;
387 : }
388 :
389 : }
390 :
391 8 : void IconSetRule::importIcon(const AttributeList& rAttribs)
392 : {
393 8 : OUString aIconSet = rAttribs.getString(XML_iconSet, OUString());
394 8 : sal_Int32 nIndex = rAttribs.getInteger(XML_iconId, -1);
395 8 : if (aIconSet == "NoIcons")
396 : {
397 2 : nIndex = -1;
398 : }
399 :
400 8 : ScIconSetType eIconSetType = getType(aIconSet);
401 8 : mxFormatData->maCustomVector.push_back(std::pair<ScIconSetType, sal_Int32>(eIconSetType, nIndex));
402 8 : }
403 :
404 5 : void IconSetRule::SetData( ScIconSetFormat* pFormat, ScDocument* pDoc, const ScAddress& rPos )
405 : {
406 24 : for(size_t i = 0; i < maEntries.size(); ++i)
407 : {
408 19 : ScColorScaleEntry* pModelEntry = ConvertToModel( maEntries[i], pDoc, rPos );
409 19 : mxFormatData->maEntries.push_back(pModelEntry);
410 : }
411 :
412 5 : mxFormatData->eIconSetType = getType(maIconSetType);
413 5 : mxFormatData->mbCustom = mbCustom;
414 5 : pFormat->SetIconSetData(mxFormatData.release());
415 5 : }
416 :
417 67 : CondFormatRuleModel::CondFormatRuleModel() :
418 : mnPriority( -1 ),
419 : mnType( XML_TOKEN_INVALID ),
420 : mnOperator( XML_TOKEN_INVALID ),
421 : mnTimePeriod( XML_TOKEN_INVALID ),
422 : mnRank( 0 ),
423 : mnStdDev( 0 ),
424 : mnDxfId( -1 ),
425 : mbStopIfTrue( false ),
426 : mbBottom( false ),
427 : mbPercent( false ),
428 : mbAboveAverage( true ),
429 67 : mbEqualAverage( false )
430 : {
431 67 : }
432 :
433 0 : void CondFormatRuleModel::setBiffOperator( sal_Int32 nOperator )
434 : {
435 : static const sal_Int32 spnOperators[] = {
436 : XML_TOKEN_INVALID, XML_between, XML_notBetween, XML_equal, XML_notEqual,
437 : XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
438 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
439 0 : }
440 :
441 0 : void CondFormatRuleModel::setBiff12TextType( sal_Int32 nOperator )
442 : {
443 : // note: type XML_notContainsText vs. operator XML_notContains
444 : static const sal_Int32 spnTypes[] = { XML_containsText, XML_notContainsText, XML_beginsWith, XML_endsWith };
445 0 : mnType = STATIC_ARRAY_SELECT( spnTypes, nOperator, XML_TOKEN_INVALID );
446 : static const sal_Int32 spnOperators[] = { XML_containsText, XML_notContains, XML_beginsWith, XML_endsWith };
447 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
448 0 : }
449 :
450 67 : CondFormatRule::CondFormatRule( const CondFormat& rCondFormat, ScConditionalFormat* pFormat ) :
451 : WorksheetHelper( rCondFormat ),
452 : mrCondFormat( rCondFormat ),
453 67 : mpFormat(pFormat)
454 : {
455 67 : }
456 :
457 67 : void CondFormatRule::importCfRule( const AttributeList& rAttribs )
458 : {
459 67 : maModel.maText = rAttribs.getString( XML_text, OUString() );
460 67 : maModel.mnPriority = rAttribs.getInteger( XML_priority, -1 );
461 67 : maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
462 67 : maModel.mnOperator = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
463 67 : maModel.mnTimePeriod = rAttribs.getToken( XML_timePeriod, XML_TOKEN_INVALID );
464 67 : maModel.mnRank = rAttribs.getInteger( XML_rank, 0 );
465 67 : maModel.mnStdDev = rAttribs.getInteger( XML_stdDev, 0 );
466 67 : maModel.mnDxfId = rAttribs.getInteger( XML_dxfId, -1 );
467 67 : maModel.mbStopIfTrue = rAttribs.getBool( XML_stopIfTrue, false );
468 67 : maModel.mbBottom = rAttribs.getBool( XML_bottom, false );
469 67 : maModel.mbPercent = rAttribs.getBool( XML_percent, false );
470 67 : maModel.mbAboveAverage = rAttribs.getBool( XML_aboveAverage, true );
471 67 : maModel.mbEqualAverage = rAttribs.getBool( XML_equalAverage, false );
472 :
473 67 : if(maModel.mnType == XML_colorScale)
474 : {
475 : //import the remaining values
476 :
477 : }
478 67 : }
479 :
480 11 : void CondFormatRule::appendFormula( const OUString& rFormula )
481 : {
482 11 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
483 11 : ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, rFormula );
484 11 : maModel.maFormulas.push_back( aTokens );
485 11 : }
486 :
487 0 : void CondFormatRule::importCfRule( SequenceInputStream& rStrm )
488 : {
489 : sal_Int32 nType, nSubType, nOperator, nFmla1Size, nFmla2Size, nFmla3Size;
490 : sal_uInt16 nFlags;
491 0 : nType = rStrm.readInt32();
492 0 : nSubType = rStrm.readInt32();
493 0 : maModel.mnDxfId = rStrm.readInt32();
494 0 : maModel.mnPriority = rStrm.readInt32();
495 0 : nOperator = rStrm.readInt32();
496 0 : rStrm.skip( 8 );
497 0 : nFlags = rStrm.readuInt16();
498 0 : nFmla1Size = rStrm.readInt32();
499 0 : nFmla2Size = rStrm.readInt32();
500 0 : nFmla3Size = rStrm.readInt32();
501 0 : rStrm >> maModel.maText;
502 :
503 : /* Import the formulas. For no obvious reason, the sizes of the formulas
504 : are already stored before. Nevertheless the following formulas contain
505 : their own sizes. */
506 :
507 : // first formula
508 : // I am not bored enough to bother simplifying these expressions
509 : SAL_WARN_IF( !( (nFmla1Size >= 0) || ((nFmla2Size == 0) && (nFmla3Size == 0)) ), "sc.filter", "CondFormatRule::importCfRule - missing first formula" );
510 : SAL_WARN_IF( !( (nFmla1Size > 0) == (rStrm.getRemaining() >= 8) ), "sc.filter", "CondFormatRule::importCfRule - formula size mismatch" );
511 0 : if( rStrm.getRemaining() >= 8 )
512 : {
513 0 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
514 0 : ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
515 0 : maModel.maFormulas.push_back( aTokens );
516 :
517 : // second formula
518 : OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" );
519 : OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
520 0 : if( rStrm.getRemaining() >= 8 )
521 : {
522 0 : aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
523 0 : maModel.maFormulas.push_back( aTokens );
524 :
525 : // third formula
526 : OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
527 0 : if( rStrm.getRemaining() >= 8 )
528 : {
529 0 : aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
530 0 : maModel.maFormulas.push_back( aTokens );
531 : }
532 0 : }
533 : }
534 :
535 : // flags
536 0 : maModel.mbStopIfTrue = getFlag( nFlags, BIFF12_CFRULE_STOPIFTRUE );
537 0 : maModel.mbBottom = getFlag( nFlags, BIFF12_CFRULE_BOTTOM );
538 0 : maModel.mbPercent = getFlag( nFlags, BIFF12_CFRULE_PERCENT );
539 0 : maModel.mbAboveAverage = getFlag( nFlags, BIFF12_CFRULE_ABOVEAVERAGE );
540 : // no flag for equalAverage, must be determined from subtype below...
541 :
542 : // Convert the type/operator settings. This is a real mess...
543 0 : switch( nType )
544 : {
545 : case BIFF12_CFRULE_TYPE_CELLIS:
546 : SAL_WARN_IF(
547 : nSubType != BIFF12_CFRULE_SUB_CELLIS, "sc.filter",
548 : "CondFormatRule::importCfRule - rule type/subtype mismatch");
549 0 : maModel.mnType = XML_cellIs;
550 0 : maModel.setBiffOperator( nOperator );
551 : OSL_ENSURE( maModel.mnOperator != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unknown operator" );
552 0 : break;
553 : case BIFF12_CFRULE_TYPE_EXPRESSION:
554 : // here we have to look at the subtype to find the real type...
555 0 : switch( nSubType )
556 : {
557 : case BIFF12_CFRULE_SUB_EXPRESSION:
558 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
559 0 : maModel.mnType = XML_expression;
560 0 : break;
561 : case BIFF12_CFRULE_SUB_UNIQUE:
562 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
563 0 : maModel.mnType = XML_uniqueValues;
564 0 : break;
565 : case BIFF12_CFRULE_SUB_TEXT:
566 0 : maModel.setBiff12TextType( nOperator );
567 : OSL_ENSURE( maModel.mnType != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unexpected operator value" );
568 0 : break;
569 : case BIFF12_CFRULE_SUB_BLANK:
570 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
571 0 : maModel.mnType = XML_containsBlanks;
572 0 : break;
573 : case BIFF12_CFRULE_SUB_NOTBLANK:
574 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
575 0 : maModel.mnType = XML_notContainsBlanks;
576 0 : break;
577 : case BIFF12_CFRULE_SUB_ERROR:
578 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
579 0 : maModel.mnType = XML_containsErrors;
580 0 : break;
581 : case BIFF12_CFRULE_SUB_NOTERROR:
582 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
583 0 : maModel.mnType = XML_notContainsErrors;
584 0 : break;
585 : case BIFF12_CFRULE_SUB_TODAY:
586 : SAL_WARN_IF(
587 : nOperator != BIFF12_CFRULE_TIMEOP_TODAY, "sc.filter",
588 : "CondFormatRule::importCfRule - unexpected time operator value");
589 0 : maModel.mnType = XML_timePeriod;
590 0 : maModel.mnTimePeriod = XML_today;
591 0 : break;
592 : case BIFF12_CFRULE_SUB_TOMORROW:
593 : SAL_WARN_IF(
594 : nOperator != BIFF12_CFRULE_TIMEOP_TOMORROW, "sc.filter",
595 : "CondFormatRule::importCfRule - unexpected time operator value");
596 0 : maModel.mnType = XML_timePeriod;
597 0 : maModel.mnTimePeriod = XML_tomorrow;
598 0 : break;
599 : case BIFF12_CFRULE_SUB_YESTERDAY:
600 : SAL_WARN_IF(
601 : nOperator != BIFF12_CFRULE_TIMEOP_YESTERDAY,
602 : "sc.filter",
603 : "CondFormatRule::importCfRule - unexpected time operator value");
604 0 : maModel.mnType = XML_timePeriod;
605 0 : maModel.mnTimePeriod = XML_yesterday;
606 0 : break;
607 : case BIFF12_CFRULE_SUB_LAST7DAYS:
608 : SAL_WARN_IF(
609 : nOperator != BIFF12_CFRULE_TIMEOP_LAST7DAYS,
610 : "sc.filter",
611 : "CondFormatRule::importCfRule - unexpected time operator value");
612 0 : maModel.mnType = XML_timePeriod;
613 0 : maModel.mnTimePeriod = XML_last7Days;
614 0 : break;
615 : case BIFF12_CFRULE_SUB_LASTMONTH:
616 : SAL_WARN_IF(
617 : nOperator != BIFF12_CFRULE_TIMEOP_LASTMONTH,
618 : "sc.filter",
619 : "CondFormatRule::importCfRule - unexpected time operator value");
620 0 : maModel.mnType = XML_timePeriod;
621 0 : maModel.mnTimePeriod = XML_lastMonth;
622 0 : break;
623 : case BIFF12_CFRULE_SUB_NEXTMONTH:
624 : SAL_WARN_IF(
625 : nOperator != BIFF12_CFRULE_TIMEOP_NEXTMONTH,
626 : "sc.filter",
627 : "CondFormatRule::importCfRule - unexpected time operator value");
628 0 : maModel.mnType = XML_timePeriod;
629 0 : maModel.mnTimePeriod = XML_nextMonth;
630 0 : break;
631 : case BIFF12_CFRULE_SUB_THISWEEK:
632 : SAL_WARN_IF(
633 : nOperator != BIFF12_CFRULE_TIMEOP_THISWEEK, "sc.filter",
634 : "CondFormatRule::importCfRule - unexpected time operator value");
635 0 : maModel.mnType = XML_timePeriod;
636 0 : maModel.mnTimePeriod = XML_thisWeek;
637 0 : break;
638 : case BIFF12_CFRULE_SUB_NEXTWEEK:
639 : SAL_WARN_IF(
640 : nOperator != BIFF12_CFRULE_TIMEOP_NEXTWEEK, "sc.filter",
641 : "CondFormatRule::importCfRule - unexpected time operator value");
642 0 : maModel.mnType = XML_timePeriod;
643 0 : maModel.mnTimePeriod = XML_nextWeek;
644 0 : break;
645 : case BIFF12_CFRULE_SUB_LASTWEEK:
646 : SAL_WARN_IF(
647 : nOperator != BIFF12_CFRULE_TIMEOP_LASTWEEK, "sc.filter",
648 : "CondFormatRule::importCfRule - unexpected time operator value");
649 0 : maModel.mnType = XML_timePeriod;
650 0 : maModel.mnTimePeriod = XML_lastWeek;
651 0 : break;
652 : case BIFF12_CFRULE_SUB_THISMONTH:
653 : SAL_WARN_IF(
654 : nOperator != BIFF12_CFRULE_TIMEOP_THISMONTH,
655 : "sc.filter",
656 : "CondFormatRule::importCfRule - unexpected time operator value");
657 0 : maModel.mnType = XML_timePeriod;
658 0 : maModel.mnTimePeriod = XML_thisMonth;
659 0 : break;
660 : case BIFF12_CFRULE_SUB_ABOVEAVERAGE:
661 : OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
662 0 : maModel.mnType = XML_aboveAverage;
663 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
664 0 : maModel.mbAboveAverage = true;
665 0 : maModel.mbEqualAverage = false; // does not exist as real flag...
666 0 : break;
667 : case BIFF12_CFRULE_SUB_BELOWAVERAGE:
668 : OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
669 0 : maModel.mnType = XML_aboveAverage;
670 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
671 0 : maModel.mbAboveAverage = false;
672 0 : maModel.mbEqualAverage = false; // does not exist as real flag...
673 0 : break;
674 : case BIFF12_CFRULE_SUB_DUPLICATE:
675 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
676 0 : maModel.mnType = XML_duplicateValues;
677 0 : break;
678 : case BIFF12_CFRULE_SUB_EQABOVEAVERAGE:
679 : OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
680 0 : maModel.mnType = XML_aboveAverage;
681 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
682 0 : maModel.mbAboveAverage = true;
683 0 : maModel.mbEqualAverage = true; // does not exist as real flag...
684 0 : break;
685 : case BIFF12_CFRULE_SUB_EQBELOWAVERAGE:
686 : OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
687 0 : maModel.mnType = XML_aboveAverage;
688 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
689 0 : maModel.mbAboveAverage = false;
690 0 : maModel.mbEqualAverage = true; // does not exist as real flag...
691 0 : break;
692 : }
693 0 : break;
694 : case BIFF12_CFRULE_TYPE_COLORSCALE:
695 : SAL_WARN_IF(
696 : nSubType != BIFF12_CFRULE_SUB_COLORSCALE, "sc.filter",
697 : "CondFormatRule::importCfRule - rule type/subtype mismatch");
698 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
699 0 : maModel.mnType = XML_colorScale;
700 0 : break;
701 : case BIFF12_CFRULE_TYPE_DATABAR:
702 : SAL_WARN_IF(
703 : nSubType != BIFF12_CFRULE_SUB_DATABAR, "sc.filter",
704 : "CondFormatRule::importCfRule - rule type/subtype mismatch");
705 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
706 0 : maModel.mnType = XML_dataBar;
707 0 : break;
708 : case BIFF12_CFRULE_TYPE_TOPTEN:
709 : SAL_WARN_IF(
710 : nSubType != BIFF12_CFRULE_SUB_TOPTEN, "sc.filter",
711 : "CondFormatRule::importCfRule - rule type/subtype mismatch");
712 0 : maModel.mnType = XML_top10;
713 0 : maModel.mnRank = nOperator; // operator field used for rank value
714 0 : break;
715 : case BIFF12_CFRULE_TYPE_ICONSET:
716 : SAL_WARN_IF(
717 : nSubType != BIFF12_CFRULE_SUB_ICONSET, "sc.filter",
718 : "CondFormatRule::importCfRule - rule type/subtype mismatch");
719 : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
720 0 : maModel.mnType = XML_iconSet;
721 0 : break;
722 : default:
723 : OSL_FAIL( "CondFormatRule::importCfRule - unknown rule type" );
724 : }
725 0 : }
726 :
727 67 : void CondFormatRule::finalizeImport()
728 : {
729 67 : ScConditionMode eOperator = SC_COND_NONE;
730 :
731 : /* Replacement formula for unsupported rule types (text comparison rules,
732 : time period rules, cell type rules). The replacement formulas below may
733 : contain several placeholders:
734 : - '#B' will be replaced by the current relative base address (may occur
735 : several times).
736 : - '#R' will be replaced by the entire range list of the conditional
737 : formatting (absolute addresses).
738 : - '#T' will be replaced by the quoted comparison text.
739 : - '#L' will be replaced by the length of the comparison text (from
740 : the 'text' attribute) used in text comparison rules.
741 : - '#K' will be replaced by the rank (from the 'rank' attribute) used in
742 : top-10 rules.
743 : - '#M' will be replaced by the top/bottom flag (from the 'bottom'
744 : attribute) used in the RANK function in top-10 rules.
745 : - '#C' will be replaced by one of the comparison operators <, >, <=, or
746 : >=, according to the 'aboveAverage' and 'equalAverage' flags.
747 : */
748 67 : OUString aReplaceFormula;
749 :
750 67 : switch( maModel.mnType )
751 : {
752 : case XML_cellIs:
753 0 : eOperator = static_cast<ScConditionMode>(CondFormatBuffer::convertToInternalOperator( maModel.mnOperator ));
754 0 : break;
755 : case XML_duplicateValues:
756 0 : eOperator = SC_COND_DUPLICATE;
757 0 : break;
758 : case XML_uniqueValues:
759 0 : eOperator = SC_COND_NOTDUPLICATE;
760 0 : break;
761 : case XML_expression:
762 6 : eOperator = SC_COND_DIRECT;
763 6 : break;
764 : case XML_containsText:
765 : OSL_ENSURE( maModel.mnOperator == XML_containsText, "CondFormatRule::finalizeImport - unexpected operator" );
766 1 : eOperator = SC_COND_CONTAINS_TEXT;
767 1 : break;
768 : case XML_notContainsText:
769 : // note: type XML_notContainsText vs. operator XML_notContains
770 : OSL_ENSURE( maModel.mnOperator == XML_notContains, "CondFormatRule::finalizeImport - unexpected operator" );
771 0 : eOperator = SC_COND_NOT_CONTAINS_TEXT;
772 0 : break;
773 : case XML_beginsWith:
774 : OSL_ENSURE( maModel.mnOperator == XML_beginsWith, "CondFormatRule::finalizeImport - unexpected operator" );
775 0 : eOperator = SC_COND_BEGINS_WITH;
776 0 : break;
777 : case XML_endsWith:
778 : OSL_ENSURE( maModel.mnOperator == XML_endsWith, "CondFormatRule::finalizeImport - unexpected operator" );
779 0 : eOperator = SC_COND_ENDS_WITH;
780 0 : break;
781 : case XML_timePeriod:
782 0 : break;
783 : case XML_containsBlanks:
784 0 : aReplaceFormula = "LEN(TRIM(#B))=0";
785 0 : break;
786 : case XML_notContainsBlanks:
787 0 : aReplaceFormula = "LEN(TRIM(#B))>0";
788 0 : break;
789 : case XML_containsErrors:
790 0 : eOperator = SC_COND_ERROR;
791 0 : break;
792 : case XML_notContainsErrors:
793 0 : eOperator = SC_COND_NOERROR;
794 0 : break;
795 : case XML_top10:
796 12 : if(maModel.mbPercent)
797 : {
798 6 : if(maModel.mbBottom)
799 3 : eOperator = SC_COND_BOTTOM_PERCENT;
800 : else
801 3 : eOperator = SC_COND_TOP_PERCENT;
802 : }
803 : else
804 : {
805 6 : if(maModel.mbBottom)
806 3 : eOperator = SC_COND_BOTTOM10;
807 : else
808 3 : eOperator = SC_COND_TOP10;
809 : }
810 12 : break;
811 : case XML_aboveAverage:
812 12 : if(maModel.mbAboveAverage)
813 : {
814 6 : if(maModel.mbEqualAverage)
815 3 : eOperator = SC_COND_ABOVE_EQUAL_AVERAGE;
816 : else
817 3 : eOperator = SC_COND_ABOVE_AVERAGE;
818 : }
819 : else
820 : {
821 6 : if(maModel.mbEqualAverage)
822 3 : eOperator = SC_COND_BELOW_EQUAL_AVERAGE;
823 : else
824 3 : eOperator = SC_COND_BELOW_AVERAGE;
825 : }
826 12 : break;
827 : case XML_colorScale:
828 19 : break;
829 : }
830 :
831 67 : if( !aReplaceFormula.isEmpty() )
832 : {
833 0 : OUString aAddress;
834 0 : sal_Int32 nStrPos = aReplaceFormula.getLength();
835 0 : while( (nStrPos = aReplaceFormula.lastIndexOf( '#', nStrPos )) >= 0 )
836 : {
837 0 : switch( aReplaceFormula[ nStrPos + 1 ] )
838 : {
839 : case 'B': // current base address
840 0 : if( aAddress.isEmpty() )
841 0 : aAddress = FormulaProcessorBase::generateAddress2dString( mrCondFormat.getRanges().getBaseAddress(), false );
842 0 : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aAddress );
843 0 : break;
844 : default:
845 : OSL_FAIL( "CondFormatRule::finalizeImport - unknown placeholder" );
846 : }
847 : }
848 :
849 : // set the replacement formula
850 0 : maModel.maFormulas.clear();
851 0 : appendFormula( aReplaceFormula );
852 0 : eOperator = SC_COND_DIRECT;
853 : }
854 :
855 67 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
856 67 : ScAddress aPos;
857 67 : ScUnoConversion::FillScAddress( aPos, aBaseAddr );
858 :
859 67 : if( eOperator == SC_COND_ERROR || eOperator == SC_COND_NOERROR )
860 : {
861 0 : ScDocument& rDoc = getScDocument();
862 0 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
863 0 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry( eOperator, NULL, NULL, &rDoc, aPos, aStyleName );
864 0 : mpFormat->AddEntry(pNewEntry);
865 : }
866 67 : else if( eOperator == SC_COND_BEGINS_WITH || eOperator == SC_COND_ENDS_WITH ||
867 66 : eOperator == SC_COND_CONTAINS_TEXT || eOperator == SC_COND_NOT_CONTAINS_TEXT )
868 : {
869 1 : ScDocument& rDoc = getScDocument();
870 1 : ScTokenArray aTokenArray;
871 1 : svl::SharedStringPool& rSPool = rDoc.GetSharedStringPool();
872 1 : aTokenArray.AddString(rSPool.intern(maModel.maText));
873 2 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
874 1 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry( eOperator, &aTokenArray, NULL, &rDoc, aPos, aStyleName );
875 2 : mpFormat->AddEntry(pNewEntry);
876 : }
877 66 : else if( (eOperator != SC_COND_NONE) && !maModel.maFormulas.empty() )
878 : {
879 10 : ScDocument& rDoc = getScDocument();
880 10 : std::unique_ptr<ScTokenArray> pTokenArray2;
881 10 : if( maModel.maFormulas.size() >= 2)
882 : {
883 0 : pTokenArray2.reset(new ScTokenArray());
884 0 : ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] );
885 : }
886 :
887 20 : ScTokenArray aTokenArray;
888 20 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
889 10 : ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] );
890 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(eOperator,
891 10 : &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName);
892 20 : mpFormat->AddEntry(pNewEntry);
893 : }
894 56 : else if ( eOperator == SC_COND_TOP10 || eOperator == SC_COND_BOTTOM10 ||
895 47 : eOperator == SC_COND_TOP_PERCENT || eOperator == SC_COND_BOTTOM_PERCENT )
896 : {
897 12 : ScDocument& rDoc = getScDocument();
898 12 : ScTokenArray aTokenArray;
899 12 : aTokenArray.AddDouble( maModel.mnRank );
900 24 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
901 12 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry( eOperator, &aTokenArray, NULL, &rDoc, aPos, aStyleName );
902 24 : mpFormat->AddEntry(pNewEntry);
903 : }
904 44 : else if( eOperator == SC_COND_ABOVE_AVERAGE || eOperator == SC_COND_BELOW_AVERAGE ||
905 38 : eOperator == SC_COND_ABOVE_EQUAL_AVERAGE || eOperator == SC_COND_BELOW_EQUAL_AVERAGE )
906 : {
907 8 : ScDocument& rDoc = getScDocument();
908 : // actually that is still unsupported
909 8 : ScTokenArray aTokenArrayDev;
910 8 : aTokenArrayDev.AddDouble( maModel.mnStdDev );
911 16 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
912 8 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry( eOperator, &aTokenArrayDev, NULL, &rDoc, aPos, aStyleName );
913 16 : mpFormat->AddEntry(pNewEntry);
914 : }
915 36 : else if( eOperator == SC_COND_DUPLICATE || eOperator == SC_COND_NOTDUPLICATE )
916 : {
917 0 : ScDocument& rDoc = getScDocument();
918 0 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
919 0 : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry( eOperator, NULL, NULL, &rDoc, aPos, aStyleName );
920 0 : mpFormat->AddEntry(pNewEntry);
921 : }
922 36 : else if( maModel.mnType == XML_timePeriod )
923 : {
924 0 : condformat::ScCondFormatDateType eDateType = condformat::TODAY;
925 0 : switch( maModel.mnTimePeriod )
926 : {
927 : case XML_yesterday:
928 0 : eDateType = condformat::YESTERDAY;
929 0 : break;
930 : case XML_today:
931 0 : eDateType = condformat::TODAY;
932 0 : break;
933 : case XML_tomorrow:
934 0 : eDateType = condformat::TOMORROW;
935 0 : break;
936 : case XML_last7Days:
937 0 : eDateType = condformat::LAST7DAYS;
938 0 : break;
939 : case XML_lastWeek:
940 0 : eDateType = condformat::LASTWEEK;
941 0 : break;
942 : case XML_thisWeek:
943 0 : eDateType = condformat::THISWEEK;
944 0 : break;
945 : case XML_nextWeek:
946 0 : eDateType = condformat::NEXTWEEK;
947 0 : break;
948 : case XML_lastMonth:
949 0 : eDateType = condformat::LASTMONTH;
950 0 : break;
951 : case XML_thisMonth:
952 0 : eDateType = condformat::THISMONTH;
953 0 : break;
954 : case XML_nextMonth:
955 0 : eDateType = condformat::NEXTMONTH;
956 0 : break;
957 : default:
958 : SAL_WARN("sc", "CondFormatRule::finalizeImport - unknown time period type" );
959 : }
960 :
961 0 : ScDocument& rDoc = getScDocument();
962 0 : ScCondDateFormatEntry* pFormatEntry = new ScCondDateFormatEntry(&rDoc);
963 0 : pFormatEntry->SetDateType(eDateType);
964 0 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
965 0 : pFormatEntry->SetStyleName( aStyleName );
966 :
967 0 : mpFormat->AddEntry(pFormatEntry);
968 : }
969 36 : else if( mpColor )
970 : {
971 19 : ScDocument& rDoc = getScDocument();
972 19 : ScColorScaleFormat* pFormatEntry = new ScColorScaleFormat(&rDoc);
973 :
974 19 : mpFormat->AddEntry(pFormatEntry);
975 :
976 19 : mpColor->AddEntries( pFormatEntry, &rDoc, aPos );
977 : }
978 17 : else if (mpDataBar)
979 : {
980 17 : ScDocument& rDoc = getScDocument();
981 17 : ScDataBarFormat* pFormatEntry = new ScDataBarFormat(&rDoc);
982 :
983 17 : mpFormat->AddEntry(pFormatEntry);
984 17 : mpDataBar->SetData( pFormatEntry, &rDoc, aPos );
985 :
986 : }
987 0 : else if(mpIconSet)
988 : {
989 0 : ScDocument& rDoc = getScDocument();
990 0 : ScIconSetFormat* pFormatEntry = new ScIconSetFormat(&rDoc);
991 :
992 0 : mpFormat->AddEntry(pFormatEntry);
993 0 : mpIconSet->SetData( pFormatEntry, &rDoc, aPos );
994 67 : }
995 67 : }
996 :
997 94 : ColorScaleRule* CondFormatRule::getColorScale()
998 : {
999 94 : if(!mpColor)
1000 19 : mpColor.reset( new ColorScaleRule(mrCondFormat) );
1001 :
1002 94 : return mpColor.get();
1003 : }
1004 :
1005 85 : DataBarRule* CondFormatRule::getDataBar()
1006 : {
1007 85 : if(!mpDataBar)
1008 17 : mpDataBar.reset( new DataBarRule(mrCondFormat) );
1009 :
1010 85 : return mpDataBar.get();
1011 : }
1012 :
1013 0 : IconSetRule* CondFormatRule::getIconSet()
1014 : {
1015 0 : if(!mpIconSet)
1016 0 : mpIconSet.reset( new IconSetRule(mrCondFormat) );
1017 :
1018 0 : return mpIconSet.get();
1019 : }
1020 :
1021 67 : CondFormatModel::CondFormatModel() :
1022 67 : mbPivot( false )
1023 : {
1024 67 : }
1025 :
1026 67 : CondFormat::CondFormat( const WorksheetHelper& rHelper ) :
1027 : WorksheetHelper( rHelper ),
1028 : mpFormat(NULL),
1029 67 : mbReadyForFinalize(false)
1030 : {
1031 67 : }
1032 :
1033 67 : void CondFormat::importConditionalFormatting( const AttributeList& rAttribs )
1034 : {
1035 67 : getAddressConverter().convertToCellRangeList( maModel.maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
1036 67 : maModel.mbPivot = rAttribs.getBool( XML_pivot, false );
1037 67 : mpFormat = new ScConditionalFormat(0, &getScDocument());
1038 67 : }
1039 :
1040 67 : CondFormatRuleRef CondFormat::importCfRule( const AttributeList& rAttribs )
1041 : {
1042 67 : CondFormatRuleRef xRule = createRule();
1043 67 : xRule->importCfRule( rAttribs );
1044 67 : insertRule( xRule );
1045 67 : return xRule;
1046 : }
1047 :
1048 0 : void CondFormat::importCondFormatting( SequenceInputStream& rStrm )
1049 : {
1050 0 : BinRangeList aRanges;
1051 0 : rStrm.skip( 8 );
1052 0 : rStrm >> aRanges;
1053 0 : getAddressConverter().convertToCellRangeList( maModel.maRanges, aRanges, getSheetIndex(), true );
1054 0 : mpFormat = new ScConditionalFormat(0, &getScDocument());
1055 0 : }
1056 :
1057 0 : void CondFormat::importCfRule( SequenceInputStream& rStrm )
1058 : {
1059 0 : CondFormatRuleRef xRule = createRule();
1060 0 : xRule->importCfRule( rStrm );
1061 0 : insertRule( xRule );
1062 0 : }
1063 :
1064 67 : void CondFormat::finalizeImport()
1065 : {
1066 : // probably some error in the xml if we are not ready
1067 67 : if ( !mbReadyForFinalize )
1068 67 : return;
1069 67 : ScDocument& rDoc = getScDocument();
1070 67 : maRules.forEachMem( &CondFormatRule::finalizeImport );
1071 67 : SCTAB nTab = maModel.maRanges.getBaseAddress().Sheet;
1072 67 : sal_Int32 nIndex = getScDocument().AddCondFormat(mpFormat, nTab);
1073 :
1074 67 : ScRangeList aList;
1075 134 : for( ::std::vector< CellRangeAddress >::const_iterator itr = maModel.maRanges.begin(); itr != maModel.maRanges.end(); ++itr)
1076 : {
1077 67 : ScRange aRange;
1078 67 : ScUnoConversion::FillScRange(aRange, *itr);
1079 67 : aList.Append(aRange);
1080 : }
1081 67 : rDoc.AddCondFormatData( aList, nTab, nIndex );
1082 67 : mpFormat->SetRange(aList);
1083 : }
1084 :
1085 67 : CondFormatRuleRef CondFormat::createRule()
1086 : {
1087 67 : return CondFormatRuleRef( new CondFormatRule( *this, mpFormat ) );
1088 : }
1089 :
1090 67 : void CondFormat::insertRule( CondFormatRuleRef xRule )
1091 : {
1092 67 : if( xRule.get() && (xRule->getPriority() > 0) )
1093 : {
1094 : OSL_ENSURE( maRules.find( xRule->getPriority() ) == maRules.end(), "CondFormat::insertRule - multiple rules with equal priority" );
1095 67 : maRules[ xRule->getPriority() ] = xRule;
1096 : }
1097 67 : }
1098 :
1099 269 : CondFormatBuffer::CondFormatBuffer( const WorksheetHelper& rHelper ) :
1100 269 : WorksheetHelper( rHelper )
1101 : {
1102 269 : }
1103 :
1104 67 : CondFormatRef CondFormatBuffer::importConditionalFormatting( const AttributeList& rAttribs )
1105 : {
1106 67 : CondFormatRef xCondFmt = createCondFormat();
1107 67 : xCondFmt->importConditionalFormatting( rAttribs );
1108 67 : return xCondFmt;
1109 : }
1110 :
1111 : namespace {
1112 :
1113 22 : ScConditionalFormat* findFormatByRange(const ScRangeList& rRange, ScDocument* pDoc, SCTAB nTab)
1114 : {
1115 22 : ScConditionalFormatList* pList = pDoc->GetCondFormList(nTab);
1116 56 : for (auto itr = pList->begin(); itr != pList->end(); ++itr)
1117 : {
1118 51 : if (itr->GetRange() == rRange)
1119 : {
1120 17 : return &(*itr);
1121 : }
1122 : }
1123 :
1124 5 : return NULL;
1125 : }
1126 :
1127 : }
1128 :
1129 269 : void CondFormatBuffer::finalizeImport()
1130 : {
1131 269 : CondFormatVec::iterator it = maCondFormats.begin();
1132 269 : CondFormatVec::iterator it_end = maCondFormats.end();
1133 336 : for( ; it != it_end; ++it )
1134 : {
1135 67 : if ( (*it).get() )
1136 67 : (*it).get()->finalizeImport();
1137 : }
1138 269 : ExtCfDataBarRuleVec::iterator ext_it = maCfRules.begin();
1139 269 : ExtCfDataBarRuleVec::iterator ext_end = maCfRules.end();
1140 354 : for ( ; ext_it != ext_end; ++ext_it )
1141 : {
1142 85 : if ( (*ext_it).get() )
1143 85 : (*ext_it).get()->finalizeImport();
1144 : }
1145 :
1146 291 : for (auto itr = maExtCondFormats.begin(); itr != maExtCondFormats.end(); ++itr)
1147 : {
1148 22 : ScDocument* pDoc = &getScDocument();
1149 :
1150 22 : const ScRangeList& rRange = itr->getRange();
1151 22 : SCTAB nTab = rRange.front()->aStart.Tab();
1152 22 : ScConditionalFormat* pFormat = findFormatByRange(rRange, pDoc, nTab);
1153 22 : if (!pFormat)
1154 : {
1155 : // create new conditional format and insert it
1156 5 : pFormat = new ScConditionalFormat(0, pDoc);
1157 5 : pFormat->SetRange(rRange);
1158 5 : sal_uLong nKey = pDoc->AddCondFormat(pFormat, nTab);
1159 5 : pDoc->AddCondFormatData(rRange, nTab, nKey);
1160 : }
1161 :
1162 22 : const boost::ptr_vector<ScFormatEntry>& rEntries = itr->getEntries();
1163 27 : for (auto i = rEntries.begin(); i != rEntries.end(); ++i)
1164 : {
1165 5 : pFormat->AddEntry(i->Clone(pDoc));
1166 : }
1167 : }
1168 269 : }
1169 :
1170 0 : CondFormatRef CondFormatBuffer::importCondFormatting( SequenceInputStream& rStrm )
1171 : {
1172 0 : CondFormatRef xCondFmt = createCondFormat();
1173 0 : xCondFmt->importCondFormatting( rStrm );
1174 0 : return xCondFmt;
1175 : }
1176 :
1177 85 : ExtCfDataBarRuleRef CondFormatBuffer::createExtCfDataBarRule(ScDataBarFormatData* pTarget)
1178 : {
1179 85 : ExtCfDataBarRuleRef extRule( new ExtCfDataBarRule( pTarget, *this ) );
1180 85 : maCfRules.push_back( extRule );
1181 85 : return extRule;
1182 : }
1183 :
1184 22 : boost::ptr_vector<ExtCfCondFormat>& CondFormatBuffer::importExtCondFormat()
1185 : {
1186 22 : return maExtCondFormats;
1187 : }
1188 :
1189 0 : sal_Int32 CondFormatBuffer::convertToApiOperator( sal_Int32 nToken )
1190 : {
1191 0 : switch( nToken )
1192 : {
1193 0 : case XML_between: return ConditionOperator2::BETWEEN;
1194 0 : case XML_equal: return ConditionOperator2::EQUAL;
1195 0 : case XML_greaterThan: return ConditionOperator2::GREATER;
1196 0 : case XML_greaterThanOrEqual: return ConditionOperator2::GREATER_EQUAL;
1197 0 : case XML_lessThan: return ConditionOperator2::LESS;
1198 0 : case XML_lessThanOrEqual: return ConditionOperator2::LESS_EQUAL;
1199 0 : case XML_notBetween: return ConditionOperator2::NOT_BETWEEN;
1200 0 : case XML_notEqual: return ConditionOperator2::NOT_EQUAL;
1201 0 : case XML_duplicateValues: return ConditionOperator2::DUPLICATE;
1202 : }
1203 0 : return ConditionOperator2::NONE;
1204 : }
1205 :
1206 0 : sal_Int32 CondFormatBuffer::convertToInternalOperator( sal_Int32 nToken )
1207 : {
1208 0 : switch( nToken )
1209 : {
1210 0 : case XML_between: return SC_COND_BETWEEN;
1211 0 : case XML_equal: return SC_COND_EQUAL;
1212 0 : case XML_greaterThan: return SC_COND_GREATER;
1213 0 : case XML_greaterThanOrEqual: return SC_COND_EQGREATER;
1214 0 : case XML_lessThan: return SC_COND_LESS;
1215 0 : case XML_lessThanOrEqual: return SC_COND_EQLESS;
1216 0 : case XML_notBetween: return SC_COND_NOTBETWEEN;
1217 0 : case XML_notEqual: return SC_COND_NOTEQUAL;
1218 0 : case XML_duplicateValues: return SC_COND_DUPLICATE;
1219 0 : case XML_uniqueValues: return SC_COND_NOTDUPLICATE;
1220 : }
1221 0 : return ConditionOperator2::NONE;
1222 : }
1223 :
1224 : // private --------------------------------------------------------------------
1225 :
1226 67 : CondFormatRef CondFormatBuffer::createCondFormat()
1227 : {
1228 67 : CondFormatRef xCondFmt( new CondFormat( *this ) );
1229 67 : maCondFormats.push_back( xCondFmt );
1230 67 : return xCondFmt;
1231 : }
1232 :
1233 85 : ExtCfDataBarRule::ExtCfDataBarRule(ScDataBarFormatData* pTarget, WorksheetHelper& rParent):
1234 : WorksheetHelper(rParent),
1235 : mnRuleType( ExtCfDataBarRule::UNKNOWN ),
1236 85 : mpTarget(pTarget)
1237 : {
1238 85 : }
1239 :
1240 85 : void ExtCfDataBarRule::finalizeImport()
1241 : {
1242 85 : switch ( mnRuleType )
1243 : {
1244 : case DATABAR:
1245 : {
1246 17 : ScDataBarFormatData* pDataBar = mpTarget;
1247 17 : if( maModel.maAxisPosition == "none" )
1248 0 : pDataBar->meAxisPosition = databar::NONE;
1249 17 : else if( maModel.maAxisPosition == "middle" )
1250 3 : pDataBar->meAxisPosition = databar::MIDDLE;
1251 : else
1252 14 : pDataBar->meAxisPosition = databar::AUTOMATIC;
1253 17 : pDataBar->mbGradient = maModel.mbGradient;
1254 17 : break;
1255 : }
1256 : case AXISCOLOR:
1257 : {
1258 17 : ScDataBarFormatData* pDataBar = mpTarget;
1259 17 : pDataBar->maAxisColor = maModel.mnAxisColor;
1260 17 : break;
1261 : }
1262 : case NEGATIVEFILLCOLOR:
1263 : {
1264 17 : ScDataBarFormatData* pDataBar = mpTarget;
1265 17 : pDataBar->mpNegativeColor.reset( new ::Color(maModel.mnNegativeColor) );
1266 17 : pDataBar->mbNeg = true;
1267 17 : break;
1268 : }
1269 : case CFVO:
1270 : {
1271 34 : ScDataBarFormatData* pDataBar = mpTarget;
1272 34 : ScColorScaleEntry* pEntry = NULL;
1273 34 : if(maModel.mbIsLower)
1274 17 : pEntry = pDataBar->mpLowerLimit.get();
1275 : else
1276 17 : pEntry = pDataBar->mpUpperLimit.get();
1277 :
1278 34 : if(maModel.maColorScaleType == "min")
1279 3 : pEntry->SetType(COLORSCALE_MIN);
1280 31 : else if (maModel.maColorScaleType == "max")
1281 3 : pEntry->SetType(COLORSCALE_MAX);
1282 28 : else if (maModel.maColorScaleType == "autoMin")
1283 8 : pEntry->SetType(COLORSCALE_AUTO);
1284 20 : else if (maModel.maColorScaleType == "autoMax")
1285 8 : pEntry->SetType(COLORSCALE_AUTO);
1286 12 : else if (maModel.maColorScaleType == "percentile")
1287 3 : pEntry->SetType(COLORSCALE_PERCENTILE);
1288 9 : else if (maModel.maColorScaleType == "percent")
1289 3 : pEntry->SetType(COLORSCALE_PERCENT);
1290 6 : else if (maModel.maColorScaleType == "formula")
1291 3 : pEntry->SetType(COLORSCALE_FORMULA);
1292 34 : break;
1293 : }
1294 : case UNKNOWN: // nothing to do
1295 : default:
1296 0 : break;
1297 : }
1298 85 : }
1299 :
1300 17 : void ExtCfDataBarRule::importDataBar( const AttributeList& rAttribs )
1301 : {
1302 17 : mnRuleType = DATABAR;
1303 17 : maModel.mbGradient = rAttribs.getBool( XML_gradient, true );
1304 17 : maModel.maAxisPosition = rAttribs.getString( XML_axisPosition, "automatic" );
1305 17 : }
1306 :
1307 17 : void ExtCfDataBarRule::importNegativeFillColor( const AttributeList& rAttribs )
1308 : {
1309 17 : mnRuleType = NEGATIVEFILLCOLOR;
1310 17 : ThemeBuffer& rThemeBuffer = getTheme();
1311 17 : GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
1312 17 : ::Color aColor = importOOXColor(rAttribs, rThemeBuffer, rGraphicHelper);
1313 17 : maModel.mnNegativeColor = aColor;
1314 17 : }
1315 :
1316 17 : void ExtCfDataBarRule::importAxisColor( const AttributeList& rAttribs )
1317 : {
1318 17 : mnRuleType = AXISCOLOR;
1319 17 : ThemeBuffer& rThemeBuffer = getTheme();
1320 17 : GraphicHelper& rGraphicHelper = getBaseFilter().getGraphicHelper();
1321 17 : ::Color aColor = importOOXColor(rAttribs, rThemeBuffer, rGraphicHelper);
1322 17 : maModel.mnAxisColor = aColor;
1323 17 : }
1324 :
1325 34 : void ExtCfDataBarRule::importCfvo( const AttributeList& rAttribs )
1326 : {
1327 34 : mnRuleType = CFVO;
1328 34 : maModel.maColorScaleType = rAttribs.getString( XML_type, OUString() );
1329 34 : }
1330 :
1331 22 : ExtCfCondFormat::ExtCfCondFormat(const ScRangeList& rRange, boost::ptr_vector<ScFormatEntry>& rEntries):
1332 22 : maRange(rRange)
1333 : {
1334 22 : maEntries.transfer(maEntries.begin(), rEntries.begin(), rEntries.end(), rEntries);
1335 22 : }
1336 :
1337 22 : ExtCfCondFormat::~ExtCfCondFormat()
1338 : {
1339 22 : }
1340 :
1341 22 : const ScRangeList& ExtCfCondFormat::getRange()
1342 : {
1343 22 : return maRange;
1344 : }
1345 :
1346 22 : const boost::ptr_vector<ScFormatEntry>& ExtCfCondFormat::getEntries()
1347 : {
1348 22 : return maEntries;
1349 : }
1350 :
1351 : } // namespace xls
1352 30 : } // namespace oox
1353 :
1354 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|