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 INCLUDED_SC_INC_CONDITIO_HXX
21 #define INCLUDED_SC_INC_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
;
45 struct RefUpdateContext
;
46 struct RefUpdateInsertTabContext
;
47 struct RefUpdateDeleteTabContext
;
48 struct RefUpdateMoveTabContext
;
53 #define SC_COND_NOBLANKS 1
71 SC_COND_BOTTOM_PERCENT
,
72 SC_COND_ABOVE_AVERAGE
,
73 SC_COND_BELOW_AVERAGE
,
74 SC_COND_ABOVE_EQUAL_AVERAGE
,
75 SC_COND_BELOW_EQUAL_AVERAGE
,
80 SC_COND_CONTAINS_TEXT
,
81 SC_COND_NOT_CONTAINS_TEXT
,
85 class ScConditionalFormat
;
92 enum ScFormatEntryType
103 struct ScCondFormatData
111 ScDataBarInfo
* pDataBar
;
112 ScIconSetInfo
* pIconSet
;
116 class SC_DLLPUBLIC ScFormatEntry
119 ScFormatEntry(ScDocument
* pDoc
);
120 virtual ~ScFormatEntry() {}
122 virtual condformat::ScFormatEntryType
GetType() const = 0;
123 virtual void UpdateReference( sc::RefUpdateContext
& rCxt
) = 0;
124 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext
& rCxt
) = 0;
125 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext
& rCxt
) = 0;
126 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext
& rCxt
) = 0;
128 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const = 0;
130 virtual void SetParent( ScConditionalFormat
* pNew
) = 0;
132 bool operator==( const ScFormatEntry
& ) const;
134 virtual void startRendering();
135 virtual void endRendering();
141 class approx_less
: public std::binary_function
<double, double, bool>
144 bool operator() (double nVal1
, double nVal2
) const
146 if(nVal1
< nVal2
&& !rtl::math::approxEqual(nVal1
, nVal2
))
153 class SC_DLLPUBLIC ScConditionEntry
: public ScFormatEntry
158 double nVal1
; // input or calculated
160 OUString aStrVal1
; // input or calculated
162 OUString aStrNmsp1
; // namespace to be used on (re)compilation, e.g. in XML import
163 OUString aStrNmsp2
; // namespace to be used on (re)compilation, e.g. in XML import
164 formula::FormulaGrammar::Grammar eTempGrammar1
; // grammar to be used on (re)compilation, e.g. in XML import
165 formula::FormulaGrammar::Grammar eTempGrammar2
; // grammar to be used on (re)compilation, e.g. in XML import
166 bool bIsStr1
; // for recognition of empty strings
168 ScTokenArray
* pFormula1
; // entered formula
169 ScTokenArray
* pFormula2
;
170 ScAddress aSrcPos
; // source position for formulas
172 OUString aSrcString
; // formula source position as text during XML import
173 ScFormulaCell
* pFCell1
;
174 ScFormulaCell
* pFCell2
;
179 void MakeCells( const ScAddress
& rPos
);
180 void Compile( const OUString
& rExpr1
, const OUString
& rExpr2
,
181 const OUString
& rExprNmsp1
, const OUString
& rExprNmsp2
,
182 formula::FormulaGrammar::Grammar eGrammar1
,
183 formula::FormulaGrammar::Grammar eGrammar2
,
185 void Interpret( const ScAddress
& rPos
);
187 bool IsValid( double nArg
, const ScAddress
& rPos
) const;
188 bool IsValidStr( const OUString
& rArg
, const ScAddress
& rPos
) const;
191 ScConditionEntry( ScConditionMode eOper
,
192 const OUString
& rExpr1
, const OUString
& rExpr2
,
193 ScDocument
* pDocument
, const ScAddress
& rPos
,
194 const OUString
& rExprNmsp1
, const OUString
& rExprNmsp2
,
195 formula::FormulaGrammar::Grammar eGrammar1
,
196 formula::FormulaGrammar::Grammar eGrammar2
);
197 ScConditionEntry( ScConditionMode eOper
,
198 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
199 ScDocument
* pDocument
, const ScAddress
& rPos
);
200 ScConditionEntry( const ScConditionEntry
& r
); // flat copy of formulas
201 // true copy of formulas (for Ref-Undo):
202 ScConditionEntry( ScDocument
* pDocument
, const ScConditionEntry
& r
);
203 virtual ~ScConditionEntry();
205 bool operator== ( const ScConditionEntry
& r
) const;
207 virtual void SetParent( ScConditionalFormat
* pNew
) SAL_OVERRIDE
{ pCondFormat
= pNew
; }
209 bool IsCellValid( ScRefCellValue
& rCell
, const ScAddress
& rPos
) const;
211 ScConditionMode
GetOperation() const { return eOp
; }
212 void SetOperation(ScConditionMode eMode
);
213 bool IsIgnoreBlank() const { return ( nOptions
& SC_COND_NOBLANKS
) == 0; }
214 void SetIgnoreBlank(bool bSet
);
215 ScAddress
GetSrcPos() const { return aSrcPos
; }
217 ScAddress
GetValidSrcPos() const; // adjusted to allow textual representation of expressions
219 void SetSrcString( const OUString
& rNew
); // for XML import
221 void SetFormula1( const ScTokenArray
& rArray
);
222 void SetFormula2( const ScTokenArray
& rArray
);
224 OUString
GetExpression( const ScAddress
& rCursor
, sal_uInt16 nPos
, sal_uLong nNumFmt
= 0,
225 const formula::FormulaGrammar::Grammar eGrammar
= formula::FormulaGrammar::GRAM_DEFAULT
) const;
227 ScTokenArray
* CreateTokenArry( sal_uInt16 nPos
) const;
231 virtual void UpdateReference( sc::RefUpdateContext
& rCxt
) SAL_OVERRIDE
;
232 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext
& rCxt
) SAL_OVERRIDE
;
233 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext
& rCxt
) SAL_OVERRIDE
;
234 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext
& rCxt
) SAL_OVERRIDE
;
236 void SourceChanged( const ScAddress
& rChanged
);
238 bool MarkUsedExternalReferences() const;
240 virtual condformat::ScFormatEntryType
GetType() const SAL_OVERRIDE
{ return condformat::CONDITION
; }
242 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
= NULL
) const SAL_OVERRIDE
;
244 static ScConditionMode
GetModeFromApi(sal_Int32 nOperator
);
246 virtual void endRendering() SAL_OVERRIDE
;
247 virtual void startRendering() SAL_OVERRIDE
;
250 virtual void DataChanged( const ScRange
* pModified
) const;
251 ScDocument
* GetDocument() const { return mpDoc
; }
252 ScConditionalFormat
* pCondFormat
;
256 bool IsDuplicate(double nArg
, const OUString
& rStr
) const;
257 bool IsTopNElement( double nArg
) const;
258 bool IsTopNPercent( double nArg
) const;
259 bool IsBottomNElement( double nArg
) const;
260 bool IsBottomNPercent( double nArg
) const;
261 bool IsAboveAverage( double nArg
, bool bEqual
) const;
262 bool IsBelowAverage( double nArg
, bool bEqual
) const;
264 bool IsError( const ScAddress
& rPos
) const;
266 void FillCache() const;
268 struct ScConditionEntryCache
270 typedef std::map
<OUString
, sal_Int32
> StringCacheType
;
271 StringCacheType maStrings
;
272 typedef std::map
<double, sal_Int32
, approx_less
> ValueCacheType
;
273 ValueCacheType maValues
;
275 // cache them for easier access
278 ScConditionEntryCache():
282 mutable boost::scoped_ptr
<ScConditionEntryCache
> mpCache
;
285 // single condition entry for conditional formatting
286 class SC_DLLPUBLIC ScCondFormatEntry
: public ScConditionEntry
290 using ScConditionEntry::operator==;
293 ScCondFormatEntry( ScConditionMode eOper
,
294 const OUString
& rExpr1
, const OUString
& rExpr2
,
295 ScDocument
* pDocument
, const ScAddress
& rPos
,
296 const OUString
& rStyle
,
297 const OUString
& rExprNmsp1
= EMPTY_OUSTRING
,
298 const OUString
& rExprNmsp2
= EMPTY_OUSTRING
,
299 formula::FormulaGrammar::Grammar eGrammar1
= formula::FormulaGrammar::GRAM_DEFAULT
,
300 formula::FormulaGrammar::Grammar eGrammar2
= formula::FormulaGrammar::GRAM_DEFAULT
);
301 ScCondFormatEntry( ScConditionMode eOper
,
302 const ScTokenArray
* pArr1
, const ScTokenArray
* pArr2
,
303 ScDocument
* pDocument
, const ScAddress
& rPos
,
304 const OUString
& rStyle
);
305 ScCondFormatEntry( const ScCondFormatEntry
& r
);
306 ScCondFormatEntry( ScDocument
* pDocument
, const ScCondFormatEntry
& r
);
307 virtual ~ScCondFormatEntry();
309 bool operator== ( const ScCondFormatEntry
& r
) const;
311 const OUString
& GetStyle() const { return aStyleName
; }
312 void UpdateStyleName(const OUString
& rNew
) { aStyleName
=rNew
; }
313 virtual ScFormatEntry
* Clone(ScDocument
* pDoc
) const SAL_OVERRIDE
;
316 virtual void DataChanged( const ScRange
* pModified
) const SAL_OVERRIDE
;
319 namespace condformat
{
321 enum ScCondFormatDateType
340 class SC_DLLPUBLIC ScCondDateFormatEntry
: public ScFormatEntry
343 ScCondDateFormatEntry(ScDocument
* pDoc
);
344 ScCondDateFormatEntry(ScDocument
* pDoc
, const ScCondDateFormatEntry
& rEntry
);
346 bool IsValid( const ScAddress
& rPos
) const;
348 void SetDateType(condformat::ScCondFormatDateType eType
);
349 condformat::ScCondFormatDateType
GetDateType() const { return meType
;}
351 const OUString
& GetStyleName() const { return maStyleName
;}
352 void SetStyleName( const OUString
& rStyleName
);
354 virtual condformat::ScFormatEntryType
GetType() const SAL_OVERRIDE
{ return condformat::DATE
; }
355 virtual void UpdateReference( sc::RefUpdateContext
& ) SAL_OVERRIDE
{}
356 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext
& ) SAL_OVERRIDE
{}
357 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext
& ) SAL_OVERRIDE
{}
358 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext
& ) SAL_OVERRIDE
{}
360 virtual ScFormatEntry
* Clone( ScDocument
* pDoc
= NULL
) const SAL_OVERRIDE
;
362 virtual void SetParent( ScConditionalFormat
* ) SAL_OVERRIDE
{}
364 bool operator==( const ScFormatEntry
& ) const;
366 virtual void startRendering() SAL_OVERRIDE
;
367 virtual void endRendering() SAL_OVERRIDE
;
370 condformat::ScCondFormatDateType meType
;
372 mutable boost::scoped_ptr
<Date
> mpCache
;
374 OUString maStyleName
;
377 // complete conditional formatting
378 class SC_DLLPUBLIC ScConditionalFormat
: private boost::noncopyable
381 sal_uInt32 nKey
; // Index in attributes
383 typedef boost::ptr_vector
<ScFormatEntry
> CondFormatContainer
;
384 CondFormatContainer maEntries
;
385 ScRangeList maRanges
; // Ranges for conditional format
388 ScConditionalFormat(sal_uInt32 nNewKey
, ScDocument
* pDocument
);
389 ~ScConditionalFormat();
391 // true copy of formulas (for Ref-Undo / between documents)
392 ScConditionalFormat
* Clone(ScDocument
* pNewDoc
= NULL
) const;
394 void AddEntry( ScFormatEntry
* pNew
);
395 void RemoveEntry(size_t nIndex
);
396 void SetRange( const ScRangeList
& rRanges
);
397 const ScRangeList
& GetRange() const { return maRanges
; }
398 // don't use the same name as for the const version
399 ScRangeList
& GetRangeList() { return maRanges
; }
401 ScDocument
* GetDocument() { return pDoc
; }
403 bool IsEmpty() const;
408 void UpdateReference( sc::RefUpdateContext
& rCxt
, bool bCopyAsMove
= false );
409 void UpdateInsertTab( sc::RefUpdateInsertTabContext
& rCxt
);
410 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext
& rCxt
);
411 void UpdateMoveTab( sc::RefUpdateMoveTabContext
& rCxt
);
413 void InsertRow(SCTAB nTab
, SCCOL nColStart
, SCCOL nColEnd
, SCROW nRowStart
, SCSIZE nSize
);
414 void InsertCol(SCTAB nTab
, SCROW nRowStart
, SCROW nRowEnd
, SCCOL nColStart
, SCSIZE nSize
);
416 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
417 void RenameCellStyle( const OUString
& rOld
, const OUString
& rNew
);
419 void SourceChanged( const ScAddress
& rAddr
);
421 const ScFormatEntry
* GetEntry( sal_uInt16 nPos
) const;
423 const OUString
& GetCellStyle( ScRefCellValue
& rCell
, const ScAddress
& rPos
) const;
425 ScCondFormatData
GetData( ScRefCellValue
& rCell
, 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;
436 // sorted (via boost::ptr_set) by Index
437 // operator== only for sorting
438 bool operator ==( const ScConditionalFormat
& r
) const { return nKey
== r
.nKey
; }
439 bool operator < ( const ScConditionalFormat
& r
) const { return nKey
< r
.nKey
; }
441 void startRendering();
445 // List of all conditional formats in a sheet
446 class SC_DLLPUBLIC ScConditionalFormatList
449 typedef boost::ptr_set
<ScConditionalFormat
> ConditionalFormatContainer
;
450 ConditionalFormatContainer maConditionalFormats
;
452 void operator =(ScConditionalFormatList
const &) SAL_DELETED_FUNCTION
;
455 ScConditionalFormatList() {}
456 ScConditionalFormatList(const ScConditionalFormatList
& rList
);
457 ScConditionalFormatList(ScDocument
* pDoc
, const ScConditionalFormatList
& rList
);
458 ~ScConditionalFormatList() {}
460 void InsertNew( ScConditionalFormat
* pNew
);
463 * Checks that all cond formats have a non empty range.
464 * Deletes empty cond formats.
465 * @return true if all cond formats were valid
467 bool CheckAllEntries();
469 ScConditionalFormat
* GetFormat( sal_uInt32 nKey
);
470 const ScConditionalFormat
* GetFormat( sal_uInt32 nKey
) const;
474 void UpdateReference( sc::RefUpdateContext
& rCxt
);
475 void UpdateInsertTab( sc::RefUpdateInsertTabContext
& rCxt
);
476 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext
& rCxt
);
477 void UpdateMoveTab( sc::RefUpdateMoveTabContext
& rCxt
);
479 void InsertRow(SCTAB nTab
, SCCOL nColStart
, SCCOL nColEnd
, SCROW nRowStart
, SCSIZE nSize
);
480 void InsertCol(SCTAB nTab
, SCROW nRowStart
, SCROW nRowEnd
, SCCOL nColStart
, SCSIZE nSize
);
482 void RenameCellStyle( const OUString
& rOld
, const OUString
& rNew
);
483 void DeleteArea( SCCOL nCol1
, SCROW nRow1
, SCCOL nCol2
, SCROW nRow2
);
485 void SourceChanged( const ScAddress
& rAddr
);
487 bool operator==( const ScConditionalFormatList
& r
) const; // for Ref-Undo
489 typedef ConditionalFormatContainer::iterator iterator
;
490 typedef ConditionalFormatContainer::const_iterator const_iterator
;
493 const_iterator
begin() const;
495 const_iterator
end() const;
500 void erase(sal_uLong nIndex
);
502 void startRendering();
508 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */