1b3f79822SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3b3f79822SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4b3f79822SAndrew Rist * or more contributor license agreements. See the NOTICE file
5b3f79822SAndrew Rist * distributed with this work for additional information
6b3f79822SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7b3f79822SAndrew Rist * to you under the Apache License, Version 2.0 (the
8b3f79822SAndrew Rist * "License"); you may not use this file except in compliance
9b3f79822SAndrew Rist * with the License. You may obtain a copy of the License at
10b3f79822SAndrew Rist *
11b3f79822SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12b3f79822SAndrew Rist *
13b3f79822SAndrew Rist * Unless required by applicable law or agreed to in writing,
14b3f79822SAndrew Rist * software distributed under the License is distributed on an
15b3f79822SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16b3f79822SAndrew Rist * KIND, either express or implied. See the License for the
17b3f79822SAndrew Rist * specific language governing permissions and limitations
18b3f79822SAndrew Rist * under the License.
19b3f79822SAndrew Rist *
20b3f79822SAndrew Rist *************************************************************/
21b3f79822SAndrew Rist
22b3f79822SAndrew Rist
23cdf0e10cSrcweir
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sc.hxx"
26cdf0e10cSrcweir
27cdf0e10cSrcweir
28cdf0e10cSrcweir
29cdf0e10cSrcweir //------------------------------------------------------------------
30cdf0e10cSrcweir
31cdf0e10cSrcweir #include "scitems.hxx"
32cdf0e10cSrcweir #include <sfx2/objsh.hxx>
33cdf0e10cSrcweir #include <svl/itemset.hxx>
34cdf0e10cSrcweir #include <svl/zforlist.hxx>
35cdf0e10cSrcweir #include <rtl/math.hxx>
36cdf0e10cSrcweir #include <unotools/collatorwrapper.hxx>
37cdf0e10cSrcweir
38cdf0e10cSrcweir #include "conditio.hxx"
39cdf0e10cSrcweir #include "cell.hxx"
40cdf0e10cSrcweir #include "document.hxx"
41cdf0e10cSrcweir #include "hints.hxx"
42cdf0e10cSrcweir #include "compiler.hxx"
43cdf0e10cSrcweir #include "rechead.hxx"
44cdf0e10cSrcweir #include "rangelst.hxx"
45cdf0e10cSrcweir #include "stlpool.hxx"
46cdf0e10cSrcweir #include "rangenam.hxx"
47cdf0e10cSrcweir
48cdf0e10cSrcweir using namespace formula;
49cdf0e10cSrcweir //------------------------------------------------------------------------
50cdf0e10cSrcweir
51cdf0e10cSrcweir SV_IMPL_OP_PTRARR_SORT( ScConditionalFormats_Impl, ScConditionalFormatPtr );
52cdf0e10cSrcweir
53cdf0e10cSrcweir //------------------------------------------------------------------------
54cdf0e10cSrcweir
lcl_HasRelRef(ScDocument * pDoc,ScTokenArray * pFormula,sal_uInt16 nRecursion=0)55cdf0e10cSrcweir sal_Bool lcl_HasRelRef( ScDocument* pDoc, ScTokenArray* pFormula, sal_uInt16 nRecursion = 0 )
56cdf0e10cSrcweir {
57cdf0e10cSrcweir if (pFormula)
58cdf0e10cSrcweir {
59cdf0e10cSrcweir pFormula->Reset();
60cdf0e10cSrcweir FormulaToken* t;
61cdf0e10cSrcweir for( t = pFormula->Next(); t; t = pFormula->Next() )
62cdf0e10cSrcweir {
63cdf0e10cSrcweir switch( t->GetType() )
64cdf0e10cSrcweir {
65cdf0e10cSrcweir case svDoubleRef:
66cdf0e10cSrcweir {
67cdf0e10cSrcweir ScSingleRefData& rRef2 = static_cast<ScToken*>(t)->GetDoubleRef().Ref2;
68cdf0e10cSrcweir if ( rRef2.IsColRel() || rRef2.IsRowRel() || rRef2.IsTabRel() )
69cdf0e10cSrcweir return sal_True;
70cdf0e10cSrcweir }
71cdf0e10cSrcweir // fall through
72cdf0e10cSrcweir
73cdf0e10cSrcweir case svSingleRef:
74cdf0e10cSrcweir {
75cdf0e10cSrcweir ScSingleRefData& rRef1 = static_cast<ScToken*>(t)->GetSingleRef();
76cdf0e10cSrcweir if ( rRef1.IsColRel() || rRef1.IsRowRel() || rRef1.IsTabRel() )
77cdf0e10cSrcweir return sal_True;
78cdf0e10cSrcweir }
79cdf0e10cSrcweir break;
80cdf0e10cSrcweir
81cdf0e10cSrcweir case svIndex:
82cdf0e10cSrcweir {
83cdf0e10cSrcweir if( t->GetOpCode() == ocName ) // DB areas always absolute
84cdf0e10cSrcweir if( ScRangeData* pRangeData = pDoc->GetRangeName()->FindIndex( t->GetIndex() ) )
85cdf0e10cSrcweir if( (nRecursion < 42) && lcl_HasRelRef( pDoc, pRangeData->GetCode(), nRecursion + 1 ) )
86cdf0e10cSrcweir return sal_True;
87cdf0e10cSrcweir }
88cdf0e10cSrcweir break;
89cdf0e10cSrcweir
90cdf0e10cSrcweir // #i34474# function result dependent on cell position
91cdf0e10cSrcweir case svByte:
92cdf0e10cSrcweir {
93cdf0e10cSrcweir switch( t->GetOpCode() )
94cdf0e10cSrcweir {
95cdf0e10cSrcweir case ocRow: // ROW() returns own row index
96cdf0e10cSrcweir case ocColumn: // COLUMN() returns own column index
97cdf0e10cSrcweir case ocTable: // SHEET() returns own sheet index
98cdf0e10cSrcweir case ocCell: // CELL() may return own cell address
99cdf0e10cSrcweir return sal_True;
100cdf0e10cSrcweir // break;
101cdf0e10cSrcweir default:
102cdf0e10cSrcweir {
103cdf0e10cSrcweir // added to avoid warnings
104cdf0e10cSrcweir }
105cdf0e10cSrcweir }
106cdf0e10cSrcweir }
107cdf0e10cSrcweir break;
108cdf0e10cSrcweir
109cdf0e10cSrcweir default:
110cdf0e10cSrcweir {
111cdf0e10cSrcweir // added to avoid warnings
112cdf0e10cSrcweir }
113cdf0e10cSrcweir }
114cdf0e10cSrcweir }
115cdf0e10cSrcweir }
116cdf0e10cSrcweir return sal_False;
117cdf0e10cSrcweir }
118cdf0e10cSrcweir
ScConditionEntry(const ScConditionEntry & r)119cdf0e10cSrcweir ScConditionEntry::ScConditionEntry( const ScConditionEntry& r ) :
120cdf0e10cSrcweir eOp(r.eOp),
121cdf0e10cSrcweir nOptions(r.nOptions),
122cdf0e10cSrcweir nVal1(r.nVal1),
123cdf0e10cSrcweir nVal2(r.nVal2),
124cdf0e10cSrcweir aStrVal1(r.aStrVal1),
125cdf0e10cSrcweir aStrVal2(r.aStrVal2),
126cdf0e10cSrcweir aStrNmsp1(r.aStrNmsp1),
127cdf0e10cSrcweir aStrNmsp2(r.aStrNmsp2),
128cdf0e10cSrcweir eTempGrammar1(r.eTempGrammar1),
129cdf0e10cSrcweir eTempGrammar2(r.eTempGrammar2),
130cdf0e10cSrcweir bIsStr1(r.bIsStr1),
131cdf0e10cSrcweir bIsStr2(r.bIsStr2),
132cdf0e10cSrcweir pFormula1(NULL),
133cdf0e10cSrcweir pFormula2(NULL),
134cdf0e10cSrcweir aSrcPos(r.aSrcPos),
135cdf0e10cSrcweir aSrcString(r.aSrcString),
136cdf0e10cSrcweir pFCell1(NULL),
137cdf0e10cSrcweir pFCell2(NULL),
138cdf0e10cSrcweir pDoc(r.pDoc),
139cdf0e10cSrcweir bRelRef1(r.bRelRef1),
140cdf0e10cSrcweir bRelRef2(r.bRelRef2),
141cdf0e10cSrcweir bFirstRun(sal_True)
142cdf0e10cSrcweir {
143cdf0e10cSrcweir // ScTokenArray copy ctor erzeugt flache Kopie
144cdf0e10cSrcweir
145cdf0e10cSrcweir if (r.pFormula1)
146cdf0e10cSrcweir pFormula1 = new ScTokenArray( *r.pFormula1 );
147cdf0e10cSrcweir if (r.pFormula2)
148cdf0e10cSrcweir pFormula2 = new ScTokenArray( *r.pFormula2 );
149cdf0e10cSrcweir
150cdf0e10cSrcweir // Formelzellen werden erst bei IsValid angelegt
151cdf0e10cSrcweir }
152cdf0e10cSrcweir
ScConditionEntry(ScDocument * pDocument,const ScConditionEntry & r)153cdf0e10cSrcweir ScConditionEntry::ScConditionEntry( ScDocument* pDocument, const ScConditionEntry& r ) :
154cdf0e10cSrcweir eOp(r.eOp),
155cdf0e10cSrcweir nOptions(r.nOptions),
156cdf0e10cSrcweir nVal1(r.nVal1),
157cdf0e10cSrcweir nVal2(r.nVal2),
158cdf0e10cSrcweir aStrVal1(r.aStrVal1),
159cdf0e10cSrcweir aStrVal2(r.aStrVal2),
160cdf0e10cSrcweir aStrNmsp1(r.aStrNmsp1),
161cdf0e10cSrcweir aStrNmsp2(r.aStrNmsp2),
162cdf0e10cSrcweir eTempGrammar1(r.eTempGrammar1),
163cdf0e10cSrcweir eTempGrammar2(r.eTempGrammar2),
164cdf0e10cSrcweir bIsStr1(r.bIsStr1),
165cdf0e10cSrcweir bIsStr2(r.bIsStr2),
166cdf0e10cSrcweir pFormula1(NULL),
167cdf0e10cSrcweir pFormula2(NULL),
168cdf0e10cSrcweir aSrcPos(r.aSrcPos),
169cdf0e10cSrcweir aSrcString(r.aSrcString),
170cdf0e10cSrcweir pFCell1(NULL),
171cdf0e10cSrcweir pFCell2(NULL),
172cdf0e10cSrcweir pDoc(pDocument),
173cdf0e10cSrcweir bRelRef1(r.bRelRef1),
174cdf0e10cSrcweir bRelRef2(r.bRelRef2),
175cdf0e10cSrcweir bFirstRun(sal_True)
176cdf0e10cSrcweir {
177cdf0e10cSrcweir // echte Kopie der Formeln (fuer Ref-Undo)
178cdf0e10cSrcweir
179cdf0e10cSrcweir if (r.pFormula1)
180cdf0e10cSrcweir pFormula1 = r.pFormula1->Clone();
181cdf0e10cSrcweir if (r.pFormula2)
182cdf0e10cSrcweir pFormula2 = r.pFormula2->Clone();
183cdf0e10cSrcweir
184cdf0e10cSrcweir // Formelzellen werden erst bei IsValid angelegt
185cdf0e10cSrcweir //! im Clipboard nicht - dann vorher interpretieren !!!
186cdf0e10cSrcweir }
187cdf0e10cSrcweir
ScConditionEntry(ScConditionMode eOper,const String & rExpr1,const String & rExpr2,ScDocument * pDocument,const ScAddress & rPos,const String & rExprNmsp1,const String & rExprNmsp2,FormulaGrammar::Grammar eGrammar1,FormulaGrammar::Grammar eGrammar2)188cdf0e10cSrcweir ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
189cdf0e10cSrcweir const String& rExpr1, const String& rExpr2, ScDocument* pDocument, const ScAddress& rPos,
190cdf0e10cSrcweir const String& rExprNmsp1, const String& rExprNmsp2,
191cdf0e10cSrcweir FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2 ) :
192cdf0e10cSrcweir eOp(eOper),
193cdf0e10cSrcweir nOptions(0), // spaeter...
194cdf0e10cSrcweir nVal1(0.0),
195cdf0e10cSrcweir nVal2(0.0),
196cdf0e10cSrcweir aStrNmsp1(rExprNmsp1),
197cdf0e10cSrcweir aStrNmsp2(rExprNmsp2),
198cdf0e10cSrcweir eTempGrammar1(eGrammar1),
199cdf0e10cSrcweir eTempGrammar2(eGrammar2),
200cdf0e10cSrcweir bIsStr1(sal_False),
201cdf0e10cSrcweir bIsStr2(sal_False),
202cdf0e10cSrcweir pFormula1(NULL),
203cdf0e10cSrcweir pFormula2(NULL),
204cdf0e10cSrcweir aSrcPos(rPos),
205cdf0e10cSrcweir pFCell1(NULL),
206cdf0e10cSrcweir pFCell2(NULL),
207cdf0e10cSrcweir pDoc(pDocument),
208cdf0e10cSrcweir bRelRef1(sal_False),
209cdf0e10cSrcweir bRelRef2(sal_False),
210cdf0e10cSrcweir bFirstRun(sal_True)
211cdf0e10cSrcweir {
212cdf0e10cSrcweir Compile( rExpr1, rExpr2, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2, sal_False );
213cdf0e10cSrcweir
214cdf0e10cSrcweir // Formelzellen werden erst bei IsValid angelegt
215cdf0e10cSrcweir }
216cdf0e10cSrcweir
ScConditionEntry(ScConditionMode eOper,const ScTokenArray * pArr1,const ScTokenArray * pArr2,ScDocument * pDocument,const ScAddress & rPos)217cdf0e10cSrcweir ScConditionEntry::ScConditionEntry( ScConditionMode eOper,
218cdf0e10cSrcweir const ScTokenArray* pArr1, const ScTokenArray* pArr2,
219cdf0e10cSrcweir ScDocument* pDocument, const ScAddress& rPos ) :
220cdf0e10cSrcweir eOp(eOper),
221cdf0e10cSrcweir nOptions(0), // spaeter...
222cdf0e10cSrcweir nVal1(0.0),
223cdf0e10cSrcweir nVal2(0.0),
224cdf0e10cSrcweir eTempGrammar1(FormulaGrammar::GRAM_DEFAULT),
225cdf0e10cSrcweir eTempGrammar2(FormulaGrammar::GRAM_DEFAULT),
226cdf0e10cSrcweir bIsStr1(sal_False),
227cdf0e10cSrcweir bIsStr2(sal_False),
228cdf0e10cSrcweir pFormula1(NULL),
229cdf0e10cSrcweir pFormula2(NULL),
230cdf0e10cSrcweir aSrcPos(rPos),
231cdf0e10cSrcweir pFCell1(NULL),
232cdf0e10cSrcweir pFCell2(NULL),
233cdf0e10cSrcweir pDoc(pDocument),
234cdf0e10cSrcweir bRelRef1(sal_False),
235cdf0e10cSrcweir bRelRef2(sal_False),
236cdf0e10cSrcweir bFirstRun(sal_True)
237cdf0e10cSrcweir {
238cdf0e10cSrcweir if ( pArr1 )
239cdf0e10cSrcweir {
240cdf0e10cSrcweir pFormula1 = new ScTokenArray( *pArr1 );
241cdf0e10cSrcweir if ( pFormula1->GetLen() == 1 )
242cdf0e10cSrcweir {
243cdf0e10cSrcweir // einzelne (konstante Zahl) ?
244cdf0e10cSrcweir FormulaToken* pToken = pFormula1->First();
245cdf0e10cSrcweir if ( pToken->GetOpCode() == ocPush )
246cdf0e10cSrcweir {
247cdf0e10cSrcweir if ( pToken->GetType() == svDouble )
248cdf0e10cSrcweir {
249cdf0e10cSrcweir nVal1 = pToken->GetDouble();
250cdf0e10cSrcweir DELETEZ(pFormula1); // nicht als Formel merken
251cdf0e10cSrcweir }
252cdf0e10cSrcweir else if ( pToken->GetType() == svString )
253cdf0e10cSrcweir {
254cdf0e10cSrcweir bIsStr1 = sal_True;
255cdf0e10cSrcweir aStrVal1 = pToken->GetString();
256cdf0e10cSrcweir DELETEZ(pFormula1); // nicht als Formel merken
257cdf0e10cSrcweir }
258cdf0e10cSrcweir }
259cdf0e10cSrcweir }
260cdf0e10cSrcweir bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
261cdf0e10cSrcweir }
262cdf0e10cSrcweir if ( pArr2 )
263cdf0e10cSrcweir {
264cdf0e10cSrcweir pFormula2 = new ScTokenArray( *pArr2 );
265cdf0e10cSrcweir if ( pFormula2->GetLen() == 1 )
266cdf0e10cSrcweir {
267cdf0e10cSrcweir // einzelne (konstante Zahl) ?
268cdf0e10cSrcweir FormulaToken* pToken = pFormula2->First();
269cdf0e10cSrcweir if ( pToken->GetOpCode() == ocPush )
270cdf0e10cSrcweir {
271cdf0e10cSrcweir if ( pToken->GetType() == svDouble )
272cdf0e10cSrcweir {
273cdf0e10cSrcweir nVal2 = pToken->GetDouble();
274cdf0e10cSrcweir DELETEZ(pFormula2); // nicht als Formel merken
275cdf0e10cSrcweir }
276cdf0e10cSrcweir else if ( pToken->GetType() == svString )
277cdf0e10cSrcweir {
278cdf0e10cSrcweir bIsStr2 = sal_True;
279cdf0e10cSrcweir aStrVal2 = pToken->GetString();
280cdf0e10cSrcweir DELETEZ(pFormula2); // nicht als Formel merken
281cdf0e10cSrcweir }
282cdf0e10cSrcweir }
283cdf0e10cSrcweir }
284cdf0e10cSrcweir bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
285cdf0e10cSrcweir }
286cdf0e10cSrcweir
287cdf0e10cSrcweir // formula cells are created at IsValid
288cdf0e10cSrcweir }
289cdf0e10cSrcweir
~ScConditionEntry()290cdf0e10cSrcweir ScConditionEntry::~ScConditionEntry()
291cdf0e10cSrcweir {
292cdf0e10cSrcweir delete pFCell1;
293cdf0e10cSrcweir delete pFCell2;
294cdf0e10cSrcweir
295cdf0e10cSrcweir delete pFormula1;
296cdf0e10cSrcweir delete pFormula2;
297cdf0e10cSrcweir }
298cdf0e10cSrcweir
Compile(const String & rExpr1,const String & rExpr2,const String & rExprNmsp1,const String & rExprNmsp2,FormulaGrammar::Grammar eGrammar1,FormulaGrammar::Grammar eGrammar2,sal_Bool bTextToReal)299cdf0e10cSrcweir void ScConditionEntry::Compile( const String& rExpr1, const String& rExpr2,
300cdf0e10cSrcweir const String& rExprNmsp1, const String& rExprNmsp2,
301cdf0e10cSrcweir FormulaGrammar::Grammar eGrammar1, FormulaGrammar::Grammar eGrammar2, sal_Bool bTextToReal )
302cdf0e10cSrcweir {
303cdf0e10cSrcweir if ( rExpr1.Len() || rExpr2.Len() )
304cdf0e10cSrcweir {
305cdf0e10cSrcweir ScCompiler aComp( pDoc, aSrcPos );
306cdf0e10cSrcweir
307cdf0e10cSrcweir if ( rExpr1.Len() )
308cdf0e10cSrcweir {
309cdf0e10cSrcweir aComp.SetGrammar( eGrammar1 );
310cdf0e10cSrcweir if ( pDoc->IsImportingXML() && !bTextToReal )
311cdf0e10cSrcweir {
312cdf0e10cSrcweir // temporary formula string as string tokens
313cdf0e10cSrcweir //! merge with lcl_ScDocFunc_CreateTokenArrayXML
314cdf0e10cSrcweir pFormula1 = new ScTokenArray;
315cdf0e10cSrcweir pFormula1->AddString( rExpr1 );
316cdf0e10cSrcweir // bRelRef1 is set when the formula is compiled again (CompileXML)
317cdf0e10cSrcweir }
318cdf0e10cSrcweir else
319cdf0e10cSrcweir {
320cdf0e10cSrcweir pFormula1 = aComp.CompileString( rExpr1, rExprNmsp1 );
321cdf0e10cSrcweir if ( pFormula1->GetLen() == 1 )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir // einzelne (konstante Zahl) ?
324cdf0e10cSrcweir FormulaToken* pToken = pFormula1->First();
325cdf0e10cSrcweir if ( pToken->GetOpCode() == ocPush )
326cdf0e10cSrcweir {
327cdf0e10cSrcweir if ( pToken->GetType() == svDouble )
328cdf0e10cSrcweir {
329cdf0e10cSrcweir nVal1 = pToken->GetDouble();
330cdf0e10cSrcweir DELETEZ(pFormula1); // nicht als Formel merken
331cdf0e10cSrcweir }
332cdf0e10cSrcweir else if ( pToken->GetType() == svString )
333cdf0e10cSrcweir {
334cdf0e10cSrcweir bIsStr1 = sal_True;
335cdf0e10cSrcweir aStrVal1 = pToken->GetString();
336cdf0e10cSrcweir DELETEZ(pFormula1); // nicht als Formel merken
337cdf0e10cSrcweir }
338cdf0e10cSrcweir }
339cdf0e10cSrcweir }
340cdf0e10cSrcweir bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
341cdf0e10cSrcweir }
342cdf0e10cSrcweir }
343cdf0e10cSrcweir
344cdf0e10cSrcweir if ( rExpr2.Len() )
345cdf0e10cSrcweir {
346cdf0e10cSrcweir aComp.SetGrammar( eGrammar2 );
347cdf0e10cSrcweir if ( pDoc->IsImportingXML() && !bTextToReal )
348cdf0e10cSrcweir {
349cdf0e10cSrcweir // temporary formula string as string tokens
350cdf0e10cSrcweir //! merge with lcl_ScDocFunc_CreateTokenArrayXML
351cdf0e10cSrcweir pFormula2 = new ScTokenArray;
352cdf0e10cSrcweir pFormula2->AddString( rExpr2 );
353cdf0e10cSrcweir // bRelRef2 is set when the formula is compiled again (CompileXML)
354cdf0e10cSrcweir }
355cdf0e10cSrcweir else
356cdf0e10cSrcweir {
357cdf0e10cSrcweir pFormula2 = aComp.CompileString( rExpr2, rExprNmsp2 );
358cdf0e10cSrcweir if ( pFormula2->GetLen() == 1 )
359cdf0e10cSrcweir {
360cdf0e10cSrcweir // einzelne (konstante Zahl) ?
361cdf0e10cSrcweir FormulaToken* pToken = pFormula2->First();
362cdf0e10cSrcweir if ( pToken->GetOpCode() == ocPush )
363cdf0e10cSrcweir {
364cdf0e10cSrcweir if ( pToken->GetType() == svDouble )
365cdf0e10cSrcweir {
366cdf0e10cSrcweir nVal2 = pToken->GetDouble();
367cdf0e10cSrcweir DELETEZ(pFormula2); // nicht als Formel merken
368cdf0e10cSrcweir }
369cdf0e10cSrcweir else if ( pToken->GetType() == svString )
370cdf0e10cSrcweir {
371cdf0e10cSrcweir bIsStr2 = sal_True;
372cdf0e10cSrcweir aStrVal2 = pToken->GetString();
373cdf0e10cSrcweir DELETEZ(pFormula2); // nicht als Formel merken
374cdf0e10cSrcweir }
375cdf0e10cSrcweir }
376cdf0e10cSrcweir }
377cdf0e10cSrcweir bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
378cdf0e10cSrcweir }
379cdf0e10cSrcweir }
380cdf0e10cSrcweir }
381cdf0e10cSrcweir }
382cdf0e10cSrcweir
MakeCells(const ScAddress & rPos)383cdf0e10cSrcweir void ScConditionEntry::MakeCells( const ScAddress& rPos ) // Formelzellen anlegen
384cdf0e10cSrcweir {
385cdf0e10cSrcweir if ( !pDoc->IsClipOrUndo() ) // nie im Clipboard rechnen!
386cdf0e10cSrcweir {
387cdf0e10cSrcweir if ( pFormula1 && !pFCell1 && !bRelRef1 )
388cdf0e10cSrcweir {
389cdf0e10cSrcweir pFCell1 = new ScFormulaCell( pDoc, rPos, pFormula1 );
390cdf0e10cSrcweir pFCell1->StartListeningTo( pDoc );
391cdf0e10cSrcweir }
392cdf0e10cSrcweir
393cdf0e10cSrcweir if ( pFormula2 && !pFCell2 && !bRelRef2 )
394cdf0e10cSrcweir {
395cdf0e10cSrcweir pFCell2 = new ScFormulaCell( pDoc, rPos, pFormula2 );
396cdf0e10cSrcweir pFCell2->StartListeningTo( pDoc );
397cdf0e10cSrcweir }
398cdf0e10cSrcweir }
399cdf0e10cSrcweir }
400cdf0e10cSrcweir
SetIgnoreBlank(sal_Bool bSet)401cdf0e10cSrcweir void ScConditionEntry::SetIgnoreBlank(sal_Bool bSet)
402cdf0e10cSrcweir {
403cdf0e10cSrcweir // Das Bit SC_COND_NOBLANKS wird gesetzt, wenn Blanks nicht ignoriert werden
404cdf0e10cSrcweir // (nur bei Gueltigkeit)
405cdf0e10cSrcweir
406cdf0e10cSrcweir if (bSet)
407cdf0e10cSrcweir nOptions &= ~SC_COND_NOBLANKS;
408cdf0e10cSrcweir else
409cdf0e10cSrcweir nOptions |= SC_COND_NOBLANKS;
410cdf0e10cSrcweir }
411cdf0e10cSrcweir
CompileAll()412cdf0e10cSrcweir void ScConditionEntry::CompileAll()
413cdf0e10cSrcweir {
414cdf0e10cSrcweir // Formelzellen loeschen, dann wird beim naechsten IsValid neu kompiliert
415cdf0e10cSrcweir
416cdf0e10cSrcweir DELETEZ(pFCell1);
417cdf0e10cSrcweir DELETEZ(pFCell2);
418cdf0e10cSrcweir }
419cdf0e10cSrcweir
CompileXML()420cdf0e10cSrcweir void ScConditionEntry::CompileXML()
421cdf0e10cSrcweir {
422cdf0e10cSrcweir // #b4974740# First parse the formula source position if it was stored as text
423cdf0e10cSrcweir
424cdf0e10cSrcweir if ( aSrcString.Len() )
425cdf0e10cSrcweir {
426cdf0e10cSrcweir ScAddress aNew;
427cdf0e10cSrcweir /* XML is always in OOo:A1 format, although R1C1 would be more amenable
428cdf0e10cSrcweir * to compression */
429cdf0e10cSrcweir if ( aNew.Parse( aSrcString, pDoc ) & SCA_VALID )
430cdf0e10cSrcweir aSrcPos = aNew;
431cdf0e10cSrcweir // if the position is invalid, there isn't much we can do at this time
432cdf0e10cSrcweir aSrcString.Erase();
433cdf0e10cSrcweir }
434cdf0e10cSrcweir
435cdf0e10cSrcweir // Convert the text tokens that were created during XML import into real tokens.
436cdf0e10cSrcweir
437cdf0e10cSrcweir Compile( GetExpression(aSrcPos, 0, 0, eTempGrammar1),
438cdf0e10cSrcweir GetExpression(aSrcPos, 1, 0, eTempGrammar2),
439cdf0e10cSrcweir aStrNmsp1, aStrNmsp2, eTempGrammar1, eTempGrammar2, sal_True );
440cdf0e10cSrcweir }
441cdf0e10cSrcweir
SetSrcString(const String & rNew)442cdf0e10cSrcweir void ScConditionEntry::SetSrcString( const String& rNew )
443cdf0e10cSrcweir {
444cdf0e10cSrcweir // aSrcString is only evaluated in CompileXML
445cdf0e10cSrcweir DBG_ASSERT( pDoc->IsImportingXML(), "SetSrcString is only valid for XML import" );
446cdf0e10cSrcweir
447cdf0e10cSrcweir aSrcString = rNew;
448cdf0e10cSrcweir }
449cdf0e10cSrcweir
SetFormula1(const ScTokenArray & rArray)450cdf0e10cSrcweir void ScConditionEntry::SetFormula1( const ScTokenArray& rArray )
451cdf0e10cSrcweir {
452cdf0e10cSrcweir DELETEZ( pFormula1 );
453cdf0e10cSrcweir if( rArray.GetLen() > 0 )
454cdf0e10cSrcweir {
455cdf0e10cSrcweir pFormula1 = new ScTokenArray( rArray );
456cdf0e10cSrcweir bRelRef1 = lcl_HasRelRef( pDoc, pFormula1 );
457cdf0e10cSrcweir }
458cdf0e10cSrcweir }
459cdf0e10cSrcweir
SetFormula2(const ScTokenArray & rArray)460cdf0e10cSrcweir void ScConditionEntry::SetFormula2( const ScTokenArray& rArray )
461cdf0e10cSrcweir {
462cdf0e10cSrcweir DELETEZ( pFormula2 );
463cdf0e10cSrcweir if( rArray.GetLen() > 0 )
464cdf0e10cSrcweir {
465cdf0e10cSrcweir pFormula2 = new ScTokenArray( rArray );
466cdf0e10cSrcweir bRelRef2 = lcl_HasRelRef( pDoc, pFormula2 );
467cdf0e10cSrcweir }
468cdf0e10cSrcweir }
469cdf0e10cSrcweir
lcl_CondUpdateInsertTab(ScTokenArray & rCode,SCTAB nInsTab,SCTAB nPosTab,sal_Bool & rChanged)470cdf0e10cSrcweir void lcl_CondUpdateInsertTab( ScTokenArray& rCode, SCTAB nInsTab, SCTAB nPosTab, sal_Bool& rChanged )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir // Insert table: only update absolute table references.
473cdf0e10cSrcweir // (Similar to ScCompiler::UpdateInsertTab with bIsName=sal_True, result is the same as for named ranges)
474cdf0e10cSrcweir // For deleting, ScCompiler::UpdateDeleteTab is used because of the handling of invalid references.
475cdf0e10cSrcweir
476cdf0e10cSrcweir rCode.Reset();
477cdf0e10cSrcweir ScToken* p = static_cast<ScToken*>(rCode.GetNextReference());
478cdf0e10cSrcweir while( p )
479cdf0e10cSrcweir {
480cdf0e10cSrcweir ScSingleRefData& rRef1 = p->GetSingleRef();
481cdf0e10cSrcweir if ( !rRef1.IsTabRel() && nInsTab <= rRef1.nTab )
482cdf0e10cSrcweir {
483cdf0e10cSrcweir rRef1.nTab += 1;
484cdf0e10cSrcweir rRef1.nRelTab = rRef1.nTab - nPosTab;
485cdf0e10cSrcweir rChanged = sal_True;
486cdf0e10cSrcweir }
487cdf0e10cSrcweir if( p->GetType() == svDoubleRef )
488cdf0e10cSrcweir {
489cdf0e10cSrcweir ScSingleRefData& rRef2 = p->GetDoubleRef().Ref2;
490cdf0e10cSrcweir if ( !rRef2.IsTabRel() && nInsTab <= rRef2.nTab )
491cdf0e10cSrcweir {
492cdf0e10cSrcweir rRef2.nTab += 1;
493cdf0e10cSrcweir rRef2.nRelTab = rRef2.nTab - nPosTab;
494cdf0e10cSrcweir rChanged = sal_True;
495cdf0e10cSrcweir }
496cdf0e10cSrcweir }
497cdf0e10cSrcweir p = static_cast<ScToken*>(rCode.GetNextReference());
498cdf0e10cSrcweir }
499cdf0e10cSrcweir }
500cdf0e10cSrcweir
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & rRange,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)501cdf0e10cSrcweir void ScConditionEntry::UpdateReference( UpdateRefMode eUpdateRefMode,
502cdf0e10cSrcweir const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
503cdf0e10cSrcweir {
504cdf0e10cSrcweir sal_Bool bInsertTab = ( eUpdateRefMode == URM_INSDEL && nDz == 1 );
505cdf0e10cSrcweir sal_Bool bDeleteTab = ( eUpdateRefMode == URM_INSDEL && nDz == -1 );
506cdf0e10cSrcweir
507cdf0e10cSrcweir sal_Bool bChanged1 = sal_False;
508cdf0e10cSrcweir sal_Bool bChanged2 = sal_False;
509cdf0e10cSrcweir
510cdf0e10cSrcweir if (pFormula1)
511cdf0e10cSrcweir {
512cdf0e10cSrcweir if ( bInsertTab )
513cdf0e10cSrcweir lcl_CondUpdateInsertTab( *pFormula1, rRange.aStart.Tab(), aSrcPos.Tab(), bChanged1 );
514cdf0e10cSrcweir else
515cdf0e10cSrcweir {
516cdf0e10cSrcweir ScCompiler aComp( pDoc, aSrcPos, *pFormula1 );
517cdf0e10cSrcweir aComp.SetGrammar(pDoc->GetGrammar());
518cdf0e10cSrcweir if ( bDeleteTab )
519cdf0e10cSrcweir aComp.UpdateDeleteTab( rRange.aStart.Tab(), sal_False, sal_True, bChanged1 );
520cdf0e10cSrcweir else
521cdf0e10cSrcweir aComp.UpdateNameReference( eUpdateRefMode, rRange, nDx, nDy, nDz, bChanged1 );
522cdf0e10cSrcweir }
523cdf0e10cSrcweir
524cdf0e10cSrcweir if (bChanged1)
525cdf0e10cSrcweir DELETEZ(pFCell1); // is created again in IsValid
526cdf0e10cSrcweir }
527cdf0e10cSrcweir if (pFormula2)
528cdf0e10cSrcweir {
529cdf0e10cSrcweir if ( bInsertTab )
530cdf0e10cSrcweir lcl_CondUpdateInsertTab( *pFormula2, rRange.aStart.Tab(), aSrcPos.Tab(), bChanged2 );
531cdf0e10cSrcweir else
532cdf0e10cSrcweir {
533cdf0e10cSrcweir ScCompiler aComp( pDoc, aSrcPos, *pFormula2);
534cdf0e10cSrcweir aComp.SetGrammar(pDoc->GetGrammar());
535cdf0e10cSrcweir if ( bDeleteTab )
536cdf0e10cSrcweir aComp.UpdateDeleteTab( rRange.aStart.Tab(), sal_False, sal_True, bChanged2 );
537cdf0e10cSrcweir else
538cdf0e10cSrcweir aComp.UpdateNameReference( eUpdateRefMode, rRange, nDx, nDy, nDz, bChanged2 );
539cdf0e10cSrcweir }
540cdf0e10cSrcweir
541cdf0e10cSrcweir if (bChanged2)
542cdf0e10cSrcweir DELETEZ(pFCell2); // is created again in IsValid
543cdf0e10cSrcweir }
544cdf0e10cSrcweir }
545cdf0e10cSrcweir
UpdateMoveTab(SCTAB nOldPos,SCTAB nNewPos)546cdf0e10cSrcweir void ScConditionEntry::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
547cdf0e10cSrcweir {
548cdf0e10cSrcweir if (pFormula1)
549cdf0e10cSrcweir {
550cdf0e10cSrcweir ScCompiler aComp( pDoc, aSrcPos, *pFormula1);
551cdf0e10cSrcweir aComp.SetGrammar(pDoc->GetGrammar());
552cdf0e10cSrcweir aComp.UpdateMoveTab(nOldPos, nNewPos, sal_True );
553cdf0e10cSrcweir DELETEZ(pFCell1);
554cdf0e10cSrcweir }
555cdf0e10cSrcweir if (pFormula2)
556cdf0e10cSrcweir {
557cdf0e10cSrcweir ScCompiler aComp( pDoc, aSrcPos, *pFormula2);
558cdf0e10cSrcweir aComp.SetGrammar(pDoc->GetGrammar());
559cdf0e10cSrcweir aComp.UpdateMoveTab(nOldPos, nNewPos, sal_True );
560cdf0e10cSrcweir DELETEZ(pFCell2);
561cdf0e10cSrcweir }
562cdf0e10cSrcweir }
563cdf0e10cSrcweir
564cdf0e10cSrcweir //! als Vergleichsoperator ans TokenArray ???
565cdf0e10cSrcweir
lcl_IsEqual(const ScTokenArray * pArr1,const ScTokenArray * pArr2)566cdf0e10cSrcweir sal_Bool lcl_IsEqual( const ScTokenArray* pArr1, const ScTokenArray* pArr2 )
567cdf0e10cSrcweir {
568cdf0e10cSrcweir // verglichen wird nur das nicht-UPN Array
569cdf0e10cSrcweir
570cdf0e10cSrcweir if ( pArr1 && pArr2 )
571cdf0e10cSrcweir {
572cdf0e10cSrcweir sal_uInt16 nLen = pArr1->GetLen();
573cdf0e10cSrcweir if ( pArr2->GetLen() != nLen )
574cdf0e10cSrcweir return sal_False;
575cdf0e10cSrcweir
576cdf0e10cSrcweir FormulaToken** ppToken1 = pArr1->GetArray();
577cdf0e10cSrcweir FormulaToken** ppToken2 = pArr2->GetArray();
578cdf0e10cSrcweir for (sal_uInt16 i=0; i<nLen; i++)
579cdf0e10cSrcweir {
580cdf0e10cSrcweir if ( ppToken1[i] != ppToken2[i] &&
581cdf0e10cSrcweir !(*ppToken1[i] == *ppToken2[i]) )
582cdf0e10cSrcweir return sal_False; // Unterschied
583cdf0e10cSrcweir }
584cdf0e10cSrcweir return sal_True; // alle Eintraege gleich
585cdf0e10cSrcweir }
586cdf0e10cSrcweir else
587cdf0e10cSrcweir return !pArr1 && !pArr2; // beide 0 -> gleich
588cdf0e10cSrcweir }
589cdf0e10cSrcweir
operator ==(const ScConditionEntry & r) const590cdf0e10cSrcweir int ScConditionEntry::operator== ( const ScConditionEntry& r ) const
591cdf0e10cSrcweir {
592cdf0e10cSrcweir sal_Bool bEq = (eOp == r.eOp && nOptions == r.nOptions &&
593cdf0e10cSrcweir lcl_IsEqual( pFormula1, r.pFormula1 ) &&
594cdf0e10cSrcweir lcl_IsEqual( pFormula2, r.pFormula2 ));
595cdf0e10cSrcweir if (bEq)
596cdf0e10cSrcweir {
597cdf0e10cSrcweir // for formulas, the reference positions must be compared, too
598cdf0e10cSrcweir // (including aSrcString, for inserting the entries during XML import)
599cdf0e10cSrcweir if ( ( pFormula1 || pFormula2 ) && ( aSrcPos != r.aSrcPos || aSrcString != r.aSrcString ) )
600cdf0e10cSrcweir bEq = sal_False;
601cdf0e10cSrcweir
602cdf0e10cSrcweir // wenn keine Formeln, Werte vergleichen
603cdf0e10cSrcweir if ( !pFormula1 && ( nVal1 != r.nVal1 || aStrVal1 != r.aStrVal1 || bIsStr1 != r.bIsStr1 ) )
604cdf0e10cSrcweir bEq = sal_False;
605cdf0e10cSrcweir if ( !pFormula2 && ( nVal2 != r.nVal2 || aStrVal2 != r.aStrVal2 || bIsStr2 != r.bIsStr2 ) )
606cdf0e10cSrcweir bEq = sal_False;
607cdf0e10cSrcweir }
608cdf0e10cSrcweir
609cdf0e10cSrcweir return bEq;
610cdf0e10cSrcweir }
611cdf0e10cSrcweir
Interpret(const ScAddress & rPos)612cdf0e10cSrcweir void ScConditionEntry::Interpret( const ScAddress& rPos )
613cdf0e10cSrcweir {
614cdf0e10cSrcweir // Formelzellen anlegen
615cdf0e10cSrcweir // dabei koennen neue Broadcaster (Note-Zellen) ins Dokument eingefuegt werden !!!!
616cdf0e10cSrcweir
617cdf0e10cSrcweir if ( ( pFormula1 && !pFCell1 ) || ( pFormula2 && !pFCell2 ) )
618cdf0e10cSrcweir MakeCells( rPos );
619cdf0e10cSrcweir
620cdf0e10cSrcweir // Formeln auswerten
621cdf0e10cSrcweir
622cdf0e10cSrcweir sal_Bool bDirty = sal_False; //! 1 und 2 getrennt ???
623cdf0e10cSrcweir
624cdf0e10cSrcweir ScFormulaCell* pTemp1 = NULL;
625cdf0e10cSrcweir ScFormulaCell* pEff1 = pFCell1;
626cdf0e10cSrcweir if ( bRelRef1 )
627cdf0e10cSrcweir {
628cdf0e10cSrcweir pTemp1 = new ScFormulaCell( pDoc, rPos, pFormula1 ); // ohne Listening
629cdf0e10cSrcweir pEff1 = pTemp1;
630cdf0e10cSrcweir }
631cdf0e10cSrcweir if ( pEff1 )
632cdf0e10cSrcweir {
633cdf0e10cSrcweir if (!pEff1->IsRunning()) // keine 522 erzeugen
634cdf0e10cSrcweir {
635cdf0e10cSrcweir //! Changed statt Dirty abfragen !!!
636*6dfe295fSWang Lei if (pEff1->GetDirty() && !bRelRef1 && pDoc->GetAutoCalc())
637cdf0e10cSrcweir bDirty = sal_True;
638cdf0e10cSrcweir if (pEff1->IsValue())
639cdf0e10cSrcweir {
640cdf0e10cSrcweir bIsStr1 = sal_False;
641cdf0e10cSrcweir nVal1 = pEff1->GetValue();
642cdf0e10cSrcweir aStrVal1.Erase();
643cdf0e10cSrcweir }
644cdf0e10cSrcweir else
645cdf0e10cSrcweir {
646cdf0e10cSrcweir bIsStr1 = sal_True;
647cdf0e10cSrcweir pEff1->GetString( aStrVal1 );
648cdf0e10cSrcweir nVal1 = 0.0;
649cdf0e10cSrcweir }
650cdf0e10cSrcweir }
651cdf0e10cSrcweir }
652cdf0e10cSrcweir delete pTemp1;
653cdf0e10cSrcweir
654cdf0e10cSrcweir ScFormulaCell* pTemp2 = NULL;
655cdf0e10cSrcweir ScFormulaCell* pEff2 = pFCell2; //@ 1!=2
656cdf0e10cSrcweir if ( bRelRef2 )
657cdf0e10cSrcweir {
658cdf0e10cSrcweir pTemp2 = new ScFormulaCell( pDoc, rPos, pFormula2 ); // ohne Listening
659cdf0e10cSrcweir pEff2 = pTemp2;
660cdf0e10cSrcweir }
661cdf0e10cSrcweir if ( pEff2 )
662cdf0e10cSrcweir {
663cdf0e10cSrcweir if (!pEff2->IsRunning()) // keine 522 erzeugen
664cdf0e10cSrcweir {
665*6dfe295fSWang Lei if (pEff2->GetDirty() && !bRelRef2 && pDoc->GetAutoCalc())
666cdf0e10cSrcweir bDirty = sal_True;
667cdf0e10cSrcweir if (pEff2->IsValue())
668cdf0e10cSrcweir {
669cdf0e10cSrcweir bIsStr2 = sal_False;
670cdf0e10cSrcweir nVal2 = pEff2->GetValue();
671cdf0e10cSrcweir aStrVal2.Erase();
672cdf0e10cSrcweir }
673cdf0e10cSrcweir else
674cdf0e10cSrcweir {
675cdf0e10cSrcweir bIsStr2 = sal_True;
676cdf0e10cSrcweir pEff2->GetString( aStrVal2 );
677cdf0e10cSrcweir nVal2 = 0.0;
678cdf0e10cSrcweir }
679cdf0e10cSrcweir }
680cdf0e10cSrcweir }
681cdf0e10cSrcweir delete pTemp2;
682cdf0e10cSrcweir
683cdf0e10cSrcweir // wenn IsRunning, bleiben die letzten Werte erhalten
684cdf0e10cSrcweir
685cdf0e10cSrcweir if (bDirty && !bFirstRun)
686cdf0e10cSrcweir {
687cdf0e10cSrcweir // bei bedingten Formaten neu painten
688cdf0e10cSrcweir
689cdf0e10cSrcweir DataChanged( NULL ); // alles
690cdf0e10cSrcweir }
691cdf0e10cSrcweir
692cdf0e10cSrcweir bFirstRun = sal_False;
693cdf0e10cSrcweir }
694cdf0e10cSrcweir
IsValid(double nArg) const695cdf0e10cSrcweir sal_Bool ScConditionEntry::IsValid( double nArg ) const
696cdf0e10cSrcweir {
697cdf0e10cSrcweir // Interpret muss schon gerufen sein
698cdf0e10cSrcweir
699cdf0e10cSrcweir if ( bIsStr1 )
700cdf0e10cSrcweir {
701cdf0e10cSrcweir // wenn auf String getestet wird, bei Zahlen immer sal_False, ausser bei "ungleich"
702cdf0e10cSrcweir
703cdf0e10cSrcweir return ( eOp == SC_COND_NOTEQUAL );
704cdf0e10cSrcweir }
705cdf0e10cSrcweir
706cdf0e10cSrcweir if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
707cdf0e10cSrcweir if ( bIsStr2 )
708cdf0e10cSrcweir return sal_False;
709cdf0e10cSrcweir
710cdf0e10cSrcweir double nComp1 = nVal1; // Kopie, damit vertauscht werden kann
711cdf0e10cSrcweir double nComp2 = nVal2;
712cdf0e10cSrcweir
713cdf0e10cSrcweir if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
714cdf0e10cSrcweir if ( nComp1 > nComp2 )
715cdf0e10cSrcweir {
716cdf0e10cSrcweir // richtige Reihenfolge fuer Wertebereich
717cdf0e10cSrcweir double nTemp = nComp1; nComp1 = nComp2; nComp2 = nTemp;
718cdf0e10cSrcweir }
719cdf0e10cSrcweir
720cdf0e10cSrcweir // Alle Grenzfaelle muessen per ::rtl::math::approxEqual getestet werden!
721cdf0e10cSrcweir
722cdf0e10cSrcweir sal_Bool bValid = sal_False;
723cdf0e10cSrcweir switch (eOp)
724cdf0e10cSrcweir {
725cdf0e10cSrcweir case SC_COND_NONE:
726cdf0e10cSrcweir break; // immer sal_False;
727cdf0e10cSrcweir case SC_COND_EQUAL:
728cdf0e10cSrcweir bValid = ::rtl::math::approxEqual( nArg, nComp1 );
729cdf0e10cSrcweir break;
730cdf0e10cSrcweir case SC_COND_NOTEQUAL:
731cdf0e10cSrcweir bValid = !::rtl::math::approxEqual( nArg, nComp1 );
732cdf0e10cSrcweir break;
733cdf0e10cSrcweir case SC_COND_GREATER:
734cdf0e10cSrcweir bValid = ( nArg > nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
735cdf0e10cSrcweir break;
736cdf0e10cSrcweir case SC_COND_EQGREATER:
737cdf0e10cSrcweir bValid = ( nArg >= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
738cdf0e10cSrcweir break;
739cdf0e10cSrcweir case SC_COND_LESS:
740cdf0e10cSrcweir bValid = ( nArg < nComp1 ) && !::rtl::math::approxEqual( nArg, nComp1 );
741cdf0e10cSrcweir break;
742cdf0e10cSrcweir case SC_COND_EQLESS:
743cdf0e10cSrcweir bValid = ( nArg <= nComp1 ) || ::rtl::math::approxEqual( nArg, nComp1 );
744cdf0e10cSrcweir break;
745cdf0e10cSrcweir case SC_COND_BETWEEN:
746cdf0e10cSrcweir bValid = ( nArg >= nComp1 && nArg <= nComp2 ) ||
747cdf0e10cSrcweir ::rtl::math::approxEqual( nArg, nComp1 ) || ::rtl::math::approxEqual( nArg, nComp2 );
748cdf0e10cSrcweir break;
749cdf0e10cSrcweir case SC_COND_NOTBETWEEN:
750cdf0e10cSrcweir bValid = ( nArg < nComp1 || nArg > nComp2 ) &&
751cdf0e10cSrcweir !::rtl::math::approxEqual( nArg, nComp1 ) && !::rtl::math::approxEqual( nArg, nComp2 );
752cdf0e10cSrcweir break;
753cdf0e10cSrcweir case SC_COND_DIRECT:
754cdf0e10cSrcweir bValid = !::rtl::math::approxEqual( nComp1, 0.0 );
755cdf0e10cSrcweir break;
756cdf0e10cSrcweir default:
757cdf0e10cSrcweir DBG_ERROR("unbekannte Operation bei ScConditionEntry");
758cdf0e10cSrcweir break;
759cdf0e10cSrcweir }
760cdf0e10cSrcweir return bValid;
761cdf0e10cSrcweir }
762cdf0e10cSrcweir
IsValidStr(const String & rArg) const763cdf0e10cSrcweir sal_Bool ScConditionEntry::IsValidStr( const String& rArg ) const
764cdf0e10cSrcweir {
765cdf0e10cSrcweir // Interpret muss schon gerufen sein
766cdf0e10cSrcweir
767cdf0e10cSrcweir if ( eOp == SC_COND_DIRECT ) // Formel ist unabhaengig vom Inhalt
768cdf0e10cSrcweir return !::rtl::math::approxEqual( nVal1, 0.0 );
769cdf0e10cSrcweir
770cdf0e10cSrcweir // Wenn Bedingung Zahl enthaelt, immer sal_False, ausser bei "ungleich"
771cdf0e10cSrcweir
772cdf0e10cSrcweir if ( !bIsStr1 )
773cdf0e10cSrcweir return ( eOp == SC_COND_NOTEQUAL );
774cdf0e10cSrcweir if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
775cdf0e10cSrcweir if ( !bIsStr2 )
776cdf0e10cSrcweir return sal_False;
777cdf0e10cSrcweir
778cdf0e10cSrcweir String aUpVal1( aStrVal1 ); //! als Member? (dann auch in Interpret setzen)
779cdf0e10cSrcweir String aUpVal2( aStrVal2 );
780cdf0e10cSrcweir
781cdf0e10cSrcweir if ( eOp == SC_COND_BETWEEN || eOp == SC_COND_NOTBETWEEN )
782cdf0e10cSrcweir if ( ScGlobal::GetCollator()->compareString( aUpVal1, aUpVal2 )
783cdf0e10cSrcweir == COMPARE_GREATER )
784cdf0e10cSrcweir {
785cdf0e10cSrcweir // richtige Reihenfolge fuer Wertebereich
786cdf0e10cSrcweir String aTemp( aUpVal1 ); aUpVal1 = aUpVal2; aUpVal2 = aTemp;
787cdf0e10cSrcweir }
788cdf0e10cSrcweir
789cdf0e10cSrcweir sal_Bool bValid;
790cdf0e10cSrcweir switch ( eOp )
791cdf0e10cSrcweir {
792cdf0e10cSrcweir case SC_COND_EQUAL:
793cdf0e10cSrcweir bValid = (ScGlobal::GetCollator()->compareString(
794cdf0e10cSrcweir rArg, aUpVal1 ) == COMPARE_EQUAL);
795cdf0e10cSrcweir break;
796cdf0e10cSrcweir case SC_COND_NOTEQUAL:
797cdf0e10cSrcweir bValid = (ScGlobal::GetCollator()->compareString(
798cdf0e10cSrcweir rArg, aUpVal1 ) != COMPARE_EQUAL);
799cdf0e10cSrcweir break;
800cdf0e10cSrcweir default:
801cdf0e10cSrcweir {
802cdf0e10cSrcweir sal_Int32 nCompare = ScGlobal::GetCollator()->compareString(
803cdf0e10cSrcweir rArg, aUpVal1 );
804cdf0e10cSrcweir switch ( eOp )
805cdf0e10cSrcweir {
806cdf0e10cSrcweir case SC_COND_GREATER:
807cdf0e10cSrcweir bValid = ( nCompare == COMPARE_GREATER );
808cdf0e10cSrcweir break;
809cdf0e10cSrcweir case SC_COND_EQGREATER:
810cdf0e10cSrcweir bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_GREATER );
811cdf0e10cSrcweir break;
812cdf0e10cSrcweir case SC_COND_LESS:
813cdf0e10cSrcweir bValid = ( nCompare == COMPARE_LESS );
814cdf0e10cSrcweir break;
815cdf0e10cSrcweir case SC_COND_EQLESS:
816cdf0e10cSrcweir bValid = ( nCompare == COMPARE_EQUAL || nCompare == COMPARE_LESS );
817cdf0e10cSrcweir break;
818cdf0e10cSrcweir case SC_COND_BETWEEN:
819cdf0e10cSrcweir case SC_COND_NOTBETWEEN:
820cdf0e10cSrcweir // Test auf NOTBETWEEN:
821cdf0e10cSrcweir bValid = ( nCompare == COMPARE_LESS ||
822cdf0e10cSrcweir ScGlobal::GetCollator()->compareString( rArg,
823cdf0e10cSrcweir aUpVal2 ) == COMPARE_GREATER );
824cdf0e10cSrcweir if ( eOp == SC_COND_BETWEEN )
825cdf0e10cSrcweir bValid = !bValid;
826cdf0e10cSrcweir break;
827cdf0e10cSrcweir // SC_COND_DIRECT schon oben abgefragt
828cdf0e10cSrcweir default:
829cdf0e10cSrcweir DBG_ERROR("unbekannte Operation bei ScConditionEntry");
830cdf0e10cSrcweir bValid = sal_False;
831cdf0e10cSrcweir break;
832cdf0e10cSrcweir }
833cdf0e10cSrcweir }
834cdf0e10cSrcweir }
835cdf0e10cSrcweir return bValid;
836cdf0e10cSrcweir }
837cdf0e10cSrcweir
IsCellValid(ScBaseCell * pCell,const ScAddress & rPos) const838cdf0e10cSrcweir sal_Bool ScConditionEntry::IsCellValid( ScBaseCell* pCell, const ScAddress& rPos ) const
839cdf0e10cSrcweir {
840cdf0e10cSrcweir ((ScConditionEntry*)this)->Interpret(rPos); // Formeln auswerten
841cdf0e10cSrcweir
842cdf0e10cSrcweir double nArg = 0.0;
843cdf0e10cSrcweir String aArgStr;
844cdf0e10cSrcweir sal_Bool bVal = sal_True;
845cdf0e10cSrcweir
846cdf0e10cSrcweir if ( pCell )
847cdf0e10cSrcweir {
848cdf0e10cSrcweir CellType eType = pCell->GetCellType();
849cdf0e10cSrcweir switch (eType)
850cdf0e10cSrcweir {
851cdf0e10cSrcweir case CELLTYPE_VALUE:
852cdf0e10cSrcweir nArg = ((ScValueCell*)pCell)->GetValue();
853cdf0e10cSrcweir break;
854cdf0e10cSrcweir case CELLTYPE_FORMULA:
855cdf0e10cSrcweir {
856cdf0e10cSrcweir ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
857cdf0e10cSrcweir bVal = pFCell->IsValue();
858cdf0e10cSrcweir if (bVal)
859cdf0e10cSrcweir nArg = pFCell->GetValue();
860cdf0e10cSrcweir else
861cdf0e10cSrcweir pFCell->GetString(aArgStr);
862cdf0e10cSrcweir }
863cdf0e10cSrcweir break;
864cdf0e10cSrcweir case CELLTYPE_STRING:
865cdf0e10cSrcweir case CELLTYPE_EDIT:
866cdf0e10cSrcweir bVal = sal_False;
867cdf0e10cSrcweir if ( eType == CELLTYPE_STRING )
868cdf0e10cSrcweir ((ScStringCell*)pCell)->GetString(aArgStr);
869cdf0e10cSrcweir else
870cdf0e10cSrcweir ((ScEditCell*)pCell)->GetString(aArgStr);
871cdf0e10cSrcweir break;
872cdf0e10cSrcweir
873cdf0e10cSrcweir default:
874cdf0e10cSrcweir pCell = NULL; // Note-Zellen wie leere
875cdf0e10cSrcweir break;
876cdf0e10cSrcweir }
877cdf0e10cSrcweir }
878cdf0e10cSrcweir
879cdf0e10cSrcweir if (!pCell)
880cdf0e10cSrcweir if (bIsStr1)
881cdf0e10cSrcweir bVal = sal_False; // leere Zellen je nach Bedingung
882cdf0e10cSrcweir
883cdf0e10cSrcweir if (bVal)
884cdf0e10cSrcweir return IsValid( nArg );
885cdf0e10cSrcweir else
886cdf0e10cSrcweir return IsValidStr( aArgStr );
887cdf0e10cSrcweir }
888cdf0e10cSrcweir
GetExpression(const ScAddress & rCursor,sal_uInt16 nIndex,sal_uLong nNumFmt,const FormulaGrammar::Grammar eGrammar) const889cdf0e10cSrcweir String ScConditionEntry::GetExpression( const ScAddress& rCursor, sal_uInt16 nIndex,
890cdf0e10cSrcweir sal_uLong nNumFmt,
891cdf0e10cSrcweir const FormulaGrammar::Grammar eGrammar ) const
892cdf0e10cSrcweir {
893cdf0e10cSrcweir String aRet;
894cdf0e10cSrcweir
895cdf0e10cSrcweir if ( FormulaGrammar::isEnglish( eGrammar) && nNumFmt == 0 )
896cdf0e10cSrcweir nNumFmt = pDoc->GetFormatTable()->GetStandardIndex( LANGUAGE_ENGLISH_US );
897cdf0e10cSrcweir
898cdf0e10cSrcweir if ( nIndex==0 )
899cdf0e10cSrcweir {
900cdf0e10cSrcweir if ( pFormula1 )
901cdf0e10cSrcweir {
902cdf0e10cSrcweir ScCompiler aComp(pDoc, rCursor, *pFormula1);
903cdf0e10cSrcweir aComp.SetGrammar(eGrammar);
904cdf0e10cSrcweir aComp.CreateStringFromTokenArray( aRet );
905cdf0e10cSrcweir }
906cdf0e10cSrcweir else if (bIsStr1)
907cdf0e10cSrcweir {
908cdf0e10cSrcweir aRet = '"';
909cdf0e10cSrcweir aRet += aStrVal1;
910cdf0e10cSrcweir aRet += '"';
911cdf0e10cSrcweir }
912cdf0e10cSrcweir else
913cdf0e10cSrcweir pDoc->GetFormatTable()->GetInputLineString(nVal1, nNumFmt, aRet);
914cdf0e10cSrcweir }
915cdf0e10cSrcweir else if ( nIndex==1 )
916cdf0e10cSrcweir {
917cdf0e10cSrcweir if ( pFormula2 )
918cdf0e10cSrcweir {
919cdf0e10cSrcweir ScCompiler aComp(pDoc, rCursor, *pFormula2);
920cdf0e10cSrcweir aComp.SetGrammar(eGrammar);
921cdf0e10cSrcweir aComp.CreateStringFromTokenArray( aRet );
922cdf0e10cSrcweir }
923cdf0e10cSrcweir else if (bIsStr2)
924cdf0e10cSrcweir {
925cdf0e10cSrcweir aRet = '"';
926cdf0e10cSrcweir aRet += aStrVal2;
927cdf0e10cSrcweir aRet += '"';
928cdf0e10cSrcweir }
929cdf0e10cSrcweir else
930cdf0e10cSrcweir pDoc->GetFormatTable()->GetInputLineString(nVal2, nNumFmt, aRet);
931cdf0e10cSrcweir }
932cdf0e10cSrcweir else
933cdf0e10cSrcweir {
934cdf0e10cSrcweir DBG_ERROR("GetExpression: falscher Index");
935cdf0e10cSrcweir }
936cdf0e10cSrcweir
937cdf0e10cSrcweir return aRet;
938cdf0e10cSrcweir }
939cdf0e10cSrcweir
CreateTokenArry(sal_uInt16 nIndex) const940cdf0e10cSrcweir ScTokenArray* ScConditionEntry::CreateTokenArry( sal_uInt16 nIndex ) const
941cdf0e10cSrcweir {
942cdf0e10cSrcweir ScTokenArray* pRet = NULL;
943cdf0e10cSrcweir ScAddress aAddr;
944cdf0e10cSrcweir
945cdf0e10cSrcweir if ( nIndex==0 )
946cdf0e10cSrcweir {
947cdf0e10cSrcweir if ( pFormula1 )
948cdf0e10cSrcweir pRet = new ScTokenArray( *pFormula1 );
949cdf0e10cSrcweir else
950cdf0e10cSrcweir {
951cdf0e10cSrcweir pRet = new ScTokenArray();
952cdf0e10cSrcweir if (bIsStr1)
953cdf0e10cSrcweir pRet->AddString( aStrVal1.GetBuffer() );
954cdf0e10cSrcweir else
955cdf0e10cSrcweir pRet->AddDouble( nVal1 );
956cdf0e10cSrcweir }
957cdf0e10cSrcweir }
958cdf0e10cSrcweir else if ( nIndex==1 )
959cdf0e10cSrcweir {
960cdf0e10cSrcweir if ( pFormula2 )
961cdf0e10cSrcweir pRet = new ScTokenArray( *pFormula2 );
962cdf0e10cSrcweir else
963cdf0e10cSrcweir {
964cdf0e10cSrcweir pRet = new ScTokenArray();
965cdf0e10cSrcweir if (bIsStr2)
966cdf0e10cSrcweir pRet->AddString( aStrVal2.GetBuffer() );
967cdf0e10cSrcweir else
968cdf0e10cSrcweir pRet->AddDouble( nVal2 );
969cdf0e10cSrcweir }
970cdf0e10cSrcweir }
971cdf0e10cSrcweir else
972cdf0e10cSrcweir {
973cdf0e10cSrcweir DBG_ERROR("GetExpression: falscher Index");
974cdf0e10cSrcweir }
975cdf0e10cSrcweir
976cdf0e10cSrcweir return pRet;
977cdf0e10cSrcweir }
978cdf0e10cSrcweir
SourceChanged(const ScAddress & rChanged)979cdf0e10cSrcweir void ScConditionEntry::SourceChanged( const ScAddress& rChanged )
980cdf0e10cSrcweir {
981cdf0e10cSrcweir for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
982cdf0e10cSrcweir {
983cdf0e10cSrcweir ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
984cdf0e10cSrcweir if (pFormula)
985cdf0e10cSrcweir {
986cdf0e10cSrcweir pFormula->Reset();
987cdf0e10cSrcweir ScToken* t;
988cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
989cdf0e10cSrcweir {
990cdf0e10cSrcweir SingleDoubleRefProvider aProv( *t );
991cdf0e10cSrcweir if ( aProv.Ref1.IsColRel() || aProv.Ref1.IsRowRel() || aProv.Ref1.IsTabRel() ||
992cdf0e10cSrcweir aProv.Ref2.IsColRel() || aProv.Ref2.IsRowRel() || aProv.Ref2.IsTabRel() )
993cdf0e10cSrcweir {
994cdf0e10cSrcweir // absolut muss getroffen sein, relativ bestimmt Bereich
995cdf0e10cSrcweir
996cdf0e10cSrcweir sal_Bool bHit = sal_True;
997cdf0e10cSrcweir SCsCOL nCol1;
998cdf0e10cSrcweir SCsROW nRow1;
999cdf0e10cSrcweir SCsTAB nTab1;
1000cdf0e10cSrcweir SCsCOL nCol2;
1001cdf0e10cSrcweir SCsROW nRow2;
1002cdf0e10cSrcweir SCsTAB nTab2;
1003cdf0e10cSrcweir
1004cdf0e10cSrcweir if ( aProv.Ref1.IsColRel() )
1005cdf0e10cSrcweir nCol2 = rChanged.Col() - aProv.Ref1.nRelCol;
1006cdf0e10cSrcweir else
1007cdf0e10cSrcweir {
1008cdf0e10cSrcweir bHit &= ( rChanged.Col() >= aProv.Ref1.nCol );
1009cdf0e10cSrcweir nCol2 = MAXCOL;
1010cdf0e10cSrcweir }
1011cdf0e10cSrcweir if ( aProv.Ref1.IsRowRel() )
1012cdf0e10cSrcweir nRow2 = rChanged.Row() - aProv.Ref1.nRelRow;
1013cdf0e10cSrcweir else
1014cdf0e10cSrcweir {
1015cdf0e10cSrcweir bHit &= ( rChanged.Row() >= aProv.Ref1.nRow );
1016cdf0e10cSrcweir nRow2 = MAXROW;
1017cdf0e10cSrcweir }
1018cdf0e10cSrcweir if ( aProv.Ref1.IsTabRel() )
1019cdf0e10cSrcweir nTab2 = rChanged.Tab() - aProv.Ref1.nRelTab;
1020cdf0e10cSrcweir else
1021cdf0e10cSrcweir {
1022cdf0e10cSrcweir bHit &= ( rChanged.Tab() >= aProv.Ref1.nTab );
1023cdf0e10cSrcweir nTab2 = MAXTAB;
1024cdf0e10cSrcweir }
1025cdf0e10cSrcweir
1026cdf0e10cSrcweir if ( aProv.Ref2.IsColRel() )
1027cdf0e10cSrcweir nCol1 = rChanged.Col() - aProv.Ref2.nRelCol;
1028cdf0e10cSrcweir else
1029cdf0e10cSrcweir {
1030cdf0e10cSrcweir bHit &= ( rChanged.Col() <= aProv.Ref2.nCol );
1031cdf0e10cSrcweir nCol1 = 0;
1032cdf0e10cSrcweir }
1033cdf0e10cSrcweir if ( aProv.Ref2.IsRowRel() )
1034cdf0e10cSrcweir nRow1 = rChanged.Row() - aProv.Ref2.nRelRow;
1035cdf0e10cSrcweir else
1036cdf0e10cSrcweir {
1037cdf0e10cSrcweir bHit &= ( rChanged.Row() <= aProv.Ref2.nRow );
1038cdf0e10cSrcweir nRow1 = 0;
1039cdf0e10cSrcweir }
1040cdf0e10cSrcweir if ( aProv.Ref2.IsTabRel() )
1041cdf0e10cSrcweir nTab1 = rChanged.Tab() - aProv.Ref2.nRelTab;
1042cdf0e10cSrcweir else
1043cdf0e10cSrcweir {
1044cdf0e10cSrcweir bHit &= ( rChanged.Tab() <= aProv.Ref2.nTab );
1045cdf0e10cSrcweir nTab1 = 0;
1046cdf0e10cSrcweir }
1047cdf0e10cSrcweir
1048cdf0e10cSrcweir if ( bHit )
1049cdf0e10cSrcweir {
1050cdf0e10cSrcweir //! begrenzen
1051cdf0e10cSrcweir
1052cdf0e10cSrcweir ScRange aPaint( nCol1,nRow1,nTab1, nCol2,nRow2,nTab2 );
1053cdf0e10cSrcweir
1054cdf0e10cSrcweir // kein Paint, wenn es nur die Zelle selber ist
1055cdf0e10cSrcweir if ( aPaint.aStart != rChanged || aPaint.aEnd != rChanged )
1056cdf0e10cSrcweir DataChanged( &aPaint );
1057cdf0e10cSrcweir }
1058cdf0e10cSrcweir }
1059cdf0e10cSrcweir }
1060cdf0e10cSrcweir }
1061cdf0e10cSrcweir }
1062cdf0e10cSrcweir }
1063cdf0e10cSrcweir
GetValidSrcPos() const1064cdf0e10cSrcweir ScAddress ScConditionEntry::GetValidSrcPos() const
1065cdf0e10cSrcweir {
1066cdf0e10cSrcweir // return a position that's adjusted to allow textual representation of expressions if possible
1067cdf0e10cSrcweir
1068cdf0e10cSrcweir SCTAB nMinTab = aSrcPos.Tab();
1069cdf0e10cSrcweir SCTAB nMaxTab = nMinTab;
1070cdf0e10cSrcweir
1071cdf0e10cSrcweir for (sal_uInt16 nPass = 0; nPass < 2; nPass++)
1072cdf0e10cSrcweir {
1073cdf0e10cSrcweir ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
1074cdf0e10cSrcweir if (pFormula)
1075cdf0e10cSrcweir {
1076cdf0e10cSrcweir pFormula->Reset();
1077cdf0e10cSrcweir ScToken* t;
1078cdf0e10cSrcweir while ( ( t = static_cast<ScToken*>(pFormula->GetNextReference()) ) != NULL )
1079cdf0e10cSrcweir {
1080cdf0e10cSrcweir ScSingleRefData& rRef1 = t->GetSingleRef();
1081cdf0e10cSrcweir if ( rRef1.IsTabRel() && !rRef1.IsTabDeleted() )
1082cdf0e10cSrcweir {
1083cdf0e10cSrcweir if ( rRef1.nTab < nMinTab )
1084cdf0e10cSrcweir nMinTab = rRef1.nTab;
1085cdf0e10cSrcweir if ( rRef1.nTab > nMaxTab )
1086cdf0e10cSrcweir nMaxTab = rRef1.nTab;
1087cdf0e10cSrcweir }
1088cdf0e10cSrcweir if ( t->GetType() == svDoubleRef )
1089cdf0e10cSrcweir {
1090cdf0e10cSrcweir ScSingleRefData& rRef2 = t->GetDoubleRef().Ref2;
1091cdf0e10cSrcweir if ( rRef2.IsTabRel() && !rRef2.IsTabDeleted() )
1092cdf0e10cSrcweir {
1093cdf0e10cSrcweir if ( rRef2.nTab < nMinTab )
1094cdf0e10cSrcweir nMinTab = rRef2.nTab;
1095cdf0e10cSrcweir if ( rRef2.nTab > nMaxTab )
1096cdf0e10cSrcweir nMaxTab = rRef2.nTab;
1097cdf0e10cSrcweir }
1098cdf0e10cSrcweir }
1099cdf0e10cSrcweir }
1100cdf0e10cSrcweir }
1101cdf0e10cSrcweir }
1102cdf0e10cSrcweir
1103cdf0e10cSrcweir ScAddress aValidPos = aSrcPos;
1104cdf0e10cSrcweir SCTAB nTabCount = pDoc->GetTableCount();
1105cdf0e10cSrcweir if ( nMaxTab >= nTabCount && nMinTab > 0 )
1106cdf0e10cSrcweir aValidPos.SetTab( aSrcPos.Tab() - nMinTab ); // so the lowest tab ref will be on 0
1107cdf0e10cSrcweir
1108cdf0e10cSrcweir if ( aValidPos.Tab() >= nTabCount )
1109cdf0e10cSrcweir aValidPos.SetTab( nTabCount - 1 ); // ensure a valid position even if some references will be invalid
1110cdf0e10cSrcweir
1111cdf0e10cSrcweir return aValidPos;
1112cdf0e10cSrcweir }
1113cdf0e10cSrcweir
DataChanged(const ScRange *) const1114cdf0e10cSrcweir void ScConditionEntry::DataChanged( const ScRange* /* pModified */ ) const
1115cdf0e10cSrcweir {
1116cdf0e10cSrcweir // nix
1117cdf0e10cSrcweir }
1118cdf0e10cSrcweir
MarkUsedExternalReferences() const1119cdf0e10cSrcweir bool ScConditionEntry::MarkUsedExternalReferences() const
1120cdf0e10cSrcweir {
1121cdf0e10cSrcweir bool bAllMarked = false;
1122cdf0e10cSrcweir for (sal_uInt16 nPass = 0; !bAllMarked && nPass < 2; nPass++)
1123cdf0e10cSrcweir {
1124cdf0e10cSrcweir ScTokenArray* pFormula = nPass ? pFormula2 : pFormula1;
1125cdf0e10cSrcweir if (pFormula)
1126cdf0e10cSrcweir bAllMarked = pDoc->MarkUsedExternalReferences( *pFormula);
1127cdf0e10cSrcweir }
1128cdf0e10cSrcweir return bAllMarked;
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir
1131cdf0e10cSrcweir //------------------------------------------------------------------------
1132cdf0e10cSrcweir
ScCondFormatEntry(ScConditionMode eOper,const String & rExpr1,const String & rExpr2,ScDocument * pDocument,const ScAddress & rPos,const String & rStyle,const String & rExprNmsp1,const String & rExprNmsp2,FormulaGrammar::Grammar eGrammar1,FormulaGrammar::Grammar eGrammar2)1133cdf0e10cSrcweir ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
1134cdf0e10cSrcweir const String& rExpr1, const String& rExpr2,
1135cdf0e10cSrcweir ScDocument* pDocument, const ScAddress& rPos,
1136cdf0e10cSrcweir const String& rStyle,
1137cdf0e10cSrcweir const String& rExprNmsp1, const String& rExprNmsp2,
1138cdf0e10cSrcweir FormulaGrammar::Grammar eGrammar1,
1139cdf0e10cSrcweir FormulaGrammar::Grammar eGrammar2 ) :
1140cdf0e10cSrcweir ScConditionEntry( eOper, rExpr1, rExpr2, pDocument, rPos, rExprNmsp1, rExprNmsp2, eGrammar1, eGrammar2 ),
1141cdf0e10cSrcweir aStyleName( rStyle ),
1142cdf0e10cSrcweir pParent( NULL )
1143cdf0e10cSrcweir {
1144cdf0e10cSrcweir }
1145cdf0e10cSrcweir
ScCondFormatEntry(ScConditionMode eOper,const ScTokenArray * pArr1,const ScTokenArray * pArr2,ScDocument * pDocument,const ScAddress & rPos,const String & rStyle)1146cdf0e10cSrcweir ScCondFormatEntry::ScCondFormatEntry( ScConditionMode eOper,
1147cdf0e10cSrcweir const ScTokenArray* pArr1, const ScTokenArray* pArr2,
1148cdf0e10cSrcweir ScDocument* pDocument, const ScAddress& rPos,
1149cdf0e10cSrcweir const String& rStyle ) :
1150cdf0e10cSrcweir ScConditionEntry( eOper, pArr1, pArr2, pDocument, rPos ),
1151cdf0e10cSrcweir aStyleName( rStyle ),
1152cdf0e10cSrcweir pParent( NULL )
1153cdf0e10cSrcweir {
1154cdf0e10cSrcweir }
1155cdf0e10cSrcweir
ScCondFormatEntry(const ScCondFormatEntry & r)1156cdf0e10cSrcweir ScCondFormatEntry::ScCondFormatEntry( const ScCondFormatEntry& r ) :
1157cdf0e10cSrcweir ScConditionEntry( r ),
1158cdf0e10cSrcweir aStyleName( r.aStyleName ),
1159cdf0e10cSrcweir pParent( NULL )
1160cdf0e10cSrcweir {
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir
ScCondFormatEntry(ScDocument * pDocument,const ScCondFormatEntry & r)1163cdf0e10cSrcweir ScCondFormatEntry::ScCondFormatEntry( ScDocument* pDocument, const ScCondFormatEntry& r ) :
1164cdf0e10cSrcweir ScConditionEntry( pDocument, r ),
1165cdf0e10cSrcweir aStyleName( r.aStyleName ),
1166cdf0e10cSrcweir pParent( NULL )
1167cdf0e10cSrcweir {
1168cdf0e10cSrcweir }
1169cdf0e10cSrcweir
operator ==(const ScCondFormatEntry & r) const1170cdf0e10cSrcweir int ScCondFormatEntry::operator== ( const ScCondFormatEntry& r ) const
1171cdf0e10cSrcweir {
1172cdf0e10cSrcweir return ScConditionEntry::operator==( r ) &&
1173cdf0e10cSrcweir aStyleName == r.aStyleName;
1174cdf0e10cSrcweir
1175cdf0e10cSrcweir // Range wird nicht verglichen
1176cdf0e10cSrcweir }
1177cdf0e10cSrcweir
~ScCondFormatEntry()1178cdf0e10cSrcweir ScCondFormatEntry::~ScCondFormatEntry()
1179cdf0e10cSrcweir {
1180cdf0e10cSrcweir }
1181cdf0e10cSrcweir
DataChanged(const ScRange * pModified) const1182cdf0e10cSrcweir void ScCondFormatEntry::DataChanged( const ScRange* pModified ) const
1183cdf0e10cSrcweir {
1184cdf0e10cSrcweir if ( pParent )
1185cdf0e10cSrcweir pParent->DoRepaint( pModified );
1186cdf0e10cSrcweir }
1187cdf0e10cSrcweir
1188cdf0e10cSrcweir //------------------------------------------------------------------------
1189cdf0e10cSrcweir
ScConditionalFormat(sal_uInt32 nNewKey,ScDocument * pDocument)1190cdf0e10cSrcweir ScConditionalFormat::ScConditionalFormat(sal_uInt32 nNewKey, ScDocument* pDocument) :
1191cdf0e10cSrcweir pDoc( pDocument ),
1192cdf0e10cSrcweir pAreas( NULL ),
1193cdf0e10cSrcweir nKey( nNewKey ),
1194cdf0e10cSrcweir ppEntries( NULL ),
1195cdf0e10cSrcweir nEntryCount( 0 )
1196cdf0e10cSrcweir {
1197cdf0e10cSrcweir }
1198cdf0e10cSrcweir
ScConditionalFormat(const ScConditionalFormat & r)1199cdf0e10cSrcweir ScConditionalFormat::ScConditionalFormat(const ScConditionalFormat& r) :
1200cdf0e10cSrcweir pDoc( r.pDoc ),
1201cdf0e10cSrcweir pAreas( NULL ),
1202cdf0e10cSrcweir nKey( r.nKey ),
1203cdf0e10cSrcweir ppEntries( NULL ),
1204cdf0e10cSrcweir nEntryCount( r.nEntryCount )
1205cdf0e10cSrcweir {
1206cdf0e10cSrcweir if (nEntryCount)
1207cdf0e10cSrcweir {
1208cdf0e10cSrcweir ppEntries = new ScCondFormatEntry*[nEntryCount];
1209cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1210cdf0e10cSrcweir {
1211cdf0e10cSrcweir ppEntries[i] = new ScCondFormatEntry(*r.ppEntries[i]);
1212cdf0e10cSrcweir ppEntries[i]->SetParent(this);
1213cdf0e10cSrcweir }
1214cdf0e10cSrcweir }
1215cdf0e10cSrcweir }
1216cdf0e10cSrcweir
Clone(ScDocument * pNewDoc) const1217cdf0e10cSrcweir ScConditionalFormat* ScConditionalFormat::Clone(ScDocument* pNewDoc) const
1218cdf0e10cSrcweir {
1219cdf0e10cSrcweir // echte Kopie der Formeln (fuer Ref-Undo / zwischen Dokumenten)
1220cdf0e10cSrcweir
1221cdf0e10cSrcweir if (!pNewDoc)
1222cdf0e10cSrcweir pNewDoc = pDoc;
1223cdf0e10cSrcweir
1224cdf0e10cSrcweir ScConditionalFormat* pNew = new ScConditionalFormat(nKey, pNewDoc);
1225cdf0e10cSrcweir DBG_ASSERT(!pNew->ppEntries, "wo kommen die Eintraege her?");
1226cdf0e10cSrcweir
1227cdf0e10cSrcweir if (nEntryCount)
1228cdf0e10cSrcweir {
1229cdf0e10cSrcweir pNew->ppEntries = new ScCondFormatEntry*[nEntryCount];
1230cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1231cdf0e10cSrcweir {
1232cdf0e10cSrcweir pNew->ppEntries[i] = new ScCondFormatEntry( pNewDoc, *ppEntries[i] );
1233cdf0e10cSrcweir pNew->ppEntries[i]->SetParent(pNew);
1234cdf0e10cSrcweir }
1235cdf0e10cSrcweir pNew->nEntryCount = nEntryCount;
1236cdf0e10cSrcweir }
1237cdf0e10cSrcweir
1238cdf0e10cSrcweir return pNew;
1239cdf0e10cSrcweir }
1240cdf0e10cSrcweir
EqualEntries(const ScConditionalFormat & r) const1241cdf0e10cSrcweir sal_Bool ScConditionalFormat::EqualEntries( const ScConditionalFormat& r ) const
1242cdf0e10cSrcweir {
1243cdf0e10cSrcweir if ( nEntryCount != r.nEntryCount )
1244cdf0e10cSrcweir return sal_False;
1245cdf0e10cSrcweir
1246cdf0e10cSrcweir //! auf gleiche Eintraege in anderer Reihenfolge testen ???
1247cdf0e10cSrcweir
1248cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1249cdf0e10cSrcweir if ( ! (*ppEntries[i] == *r.ppEntries[i]) )
1250cdf0e10cSrcweir return sal_False;
1251cdf0e10cSrcweir
1252cdf0e10cSrcweir return sal_True;
1253cdf0e10cSrcweir }
1254cdf0e10cSrcweir
AddEntry(const ScCondFormatEntry & rNew)1255cdf0e10cSrcweir void ScConditionalFormat::AddEntry( const ScCondFormatEntry& rNew )
1256cdf0e10cSrcweir {
1257cdf0e10cSrcweir ScCondFormatEntry** ppNew = new ScCondFormatEntry*[nEntryCount+1];
1258cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1259cdf0e10cSrcweir ppNew[i] = ppEntries[i];
1260cdf0e10cSrcweir ppNew[nEntryCount] = new ScCondFormatEntry(rNew);
1261cdf0e10cSrcweir ppNew[nEntryCount]->SetParent(this);
1262cdf0e10cSrcweir ++nEntryCount;
1263cdf0e10cSrcweir delete[] ppEntries;
1264cdf0e10cSrcweir ppEntries = ppNew;
1265cdf0e10cSrcweir }
1266cdf0e10cSrcweir
~ScConditionalFormat()1267cdf0e10cSrcweir ScConditionalFormat::~ScConditionalFormat()
1268cdf0e10cSrcweir {
1269cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1270cdf0e10cSrcweir delete ppEntries[i];
1271cdf0e10cSrcweir delete[] ppEntries;
1272cdf0e10cSrcweir
1273cdf0e10cSrcweir delete pAreas;
1274cdf0e10cSrcweir }
1275cdf0e10cSrcweir
GetEntry(sal_uInt16 nPos) const1276cdf0e10cSrcweir const ScCondFormatEntry* ScConditionalFormat::GetEntry( sal_uInt16 nPos ) const
1277cdf0e10cSrcweir {
1278cdf0e10cSrcweir if ( nPos < nEntryCount )
1279cdf0e10cSrcweir return ppEntries[nPos];
1280cdf0e10cSrcweir else
1281cdf0e10cSrcweir return NULL;
1282cdf0e10cSrcweir }
1283cdf0e10cSrcweir
GetCellStyle(ScBaseCell * pCell,const ScAddress & rPos) const1284cdf0e10cSrcweir const String& ScConditionalFormat::GetCellStyle( ScBaseCell* pCell, const ScAddress& rPos ) const
1285cdf0e10cSrcweir {
1286cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1287cdf0e10cSrcweir if ( ppEntries[i]->IsCellValid( pCell, rPos ) )
1288cdf0e10cSrcweir return ppEntries[i]->GetStyle();
1289cdf0e10cSrcweir
1290cdf0e10cSrcweir return EMPTY_STRING;
1291cdf0e10cSrcweir }
1292cdf0e10cSrcweir
lcl_Extend(ScRange & rRange,ScDocument * pDoc,sal_Bool bLines)1293cdf0e10cSrcweir void lcl_Extend( ScRange& rRange, ScDocument* pDoc, sal_Bool bLines )
1294cdf0e10cSrcweir {
1295cdf0e10cSrcweir SCTAB nTab = rRange.aStart.Tab();
1296cdf0e10cSrcweir DBG_ASSERT(rRange.aEnd.Tab() == nTab, "lcl_Extend - mehrere Tabellen?");
1297cdf0e10cSrcweir
1298cdf0e10cSrcweir SCCOL nStartCol = rRange.aStart.Col();
1299cdf0e10cSrcweir SCROW nStartRow = rRange.aStart.Row();
1300cdf0e10cSrcweir SCCOL nEndCol = rRange.aEnd.Col();
1301cdf0e10cSrcweir SCROW nEndRow = rRange.aEnd.Row();
1302cdf0e10cSrcweir
1303cdf0e10cSrcweir sal_Bool bEx = pDoc->ExtendMerge( nStartCol, nStartRow, nEndCol, nEndRow, nTab );
1304cdf0e10cSrcweir
1305cdf0e10cSrcweir if (bLines)
1306cdf0e10cSrcweir {
1307cdf0e10cSrcweir if (nStartCol > 0) --nStartCol;
1308cdf0e10cSrcweir if (nStartRow > 0) --nStartRow;
1309cdf0e10cSrcweir if (nEndCol < MAXCOL) ++nEndCol;
1310cdf0e10cSrcweir if (nEndRow < MAXROW) ++nEndRow;
1311cdf0e10cSrcweir }
1312cdf0e10cSrcweir
1313cdf0e10cSrcweir if ( bEx || bLines )
1314cdf0e10cSrcweir {
1315cdf0e10cSrcweir rRange.aStart.Set( nStartCol, nStartRow, nTab );
1316cdf0e10cSrcweir rRange.aEnd.Set( nEndCol, nEndRow, nTab );
1317cdf0e10cSrcweir }
1318cdf0e10cSrcweir }
1319cdf0e10cSrcweir
lcl_CutRange(ScRange & rRange,const ScRange & rOther)1320cdf0e10cSrcweir sal_Bool lcl_CutRange( ScRange& rRange, const ScRange& rOther )
1321cdf0e10cSrcweir {
1322cdf0e10cSrcweir rRange.Justify();
1323cdf0e10cSrcweir ScRange aCmpRange = rOther;
1324cdf0e10cSrcweir aCmpRange.Justify();
1325cdf0e10cSrcweir
1326cdf0e10cSrcweir if ( rRange.aStart.Col() <= aCmpRange.aEnd.Col() &&
1327cdf0e10cSrcweir rRange.aEnd.Col() >= aCmpRange.aStart.Col() &&
1328cdf0e10cSrcweir rRange.aStart.Row() <= aCmpRange.aEnd.Row() &&
1329cdf0e10cSrcweir rRange.aEnd.Row() >= aCmpRange.aStart.Row() &&
1330cdf0e10cSrcweir rRange.aStart.Tab() <= aCmpRange.aEnd.Tab() &&
1331cdf0e10cSrcweir rRange.aEnd.Tab() >= aCmpRange.aStart.Tab() )
1332cdf0e10cSrcweir {
1333cdf0e10cSrcweir if ( rRange.aStart.Col() < aCmpRange.aStart.Col() )
1334cdf0e10cSrcweir rRange.aStart.SetCol( aCmpRange.aStart.Col() );
1335cdf0e10cSrcweir if ( rRange.aStart.Row() < aCmpRange.aStart.Row() )
1336cdf0e10cSrcweir rRange.aStart.SetRow( aCmpRange.aStart.Row() );
1337cdf0e10cSrcweir if ( rRange.aStart.Tab() < aCmpRange.aStart.Tab() )
1338cdf0e10cSrcweir rRange.aStart.SetTab( aCmpRange.aStart.Tab() );
1339cdf0e10cSrcweir if ( rRange.aEnd.Col() > aCmpRange.aEnd.Col() )
1340cdf0e10cSrcweir rRange.aEnd.SetCol( aCmpRange.aEnd.Col() );
1341cdf0e10cSrcweir if ( rRange.aEnd.Row() > aCmpRange.aEnd.Row() )
1342cdf0e10cSrcweir rRange.aEnd.SetRow( aCmpRange.aEnd.Row() );
1343cdf0e10cSrcweir if ( rRange.aEnd.Tab() > aCmpRange.aEnd.Tab() )
1344cdf0e10cSrcweir rRange.aEnd.SetTab( aCmpRange.aEnd.Tab() );
1345cdf0e10cSrcweir
1346cdf0e10cSrcweir return sal_True;
1347cdf0e10cSrcweir }
1348cdf0e10cSrcweir
1349cdf0e10cSrcweir return sal_False; // ausserhalb
1350cdf0e10cSrcweir }
1351cdf0e10cSrcweir
DoRepaint(const ScRange * pModified)1352cdf0e10cSrcweir void ScConditionalFormat::DoRepaint( const ScRange* pModified )
1353cdf0e10cSrcweir {
1354cdf0e10cSrcweir sal_uInt16 i;
1355cdf0e10cSrcweir SfxObjectShell* pSh = pDoc->GetDocumentShell();
1356cdf0e10cSrcweir if (pSh)
1357cdf0e10cSrcweir {
1358cdf0e10cSrcweir // Rahmen/Schatten enthalten?
1359cdf0e10cSrcweir // (alle Bedingungen testen)
1360cdf0e10cSrcweir sal_Bool bExtend = sal_False;
1361cdf0e10cSrcweir sal_Bool bRotate = sal_False;
1362cdf0e10cSrcweir sal_Bool bAttrTested = sal_False;
1363cdf0e10cSrcweir
1364cdf0e10cSrcweir if (!pAreas) // RangeList ggf. holen
1365cdf0e10cSrcweir {
1366cdf0e10cSrcweir pAreas = new ScRangeList;
1367cdf0e10cSrcweir pDoc->FindConditionalFormat( nKey, *pAreas );
1368cdf0e10cSrcweir }
1369cdf0e10cSrcweir sal_uInt16 nCount = (sal_uInt16) pAreas->Count();
1370cdf0e10cSrcweir for (i=0; i<nCount; i++)
1371cdf0e10cSrcweir {
1372cdf0e10cSrcweir ScRange aRange = *pAreas->GetObject(i);
1373cdf0e10cSrcweir sal_Bool bDo = sal_True;
1374cdf0e10cSrcweir if ( pModified )
1375cdf0e10cSrcweir {
1376cdf0e10cSrcweir if ( !lcl_CutRange( aRange, *pModified ) )
1377cdf0e10cSrcweir bDo = sal_False;
1378cdf0e10cSrcweir }
1379cdf0e10cSrcweir if (bDo)
1380cdf0e10cSrcweir {
1381cdf0e10cSrcweir if ( !bAttrTested )
1382cdf0e10cSrcweir {
1383cdf0e10cSrcweir // #116562# Look at the style's content only if the repaint is necessary
1384cdf0e10cSrcweir // for any condition, to avoid the time-consuming Find() if there are many
1385cdf0e10cSrcweir // conditional formats and styles.
1386cdf0e10cSrcweir for (sal_uInt16 nEntry=0; nEntry<nEntryCount; nEntry++)
1387cdf0e10cSrcweir {
1388cdf0e10cSrcweir String aStyle = ppEntries[nEntry]->GetStyle();
1389cdf0e10cSrcweir if (aStyle.Len())
1390cdf0e10cSrcweir {
1391cdf0e10cSrcweir SfxStyleSheetBase* pStyleSheet =
1392cdf0e10cSrcweir pDoc->GetStyleSheetPool()->Find( aStyle, SFX_STYLE_FAMILY_PARA );
1393cdf0e10cSrcweir if ( pStyleSheet )
1394cdf0e10cSrcweir {
1395cdf0e10cSrcweir const SfxItemSet& rSet = pStyleSheet->GetItemSet();
1396cdf0e10cSrcweir if (rSet.GetItemState( ATTR_BORDER, sal_True ) == SFX_ITEM_SET ||
1397cdf0e10cSrcweir rSet.GetItemState( ATTR_SHADOW, sal_True ) == SFX_ITEM_SET)
1398cdf0e10cSrcweir {
1399cdf0e10cSrcweir bExtend = sal_True;
1400cdf0e10cSrcweir }
1401cdf0e10cSrcweir if (rSet.GetItemState( ATTR_ROTATE_VALUE, sal_True ) == SFX_ITEM_SET ||
1402cdf0e10cSrcweir rSet.GetItemState( ATTR_ROTATE_MODE, sal_True ) == SFX_ITEM_SET)
1403cdf0e10cSrcweir {
1404cdf0e10cSrcweir bRotate = sal_True;
1405cdf0e10cSrcweir }
1406cdf0e10cSrcweir }
1407cdf0e10cSrcweir }
1408cdf0e10cSrcweir }
1409cdf0e10cSrcweir bAttrTested = sal_True;
1410cdf0e10cSrcweir }
1411cdf0e10cSrcweir
1412cdf0e10cSrcweir lcl_Extend( aRange, pDoc, bExtend ); // zusammengefasste und bExtend
1413cdf0e10cSrcweir if ( bRotate )
1414cdf0e10cSrcweir {
1415cdf0e10cSrcweir aRange.aStart.SetCol(0);
1416cdf0e10cSrcweir aRange.aEnd.SetCol(MAXCOL); // gedreht: ganze Zeilen
1417cdf0e10cSrcweir }
1418cdf0e10cSrcweir
1419cdf0e10cSrcweir // gedreht -> ganze Zeilen
1420cdf0e10cSrcweir if ( aRange.aStart.Col() != 0 || aRange.aEnd.Col() != MAXCOL )
1421cdf0e10cSrcweir {
1422cdf0e10cSrcweir if ( pDoc->HasAttrib( 0,aRange.aStart.Row(),aRange.aStart.Tab(),
1423cdf0e10cSrcweir MAXCOL,aRange.aEnd.Row(),aRange.aEnd.Tab(),
1424cdf0e10cSrcweir HASATTR_ROTATE ) )
1425cdf0e10cSrcweir {
1426cdf0e10cSrcweir aRange.aStart.SetCol(0);
1427cdf0e10cSrcweir aRange.aEnd.SetCol(MAXCOL);
1428cdf0e10cSrcweir }
1429cdf0e10cSrcweir }
1430cdf0e10cSrcweir
1431cdf0e10cSrcweir pDoc->RepaintRange( aRange );
1432cdf0e10cSrcweir }
1433cdf0e10cSrcweir }
1434cdf0e10cSrcweir }
1435cdf0e10cSrcweir }
1436cdf0e10cSrcweir
InvalidateArea()1437cdf0e10cSrcweir void ScConditionalFormat::InvalidateArea()
1438cdf0e10cSrcweir {
1439cdf0e10cSrcweir delete pAreas;
1440cdf0e10cSrcweir pAreas = NULL;
1441cdf0e10cSrcweir }
1442cdf0e10cSrcweir
CompileAll()1443cdf0e10cSrcweir void ScConditionalFormat::CompileAll()
1444cdf0e10cSrcweir {
1445cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1446cdf0e10cSrcweir ppEntries[i]->CompileAll();
1447cdf0e10cSrcweir }
1448cdf0e10cSrcweir
CompileXML()1449cdf0e10cSrcweir void ScConditionalFormat::CompileXML()
1450cdf0e10cSrcweir {
1451cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1452cdf0e10cSrcweir ppEntries[i]->CompileXML();
1453cdf0e10cSrcweir }
1454cdf0e10cSrcweir
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & rRange,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)1455cdf0e10cSrcweir void ScConditionalFormat::UpdateReference( UpdateRefMode eUpdateRefMode,
1456cdf0e10cSrcweir const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
1457cdf0e10cSrcweir {
1458cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1459cdf0e10cSrcweir ppEntries[i]->UpdateReference(eUpdateRefMode, rRange, nDx, nDy, nDz);
1460cdf0e10cSrcweir
1461cdf0e10cSrcweir delete pAreas; // aus dem AttrArray kommt beim Einfuegen/Loeschen kein Aufruf
1462cdf0e10cSrcweir pAreas = NULL;
1463cdf0e10cSrcweir }
1464cdf0e10cSrcweir
RenameCellStyle(const String & rOld,const String & rNew)1465cdf0e10cSrcweir void ScConditionalFormat::RenameCellStyle(const String& rOld, const String& rNew)
1466cdf0e10cSrcweir {
1467cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1468cdf0e10cSrcweir if ( ppEntries[i]->GetStyle() == rOld )
1469cdf0e10cSrcweir ppEntries[i]->UpdateStyleName( rNew );
1470cdf0e10cSrcweir }
1471cdf0e10cSrcweir
UpdateMoveTab(SCTAB nOldPos,SCTAB nNewPos)1472cdf0e10cSrcweir void ScConditionalFormat::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
1473cdf0e10cSrcweir {
1474cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1475cdf0e10cSrcweir ppEntries[i]->UpdateMoveTab( nOldPos, nNewPos );
1476cdf0e10cSrcweir
1477cdf0e10cSrcweir delete pAreas; // aus dem AttrArray kommt beim Einfuegen/Loeschen kein Aufruf
1478cdf0e10cSrcweir pAreas = NULL;
1479cdf0e10cSrcweir }
1480cdf0e10cSrcweir
SourceChanged(const ScAddress & rAddr)1481cdf0e10cSrcweir void ScConditionalFormat::SourceChanged( const ScAddress& rAddr )
1482cdf0e10cSrcweir {
1483cdf0e10cSrcweir for (sal_uInt16 i=0; i<nEntryCount; i++)
1484cdf0e10cSrcweir ppEntries[i]->SourceChanged( rAddr );
1485cdf0e10cSrcweir }
1486cdf0e10cSrcweir
MarkUsedExternalReferences() const1487cdf0e10cSrcweir bool ScConditionalFormat::MarkUsedExternalReferences() const
1488cdf0e10cSrcweir {
1489cdf0e10cSrcweir bool bAllMarked = false;
1490cdf0e10cSrcweir for (sal_uInt16 i=0; !bAllMarked && i<nEntryCount; i++)
1491cdf0e10cSrcweir bAllMarked = ppEntries[i]->MarkUsedExternalReferences();
1492cdf0e10cSrcweir return bAllMarked;
1493cdf0e10cSrcweir }
1494cdf0e10cSrcweir
1495cdf0e10cSrcweir //------------------------------------------------------------------------
1496cdf0e10cSrcweir
ScConditionalFormatList(const ScConditionalFormatList & rList)1497cdf0e10cSrcweir ScConditionalFormatList::ScConditionalFormatList(const ScConditionalFormatList& rList) :
1498cdf0e10cSrcweir ScConditionalFormats_Impl()
1499cdf0e10cSrcweir {
1500cdf0e10cSrcweir // fuer Ref-Undo - echte Kopie mit neuen Tokens!
1501cdf0e10cSrcweir
1502cdf0e10cSrcweir sal_uInt16 nCount = rList.Count();
1503cdf0e10cSrcweir
1504cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1505cdf0e10cSrcweir InsertNew( rList[i]->Clone() );
1506cdf0e10cSrcweir
1507cdf0e10cSrcweir //! sortierte Eintraege aus rList schneller einfuegen ???
1508cdf0e10cSrcweir }
1509cdf0e10cSrcweir
ScConditionalFormatList(ScDocument * pNewDoc,const ScConditionalFormatList & rList)1510cdf0e10cSrcweir ScConditionalFormatList::ScConditionalFormatList(ScDocument* pNewDoc,
1511cdf0e10cSrcweir const ScConditionalFormatList& rList)
1512cdf0e10cSrcweir {
1513cdf0e10cSrcweir // fuer neues Dokument - echte Kopie mit neuen Tokens!
1514cdf0e10cSrcweir
1515cdf0e10cSrcweir sal_uInt16 nCount = rList.Count();
1516cdf0e10cSrcweir
1517cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1518cdf0e10cSrcweir InsertNew( rList[i]->Clone(pNewDoc) );
1519cdf0e10cSrcweir
1520cdf0e10cSrcweir //! sortierte Eintraege aus rList schneller einfuegen ???
1521cdf0e10cSrcweir }
1522cdf0e10cSrcweir
operator ==(const ScConditionalFormatList & r) const1523cdf0e10cSrcweir sal_Bool ScConditionalFormatList::operator==( const ScConditionalFormatList& r ) const
1524cdf0e10cSrcweir {
1525cdf0e10cSrcweir // fuer Ref-Undo - interne Variablen werden nicht verglichen
1526cdf0e10cSrcweir
1527cdf0e10cSrcweir sal_uInt16 nCount = Count();
1528cdf0e10cSrcweir sal_Bool bEqual = ( nCount == r.Count() );
1529cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount && bEqual; i++) // Eintraege sind sortiert
1530cdf0e10cSrcweir if ( !(*this)[i]->EqualEntries(*r[i]) ) // Eintraege unterschiedlich ?
1531cdf0e10cSrcweir bEqual = sal_False;
1532cdf0e10cSrcweir
1533cdf0e10cSrcweir return bEqual;
1534cdf0e10cSrcweir }
1535cdf0e10cSrcweir
GetFormat(sal_uInt32 nKey)1536cdf0e10cSrcweir ScConditionalFormat* ScConditionalFormatList::GetFormat( sal_uInt32 nKey )
1537cdf0e10cSrcweir {
1538cdf0e10cSrcweir //! binaer suchen
1539cdf0e10cSrcweir
1540cdf0e10cSrcweir sal_uInt16 nCount = Count();
1541cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1542cdf0e10cSrcweir if ((*this)[i]->GetKey() == nKey)
1543cdf0e10cSrcweir return (*this)[i];
1544cdf0e10cSrcweir
1545cdf0e10cSrcweir DBG_ERROR("ScConditionalFormatList: Eintrag nicht gefunden");
1546cdf0e10cSrcweir return NULL;
1547cdf0e10cSrcweir }
1548cdf0e10cSrcweir
CompileAll()1549cdf0e10cSrcweir void ScConditionalFormatList::CompileAll()
1550cdf0e10cSrcweir {
1551cdf0e10cSrcweir sal_uInt16 nCount = Count();
1552cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1553cdf0e10cSrcweir (*this)[i]->CompileAll();
1554cdf0e10cSrcweir }
1555cdf0e10cSrcweir
CompileXML()1556cdf0e10cSrcweir void ScConditionalFormatList::CompileXML()
1557cdf0e10cSrcweir {
1558cdf0e10cSrcweir sal_uInt16 nCount = Count();
1559cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1560cdf0e10cSrcweir (*this)[i]->CompileXML();
1561cdf0e10cSrcweir }
1562cdf0e10cSrcweir
UpdateReference(UpdateRefMode eUpdateRefMode,const ScRange & rRange,SCsCOL nDx,SCsROW nDy,SCsTAB nDz)1563cdf0e10cSrcweir void ScConditionalFormatList::UpdateReference( UpdateRefMode eUpdateRefMode,
1564cdf0e10cSrcweir const ScRange& rRange, SCsCOL nDx, SCsROW nDy, SCsTAB nDz )
1565cdf0e10cSrcweir {
1566cdf0e10cSrcweir sal_uInt16 nCount = Count();
1567cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1568cdf0e10cSrcweir (*this)[i]->UpdateReference( eUpdateRefMode, rRange, nDx, nDy, nDz );
1569cdf0e10cSrcweir }
1570cdf0e10cSrcweir
RenameCellStyle(const String & rOld,const String & rNew)1571cdf0e10cSrcweir void ScConditionalFormatList::RenameCellStyle( const String& rOld, const String& rNew )
1572cdf0e10cSrcweir {
1573cdf0e10cSrcweir sal_uLong nCount=Count();
1574cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1575cdf0e10cSrcweir (*this)[i]->RenameCellStyle(rOld,rNew);
1576cdf0e10cSrcweir }
1577cdf0e10cSrcweir
UpdateMoveTab(SCTAB nOldPos,SCTAB nNewPos)1578cdf0e10cSrcweir void ScConditionalFormatList::UpdateMoveTab( SCTAB nOldPos, SCTAB nNewPos )
1579cdf0e10cSrcweir {
1580cdf0e10cSrcweir sal_uInt16 nCount = Count();
1581cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1582cdf0e10cSrcweir (*this)[i]->UpdateMoveTab( nOldPos, nNewPos );
1583cdf0e10cSrcweir }
1584cdf0e10cSrcweir
SourceChanged(const ScAddress & rAddr)1585cdf0e10cSrcweir void ScConditionalFormatList::SourceChanged( const ScAddress& rAddr )
1586cdf0e10cSrcweir {
1587cdf0e10cSrcweir sal_uInt16 nCount = Count();
1588cdf0e10cSrcweir for (sal_uInt16 i=0; i<nCount; i++)
1589cdf0e10cSrcweir (*this)[i]->SourceChanged( rAddr );
1590cdf0e10cSrcweir }
1591cdf0e10cSrcweir
MarkUsedExternalReferences() const1592cdf0e10cSrcweir bool ScConditionalFormatList::MarkUsedExternalReferences() const
1593cdf0e10cSrcweir {
1594cdf0e10cSrcweir bool bAllMarked = false;
1595cdf0e10cSrcweir sal_uInt16 nCount = Count();
1596cdf0e10cSrcweir for (sal_uInt16 i=0; !bAllMarked && i<nCount; i++)
1597cdf0e10cSrcweir bAllMarked = (*this)[i]->MarkUsedExternalReferences();
1598cdf0e10cSrcweir return bAllMarked;
1599cdf0e10cSrcweir }
1600