1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #ifndef SC_CONDITIO_HXX
21 #define SC_CONDITIO_HXX
24 #include "address.hxx"
25 #include "formula/grammar.hxx"
27 #include "rangelst.hxx"
29 #include <rtl/math.hxx>
30 #include <tools/date.hxx>
34 #include <boost/ptr_container/ptr_set.hpp>
35 #include <boost/ptr_container/ptr_vector.hpp>
36 #include <boost/scoped_ptr.hpp>
46 #define SC_COND_NOBLANKS 1
48 #define DUMP_FORMAT_INFO 1
66 SC_COND_BOTTOM_PERCENT
,
67 SC_COND_ABOVE_AVERAGE
,
68 SC_COND_BELOW_AVERAGE
,
73 SC_COND_CONTAINS_TEXT
,
74 SC_COND_NOT_CONTAINS_TEXT
,
78 class ScConditionalFormat
;
85 enum ScFormatEntryType
96 struct ScCondFormatData
104 ScDataBarInfo
* pDataBar
;
105 ScIconSetInfo
* pIconSet
;
106 rtl::OUString aStyleName
;
109 class SC_DLLPUBLIC ScFormatEntry
112 ScFormatEntry(ScDocument
* pDoc
);
113 virtual ~ScFormatEntry() {}
115 virtual condformat::ScFormatEntryType
GetType() const = 0;
116 virtual void UpdateReference( UpdateRefMode eUpdateRefMode
,
117 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
) = 0;
118 virtual void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
) = 0;
120 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const = 0;
122 virtual void SetParent( ScConditionalFormat
* pNew
) = 0;
124 bool operator==( const ScFormatEntry
& ) const;
127 virtual void dumpInfo(rtl::OUStringBuffer
& rBuf
) const = 0;
130 virtual void startRendering();
131 virtual void endRendering();
137 class approx_less
: public std::binary_function
<double, double, bool>
140 bool operator() (double nVal1
, double nVal2
) const
142 if(nVal1
< nVal2
&& !rtl::math::approxEqual(nVal1
, nVal2
))
149 class SC_DLLPUBLIC ScConditionEntry
: public ScFormatEntry
154 double nVal1
; // input or calculated
156 rtl::OUString aStrVal1
; // input or calculated
157 rtl::OUString aStrVal2
;
158 rtl::OUString aStrNmsp1
; // namespace to be used on (re)compilation, e.g. in XML import
159 rtl::OUString aStrNmsp2
; // namespace to be used on (re)compilation, e.g. in XML import
160 formula::FormulaGrammar::Grammar eTempGrammar1
; // grammar to be used on (re)compilation, e.g. in XML import
161 formula::FormulaGrammar::Grammar eTempGrammar2
; // grammar to be used on (re)compilation, e.g. in XML import
162 bool bIsStr1
; // for recognition of empty strings
164 ScTokenArray
* pFormula1
; // entered formula
165 ScTokenArray
* pFormula2
;
166 ScAddress aSrcPos
; // source position for formulas
168 rtl::OUString aSrcString
; // formula source position as text during XML import
169 ScFormulaCell
* pFCell1
;
170 ScFormulaCell
* pFCell2
;
175 void MakeCells( const ScAddress
& rPos
);
176 void Compile( const rtl::OUString
& rExpr1
, const rtl::OUString
& rExpr2
,
177 const rtl::OUString
& rExprNmsp1
, const rtl::OUString
& rExprNmsp2
,
178 formula::FormulaGrammar::Grammar eGrammar1
,
179 formula::FormulaGrammar::Grammar eGrammar2
,
181 void Interpret( const ScAddress
& rPos
);
183 bool IsValid( double nArg
, const ScAddress
& rPos
) const;
184 bool IsValidStr( const rtl::OUString
& rArg
, const ScAddress
& rPos
) const;
187 ScConditionEntry( ScConditionMode eOper
,
188 const rtl::OUString
& rExpr1
, const rtl::OUString
& rExpr2
,
189 ScDocument
* pDocument
, const ScAddress
& rPos
,
190 const rtl::OUString
& rExprNmsp1
, const rtl::OUString
& rExprNmsp2
,
191 formula::FormulaGrammar::Grammar eGrammar1
,
192 formula::FormulaGrammar::Grammar eGrammar2
);
193 ScConditionEntry( ScConditionMode eOper
,
194 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
195 ScDocument
* pDocument
, const ScAddress
& rPos
);
196 ScConditionEntry( const ScConditionEntry
& r
); // flat copy of formulas
197 // true copy of formulas (for Ref-Undo):
198 ScConditionEntry( ScDocument
* pDocument
, const ScConditionEntry
& r
);
199 virtual ~ScConditionEntry();
201 int operator== ( const ScConditionEntry
& r
) const;
203 virtual void SetParent( ScConditionalFormat
* pNew
) { pCondFormat
= pNew
; }
205 bool IsCellValid( ScBaseCell
* pCell
, const ScAddress
& rPos
) const;
207 ScConditionMode
GetOperation() const { return eOp
; }
208 bool IsIgnoreBlank() const { return ( nOptions
& SC_COND_NOBLANKS
) == 0; }
209 void SetIgnoreBlank(bool bSet
);
210 ScAddress
GetSrcPos() const { return aSrcPos
; }
212 ScAddress
GetValidSrcPos() const; // adjusted to allow textual representation of expressions
214 void SetSrcString( const rtl::OUString
& rNew
); // for XML import
216 void SetFormula1( const ScTokenArray
& rArray
);
217 void SetFormula2( const ScTokenArray
& rArray
);
219 rtl::OUString
GetExpression( const ScAddress
& rCursor
, sal_uInt16 nPos
, sal_uLong nNumFmt
= 0,
220 const formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_DEFAULT
) const;
222 ScTokenArray
* CreateTokenArry( sal_uInt16 nPos
) const;
226 void UpdateReference( UpdateRefMode eUpdateRefMode
,
227 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
228 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
230 void SourceChanged( const ScAddress
& rChanged
);
232 bool MarkUsedExternalReferences() const;
234 virtual condformat::ScFormatEntryType
GetType() const { return condformat::CONDITION
; }
236 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
= NULL
) const;
238 static ScConditionMode
GetModeFromApi(sal_Int32 nOperator
);
241 virtual void dumpInfo(rtl::OUStringBuffer
& ) const {}
244 virtual void endRendering();
245 virtual void startRendering();
248 virtual void DataChanged( const ScRange
* pModified
) const;
249 ScDocument
* GetDocument() const { return mpDoc
; }
250 ScConditionalFormat
* pCondFormat
;
254 bool IsDuplicate(double nArg
, const rtl::OUString
& rStr
) const;
255 bool IsTopNElement( double nArg
) const;
256 bool IsTopNPercent( double nArg
) const;
257 bool IsBottomNElement( double nArg
) const;
258 bool IsBottomNPercent( double nArg
) const;
259 bool IsAboveAverage( double nArg
) const;
260 bool IsBelowAverage( double nArg
) const;
262 bool IsError( const ScAddress
& rPos
) const;
264 void FillCache() const;
266 struct ScConditionEntryCache
268 typedef std::map
<rtl::OUString
, sal_Int32
> StringCacheType
;
269 StringCacheType maStrings
;
270 typedef std::map
<double, sal_Int32
, approx_less
> ValueCacheType
;
271 ValueCacheType maValues
;
273 // cache them for easier access
276 ScConditionEntryCache():
280 mutable boost::scoped_ptr
<ScConditionEntryCache
> mpCache
;
284 // single entry for conditional formatting
287 class SC_DLLPUBLIC ScCondFormatEntry
: public ScConditionEntry
289 rtl::OUString aStyleName
;
291 using ScConditionEntry::operator==;
294 ScCondFormatEntry( ScConditionMode eOper
,
295 const rtl::OUString
& rExpr1
, const rtl::OUString
& rExpr2
,
296 ScDocument
* pDocument
, const ScAddress
& rPos
,
297 const rtl::OUString
& rStyle
,
298 const rtl::OUString
& rExprNmsp1
= EMPTY_STRING
,
299 const rtl::OUString
& rExprNmsp2
= EMPTY_STRING
,
300 formula::FormulaGrammar::Grammar eGrammar1
= formula::FormulaGrammar::GRAM_DEFAULT
,
301 formula::FormulaGrammar::Grammar eGrammar2
= formula::FormulaGrammar::GRAM_DEFAULT
);
302 ScCondFormatEntry( ScConditionMode eOper
,
303 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
304 ScDocument
* pDocument
, const ScAddress
& rPos
,
305 const rtl::OUString
& rStyle
);
306 ScCondFormatEntry( const ScCondFormatEntry
& r
);
307 ScCondFormatEntry( ScDocument
* pDocument
, const ScCondFormatEntry
& r
);
308 virtual ~ScCondFormatEntry();
310 int operator== ( const ScCondFormatEntry
& r
) const;
312 const rtl::OUString
& GetStyle() const { return aStyleName
; }
313 void UpdateStyleName(const rtl::OUString
& rNew
) { aStyleName
=rNew
; }
314 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
) const;
317 virtual void DataChanged( const ScRange
* pModified
) const;
320 namespace condformat
{
322 enum ScCondFormatDateType
341 class SC_DLLPUBLIC ScCondDateFormatEntry
: public ScFormatEntry
344 ScCondDateFormatEntry(ScDocument
* pDoc
);
345 ScCondDateFormatEntry(ScDocument
* pDoc
, const ScCondDateFormatEntry
& rEntry
);
347 bool IsValid( const ScAddress
& rPos
) const;
349 void SetDateType(condformat::ScCondFormatDateType eType
);
350 condformat::ScCondFormatDateType
GetDateType() const;
352 const rtl::OUString
& GetStyleName() const;
353 void SetStyleName( const rtl::OUString
& rStyleName
);
355 virtual condformat::ScFormatEntryType
GetType() const { return condformat::DATE
; }
356 virtual void UpdateReference( UpdateRefMode
, const ScRange
&,
357 SCsCOL
, SCsROW
, SCsTAB
) {}
358 virtual void UpdateMoveTab( SCTAB
, SCTAB
) {}
360 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const;
362 virtual void SetParent( ScConditionalFormat
* ) {}
364 bool operator==( const ScFormatEntry
& ) const;
367 virtual void dumpInfo(rtl::OUStringBuffer
& rBuf
) const;
370 virtual void startRendering();
371 virtual void endRendering();
374 condformat::ScCondFormatDateType meType
;
376 mutable boost::scoped_ptr
<Date
> mpCache
;
378 rtl::OUString maStyleName
;
382 // complete conditional formatting
385 class SC_DLLPUBLIC ScConditionalFormat
388 sal_uInt32 nKey
; // Index in attributes
390 typedef boost::ptr_vector
<ScFormatEntry
> CondFormatContainer
;
391 CondFormatContainer maEntries
;
392 ScRangeList maRanges
; // Ranges for conditional format
395 ScConditionalFormat(sal_uInt32 nNewKey
, ScDocument
* pDocument
);
396 ScConditionalFormat(const ScConditionalFormat
& r
);
397 ~ScConditionalFormat();
399 // true copy of formulas (for Ref-Undo / between documents)
400 ScConditionalFormat
* Clone(ScDocument
* pNewDoc
= NULL
) const;
402 void AddEntry( ScFormatEntry
* pNew
);
403 void AddRange( const ScRangeList
& rRanges
);
404 const ScRangeList
& GetRange() const { return maRanges
; }
405 // don't use the same name as for the const version
406 ScRangeList
& GetRangeList() { return maRanges
; }
408 bool IsEmpty() const { return maEntries
.empty(); }
409 size_t size() const { return maEntries
.size(); }
413 void UpdateReference( UpdateRefMode eUpdateRefMode
,
414 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
, bool bCopyAsMove
= false );
415 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
416 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
417 void RenameCellStyle( const rtl::OUString
& rOld
, const rtl::OUString
& rNew
);
419 void SourceChanged( const ScAddress
& rAddr
);
421 const ScFormatEntry
* GetEntry( sal_uInt16 nPos
) const;
423 const rtl::OUString
& GetCellStyle( ScBaseCell
* pCell
, const ScAddress
& rPos
) const;
425 ScCondFormatData
GetData( ScBaseCell
* pCell
, const ScAddress
& rPos
) const;
427 bool EqualEntries( const ScConditionalFormat
& r
) const;
429 void DoRepaint( const ScRange
* pModified
);
431 sal_uInt32
GetKey() const { return nKey
; }
432 void SetKey(sal_uInt32 nNew
) { nKey
= nNew
; } // only if not inserted!
434 bool MarkUsedExternalReferences() const;
437 void dumpInfo(rtl::OUStringBuffer
& rBuf
) const;
440 // sorted (via PTRARR) by Index
441 // operator== only for sorting
442 bool operator ==( const ScConditionalFormat
& r
) const { return nKey
== r
.nKey
; }
443 bool operator < ( const ScConditionalFormat
& r
) const { return nKey
< r
.nKey
; }
445 void startRendering();
450 // List of areas and formats:
453 class SC_DLLPUBLIC ScConditionalFormatList
456 boost::ptr_set
<ScConditionalFormat
> maConditionalFormats
;
457 typedef boost::ptr_set
<ScConditionalFormat
> ConditionalFormatContainer
;
459 ScConditionalFormatList() {}
460 ScConditionalFormatList(const ScConditionalFormatList
& rList
);
461 ScConditionalFormatList(ScDocument
* pDoc
, const ScConditionalFormatList
& rList
);
462 ~ScConditionalFormatList() {}
464 void InsertNew( ScConditionalFormat
* pNew
)
465 { maConditionalFormats
.insert(pNew
); }
467 * Checks that all cond formats have a non empty range.
468 * Deletes empty cond formats.
469 * @return true if all cond formats were valid
471 bool CheckAllEntries();
473 ScConditionalFormat
* GetFormat( sal_uInt32 nKey
);
477 void UpdateReference( UpdateRefMode eUpdateRefMode
,
478 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
479 void RenameCellStyle( const rtl::OUString
& rOld
, const rtl::OUString
& rNew
);
480 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
481 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
483 void SourceChanged( const ScAddress
& rAddr
);
485 bool operator==( const ScConditionalFormatList
& r
) const; // for Ref-Undo
487 typedef ConditionalFormatContainer::iterator iterator
;
488 typedef ConditionalFormatContainer::const_iterator const_iterator
;
491 const_iterator
begin() const;
493 const_iterator
end() const;
497 void erase(sal_uLong nIndex
);
499 void startRendering();
503 // see http://www.boost.org/doc/libs/1_49_0/libs/ptr_container/doc/tutorial.html#cloneability
505 inline ScFormatEntry
* new_clone( const ScFormatEntry
& rFormat
)
507 return rFormat
.Clone();
513 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */