Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "condformatbuffer.hxx"
30 : :
31 : : #include <com/sun/star/beans/PropertyValue.hpp>
32 : : #include <com/sun/star/container/XIndexAccess.hpp>
33 : : #include <com/sun/star/container/XNameContainer.hpp>
34 : : #include <com/sun/star/sheet/ConditionOperator2.hpp>
35 : : #include <com/sun/star/sheet/XSheetCellRanges.hpp>
36 : : #include <com/sun/star/sheet/XSheetConditionalEntries.hpp>
37 : : #include <com/sun/star/sheet/XSpreadsheet.hpp>
38 : : #include <com/sun/star/sheet/XSpreadsheetDocument.hpp>
39 : : #include <com/sun/star/sheet/XSpreadsheets.hpp>
40 : : #include <com/sun/star/style/XStyle.hpp>
41 : : #include <com/sun/star/style/XStyleFamiliesSupplier.hpp>
42 : : #include <com/sun/star/table/CellAddress.hpp>
43 : : #include <com/sun/star/table/CellRangeAddress.hpp>
44 : : #include <com/sun/star/table/XCellRange.hpp>
45 : : #include <rtl/ustrbuf.hxx>
46 : : #include <svl/intitem.hxx>
47 : : #include "oox/helper/attributelist.hxx"
48 : : #include "oox/helper/containerhelper.hxx"
49 : : #include "oox/helper/propertyset.hxx"
50 : : #include "oox/token/properties.hxx"
51 : : #include "addressconverter.hxx"
52 : : #include "biffinputstream.hxx"
53 : : #include "stylesbuffer.hxx"
54 : : #include "themebuffer.hxx"
55 : :
56 : : #include "colorscale.hxx"
57 : : #include "conditio.hxx"
58 : : #include "document.hxx"
59 : : #include "convuno.hxx"
60 : : #include "docfunc.hxx"
61 : : #include "markdata.hxx"
62 : : #include "docpool.hxx"
63 : : #include "scitems.hxx"
64 : : #include "tokenarray.hxx"
65 : : #include "tokenuno.hxx"
66 : :
67 : : namespace oox {
68 : : namespace xls {
69 : :
70 : : // ============================================================================
71 : :
72 : : using namespace ::com::sun::star::beans;
73 : : using namespace ::com::sun::star::container;
74 : : using namespace ::com::sun::star::sheet;
75 : : using namespace ::com::sun::star::style;
76 : : using namespace ::com::sun::star::table;
77 : : using namespace ::com::sun::star::uno;
78 : :
79 : : using ::rtl::OUString;
80 : : using ::rtl::OUStringBuffer;
81 : :
82 : : // ============================================================================
83 : :
84 : : namespace {
85 : :
86 : : const sal_Int32 BIFF12_CFRULE_TYPE_CELLIS = 1;
87 : : const sal_Int32 BIFF12_CFRULE_TYPE_EXPRESSION = 2;
88 : : const sal_Int32 BIFF12_CFRULE_TYPE_COLORSCALE = 3;
89 : : const sal_Int32 BIFF12_CFRULE_TYPE_DATABAR = 4;
90 : : const sal_Int32 BIFF12_CFRULE_TYPE_TOPTEN = 5;
91 : : const sal_Int32 BIFF12_CFRULE_TYPE_ICONSET = 6;
92 : :
93 : : const sal_Int32 BIFF12_CFRULE_SUB_CELLIS = 0;
94 : : const sal_Int32 BIFF12_CFRULE_SUB_EXPRESSION = 1;
95 : : const sal_Int32 BIFF12_CFRULE_SUB_COLORSCALE = 2;
96 : : const sal_Int32 BIFF12_CFRULE_SUB_DATABAR = 3;
97 : : const sal_Int32 BIFF12_CFRULE_SUB_ICONSET = 4;
98 : : const sal_Int32 BIFF12_CFRULE_SUB_TOPTEN = 5;
99 : : const sal_Int32 BIFF12_CFRULE_SUB_UNIQUE = 7;
100 : : const sal_Int32 BIFF12_CFRULE_SUB_TEXT = 8;
101 : : const sal_Int32 BIFF12_CFRULE_SUB_BLANK = 9;
102 : : const sal_Int32 BIFF12_CFRULE_SUB_NOTBLANK = 10;
103 : : const sal_Int32 BIFF12_CFRULE_SUB_ERROR = 11;
104 : : const sal_Int32 BIFF12_CFRULE_SUB_NOTERROR = 12;
105 : : const sal_Int32 BIFF12_CFRULE_SUB_TODAY = 15;
106 : : const sal_Int32 BIFF12_CFRULE_SUB_TOMORROW = 16;
107 : : const sal_Int32 BIFF12_CFRULE_SUB_YESTERDAY = 17;
108 : : const sal_Int32 BIFF12_CFRULE_SUB_LAST7DAYS = 18;
109 : : const sal_Int32 BIFF12_CFRULE_SUB_LASTMONTH = 19;
110 : : const sal_Int32 BIFF12_CFRULE_SUB_NEXTMONTH = 20;
111 : : const sal_Int32 BIFF12_CFRULE_SUB_THISWEEK = 21;
112 : : const sal_Int32 BIFF12_CFRULE_SUB_NEXTWEEK = 22;
113 : : const sal_Int32 BIFF12_CFRULE_SUB_LASTWEEK = 23;
114 : : const sal_Int32 BIFF12_CFRULE_SUB_THISMONTH = 24;
115 : : const sal_Int32 BIFF12_CFRULE_SUB_ABOVEAVERAGE = 25;
116 : : const sal_Int32 BIFF12_CFRULE_SUB_BELOWAVERAGE = 26;
117 : : const sal_Int32 BIFF12_CFRULE_SUB_DUPLICATE = 27;
118 : : const sal_Int32 BIFF12_CFRULE_SUB_EQABOVEAVERAGE = 29;
119 : : const sal_Int32 BIFF12_CFRULE_SUB_EQBELOWAVERAGE = 30;
120 : :
121 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_TODAY = 0;
122 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_YESTERDAY = 1;
123 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_LAST7DAYS = 2;
124 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_THISWEEK = 3;
125 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTWEEK = 4;
126 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_LASTMONTH = 5;
127 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_TOMORROW = 6;
128 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTWEEK = 7;
129 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_NEXTMONTH = 8;
130 : : const sal_Int32 BIFF12_CFRULE_TIMEOP_THISMONTH = 9;
131 : :
132 : : const sal_uInt16 BIFF12_CFRULE_STOPIFTRUE = 0x0002;
133 : : const sal_uInt16 BIFF12_CFRULE_ABOVEAVERAGE = 0x0004;
134 : : const sal_uInt16 BIFF12_CFRULE_BOTTOM = 0x0008;
135 : : const sal_uInt16 BIFF12_CFRULE_PERCENT = 0x0010;
136 : :
137 : : // ----------------------------------------------------------------------------
138 : :
139 : : template< typename Type >
140 : : void lclAppendProperty( ::std::vector< PropertyValue >& orProps, const OUString& rPropName, const Type& rValue )
141 : : {
142 : : orProps.push_back( PropertyValue() );
143 : : orProps.back().Name = rPropName;
144 : : orProps.back().Value <<= rValue;
145 : : }
146 : :
147 : : } // namespace
148 : :
149 : 0 : ColorScaleRule::ColorScaleRule( const CondFormat& rFormat ):
150 : : WorksheetHelper( rFormat ),
151 : : mrCondFormat( rFormat ),
152 : : mnCfvo(0),
153 [ # # ]: 0 : mnCol(0)
154 : : {
155 : 0 : }
156 : :
157 : 0 : void ColorScaleRule::importCfvo( const AttributeList& rAttribs )
158 : : {
159 [ # # ]: 0 : if(mnCfvo >= maColorScaleRuleEntries.size())
160 [ # # ]: 0 : maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry());
161 : :
162 [ # # ]: 0 : rtl::OUString aType = rAttribs.getString( XML_type, rtl::OUString() );
163 : :
164 [ # # ]: 0 : double nVal = rAttribs.getDouble( XML_val, 0.0 );
165 : 0 : maColorScaleRuleEntries[mnCfvo].mnVal = nVal;
166 [ # # ]: 0 : if (aType == "num")
167 : : {
168 : : // nothing to do
169 : : }
170 [ # # ]: 0 : else if( aType == "min" )
171 : : {
172 : 0 : maColorScaleRuleEntries[mnCfvo].mbMin = true;
173 : : }
174 [ # # ]: 0 : else if( aType == "max" )
175 : : {
176 : 0 : maColorScaleRuleEntries[mnCfvo].mbMax = true;
177 : : }
178 [ # # ]: 0 : else if( aType == "percent" )
179 : : {
180 : 0 : maColorScaleRuleEntries[mnCfvo].mbPercent = true;
181 : : }
182 [ # # ]: 0 : else if( aType == "percentile" )
183 : : {
184 : 0 : maColorScaleRuleEntries[mnCfvo].mbPercentile = true;
185 : : }
186 [ # # ]: 0 : else if( aType == "formula" )
187 : : {
188 [ # # ]: 0 : rtl::OUString aFormula = rAttribs.getString( XML_val, rtl::OUString() );
189 : 0 : maColorScaleRuleEntries[mnCfvo].maFormula = aFormula;
190 : : }
191 : :
192 : 0 : ++mnCfvo;
193 : 0 : }
194 : :
195 : : namespace {
196 : :
197 : 0 : ::Color RgbToRgbComponents( sal_Int32& nRgb )
198 : : {
199 : 0 : sal_Int32 ornR = (nRgb >> 16) & 0xFF;
200 : 0 : sal_Int32 ornG = (nRgb >> 8) & 0xFF;
201 : 0 : sal_Int32 ornB = nRgb & 0xFF;
202 : :
203 : 0 : return ::Color(ornR, ornG, ornB);
204 : : }
205 : :
206 : : }
207 : :
208 : 0 : void ColorScaleRule::importColor( const AttributeList& rAttribs )
209 : : {
210 : 0 : sal_Int32 nColor = 0;
211 [ # # ][ # # ]: 0 : if( rAttribs.hasAttribute( XML_rgb ) )
212 [ # # ]: 0 : nColor = rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT );
213 [ # # ][ # # ]: 0 : else if( rAttribs.hasAttribute( XML_theme ) )
214 : : {
215 [ # # ]: 0 : sal_uInt32 nThemeIndex = rAttribs.getUnsigned( XML_theme, 0 );
216 [ # # ][ # # ]: 0 : nColor = getTheme().getColorByToken( nThemeIndex );
217 : : }
218 : :
219 : 0 : ::Color aColor = RgbToRgbComponents( nColor );
220 : :
221 [ # # ]: 0 : if(mnCol >= maColorScaleRuleEntries.size())
222 [ # # ]: 0 : maColorScaleRuleEntries.push_back(ColorScaleRuleModelEntry());
223 : :
224 : 0 : maColorScaleRuleEntries[mnCol].maColor = aColor;
225 : 0 : ++mnCol;
226 : 0 : }
227 : :
228 : : namespace {
229 : :
230 : 0 : ScColorScaleEntry* ConvertToModel( const ColorScaleRuleModelEntry& rEntry, ScDocument* pDoc, const ScAddress& rAddr )
231 : : {
232 [ # # ]: 0 : ScColorScaleEntry* pEntry = new ScColorScaleEntry(rEntry.mnVal, rEntry.maColor);
233 : :
234 [ # # ]: 0 : if(rEntry.mbMin)
235 : 0 : pEntry->SetType(COLORSCALE_MIN);
236 [ # # ]: 0 : if(rEntry.mbMax)
237 : 0 : pEntry->SetType(COLORSCALE_MAX);
238 [ # # ]: 0 : if(rEntry.mbPercent)
239 : 0 : pEntry->SetType(COLORSCALE_PERCENT);
240 [ # # ]: 0 : if(rEntry.mbPercentile)
241 : 0 : pEntry->SetType(COLORSCALE_PERCENTILE);
242 : :
243 [ # # ]: 0 : if(!rEntry.maFormula.isEmpty())
244 : : {
245 : 0 : pEntry->SetType(COLORSCALE_FORMULA);
246 : 0 : pEntry->SetFormula(rEntry.maFormula, pDoc, rAddr, formula::FormulaGrammar::GRAM_ENGLISH_XL_A1);
247 : : }
248 : :
249 : 0 : return pEntry;
250 : : }
251 : :
252 : : }
253 : :
254 : 0 : void ColorScaleRule::AddEntries( ScColorScaleFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
255 : : {
256 [ # # ]: 0 : for(size_t i = 0; i < maColorScaleRuleEntries.size(); ++i)
257 : : {
258 : 0 : const ColorScaleRuleModelEntry& rEntry = maColorScaleRuleEntries[i];
259 : :
260 : 0 : ScColorScaleEntry* pEntry = ConvertToModel( rEntry, pDoc, rAddr );
261 : :
262 : 0 : pFormat->AddEntry( pEntry );
263 : : }
264 : 0 : }
265 : :
266 : : // ============================================================================
267 : : //
268 : 0 : DataBarRule::DataBarRule( const CondFormat& rFormat ):
269 : : WorksheetHelper( rFormat ),
270 : : mrCondFormat( rFormat ),
271 [ # # ][ # # ]: 0 : mpFormat(new ScDataBarFormatData)
272 : : {
273 : 0 : mpFormat->meAxisPosition = databar::NONE;
274 : 0 : }
275 : :
276 : 0 : void DataBarRule::importColor( const AttributeList& rAttribs )
277 : : {
278 : 0 : sal_Int32 nColor = 0;
279 [ # # ][ # # ]: 0 : if( rAttribs.hasAttribute( XML_rgb ) )
280 [ # # ]: 0 : nColor = rAttribs.getIntegerHex( XML_rgb, API_RGB_TRANSPARENT );
281 [ # # ][ # # ]: 0 : else if( rAttribs.hasAttribute( XML_theme ) )
282 : : {
283 [ # # ]: 0 : sal_uInt32 nThemeIndex = rAttribs.getUnsigned( XML_theme, 0 );
284 [ # # ][ # # ]: 0 : nColor = getTheme().getColorByToken( nThemeIndex );
285 : : }
286 : :
287 : 0 : ::Color aColor = RgbToRgbComponents( nColor );
288 : :
289 : 0 : mpFormat->maPositiveColor = aColor;
290 : 0 : }
291 : :
292 : 0 : void DataBarRule::importCfvo( const AttributeList& rAttribs )
293 : : {
294 : : ColorScaleRuleModelEntry* pEntry;
295 [ # # ]: 0 : if(!mpLowerLimit)
296 : : {
297 [ # # ][ # # ]: 0 : mpLowerLimit.reset(new ColorScaleRuleModelEntry);
298 : 0 : pEntry = mpLowerLimit.get();
299 : : }
300 : : else
301 : : {
302 [ # # ][ # # ]: 0 : mpUpperLimit.reset(new ColorScaleRuleModelEntry);
303 : 0 : pEntry = mpUpperLimit.get();
304 : : }
305 [ # # ]: 0 : rtl::OUString aType = rAttribs.getString( XML_type, rtl::OUString() );
306 : :
307 [ # # ]: 0 : double nVal = rAttribs.getDouble( XML_val, 0.0 );
308 : 0 : pEntry->mnVal = nVal;
309 [ # # ]: 0 : if (aType == "num")
310 : : {
311 : : // nothing to do
312 : : }
313 [ # # ]: 0 : else if( aType == "min" )
314 : : {
315 : 0 : pEntry->mbMin = true;
316 : : }
317 [ # # ]: 0 : else if( aType == "max" )
318 : : {
319 : 0 : pEntry->mbMax = true;
320 : : }
321 [ # # ]: 0 : else if( aType == "percent" )
322 : : {
323 : 0 : pEntry->mbPercent = true;
324 : : }
325 [ # # ]: 0 : else if( aType == "percentile" )
326 : : {
327 : 0 : pEntry->mbPercentile = true;
328 : : }
329 [ # # ]: 0 : else if( aType == "formula" )
330 : : {
331 [ # # ]: 0 : rtl::OUString aFormula = rAttribs.getString( XML_val, rtl::OUString() );
332 : 0 : pEntry->maFormula = aFormula;
333 : 0 : }
334 : 0 : }
335 : :
336 : 0 : void DataBarRule::importAttribs( const AttributeList& rAttribs )
337 : : {
338 : 0 : mpFormat->mbOnlyBar = !rAttribs.getBool( XML_showValue, true );
339 : 0 : }
340 : :
341 : 0 : void DataBarRule::SetData( ScDataBarFormat* pFormat, ScDocument* pDoc, const ScAddress& rAddr )
342 : : {
343 : 0 : ScColorScaleEntry* pUpperEntry = ConvertToModel( *mpUpperLimit.get(), pDoc, rAddr);
344 : 0 : ScColorScaleEntry* pLowerEntry = ConvertToModel( *mpLowerLimit.get(), pDoc, rAddr);
345 : :
346 : 0 : mpFormat->mpUpperLimit.reset( pUpperEntry );
347 : 0 : mpFormat->mpLowerLimit.reset( pLowerEntry );
348 : 0 : pFormat->SetDataBarData(mpFormat);
349 : 0 : }
350 : :
351 : : // ============================================================================
352 : :
353 : 0 : CondFormatRuleModel::CondFormatRuleModel() :
354 : : mnPriority( -1 ),
355 : : mnType( XML_TOKEN_INVALID ),
356 : : mnOperator( XML_TOKEN_INVALID ),
357 : : mnTimePeriod( XML_TOKEN_INVALID ),
358 : : mnRank( 0 ),
359 : : mnStdDev( 0 ),
360 : : mnDxfId( -1 ),
361 : : mbStopIfTrue( false ),
362 : : mbBottom( false ),
363 : : mbPercent( false ),
364 : : mbAboveAverage( true ),
365 : 0 : mbEqualAverage( false )
366 : : {
367 : 0 : }
368 : :
369 : 0 : void CondFormatRuleModel::setBiffOperator( sal_Int32 nOperator )
370 : : {
371 : : static const sal_Int32 spnOperators[] = {
372 : : XML_TOKEN_INVALID, XML_between, XML_notBetween, XML_equal, XML_notEqual,
373 : : XML_greaterThan, XML_lessThan, XML_greaterThanOrEqual, XML_lessThanOrEqual };
374 [ # # ]: 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
375 : 0 : }
376 : :
377 : 0 : void CondFormatRuleModel::setBiff12TextType( sal_Int32 nOperator )
378 : : {
379 : : // note: type XML_notContainsText vs. operator XML_notContains
380 : : static const sal_Int32 spnTypes[] = { XML_containsText, XML_notContainsText, XML_beginsWith, XML_endsWith };
381 [ # # ]: 0 : mnType = STATIC_ARRAY_SELECT( spnTypes, nOperator, XML_TOKEN_INVALID );
382 : : static const sal_Int32 spnOperators[] = { XML_containsText, XML_notContains, XML_beginsWith, XML_endsWith };
383 [ # # ]: 0 : mnOperator = STATIC_ARRAY_SELECT( spnOperators, nOperator, XML_TOKEN_INVALID );
384 : 0 : }
385 : :
386 : : // ============================================================================
387 : :
388 : 0 : CondFormatRule::CondFormatRule( const CondFormat& rCondFormat, ScConditionalFormat* pFormat ) :
389 : : WorksheetHelper( rCondFormat ),
390 : : mrCondFormat( rCondFormat ),
391 [ # # ]: 0 : mpFormat(pFormat)
392 : : {
393 : 0 : }
394 : :
395 : 0 : void CondFormatRule::importCfRule( const AttributeList& rAttribs )
396 : : {
397 [ # # ]: 0 : maModel.maText = rAttribs.getString( XML_text, OUString() );
398 : 0 : maModel.mnPriority = rAttribs.getInteger( XML_priority, -1 );
399 : 0 : maModel.mnType = rAttribs.getToken( XML_type, XML_TOKEN_INVALID );
400 : 0 : maModel.mnOperator = rAttribs.getToken( XML_operator, XML_TOKEN_INVALID );
401 : 0 : maModel.mnTimePeriod = rAttribs.getToken( XML_timePeriod, XML_TOKEN_INVALID );
402 : 0 : maModel.mnRank = rAttribs.getInteger( XML_rank, 0 );
403 : 0 : maModel.mnStdDev = rAttribs.getInteger( XML_stdDev, 0 );
404 : 0 : maModel.mnDxfId = rAttribs.getInteger( XML_dxfId, -1 );
405 : 0 : maModel.mbStopIfTrue = rAttribs.getBool( XML_stopIfTrue, false );
406 : 0 : maModel.mbBottom = rAttribs.getBool( XML_bottom, false );
407 : 0 : maModel.mbPercent = rAttribs.getBool( XML_percent, false );
408 : 0 : maModel.mbAboveAverage = rAttribs.getBool( XML_aboveAverage, true );
409 : 0 : maModel.mbEqualAverage = rAttribs.getBool( XML_equalAverage, false );
410 : :
411 : 0 : if(maModel.mnType == XML_colorScale)
412 : : {
413 : : //import the remaining values
414 : :
415 : : }
416 : 0 : }
417 : :
418 : 0 : void CondFormatRule::appendFormula( const OUString& rFormula )
419 : : {
420 [ # # ]: 0 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
421 [ # # ][ # # ]: 0 : ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, rFormula );
422 [ # # ][ # # ]: 0 : maModel.maFormulas.push_back( aTokens );
423 : 0 : }
424 : :
425 : 0 : void CondFormatRule::importCfRule( SequenceInputStream& rStrm )
426 : : {
427 : : sal_Int32 nType, nSubType, nOperator, nFmla1Size, nFmla2Size, nFmla3Size;
428 : : sal_uInt16 nFlags;
429 [ # # ][ # # ]: 0 : rStrm >> nType >> nSubType >> maModel.mnDxfId >> maModel.mnPriority >> nOperator;
[ # # ][ # # ]
[ # # ]
430 [ # # ]: 0 : rStrm.skip( 8 );
431 [ # # ][ # # ]: 0 : rStrm >> nFlags >> nFmla1Size >> nFmla2Size >> nFmla3Size >> maModel.maText;
[ # # ][ # # ]
[ # # ]
432 : :
433 : : /* Import the formulas. For no obvious reason, the sizes of the formulas
434 : : are already stored before. Nevertheless the following formulas contain
435 : : their own sizes. */
436 : :
437 : : // first formula
438 : : OSL_ENSURE( (nFmla1Size >= 0) || ((nFmla2Size == 0) && (nFmla3Size == 0)), "CondFormatRule::importCfRule - missing first formula" );
439 : : OSL_ENSURE( (nFmla1Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
440 [ # # ][ # # ]: 0 : if( rStrm.getRemaining() >= 8 )
441 : : {
442 [ # # ]: 0 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
443 [ # # ][ # # ]: 0 : ApiTokenSequence aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
444 [ # # ]: 0 : maModel.maFormulas.push_back( aTokens );
445 : :
446 : : // second formula
447 : : OSL_ENSURE( (nFmla2Size >= 0) || (nFmla3Size == 0), "CondFormatRule::importCfRule - missing second formula" );
448 : : OSL_ENSURE( (nFmla2Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
449 [ # # ][ # # ]: 0 : if( rStrm.getRemaining() >= 8 )
450 : : {
451 [ # # ][ # # ]: 0 : aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
[ # # ][ # # ]
452 [ # # ]: 0 : maModel.maFormulas.push_back( aTokens );
453 : :
454 : : // third formula
455 : : OSL_ENSURE( (nFmla3Size > 0) == (rStrm.getRemaining() >= 8), "CondFormatRule::importCfRule - formula size mismatch" );
456 [ # # ][ # # ]: 0 : if( rStrm.getRemaining() >= 8 )
457 : : {
458 [ # # ][ # # ]: 0 : aTokens = getFormulaParser().importFormula( aBaseAddr, FORMULATYPE_CONDFORMAT, rStrm );
[ # # ][ # # ]
459 [ # # ]: 0 : maModel.maFormulas.push_back( aTokens );
460 : : }
461 [ # # ]: 0 : }
462 : : }
463 : :
464 : : // flags
465 : 0 : maModel.mbStopIfTrue = getFlag( nFlags, BIFF12_CFRULE_STOPIFTRUE );
466 : 0 : maModel.mbBottom = getFlag( nFlags, BIFF12_CFRULE_BOTTOM );
467 : 0 : maModel.mbPercent = getFlag( nFlags, BIFF12_CFRULE_PERCENT );
468 : 0 : maModel.mbAboveAverage = getFlag( nFlags, BIFF12_CFRULE_ABOVEAVERAGE );
469 : : // no flag for equalAverage, must be determined from subtype below...
470 : :
471 : : // Convert the type/operator settings. This is a real mess...
472 [ # # # # : 0 : switch( nType )
# # # ]
473 : : {
474 : : case BIFF12_CFRULE_TYPE_CELLIS:
475 : : OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_CELLIS, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
476 : 0 : maModel.mnType = XML_cellIs;
477 : 0 : maModel.setBiffOperator( nOperator );
478 : : OSL_ENSURE( maModel.mnOperator != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unknown operator" );
479 : 0 : break;
480 : : case BIFF12_CFRULE_TYPE_EXPRESSION:
481 : : // here we have to look at the subtype to find the real type...
482 [ # # # # : 0 : switch( nSubType )
# # # # #
# # # # #
# # # # #
# # # # ]
483 : : {
484 : : case BIFF12_CFRULE_SUB_EXPRESSION:
485 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
486 : 0 : maModel.mnType = XML_expression;
487 : 0 : break;
488 : : case BIFF12_CFRULE_SUB_UNIQUE:
489 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
490 : 0 : maModel.mnType = XML_uniqueValues;
491 : 0 : break;
492 : : case BIFF12_CFRULE_SUB_TEXT:
493 : 0 : maModel.setBiff12TextType( nOperator );
494 : : OSL_ENSURE( maModel.mnType != XML_TOKEN_INVALID, "CondFormatRule::importCfRule - unexpected operator value" );
495 : 0 : break;
496 : : case BIFF12_CFRULE_SUB_BLANK:
497 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
498 : 0 : maModel.mnType = XML_containsBlanks;
499 : 0 : break;
500 : : case BIFF12_CFRULE_SUB_NOTBLANK:
501 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
502 : 0 : maModel.mnType = XML_notContainsBlanks;
503 : 0 : break;
504 : : case BIFF12_CFRULE_SUB_ERROR:
505 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
506 : 0 : maModel.mnType = XML_containsErrors;
507 : 0 : break;
508 : : case BIFF12_CFRULE_SUB_NOTERROR:
509 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
510 : 0 : maModel.mnType = XML_notContainsErrors;
511 : 0 : break;
512 : : case BIFF12_CFRULE_SUB_TODAY:
513 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TODAY, "CondFormatRule::importCfRule - unexpected time operator value" );
514 : 0 : maModel.mnType = XML_timePeriod;
515 : 0 : maModel.mnTimePeriod = XML_today;
516 : 0 : break;
517 : : case BIFF12_CFRULE_SUB_TOMORROW:
518 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_TOMORROW, "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 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_YESTERDAY, "CondFormatRule::importCfRule - unexpected time operator value" );
524 : 0 : maModel.mnType = XML_timePeriod;
525 : 0 : maModel.mnTimePeriod = XML_yesterday;
526 : 0 : break;
527 : : case BIFF12_CFRULE_SUB_LAST7DAYS:
528 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LAST7DAYS, "CondFormatRule::importCfRule - unexpected time operator value" );
529 : 0 : maModel.mnType = XML_timePeriod;
530 : 0 : maModel.mnTimePeriod = XML_last7Days;
531 : 0 : break;
532 : : case BIFF12_CFRULE_SUB_LASTMONTH:
533 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
534 : 0 : maModel.mnType = XML_timePeriod;
535 : 0 : maModel.mnTimePeriod = XML_lastMonth;
536 : 0 : break;
537 : : case BIFF12_CFRULE_SUB_NEXTMONTH:
538 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
539 : 0 : maModel.mnType = XML_timePeriod;
540 : 0 : maModel.mnTimePeriod = XML_nextMonth;
541 : 0 : break;
542 : : case BIFF12_CFRULE_SUB_THISWEEK:
543 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
544 : 0 : maModel.mnType = XML_timePeriod;
545 : 0 : maModel.mnTimePeriod = XML_thisWeek;
546 : 0 : break;
547 : : case BIFF12_CFRULE_SUB_NEXTWEEK:
548 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_NEXTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
549 : 0 : maModel.mnType = XML_timePeriod;
550 : 0 : maModel.mnTimePeriod = XML_nextWeek;
551 : 0 : break;
552 : : case BIFF12_CFRULE_SUB_LASTWEEK:
553 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_LASTWEEK, "CondFormatRule::importCfRule - unexpected time operator value" );
554 : 0 : maModel.mnType = XML_timePeriod;
555 : 0 : maModel.mnTimePeriod = XML_lastWeek;
556 : 0 : break;
557 : : case BIFF12_CFRULE_SUB_THISMONTH:
558 : : OSL_ENSURE( nOperator == BIFF12_CFRULE_TIMEOP_THISMONTH, "CondFormatRule::importCfRule - unexpected time operator value" );
559 : 0 : maModel.mnType = XML_timePeriod;
560 : 0 : maModel.mnTimePeriod = XML_thisMonth;
561 : 0 : break;
562 : : case BIFF12_CFRULE_SUB_ABOVEAVERAGE:
563 : : OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
564 : 0 : maModel.mnType = XML_aboveAverage;
565 : 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
566 : 0 : maModel.mbAboveAverage = true;
567 : 0 : maModel.mbEqualAverage = false; // does not exist as real flag...
568 : 0 : break;
569 : : case BIFF12_CFRULE_SUB_BELOWAVERAGE:
570 : : OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
571 : 0 : maModel.mnType = XML_aboveAverage;
572 : 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
573 : 0 : maModel.mbAboveAverage = false;
574 : 0 : maModel.mbEqualAverage = false; // does not exist as real flag...
575 : 0 : break;
576 : : case BIFF12_CFRULE_SUB_DUPLICATE:
577 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
578 : 0 : maModel.mnType = XML_duplicateValues;
579 : 0 : break;
580 : : case BIFF12_CFRULE_SUB_EQABOVEAVERAGE:
581 : : OSL_ENSURE( maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
582 : 0 : maModel.mnType = XML_aboveAverage;
583 : 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
584 : 0 : maModel.mbAboveAverage = true;
585 : 0 : maModel.mbEqualAverage = true; // does not exist as real flag...
586 : 0 : break;
587 : : case BIFF12_CFRULE_SUB_EQBELOWAVERAGE:
588 : : OSL_ENSURE( !maModel.mbAboveAverage, "CondFormatRule::importCfRule - wrong above-average flag" );
589 : 0 : maModel.mnType = XML_aboveAverage;
590 : 0 : maModel.mnStdDev = nOperator; // operator field used for standard deviation
591 : 0 : maModel.mbAboveAverage = false;
592 : 0 : maModel.mbEqualAverage = true; // does not exist as real flag...
593 : 0 : break;
594 : : }
595 : 0 : break;
596 : : case BIFF12_CFRULE_TYPE_COLORSCALE:
597 : : OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_COLORSCALE, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
598 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
599 : 0 : maModel.mnType = XML_colorScale;
600 : 0 : break;
601 : : case BIFF12_CFRULE_TYPE_DATABAR:
602 : : OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_DATABAR, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
603 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
604 : 0 : maModel.mnType = XML_dataBar;
605 : 0 : break;
606 : : case BIFF12_CFRULE_TYPE_TOPTEN:
607 : : OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_TOPTEN, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
608 : 0 : maModel.mnType = XML_top10;
609 : 0 : maModel.mnRank = nOperator; // operator field used for rank value
610 : 0 : break;
611 : : case BIFF12_CFRULE_TYPE_ICONSET:
612 : : OSL_ENSURE( nSubType == BIFF12_CFRULE_SUB_ICONSET, "CondFormatRule::importCfRule - rule type/subtype mismatch" );
613 : : OSL_ENSURE( nOperator == 0, "CondFormatRule::importCfRule - unexpected operator value" );
614 : 0 : maModel.mnType = XML_iconSet;
615 : 0 : break;
616 : : default:
617 : : OSL_FAIL( "CondFormatRule::importCfRule - unknown rule type" );
618 : : }
619 : 0 : }
620 : :
621 : 0 : void CondFormatRule::finalizeImport()
622 : : {
623 : 0 : sal_Int32 eOperator = ::com::sun::star::sheet::ConditionOperator2::NONE;
624 : :
625 : : /* Replacement formula for unsupported rule types (text comparison rules,
626 : : time period rules, cell type rules). The replacement formulas below may
627 : : contain several placeholders:
628 : : - '#B' will be replaced by the current relative base address (may occur
629 : : several times).
630 : : - '#R' will be replaced by the entire range list of the conditional
631 : : formatting (absolute addresses).
632 : : - '#T' will be replaced by the quoted comparison text.
633 : : - '#L' will be replaced by the length of the comparison text (from
634 : : the 'text' attribute) used in text comparison rules.
635 : : - '#K' will be replaced by the rank (from the 'rank' attribute) used in
636 : : top-10 rules.
637 : : - '#M' will be replaced by the top/bottom flag (from the 'bottom'
638 : : attribute) used in the RANK function in top-10 rules.
639 : : - '#C' will be replaced by one of the comparison operators <, >, <=, or
640 : : >=, according to the 'aboveAverage' and 'equalAverage' flags.
641 : : */
642 : 0 : OUString aReplaceFormula;
643 : :
644 [ # # # # : 0 : switch( maModel.mnType )
# # # # #
# # # # #
# # ]
645 : : {
646 : : case XML_cellIs:
647 : 0 : eOperator = CondFormatBuffer::convertToApiOperator( maModel.mnOperator );
648 : 0 : break;
649 : : case XML_duplicateValues:
650 : 0 : eOperator = CondFormatBuffer::convertToApiOperator( XML_duplicateValues );
651 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( " " );
652 : 0 : break;
653 : : case XML_expression:
654 : 0 : eOperator = ::com::sun::star::sheet::ConditionOperator2::FORMULA;
655 : 0 : break;
656 : : case XML_containsText:
657 : : OSL_ENSURE( maModel.mnOperator == XML_containsText, "CondFormatRule::finalizeImport - unexpected operator" );
658 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(SEARCH(#T,#B)))" );
659 : 0 : break;
660 : : case XML_notContainsText:
661 : : // note: type XML_notContainsText vs. operator XML_notContains
662 : : OSL_ENSURE( maModel.mnOperator == XML_notContains, "CondFormatRule::finalizeImport - unexpected operator" );
663 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "ISERROR(SEARCH(#T,#B))" );
664 : 0 : break;
665 : : case XML_beginsWith:
666 : : OSL_ENSURE( maModel.mnOperator == XML_beginsWith, "CondFormatRule::finalizeImport - unexpected operator" );
667 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "LEFT(#B,#L)=#T" );
668 : 0 : break;
669 : : case XML_endsWith:
670 : : OSL_ENSURE( maModel.mnOperator == XML_endsWith, "CondFormatRule::finalizeImport - unexpected operator" );
671 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "RIGHT(#B,#L)=#T" );
672 : 0 : break;
673 : : case XML_timePeriod:
674 [ # # # # : 0 : switch( maModel.mnTimePeriod )
# # # # #
# # ]
675 : : {
676 : : case XML_yesterday:
677 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()-1" );
678 : 0 : break;
679 : : case XML_today:
680 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()" );
681 : 0 : break;
682 : : case XML_tomorrow:
683 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "FLOOR(#B,1)=TODAY()+1" );
684 : 0 : break;
685 : : case XML_last7Days:
686 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY())" );
687 : 0 : break;
688 : : case XML_lastWeek:
689 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())-7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY()))" );
690 : 0 : break;
691 : : case XML_thisWeek:
692 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+7)" );
693 : 0 : break;
694 : : case XML_nextWeek:
695 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "AND(TODAY()-WEEKDAY(TODAY())+7<FLOOR(#B,1),FLOOR(#B,1)<=TODAY()-WEEKDAY(TODAY())+14)" );
696 : 0 : break;
697 : : case XML_lastMonth:
698 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())-1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=12,MONTH(TODAY())=1,YEAR(#B)=YEAR(TODAY())-1))" );
699 : 0 : break;
700 : : case XML_thisMonth:
701 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "AND(MONTH(#B)=MONTH(TODAY()),YEAR(#B)=YEAR(TODAY()))" );
702 : 0 : break;
703 : : case XML_nextMonth:
704 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "OR(AND(MONTH(#B)=MONTH(TODAY())+1,YEAR(#B)=YEAR(TODAY())),AND(MONTH(#B)=1,MONTH(TODAY())=12,YEAR(#B)=YEAR(TODAY())+1))" );
705 : 0 : break;
706 : : default:
707 : : OSL_FAIL( "CondFormatRule::finalizeImport - unknown time period type" );
708 : : }
709 : 0 : break;
710 : : case XML_containsBlanks:
711 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))=0" );
712 : 0 : break;
713 : : case XML_notContainsBlanks:
714 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "LEN(TRIM(#B))>0" );
715 : 0 : break;
716 : : case XML_containsErrors:
717 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "ISERROR(#B)" );
718 : 0 : break;
719 : : case XML_notContainsErrors:
720 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "NOT(ISERROR(#B))" );
721 : 0 : break;
722 : : case XML_top10:
723 [ # # ]: 0 : if( maModel.mbPercent )
724 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)/COUNT(#R)<=#K%" );
725 : : else
726 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "RANK(#B,#R,#M)<=#K" );
727 : 0 : break;
728 : : case XML_aboveAverage:
729 [ # # ]: 0 : if( maModel.mnStdDev == 0 )
730 [ # # ]: 0 : aReplaceFormula = CREATE_OUSTRING( "#B#CAVERAGE(#R)" );
731 : 0 : break;
732 : : case XML_colorScale:
733 : 0 : break;
734 : : }
735 : :
736 [ # # ]: 0 : if( !aReplaceFormula.isEmpty() )
737 : : {
738 : 0 : OUString aAddress, aRanges, aText, aComp;
739 : 0 : sal_Int32 nStrPos = aReplaceFormula.getLength();
740 [ # # ]: 0 : while( (nStrPos = aReplaceFormula.lastIndexOf( '#', nStrPos )) >= 0 )
741 : : {
742 [ # # # # : 0 : switch( aReplaceFormula[ nStrPos + 1 ] )
# # # # ]
743 : : {
744 : : case 'B': // current base address
745 [ # # ]: 0 : if( aAddress.isEmpty() )
746 [ # # ][ # # ]: 0 : aAddress = FormulaProcessorBase::generateAddress2dString( mrCondFormat.getRanges().getBaseAddress(), false );
747 : 0 : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aAddress );
748 : 0 : break;
749 : : case 'R': // range list of conditional formatting
750 [ # # ]: 0 : if( aRanges.isEmpty() )
751 [ # # ]: 0 : aRanges = FormulaProcessorBase::generateRangeList2dString( mrCondFormat.getRanges(), true, ',', true );
752 : 0 : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aRanges );
753 : 0 : break;
754 : : case 'T': // comparison text
755 [ # # ]: 0 : if( aText.isEmpty() )
756 : : // quote the comparison text, and handle embedded quote characters
757 [ # # ]: 0 : aText = FormulaProcessorBase::generateApiString( maModel.maText );
758 : 0 : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aText );
759 : 0 : break;
760 : : case 'L': // length of comparison text
761 : : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
762 : 0 : OUString::valueOf( maModel.maText.getLength() ) );
763 : 0 : break;
764 : : case 'K': // top-10 rank
765 : : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
766 : 0 : OUString::valueOf( maModel.mnRank ) );
767 : 0 : break;
768 : : case 'M': // top-10 top/bottom flag
769 : : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2,
770 [ # # ]: 0 : OUString::valueOf( static_cast< sal_Int32 >( maModel.mbBottom ? 1 : 0 ) ) );
771 : 0 : break;
772 : : case 'C': // average comparison operator
773 [ # # ]: 0 : if( aComp.isEmpty() )
774 : : aComp = maModel.mbAboveAverage ?
775 : : (maModel.mbEqualAverage ? CREATE_OUSTRING( ">=" ) : CREATE_OUSTRING( ">" )) :
776 [ # # ][ # # ]: 0 : (maModel.mbEqualAverage ? CREATE_OUSTRING( "<=" ) : CREATE_OUSTRING( "<" ));
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
777 : 0 : aReplaceFormula = aReplaceFormula.replaceAt( nStrPos, 2, aComp );
778 : 0 : break;
779 : : default:
780 : : OSL_FAIL( "CondFormatRule::finalizeImport - unknown placeholder" );
781 : : }
782 : : }
783 : :
784 : : // set the replacement formula
785 : 0 : maModel.maFormulas.clear();
786 [ # # ]: 0 : appendFormula( aReplaceFormula );
787 [ # # ]: 0 : if( eOperator != ::com::sun::star::sheet::ConditionOperator2::DUPLICATE )
788 : 0 : eOperator = ::com::sun::star::sheet::ConditionOperator2::FORMULA;
789 : : }
790 : :
791 [ # # ]: 0 : CellAddress aBaseAddr = mrCondFormat.getRanges().getBaseAddress();
792 : 0 : ScAddress aPos;
793 : 0 : ScUnoConversion::FillScAddress( aPos, aBaseAddr );
794 [ # # ][ # # ]: 0 : if( (eOperator != ::com::sun::star::sheet::ConditionOperator2::NONE) && !maModel.maFormulas.empty() )
[ # # ]
795 : : {
796 [ # # ]: 0 : ScDocument& rDoc = getScDocument();
797 : 0 : boost::scoped_ptr<ScTokenArray> pTokenArray2;
798 [ # # ]: 0 : if( maModel.maFormulas.size() >= 2)
799 : : {
800 [ # # ][ # # ]: 0 : pTokenArray2.reset(new ScTokenArray());
[ # # ]
801 [ # # ]: 0 : ScTokenConversion::ConvertToTokenArray( rDoc, *pTokenArray2.get(), maModel.maFormulas[ 1 ] );
802 : : }
803 : :
804 [ # # ]: 0 : ScTokenArray aTokenArray;
805 [ # # ][ # # ]: 0 : OUString aStyleName = getStyles().createDxfStyle( maModel.mnDxfId );
806 [ # # ]: 0 : ScTokenConversion::ConvertToTokenArray( rDoc, aTokenArray, maModel.maFormulas[ 0 ] );
807 : : ScCondFormatEntry* pNewEntry = new ScCondFormatEntry(ScCondFormatEntry::GetModeFromApi(eOperator),
808 [ # # ][ # # ]: 0 : &aTokenArray, pTokenArray2.get(), &rDoc, aPos, aStyleName);
[ # # ][ # # ]
[ # # ]
809 [ # # ][ # # ]: 0 : mpFormat->AddEntry(pNewEntry);
[ # # ]
810 : : }
811 [ # # ]: 0 : else if( mpColor )
812 : : {
813 [ # # ]: 0 : ScDocument& rDoc = getScDocument();
814 [ # # ][ # # ]: 0 : ScColorScaleFormat* pFormatEntry = new ScColorScaleFormat(&rDoc);
815 : :
816 [ # # ]: 0 : mpFormat->AddEntry(pFormatEntry);
817 : :
818 [ # # ]: 0 : mpColor->AddEntries( pFormatEntry, &rDoc, aPos );
819 : : }
820 [ # # ]: 0 : else if (mpDataBar)
821 : : {
822 [ # # ]: 0 : ScDocument& rDoc = getScDocument();
823 [ # # ][ # # ]: 0 : ScDataBarFormat* pFormatEntry = new ScDataBarFormat(&rDoc);
824 : :
825 [ # # ]: 0 : mpFormat->AddEntry(pFormatEntry);
826 [ # # ]: 0 : mpDataBar->SetData( pFormatEntry, &rDoc, aPos );
827 : :
828 : 0 : }
829 : 0 : }
830 : :
831 : 0 : ColorScaleRule* CondFormatRule::getColorScale()
832 : : {
833 [ # # ]: 0 : if(!mpColor)
834 [ # # ]: 0 : mpColor.reset( new ColorScaleRule(mrCondFormat) );
835 : :
836 : 0 : return mpColor.get();
837 : : }
838 : :
839 : 0 : DataBarRule* CondFormatRule::getDataBar()
840 : : {
841 [ # # ]: 0 : if(!mpDataBar)
842 [ # # ]: 0 : mpDataBar.reset( new DataBarRule(mrCondFormat) );
843 : :
844 : 0 : return mpDataBar.get();
845 : : }
846 : :
847 : : // ============================================================================
848 : :
849 : 0 : CondFormatModel::CondFormatModel() :
850 : 0 : mbPivot( false )
851 : : {
852 : 0 : }
853 : :
854 : : // ============================================================================
855 : :
856 : 0 : CondFormat::CondFormat( const WorksheetHelper& rHelper ) :
857 : : WorksheetHelper( rHelper ),
858 [ # # ][ # # ]: 0 : mpFormat(NULL)
859 : : {
860 : 0 : }
861 : :
862 : 0 : void CondFormat::importConditionalFormatting( const AttributeList& rAttribs )
863 : : {
864 [ # # ][ # # ]: 0 : getAddressConverter().convertToCellRangeList( maModel.maRanges, rAttribs.getString( XML_sqref, OUString() ), getSheetIndex(), true );
[ # # ]
865 : 0 : maModel.mbPivot = rAttribs.getBool( XML_pivot, false );
866 [ # # ]: 0 : mpFormat = new ScConditionalFormat(0, &getScDocument());
867 : 0 : }
868 : :
869 : 0 : CondFormatRuleRef CondFormat::importCfRule( const AttributeList& rAttribs )
870 : : {
871 : 0 : CondFormatRuleRef xRule = createRule();
872 [ # # ]: 0 : xRule->importCfRule( rAttribs );
873 [ # # ][ # # ]: 0 : insertRule( xRule );
[ # # ]
874 : 0 : return xRule;
875 : : }
876 : :
877 : 0 : void CondFormat::importCondFormatting( SequenceInputStream& rStrm )
878 : : {
879 [ # # ]: 0 : BinRangeList aRanges;
880 [ # # ]: 0 : rStrm.skip( 8 );
881 [ # # ]: 0 : rStrm >> aRanges;
882 [ # # ][ # # ]: 0 : getAddressConverter().convertToCellRangeList( maModel.maRanges, aRanges, getSheetIndex(), true );
[ # # ]
883 : 0 : }
884 : :
885 : 0 : void CondFormat::importCfRule( SequenceInputStream& rStrm )
886 : : {
887 [ # # ]: 0 : CondFormatRuleRef xRule = createRule();
888 [ # # ]: 0 : xRule->importCfRule( rStrm );
889 [ # # ][ # # ]: 0 : insertRule( xRule );
[ # # ][ # # ]
890 : 0 : }
891 : :
892 : 0 : void CondFormat::finalizeImport()
893 : : {
894 [ # # ]: 0 : ScDocument& rDoc = getScDocument();
895 [ # # ]: 0 : maRules.forEachMem( &CondFormatRule::finalizeImport );
896 [ # # ][ # # ]: 0 : sal_Int32 nIndex = getScDocument().AddCondFormat(mpFormat, maModel.maRanges.getBaseAddress().Sheet);
[ # # ]
897 : :
898 [ # # ]: 0 : ScRangeList aList;
899 [ # # ][ # # ]: 0 : for( ApiCellRangeList::const_iterator itr = maModel.maRanges.begin(); itr != maModel.maRanges.end(); ++itr)
[ # # ]
900 : : {
901 : 0 : ScRange aRange;
902 : 0 : ScUnoConversion::FillScRange(aRange, *itr);
903 [ # # ][ # # ]: 0 : ScPatternAttr aPattern( rDoc.GetPool() );
904 [ # # ][ # # ]: 0 : aPattern.GetItemSet().Put( SfxUInt32Item( ATTR_CONDITIONAL, nIndex ) );
[ # # ]
905 [ # # ]: 0 : ScMarkData aMarkData;
906 [ # # ]: 0 : aMarkData.SetMarkArea(aRange);
907 [ # # ]: 0 : rDoc.ApplySelectionPattern( aPattern , aMarkData);
908 : :
909 [ # # ]: 0 : aList.Append(aRange);
910 [ # # ][ # # ]: 0 : }
911 [ # # ][ # # ]: 0 : mpFormat->AddRange(aList);
912 : 0 : }
913 : :
914 : 0 : CondFormatRuleRef CondFormat::createRule()
915 : : {
916 [ # # ]: 0 : return CondFormatRuleRef( new CondFormatRule( *this, mpFormat ) );
917 : : }
918 : :
919 : 0 : void CondFormat::insertRule( CondFormatRuleRef xRule )
920 : : {
921 [ # # ][ # # ]: 0 : if( xRule.get() && (xRule->getPriority() > 0) )
[ # # ]
922 : : {
923 : : OSL_ENSURE( maRules.find( xRule->getPriority() ) == maRules.end(), "CondFormat::insertRule - multiple rules with equal priority" );
924 [ # # ][ # # ]: 0 : maRules[ xRule->getPriority() ] = xRule;
925 : : }
926 : 0 : }
927 : :
928 : : // ============================================================================
929 : :
930 : 60 : CondFormatBuffer::CondFormatBuffer( const WorksheetHelper& rHelper ) :
931 [ + - ]: 60 : WorksheetHelper( rHelper )
932 : : {
933 : 60 : }
934 : :
935 : 0 : CondFormatRef CondFormatBuffer::importConditionalFormatting( const AttributeList& rAttribs )
936 : : {
937 : 0 : CondFormatRef xCondFmt = createCondFormat();
938 [ # # ]: 0 : xCondFmt->importConditionalFormatting( rAttribs );
939 : 0 : return xCondFmt;
940 : : }
941 : :
942 : 0 : CondFormatRef CondFormatBuffer::importCondFormatting( SequenceInputStream& rStrm )
943 : : {
944 : 0 : CondFormatRef xCondFmt = createCondFormat();
945 [ # # ]: 0 : xCondFmt->importCondFormatting( rStrm );
946 : 0 : return xCondFmt;
947 : : }
948 : :
949 : 0 : sal_Int32 CondFormatBuffer::convertToApiOperator( sal_Int32 nToken )
950 : : {
951 [ # # # # : 0 : switch( nToken )
# # # # #
# ]
952 : : {
953 : 0 : case XML_between: return ConditionOperator2::BETWEEN;
954 : 0 : case XML_equal: return ConditionOperator2::EQUAL;
955 : 0 : case XML_greaterThan: return ConditionOperator2::GREATER;
956 : 0 : case XML_greaterThanOrEqual: return ConditionOperator2::GREATER_EQUAL;
957 : 0 : case XML_lessThan: return ConditionOperator2::LESS;
958 : 0 : case XML_lessThanOrEqual: return ConditionOperator2::LESS_EQUAL;
959 : 0 : case XML_notBetween: return ConditionOperator2::NOT_BETWEEN;
960 : 0 : case XML_notEqual: return ConditionOperator2::NOT_EQUAL;
961 : 0 : case XML_duplicateValues: return ConditionOperator2::DUPLICATE;
962 : : }
963 : 0 : return ConditionOperator2::NONE;
964 : : }
965 : :
966 : : // private --------------------------------------------------------------------
967 : :
968 : 0 : CondFormatRef CondFormatBuffer::createCondFormat()
969 : : {
970 [ # # ][ # # ]: 0 : CondFormatRef xCondFmt( new CondFormat( *this ) );
971 [ # # ]: 0 : maCondFormats.push_back( xCondFmt );
972 : 0 : return xCondFmt;
973 : : }
974 : :
975 : : // ============================================================================
976 : :
977 : : } // namespace xls
978 [ + - ][ + - ]: 24 : } // namespace oox
979 : :
980 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|