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