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