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/noncopyable.hpp>
35 #include <boost/ptr_container/ptr_set.hpp>
36 #include <boost/ptr_container/ptr_vector.hpp>
37 #include <boost/scoped_ptr.hpp>
41 struct ScRefCellValue
;
44 #define SC_COND_NOBLANKS 1
62 SC_COND_BOTTOM_PERCENT
,
63 SC_COND_ABOVE_AVERAGE
,
64 SC_COND_BELOW_AVERAGE
,
65 SC_COND_ABOVE_EQUAL_AVERAGE
,
66 SC_COND_BELOW_EQUAL_AVERAGE
,
71 SC_COND_CONTAINS_TEXT
,
72 SC_COND_NOT_CONTAINS_TEXT
,
76 class ScConditionalFormat
;
83 enum ScFormatEntryType
94 struct ScCondFormatData
102 ScDataBarInfo
* pDataBar
;
103 ScIconSetInfo
* pIconSet
;
107 class SC_DLLPUBLIC ScFormatEntry
110 ScFormatEntry(ScDocument
* pDoc
);
111 virtual ~ScFormatEntry() {}
113 virtual condformat::ScFormatEntryType
GetType() const = 0;
114 virtual void UpdateReference( UpdateRefMode eUpdateRefMode
,
115 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
) = 0;
116 virtual void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
) = 0;
118 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const = 0;
120 virtual void SetParent( ScConditionalFormat
* pNew
) = 0;
122 bool operator==( const ScFormatEntry
& ) const;
124 virtual void startRendering();
125 virtual void endRendering();
131 class approx_less
: public std::binary_function
<double, double, bool>
134 bool operator() (double nVal1
, double nVal2
) const
136 if(nVal1
< nVal2
&& !rtl::math::approxEqual(nVal1
, nVal2
))
143 class SC_DLLPUBLIC ScConditionEntry
: public ScFormatEntry
148 double nVal1
; // input or calculated
150 OUString aStrVal1
; // input or calculated
152 OUString aStrNmsp1
; // namespace to be used on (re)compilation, e.g. in XML import
153 OUString aStrNmsp2
; // namespace to be used on (re)compilation, e.g. in XML import
154 formula::FormulaGrammar::Grammar eTempGrammar1
; // grammar to be used on (re)compilation, e.g. in XML import
155 formula::FormulaGrammar::Grammar eTempGrammar2
; // grammar to be used on (re)compilation, e.g. in XML import
156 bool bIsStr1
; // for recognition of empty strings
158 ScTokenArray
* pFormula1
; // entered formula
159 ScTokenArray
* pFormula2
;
160 ScAddress aSrcPos
; // source position for formulas
162 OUString aSrcString
; // formula source position as text during XML import
163 ScFormulaCell
* pFCell1
;
164 ScFormulaCell
* pFCell2
;
169 void MakeCells( const ScAddress
& rPos
);
170 void Compile( const OUString
& rExpr1
, const OUString
& rExpr2
,
171 const OUString
& rExprNmsp1
, const OUString
& rExprNmsp2
,
172 formula::FormulaGrammar::Grammar eGrammar1
,
173 formula::FormulaGrammar::Grammar eGrammar2
,
175 void Interpret( const ScAddress
& rPos
);
177 bool IsValid( double nArg
, const ScAddress
& rPos
) const;
178 bool IsValidStr( const OUString
& rArg
, const ScAddress
& rPos
) const;
181 ScConditionEntry( ScConditionMode eOper
,
182 const OUString
& rExpr1
, const OUString
& rExpr2
,
183 ScDocument
* pDocument
, const ScAddress
& rPos
,
184 const OUString
& rExprNmsp1
, const OUString
& rExprNmsp2
,
185 formula::FormulaGrammar::Grammar eGrammar1
,
186 formula::FormulaGrammar::Grammar eGrammar2
);
187 ScConditionEntry( ScConditionMode eOper
,
188 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
189 ScDocument
* pDocument
, const ScAddress
& rPos
);
190 ScConditionEntry( const ScConditionEntry
& r
); // flat copy of formulas
191 // true copy of formulas (for Ref-Undo):
192 ScConditionEntry( ScDocument
* pDocument
, const ScConditionEntry
& r
);
193 virtual ~ScConditionEntry();
195 int operator== ( const ScConditionEntry
& r
) const;
197 virtual void SetParent( ScConditionalFormat
* pNew
) { pCondFormat
= pNew
; }
199 bool IsCellValid( ScRefCellValue
& rCell
, const ScAddress
& rPos
) const;
201 ScConditionMode
GetOperation() const { return eOp
; }
202 bool IsIgnoreBlank() const { return ( nOptions
& SC_COND_NOBLANKS
) == 0; }
203 void SetIgnoreBlank(bool bSet
);
204 ScAddress
GetSrcPos() const { return aSrcPos
; }
206 ScAddress
GetValidSrcPos() const; // adjusted to allow textual representation of expressions
208 void SetSrcString( const OUString
& rNew
); // for XML import
210 void SetFormula1( const ScTokenArray
& rArray
);
211 void SetFormula2( const ScTokenArray
& rArray
);
213 OUString
GetExpression( const ScAddress
& rCursor
, sal_uInt16 nPos
, sal_uLong nNumFmt
= 0,
214 const formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_DEFAULT
) const;
216 ScTokenArray
* CreateTokenArry( sal_uInt16 nPos
) const;
220 void UpdateReference( UpdateRefMode eUpdateRefMode
,
221 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
222 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
224 void SourceChanged( const ScAddress
& rChanged
);
226 bool MarkUsedExternalReferences() const;
228 virtual condformat::ScFormatEntryType
GetType() const { return condformat::CONDITION
; }
230 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
= NULL
) const;
232 static ScConditionMode
GetModeFromApi(sal_Int32 nOperator
);
234 virtual void endRendering();
235 virtual void startRendering();
238 virtual void DataChanged( const ScRange
* pModified
) const;
239 ScDocument
* GetDocument() const { return mpDoc
; }
240 ScConditionalFormat
* pCondFormat
;
244 bool IsDuplicate(double nArg
, const OUString
& rStr
) const;
245 bool IsTopNElement( double nArg
) const;
246 bool IsTopNPercent( double nArg
) const;
247 bool IsBottomNElement( double nArg
) const;
248 bool IsBottomNPercent( double nArg
) const;
249 bool IsAboveAverage( double nArg
, bool bEqual
) const;
250 bool IsBelowAverage( double nArg
, bool bEqual
) const;
252 bool IsError( const ScAddress
& rPos
) const;
254 void FillCache() const;
256 struct ScConditionEntryCache
258 typedef std::map
<OUString
, sal_Int32
> StringCacheType
;
259 StringCacheType maStrings
;
260 typedef std::map
<double, sal_Int32
, approx_less
> ValueCacheType
;
261 ValueCacheType maValues
;
263 // cache them for easier access
266 ScConditionEntryCache():
270 mutable boost::scoped_ptr
<ScConditionEntryCache
> mpCache
;
274 // single entry for conditional formatting
277 class SC_DLLPUBLIC ScCondFormatEntry
: public ScConditionEntry
281 using ScConditionEntry::operator==;
284 ScCondFormatEntry( ScConditionMode eOper
,
285 const OUString
& rExpr1
, const OUString
& rExpr2
,
286 ScDocument
* pDocument
, const ScAddress
& rPos
,
287 const OUString
& rStyle
,
288 const OUString
& rExprNmsp1
= EMPTY_STRING
,
289 const OUString
& rExprNmsp2
= EMPTY_STRING
,
290 formula::FormulaGrammar::Grammar eGrammar1
= formula::FormulaGrammar::GRAM_DEFAULT
,
291 formula::FormulaGrammar::Grammar eGrammar2
= formula::FormulaGrammar::GRAM_DEFAULT
);
292 ScCondFormatEntry( ScConditionMode eOper
,
293 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
294 ScDocument
* pDocument
, const ScAddress
& rPos
,
295 const OUString
& rStyle
);
296 ScCondFormatEntry( const ScCondFormatEntry
& r
);
297 ScCondFormatEntry( ScDocument
* pDocument
, const ScCondFormatEntry
& r
);
298 virtual ~ScCondFormatEntry();
300 int operator== ( const ScCondFormatEntry
& r
) const;
302 const OUString
& GetStyle() const { return aStyleName
; }
303 void UpdateStyleName(const OUString
& rNew
) { aStyleName
=rNew
; }
304 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
) const;
307 virtual void DataChanged( const ScRange
* pModified
) const;
310 namespace condformat
{
312 enum ScCondFormatDateType
331 class SC_DLLPUBLIC ScCondDateFormatEntry
: public ScFormatEntry
334 ScCondDateFormatEntry(ScDocument
* pDoc
);
335 ScCondDateFormatEntry(ScDocument
* pDoc
, const ScCondDateFormatEntry
& rEntry
);
337 bool IsValid( const ScAddress
& rPos
) const;
339 void SetDateType(condformat::ScCondFormatDateType eType
);
340 condformat::ScCondFormatDateType
GetDateType() const;
342 const OUString
& GetStyleName() const;
343 void SetStyleName( const OUString
& rStyleName
);
345 virtual condformat::ScFormatEntryType
GetType() const { return condformat::DATE
; }
346 virtual void UpdateReference( UpdateRefMode
, const ScRange
&,
347 SCsCOL
, SCsROW
, SCsTAB
) {}
348 virtual void UpdateMoveTab( SCTAB
, SCTAB
) {}
350 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const;
352 virtual void SetParent( ScConditionalFormat
* ) {}
354 bool operator==( const ScFormatEntry
& ) const;
356 virtual void startRendering();
357 virtual void endRendering();
360 condformat::ScCondFormatDateType meType
;
362 mutable boost::scoped_ptr
<Date
> mpCache
;
364 OUString maStyleName
;
368 // complete conditional formatting
371 class SC_DLLPUBLIC ScConditionalFormat
: private boost::noncopyable
374 sal_uInt32 nKey
; // Index in attributes
376 typedef boost::ptr_vector
<ScFormatEntry
> CondFormatContainer
;
377 CondFormatContainer maEntries
;
378 ScRangeList maRanges
; // Ranges for conditional format
381 ScConditionalFormat(sal_uInt32 nNewKey
, ScDocument
* pDocument
);
382 ~ScConditionalFormat();
384 // true copy of formulas (for Ref-Undo / between documents)
385 ScConditionalFormat
* Clone(ScDocument
* pNewDoc
= NULL
) const;
387 void AddEntry( ScFormatEntry
* pNew
);
388 void AddRange( const ScRangeList
& rRanges
);
389 const ScRangeList
& GetRange() const { return maRanges
; }
390 // don't use the same name as for the const version
391 ScRangeList
& GetRangeList() { return maRanges
; }
393 bool IsEmpty() const;
398 void UpdateReference( UpdateRefMode eUpdateRefMode
,
399 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
, bool bCopyAsMove
= false );
400 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
401 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
402 void RenameCellStyle( const OUString
& rOld
, const OUString
& rNew
);
404 void SourceChanged( const ScAddress
& rAddr
);
406 const ScFormatEntry
* GetEntry( sal_uInt16 nPos
) const;
408 const OUString
& GetCellStyle( ScRefCellValue
& rCell
, const ScAddress
& rPos
) const;
410 ScCondFormatData
GetData( ScRefCellValue
& rCell
, const ScAddress
& rPos
) const;
412 bool EqualEntries( const ScConditionalFormat
& r
) const;
414 void DoRepaint( const ScRange
* pModified
);
416 sal_uInt32
GetKey() const { return nKey
; }
417 void SetKey(sal_uInt32 nNew
) { nKey
= nNew
; } // only if not inserted!
419 bool MarkUsedExternalReferences() const;
421 // sorted (via PTRARR) by Index
422 // operator== only for sorting
423 bool operator ==( const ScConditionalFormat
& r
) const { return nKey
== r
.nKey
; }
424 bool operator < ( const ScConditionalFormat
& r
) const { return nKey
< r
.nKey
; }
426 void startRendering();
431 // List of areas and formats:
434 class SC_DLLPUBLIC ScConditionalFormatList
437 typedef boost::ptr_set
<ScConditionalFormat
> ConditionalFormatContainer
;
438 ConditionalFormatContainer maConditionalFormats
;
440 void operator =(ScConditionalFormatList
const &) SAL_DELETED_FUNCTION
;
443 ScConditionalFormatList() {}
444 ScConditionalFormatList(const ScConditionalFormatList
& rList
);
445 ScConditionalFormatList(ScDocument
* pDoc
, const ScConditionalFormatList
& rList
);
446 ~ScConditionalFormatList() {}
448 void InsertNew( ScConditionalFormat
* pNew
);
451 * Checks that all cond formats have a non empty range.
452 * Deletes empty cond formats.
453 * @return true if all cond formats were valid
455 bool CheckAllEntries();
457 ScConditionalFormat
* GetFormat( sal_uInt32 nKey
);
458 const ScConditionalFormat
* GetFormat( sal_uInt32 nKey
) const;
462 void UpdateReference( UpdateRefMode eUpdateRefMode
,
463 const ScRange
& rRange
, SCsCOL nDx
, SCsROW nDy
, SCsTAB nDz
);
464 void RenameCellStyle( const OUString
& rOld
, const OUString
& rNew
);
465 void UpdateMoveTab( SCTAB nOldPos
, SCTAB nNewPos
);
466 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
468 void SourceChanged( const ScAddress
& rAddr
);
470 bool operator==( const ScConditionalFormatList
& r
) const; // for Ref-Undo
472 typedef ConditionalFormatContainer::iterator iterator
;
473 typedef ConditionalFormatContainer::const_iterator const_iterator
;
476 const_iterator
begin() const;
478 const_iterator
end() const;
482 void erase(sal_uLong nIndex
);
484 void startRendering();
491 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */