build fix
[LibreOffice.git] / sc / inc / conditio.hxx
blobe3a19d05cf03bcc39a0769df3f97177456dbf6a8
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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
23 #include "global.hxx"
24 #include "address.hxx"
25 #include <formula/grammar.hxx>
26 #include "scdllapi.h"
27 #include "rangelst.hxx"
29 #include <svl/hint.hxx>
30 #include <svl/listener.hxx>
31 #include <svl/broadcast.hxx>
33 #include <comphelper/stl_types.hxx>
35 #include <rtl/math.hxx>
36 #include <tools/date.hxx>
38 #include <map>
39 #include <memory>
40 #include <set>
42 class ScFormulaCell;
43 class ScTokenArray;
44 struct ScRefCellValue;
46 namespace sc {
48 struct RefUpdateContext;
49 struct RefUpdateInsertTabContext;
50 struct RefUpdateDeleteTabContext;
51 struct RefUpdateMoveTabContext;
55 // nOptions Flags
56 #define SC_COND_NOBLANKS 1
58 enum ScConditionMode
60 SC_COND_EQUAL,
61 SC_COND_LESS,
62 SC_COND_GREATER,
63 SC_COND_EQLESS,
64 SC_COND_EQGREATER,
65 SC_COND_NOTEQUAL,
66 SC_COND_BETWEEN,
67 SC_COND_NOTBETWEEN,
68 SC_COND_DUPLICATE,
69 SC_COND_NOTDUPLICATE,
70 SC_COND_DIRECT,
71 SC_COND_TOP10,
72 SC_COND_BOTTOM10,
73 SC_COND_TOP_PERCENT,
74 SC_COND_BOTTOM_PERCENT,
75 SC_COND_ABOVE_AVERAGE,
76 SC_COND_BELOW_AVERAGE,
77 SC_COND_ABOVE_EQUAL_AVERAGE,
78 SC_COND_BELOW_EQUAL_AVERAGE,
79 SC_COND_ERROR,
80 SC_COND_NOERROR,
81 SC_COND_BEGINS_WITH,
82 SC_COND_ENDS_WITH,
83 SC_COND_CONTAINS_TEXT,
84 SC_COND_NOT_CONTAINS_TEXT,
85 SC_COND_NONE
88 class ScFormulaListener : public SvtListener
90 private:
91 std::vector<ScRange> maCells;
92 mutable bool mbDirty;
93 ScDocument* mpDoc;
94 std::function<void()> maCallbackFunction;
96 void startListening(ScTokenArray* pTokens, const ScRange& rPos);
98 public:
99 explicit ScFormulaListener(ScFormulaCell* pCell);
100 explicit ScFormulaListener(ScDocument* pDoc);
101 virtual ~ScFormulaListener() override;
103 void Notify( const SfxHint& rHint ) override;
105 bool NeedsRepaint() const;
107 void addTokenArray(ScTokenArray* pTokens, const ScRange& rRange);
108 void stopListening();
109 void setCallback(const std::function<void()>& aCallbackFunction);
112 class ScConditionalFormat;
113 struct ScDataBarInfo;
114 struct ScIconSetInfo;
116 namespace condformat
119 enum ScFormatEntryType
121 CONDITION,
122 COLORSCALE,
123 DATABAR,
124 ICONSET,
125 DATE
130 struct ScCondFormatData
132 ScCondFormatData():
133 pColorScale(nullptr),
134 pDataBar(nullptr),
135 pIconSet(nullptr) {}
137 Color* pColorScale;
138 ScDataBarInfo* pDataBar;
139 ScIconSetInfo* pIconSet;
140 OUString aStyleName;
143 class SC_DLLPUBLIC ScFormatEntry
145 public:
146 ScFormatEntry(ScDocument* pDoc);
147 virtual ~ScFormatEntry() {}
149 virtual condformat::ScFormatEntryType GetType() const = 0;
150 virtual void UpdateReference( sc::RefUpdateContext& rCxt ) = 0;
151 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt ) = 0;
152 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt ) = 0;
153 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt ) = 0;
155 virtual ScFormatEntry* Clone( ScDocument* pDoc ) const = 0;
157 virtual void SetParent( ScConditionalFormat* pNew ) = 0;
159 bool operator==( const ScFormatEntry& ) const;
161 virtual void startRendering();
162 virtual void endRendering();
163 protected:
164 ScDocument* mpDoc;
168 class approx_less : public std::binary_function<double, double, bool>
170 public:
171 bool operator() (double nVal1, double nVal2) const
173 if(nVal1 < nVal2 && !rtl::math::approxEqual(nVal1, nVal2))
174 return true;
176 return false;
180 class SC_DLLPUBLIC ScConditionEntry : public ScFormatEntry
182 // stored data:
183 ScConditionMode eOp;
184 sal_uInt16 nOptions;
185 double nVal1; // input or calculated
186 double nVal2;
187 OUString aStrVal1; // input or calculated
188 OUString aStrVal2;
189 OUString aStrNmsp1; // namespace to be used on (re)compilation, e.g. in XML import
190 OUString aStrNmsp2; // namespace to be used on (re)compilation, e.g. in XML import
191 formula::FormulaGrammar::Grammar eTempGrammar1; // grammar to be used on (re)compilation, e.g. in XML import
192 formula::FormulaGrammar::Grammar eTempGrammar2; // grammar to be used on (re)compilation, e.g. in XML import
193 bool bIsStr1; // for recognition of empty strings
194 bool bIsStr2;
195 ScTokenArray* pFormula1; // entered formula
196 ScTokenArray* pFormula2;
197 ScAddress aSrcPos; // source position for formulas
198 // temporary data:
199 OUString aSrcString; // formula source position as text during XML import
200 ScFormulaCell* pFCell1;
201 ScFormulaCell* pFCell2;
202 bool bRelRef1;
203 bool bRelRef2;
204 bool bFirstRun;
205 std::unique_ptr<ScFormulaListener> mpListener;
207 void MakeCells( const ScAddress& rPos );
208 void Compile( const OUString& rExpr1, const OUString& rExpr2,
209 const OUString& rExprNmsp1, const OUString& rExprNmsp2,
210 formula::FormulaGrammar::Grammar eGrammar1,
211 formula::FormulaGrammar::Grammar eGrammar2,
212 bool bTextToReal );
213 void Interpret( const ScAddress& rPos );
215 bool IsValid( double nArg, const ScAddress& rPos ) const;
216 bool IsValidStr( const OUString& rArg, const ScAddress& rPos ) const;
217 void StartListening();
219 public:
220 ScConditionEntry( ScConditionMode eOper,
221 const OUString& rExpr1, const OUString& rExpr2,
222 ScDocument* pDocument, const ScAddress& rPos,
223 const OUString& rExprNmsp1, const OUString& rExprNmsp2,
224 formula::FormulaGrammar::Grammar eGrammar1,
225 formula::FormulaGrammar::Grammar eGrammar2 );
226 ScConditionEntry( ScConditionMode eOper,
227 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
228 ScDocument* pDocument, const ScAddress& rPos );
229 ScConditionEntry( const ScConditionEntry& r ); // flat copy of formulas
230 // true copy of formulas (for Ref-Undo):
231 ScConditionEntry( ScDocument* pDocument, const ScConditionEntry& r );
232 virtual ~ScConditionEntry() override;
234 bool operator== ( const ScConditionEntry& r ) const;
236 virtual void SetParent( ScConditionalFormat* pNew ) override;
238 bool IsCellValid( ScRefCellValue& rCell, const ScAddress& rPos ) const;
240 ScConditionMode GetOperation() const { return eOp; }
241 void SetOperation(ScConditionMode eMode);
242 bool IsIgnoreBlank() const { return ( nOptions & SC_COND_NOBLANKS ) == 0; }
243 void SetIgnoreBlank(bool bSet);
244 const ScAddress& GetSrcPos() const { return aSrcPos; }
246 ScAddress GetValidSrcPos() const; // adjusted to allow textual representation of expressions
248 void SetSrcString( const OUString& rNew ); // for XML import
250 void SetFormula1( const ScTokenArray& rArray );
251 void SetFormula2( const ScTokenArray& rArray );
253 OUString GetExpression( const ScAddress& rCursor, sal_uInt16 nPos, sal_uLong nNumFmt = 0,
254 const formula::FormulaGrammar::Grammar eGrammar = formula::FormulaGrammar::GRAM_DEFAULT ) const;
256 /** Create a flat copy using ScTokenArray copy-ctor with
257 shared tokens. */
258 ScTokenArray* CreateFlatCopiedTokenArray( sal_uInt16 nPos ) const;
260 void CompileAll();
261 void CompileXML();
262 virtual void UpdateReference( sc::RefUpdateContext& rCxt ) override;
263 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt ) override;
264 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt ) override;
265 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt ) override;
267 bool MarkUsedExternalReferences() const;
269 virtual condformat::ScFormatEntryType GetType() const override { return condformat::CONDITION; }
271 virtual ScFormatEntry* Clone(ScDocument* pDoc) const override;
273 static ScConditionMode GetModeFromApi(sal_Int32 nOperator);
275 virtual void endRendering() override;
276 virtual void startRendering() override;
278 bool NeedsRepaint() const;
280 protected:
281 virtual void DataChanged() const;
282 ScDocument* GetDocument() const { return mpDoc; }
283 ScConditionalFormat* pCondFormat;
285 private:
287 bool IsDuplicate(double nArg, const OUString& rStr) const;
288 bool IsTopNElement( double nArg ) const;
289 bool IsTopNPercent( double nArg ) const;
290 bool IsBottomNElement( double nArg ) const;
291 bool IsBottomNPercent( double nArg ) const;
292 bool IsAboveAverage( double nArg, bool bEqual ) const;
293 bool IsBelowAverage( double nArg, bool bEqual ) const;
295 bool IsError( const ScAddress& rPos ) const;
297 void FillCache() const;
299 struct ScConditionEntryCache
301 typedef std::map<OUString, sal_Int32> StringCacheType;
302 StringCacheType maStrings;
303 typedef std::map<double, sal_Int32, approx_less> ValueCacheType;
304 ValueCacheType maValues;
306 // cache them for easier access
307 size_t nValueItems;
309 ScConditionEntryCache():
310 nValueItems(0) {}
313 mutable std::unique_ptr<ScConditionEntryCache> mpCache;
316 // single condition entry for conditional formatting
317 class SC_DLLPUBLIC ScCondFormatEntry : public ScConditionEntry
319 OUString aStyleName;
321 using ScConditionEntry::operator==;
323 public:
324 ScCondFormatEntry( ScConditionMode eOper,
325 const OUString& rExpr1, const OUString& rExpr2,
326 ScDocument* pDocument, const ScAddress& rPos,
327 const OUString& rStyle,
328 const OUString& rExprNmsp1 = EMPTY_OUSTRING,
329 const OUString& rExprNmsp2 = EMPTY_OUSTRING,
330 formula::FormulaGrammar::Grammar eGrammar1 = formula::FormulaGrammar::GRAM_DEFAULT,
331 formula::FormulaGrammar::Grammar eGrammar2 = formula::FormulaGrammar::GRAM_DEFAULT );
332 ScCondFormatEntry( ScConditionMode eOper,
333 const ScTokenArray* pArr1, const ScTokenArray* pArr2,
334 ScDocument* pDocument, const ScAddress& rPos,
335 const OUString& rStyle );
336 ScCondFormatEntry( const ScCondFormatEntry& r );
337 ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r );
338 virtual ~ScCondFormatEntry() override;
340 bool operator== ( const ScCondFormatEntry& r ) const;
342 const OUString& GetStyle() const { return aStyleName; }
343 void UpdateStyleName(const OUString& rNew) { aStyleName=rNew; }
344 virtual ScFormatEntry* Clone(ScDocument* pDoc) const override;
346 protected:
347 virtual void DataChanged() const override;
350 namespace condformat {
352 enum ScCondFormatDateType
354 TODAY,
355 YESTERDAY,
356 TOMORROW,
357 LAST7DAYS,
358 THISWEEK,
359 LASTWEEK,
360 NEXTWEEK,
361 THISMONTH,
362 LASTMONTH,
363 NEXTMONTH,
364 THISYEAR,
365 LASTYEAR,
366 NEXTYEAR
371 class SC_DLLPUBLIC ScCondDateFormatEntry : public ScFormatEntry
373 public:
374 ScCondDateFormatEntry(ScDocument* pDoc);
375 ScCondDateFormatEntry(ScDocument* pDoc, const ScCondDateFormatEntry& rEntry);
377 bool IsValid( const ScAddress& rPos ) const;
379 void SetDateType(condformat::ScCondFormatDateType eType);
380 condformat::ScCondFormatDateType GetDateType() const { return meType;}
382 const OUString& GetStyleName() const { return maStyleName;}
383 void SetStyleName( const OUString& rStyleName );
385 virtual condformat::ScFormatEntryType GetType() const override { return condformat::DATE; }
386 virtual void UpdateReference( sc::RefUpdateContext& ) override {}
387 virtual void UpdateInsertTab( sc::RefUpdateInsertTabContext& ) override {}
388 virtual void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& ) override {}
389 virtual void UpdateMoveTab( sc::RefUpdateMoveTabContext& ) override {}
391 virtual ScFormatEntry* Clone( ScDocument* pDoc ) const override;
393 virtual void SetParent( ScConditionalFormat* ) override {}
395 virtual void startRendering() override;
396 virtual void endRendering() override;
398 private:
399 condformat::ScCondFormatDateType meType;
401 mutable std::unique_ptr<Date> mpCache;
403 OUString maStyleName;
406 // complete conditional formatting
407 class SC_DLLPUBLIC ScConditionalFormat
409 ScDocument* pDoc;
410 sal_uInt32 nKey; // Index in attributes
412 typedef std::vector<std::unique_ptr<ScFormatEntry>> CondFormatContainer;
413 CondFormatContainer maEntries;
414 ScRangeList maRanges; // Ranges for conditional format
416 public:
417 ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument);
418 ~ScConditionalFormat();
419 ScConditionalFormat(const ScConditionalFormat&) = delete;
420 const ScConditionalFormat& operator=(const ScConditionalFormat&) = delete;
422 // true copy of formulas (for Ref-Undo / between documents)
423 ScConditionalFormat* Clone(ScDocument* pNewDoc = nullptr) const;
425 void AddEntry( ScFormatEntry* pNew );
426 void RemoveEntry(size_t nIndex);
427 void SetRange( const ScRangeList& rRanges );
428 const ScRangeList& GetRange() const { return maRanges; }
429 // don't use the same name as for the const version
430 ScRangeList& GetRangeList() { return maRanges; }
432 bool IsEmpty() const;
433 size_t size() const;
435 void CompileAll();
436 void CompileXML();
437 void UpdateReference( sc::RefUpdateContext& rCxt, bool bCopyAsMove = false );
438 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt );
439 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt );
440 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt );
442 void InsertRow(SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW nRowStart, SCSIZE nSize);
443 void InsertCol(SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, SCCOL nColStart, SCSIZE nSize);
445 void DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
446 void RenameCellStyle( const OUString& rOld, const OUString& rNew );
448 const ScFormatEntry* GetEntry( sal_uInt16 nPos ) const;
450 const OUString& GetCellStyle( ScRefCellValue& rCell, const ScAddress& rPos ) const;
452 ScCondFormatData GetData( ScRefCellValue& rCell, const ScAddress& rPos ) const;
454 bool EqualEntries( const ScConditionalFormat& r ) const;
456 void DoRepaint();
458 sal_uInt32 GetKey() const { return nKey; }
459 void SetKey(sal_uInt32 nNew) { nKey = nNew; } // only if not inserted!
461 bool MarkUsedExternalReferences() const;
463 // sorted (via std::set) by Index
464 bool operator < ( const ScConditionalFormat& r ) const { return nKey < r.nKey; }
466 void startRendering();
467 void endRendering();
470 // List of all conditional formats in a sheet
471 class SC_DLLPUBLIC ScConditionalFormatList
473 private:
474 typedef std::set<std::unique_ptr<ScConditionalFormat>,
475 comphelper::UniquePtrValueLess<ScConditionalFormat>> ConditionalFormatContainer;
476 ConditionalFormatContainer m_ConditionalFormats;
478 void operator =(ScConditionalFormatList const &) = delete;
480 public:
481 ScConditionalFormatList() {}
482 ScConditionalFormatList(const ScConditionalFormatList& rList);
483 ScConditionalFormatList(ScDocument* pDoc, const ScConditionalFormatList& rList);
484 ~ScConditionalFormatList() {}
486 void InsertNew( ScConditionalFormat* pNew );
489 * Checks that all cond formats have a non empty range.
490 * Deletes empty cond formats.
491 * @return true if all cond formats were valid
493 bool CheckAllEntries();
495 ScConditionalFormat* GetFormat( sal_uInt32 nKey );
496 const ScConditionalFormat* GetFormat( sal_uInt32 nKey ) const;
498 void CompileAll();
499 void CompileXML();
500 void UpdateReference( sc::RefUpdateContext& rCxt );
501 void UpdateInsertTab( sc::RefUpdateInsertTabContext& rCxt );
502 void UpdateDeleteTab( sc::RefUpdateDeleteTabContext& rCxt );
503 void UpdateMoveTab( sc::RefUpdateMoveTabContext& rCxt );
505 void InsertRow(SCTAB nTab, SCCOL nColStart, SCCOL nColEnd, SCROW nRowStart, SCSIZE nSize);
506 void InsertCol(SCTAB nTab, SCROW nRowStart, SCROW nRowEnd, SCCOL nColStart, SCSIZE nSize);
508 void RenameCellStyle( const OUString& rOld, const OUString& rNew );
509 void DeleteArea( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 );
511 typedef ConditionalFormatContainer::iterator iterator;
512 typedef ConditionalFormatContainer::const_iterator const_iterator;
514 iterator begin();
515 const_iterator begin() const;
516 iterator end();
517 const_iterator end() const;
519 size_t size() const;
521 void erase(sal_uLong nIndex);
522 void clear();
524 void startRendering();
525 void endRendering();
527 sal_uInt32 getMaxKey() const;
530 #endif
532 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */