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