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