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 <svtools/colorcfg.hxx>
31 : : #include <editeng/eeitem.hxx>
32 : : #include <editeng/outlobj.hxx>
33 : : #include <svx/sdshitm.hxx>
34 : : #include <svx/sdsxyitm.hxx>
35 : : #include <svx/sdtditm.hxx>
36 : : #include <svx/svditer.hxx>
37 : : #include <svx/svdocapt.hxx>
38 : : #include <svx/svdocirc.hxx>
39 : : #include <svx/svdopath.hxx>
40 : : #include <svx/svdorect.hxx>
41 : : #include <svx/svdpage.hxx>
42 : : #include <svx/svdundo.hxx>
43 : : #include <svx/xfillit0.hxx>
44 : : #include <svx/xflclit.hxx>
45 : : #include <svx/xlnclit.hxx>
46 : : #include <svx/xlnedcit.hxx>
47 : : #include <svx/xlnedit.hxx>
48 : : #include <svx/xlnedwit.hxx>
49 : : #include <svx/xlnstcit.hxx>
50 : : #include <svx/xlnstit.hxx>
51 : : #include <svx/xlnstwit.hxx>
52 : : #include <svx/xlnwtit.hxx>
53 : : #include <svx/xtable.hxx>
54 : : #include <editeng/outliner.hxx>
55 : : #include <editeng/editobj.hxx>
56 : : #include <svx/sxcecitm.hxx>
57 : : #include <svl/whiter.hxx>
58 : : #include <editeng/writingmodeitem.hxx>
59 : :
60 : : #include <basegfx/point/b2dpoint.hxx>
61 : : #include <basegfx/polygon/b2dpolygontools.hxx>
62 : : #include <basegfx/polygon/b2dpolygon.hxx>
63 : :
64 : : #include "detfunc.hxx"
65 : : #include "document.hxx"
66 : : #include "dociter.hxx"
67 : : #include "drwlayer.hxx"
68 : : #include "userdat.hxx"
69 : : #include "validat.hxx"
70 : : #include "cell.hxx"
71 : : #include "docpool.hxx"
72 : : #include "patattr.hxx"
73 : : #include "attrib.hxx"
74 : : #include "scmod.hxx"
75 : : #include "postit.hxx"
76 : : #include "rangelst.hxx"
77 : : #include "reftokenhelper.hxx"
78 : :
79 : : #include <vector>
80 : :
81 : : using ::std::vector;
82 : :
83 : : //------------------------------------------------------------------------
84 : :
85 : : // line ends are now created with an empty name.
86 : : // The checkForUniqueItem method then finds a unique name for the item's value.
87 : : #define SC_LINEEND_NAME EMPTY_STRING
88 : :
89 : : //------------------------------------------------------------------------
90 : :
91 : : enum DetInsertResult { // Return-Werte beim Einfuegen in einen Level
92 : : DET_INS_CONTINUE,
93 : : DET_INS_INSERTED,
94 : : DET_INS_EMPTY,
95 : : DET_INS_CIRCULAR };
96 : :
97 : :
98 : : //------------------------------------------------------------------------
99 : :
100 [ + - ][ + - ]: 13 : class ScDetectiveData
[ + - ][ + - ]
101 : : {
102 : : private:
103 : : SfxItemSet aBoxSet;
104 : : SfxItemSet aArrowSet;
105 : : SfxItemSet aToTabSet;
106 : : SfxItemSet aFromTabSet;
107 : : SfxItemSet aCircleSet; //! einzeln ?
108 : : sal_uInt16 nMaxLevel;
109 : :
110 : : public:
111 : : ScDetectiveData( SdrModel* pModel );
112 : :
113 : 0 : SfxItemSet& GetBoxSet() { return aBoxSet; }
114 : 1 : SfxItemSet& GetArrowSet() { return aArrowSet; }
115 : 0 : SfxItemSet& GetToTabSet() { return aToTabSet; }
116 : 12 : SfxItemSet& GetFromTabSet() { return aFromTabSet; }
117 : 0 : SfxItemSet& GetCircleSet() { return aCircleSet; }
118 : :
119 : 13 : void SetMaxLevel( sal_uInt16 nVal ) { nMaxLevel = nVal; }
120 : 0 : sal_uInt16 GetMaxLevel() const { return nMaxLevel; }
121 : : };
122 : :
123 : 0 : class ScCommentData
124 : : {
125 : : public:
126 : : ScCommentData( ScDocument& rDoc, SdrModel* pModel );
127 : :
128 : 0 : SfxItemSet& GetCaptionSet() { return aCaptionSet; }
129 : : void UpdateCaptionSet( const SfxItemSet& rItemSet );
130 : :
131 : : private:
132 : : SfxItemSet aCaptionSet;
133 : : };
134 : :
135 : : //------------------------------------------------------------------------
136 : :
137 : : ColorData ScDetectiveFunc::nArrowColor = 0;
138 : : ColorData ScDetectiveFunc::nErrorColor = 0;
139 : : ColorData ScDetectiveFunc::nCommentColor = 0;
140 : : sal_Bool ScDetectiveFunc::bColorsInitialized = false;
141 : :
142 : : //------------------------------------------------------------------------
143 : :
144 : 0 : sal_Bool lcl_HasThickLine( SdrObject& rObj )
145 : : {
146 : : // thin lines get width 0 -> everything greater 0 is a thick line
147 : :
148 : 0 : return ( ((const XLineWidthItem&)rObj.GetMergedItem(XATTR_LINEWIDTH)).GetValue() > 0 );
149 : : }
150 : :
151 : : //------------------------------------------------------------------------
152 : :
153 : 13 : ScDetectiveData::ScDetectiveData( SdrModel* pModel ) :
154 : 13 : aBoxSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
155 : 13 : aArrowSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
156 : 13 : aToTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
157 : 13 : aFromTabSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END ),
158 [ + - ][ + - : 52 : aCircleSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END )
+ - + - ]
159 : : {
160 : 13 : nMaxLevel = 0;
161 : :
162 [ + - ][ + - ]: 13 : aBoxSet.Put( XLineColorItem( EMPTY_STRING, Color( ScDetectiveFunc::GetArrowColor() ) ) );
[ + - ][ + - ]
[ + - ]
163 [ + - ][ + - ]: 13 : aBoxSet.Put( XFillStyleItem( XFILL_NONE ) );
[ + - ]
164 : :
165 : : // Standard-Linienenden (wie aus XLineEndList::Create) selber zusammenbasteln,
166 : : // um von den konfigurierten Linienenden unabhaengig zu sein
167 : :
168 [ + - ]: 13 : basegfx::B2DPolygon aTriangle;
169 [ + - ]: 13 : aTriangle.append(basegfx::B2DPoint(10.0, 0.0));
170 [ + - ]: 13 : aTriangle.append(basegfx::B2DPoint(0.0, 30.0));
171 [ + - ]: 13 : aTriangle.append(basegfx::B2DPoint(20.0, 30.0));
172 [ + - ]: 13 : aTriangle.setClosed(true);
173 : :
174 [ + - ]: 13 : basegfx::B2DPolygon aSquare;
175 [ + - ]: 13 : aSquare.append(basegfx::B2DPoint(0.0, 0.0));
176 [ + - ]: 13 : aSquare.append(basegfx::B2DPoint(10.0, 0.0));
177 [ + - ]: 13 : aSquare.append(basegfx::B2DPoint(10.0, 10.0));
178 [ + - ]: 13 : aSquare.append(basegfx::B2DPoint(0.0, 10.0));
179 [ + - ]: 13 : aSquare.setClosed(true);
180 : :
181 [ + - ]: 13 : basegfx::B2DPolygon aCircle(basegfx::tools::createPolygonFromEllipse(basegfx::B2DPoint(0.0, 0.0), 100.0, 100.0));
182 [ + - ]: 13 : aCircle.setClosed(true);
183 : :
184 [ + - ][ + - ]: 13 : String aName = SC_LINEEND_NAME;
185 : :
186 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aCircle) ) );
[ + - ][ + - ]
[ + - ]
187 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineStartWidthItem( 200 ) );
[ + - ]
188 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineStartCenterItem( sal_True ) );
[ + - ]
189 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
[ + - ][ + - ]
[ + - ]
190 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineEndWidthItem( 200 ) );
[ + - ]
191 [ + - ][ + - ]: 13 : aArrowSet.Put( XLineEndCenterItem( false ) );
[ + - ]
192 : :
193 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aCircle) ) );
[ + - ][ + - ]
[ + - ]
194 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineStartWidthItem( 200 ) );
[ + - ]
195 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineStartCenterItem( sal_True ) );
[ + - ]
196 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aSquare) ) );
[ + - ][ + - ]
[ + - ]
197 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineEndWidthItem( 300 ) );
[ + - ]
198 [ + - ][ + - ]: 13 : aToTabSet.Put( XLineEndCenterItem( false ) );
[ + - ]
199 : :
200 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aSquare) ) );
[ + - ][ + - ]
[ + - ]
201 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineStartWidthItem( 300 ) );
[ + - ]
202 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineStartCenterItem( sal_True ) );
[ + - ]
203 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineEndItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
[ + - ][ + - ]
[ + - ]
204 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineEndWidthItem( 200 ) );
[ + - ]
205 [ + - ][ + - ]: 13 : aFromTabSet.Put( XLineEndCenterItem( false ) );
[ + - ]
206 : :
207 [ + - ][ + - ]: 13 : aCircleSet.Put( XLineColorItem( String(), Color( ScDetectiveFunc::GetErrorColor() ) ) );
[ + - ][ + - ]
[ + - ][ + - ]
208 [ + - ][ + - ]: 13 : aCircleSet.Put( XFillStyleItem( XFILL_NONE ) );
[ + - ]
209 : 13 : sal_uInt16 nWidth = 55; // 54 = 1 Pixel
210 [ + - ][ + - ]: 13 : aCircleSet.Put( XLineWidthItem( nWidth ) );
[ + - ][ + - ]
[ + - ][ + - ]
[ + - ]
211 : 13 : }
212 : :
213 : 0 : ScCommentData::ScCommentData( ScDocument& rDoc, SdrModel* pModel ) :
214 : 0 : aCaptionSet( pModel->GetItemPool(), SDRATTR_START, SDRATTR_END, EE_ITEMS_START, EE_ITEMS_END, 0, 0 )
215 : : {
216 [ # # ]: 0 : basegfx::B2DPolygon aTriangle;
217 [ # # ]: 0 : aTriangle.append(basegfx::B2DPoint(10.0, 0.0));
218 [ # # ]: 0 : aTriangle.append(basegfx::B2DPoint(0.0, 30.0));
219 [ # # ]: 0 : aTriangle.append(basegfx::B2DPoint(20.0, 30.0));
220 [ # # ]: 0 : aTriangle.setClosed(true);
221 : :
222 [ # # ][ # # ]: 0 : String aName = SC_LINEEND_NAME;
223 : :
224 [ # # ][ # # ]: 0 : aCaptionSet.Put( XLineStartItem( aName, basegfx::B2DPolyPolygon(aTriangle) ) );
[ # # ][ # # ]
[ # # ]
225 [ # # ][ # # ]: 0 : aCaptionSet.Put( XLineStartWidthItem( 200 ) );
[ # # ]
226 [ # # ][ # # ]: 0 : aCaptionSet.Put( XLineStartCenterItem( false ) );
[ # # ]
227 [ # # ][ # # ]: 0 : aCaptionSet.Put( XFillStyleItem( XFILL_SOLID ) );
[ # # ]
228 [ # # ]: 0 : Color aYellow( ScDetectiveFunc::GetCommentColor() );
229 [ # # ][ # # ]: 0 : aCaptionSet.Put( XFillColorItem( String(), aYellow ) );
[ # # ][ # # ]
[ # # ]
230 : :
231 : : // shadow
232 : : // SdrShadowItem has sal_False, instead the shadow is set for the rectangle
233 : : // only with SetSpecialTextBoxShadow when the object is created
234 : : // (item must be set to adjust objects from older files)
235 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrShadowItem( false ) );
[ # # ]
236 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrShadowXDistItem( 100 ) );
[ # # ]
237 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrShadowYDistItem( 100 ) );
[ # # ]
238 : :
239 : : // text attributes
240 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextLeftDistItem( 100 ) );
[ # # ]
241 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextRightDistItem( 100 ) );
[ # # ]
242 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextUpperDistItem( 100 ) );
[ # # ]
243 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextLowerDistItem( 100 ) );
[ # # ]
244 : :
245 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextAutoGrowWidthItem( false ) );
[ # # ]
246 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrTextAutoGrowHeightItem( sal_True ) );
[ # # ]
247 : :
248 : : // do use the default cell style, so the user has a chance to
249 : : // modify the font for the annotations
250 [ # # ][ # # ]: 0 : ((const ScPatternAttr&)rDoc.GetPool()->GetDefaultItem(ATTR_PATTERN)).
251 [ # # ]: 0 : FillEditItemSet( &aCaptionSet );
252 : :
253 : : // support the best position for the tail connector now that
254 : : // that notes can be resized and repositioned.
255 [ # # ][ # # ]: 0 : aCaptionSet.Put( SdrCaptionEscDirItem( SDRCAPT_ESCBESTFIT) );
[ # # ][ # # ]
[ # # ]
256 : 0 : }
257 : :
258 : 0 : void ScCommentData::UpdateCaptionSet( const SfxItemSet& rItemSet )
259 : : {
260 [ # # ]: 0 : SfxWhichIter aWhichIter( rItemSet );
261 : 0 : const SfxPoolItem* pPoolItem = 0;
262 : :
263 [ # # ][ # # ]: 0 : for( sal_uInt16 nWhich = aWhichIter.FirstWhich(); nWhich > 0; nWhich = aWhichIter.NextWhich() )
[ # # ]
264 : : {
265 [ # # ][ # # ]: 0 : if(rItemSet.GetItemState(nWhich, false, &pPoolItem) == SFX_ITEM_SET)
266 : : {
267 [ # # # # ]: 0 : switch(nWhich)
268 : : {
269 : : case SDRATTR_SHADOW:
270 : : // use existing Caption default - appears that setting this
271 : : // to true screws up the tail appearance. See also comment
272 : : // for default setting above.
273 : 0 : break;
274 : : case SDRATTR_SHADOWXDIST:
275 : : // use existing Caption default - svx sets a value of 35
276 : : // but default 100 gives a better appearance.
277 : 0 : break;
278 : : case SDRATTR_SHADOWYDIST:
279 : : // use existing Caption default - svx sets a value of 35
280 : : // but default 100 gives a better appearance.
281 : 0 : break;
282 : :
283 : : default:
284 [ # # ]: 0 : aCaptionSet.Put(*pPoolItem);
285 : : }
286 : : }
287 [ # # ]: 0 : }
288 : 0 : }
289 : :
290 : : //------------------------------------------------------------------------
291 : :
292 : 25 : void ScDetectiveFunc::Modified()
293 : : {
294 [ - + ]: 25 : if (pDoc->IsStreamValid(nTab))
295 : 0 : pDoc->SetStreamValid(nTab, false);
296 : 25 : }
297 : :
298 : 0 : inline sal_Bool Intersect( SCCOL nStartCol1, SCROW nStartRow1, SCCOL nEndCol1, SCROW nEndRow1,
299 : : SCCOL nStartCol2, SCROW nStartRow2, SCCOL nEndCol2, SCROW nEndRow2 )
300 : : {
301 : : return nEndCol1 >= nStartCol2 && nEndCol2 >= nStartCol1 &&
302 [ # # ][ # # ]: 0 : nEndRow1 >= nStartRow2 && nEndRow2 >= nStartRow1;
[ # # ][ # # ]
303 : : }
304 : :
305 : 13 : sal_Bool ScDetectiveFunc::HasError( const ScRange& rRange, ScAddress& rErrPos )
306 : : {
307 : 13 : rErrPos = rRange.aStart;
308 : 13 : sal_uInt16 nError = 0;
309 : :
310 [ + - ]: 13 : ScCellIterator aCellIter( pDoc, rRange);
311 [ + - ]: 13 : ScBaseCell* pCell = aCellIter.GetFirst();
312 [ + + ]: 26 : while (pCell)
313 : : {
314 [ - + ]: 13 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
315 : : {
316 [ # # ][ # # ]: 0 : nError = ((ScFormulaCell*)pCell)->GetErrCode();
317 [ # # ]: 0 : if (nError)
318 : 0 : rErrPos.Set( aCellIter.GetCol(), aCellIter.GetRow(), aCellIter.GetTab() );
319 : : }
320 [ + - ]: 13 : pCell = aCellIter.GetNext();
321 : : }
322 : :
323 : 13 : return (nError != 0);
324 : : }
325 : :
326 : 54 : Point ScDetectiveFunc::GetDrawPos( SCCOL nCol, SCROW nRow, DrawPosMode eMode ) const
327 : : {
328 : : OSL_ENSURE( ValidColRow( nCol, nRow ), "ScDetectiveFunc::GetDrawPos - invalid cell address" );
329 : 54 : SanitizeCol( nCol );
330 : 54 : SanitizeRow( nRow );
331 : :
332 : 54 : Point aPos;
333 : :
334 [ + + + - : 54 : switch( eMode )
- - ]
335 : : {
336 : : case DRAWPOS_TOPLEFT:
337 : 14 : break;
338 : : case DRAWPOS_BOTTOMRIGHT:
339 : 14 : ++nCol;
340 : 14 : ++nRow;
341 : 14 : break;
342 : : case DRAWPOS_DETARROW:
343 : 26 : aPos.X() += pDoc->GetColWidth( nCol, nTab ) / 4;
344 : 26 : aPos.Y() += pDoc->GetRowHeight( nRow, nTab ) / 2;
345 : 26 : break;
346 : : case DRAWPOS_CAPTIONLEFT:
347 : 0 : aPos.X() += 6;
348 : 0 : break;
349 : : case DRAWPOS_CAPTIONRIGHT:
350 : : {
351 : : // find right end of passed cell position
352 : 0 : const ScMergeAttr* pMerge = static_cast< const ScMergeAttr* >( pDoc->GetAttr( nCol, nRow, nTab, ATTR_MERGE ) );
353 [ # # ]: 0 : if ( pMerge->GetColMerge() > 1 )
354 : 0 : nCol = nCol + pMerge->GetColMerge();
355 : : else
356 : 0 : ++nCol;
357 : 0 : aPos.X() -= 6;
358 : : }
359 : 0 : break;
360 : : }
361 : :
362 [ + + ]: 392 : for ( SCCOL i = 0; i < nCol; ++i )
363 : 338 : aPos.X() += pDoc->GetColWidth( i, nTab );
364 : 54 : aPos.Y() += pDoc->GetRowHeight( 0, nRow - 1, nTab );
365 : :
366 : 54 : aPos.X() = static_cast< long >( aPos.X() * HMM_PER_TWIPS );
367 : 54 : aPos.Y() = static_cast< long >( aPos.Y() * HMM_PER_TWIPS );
368 : :
369 [ - + ]: 54 : if ( pDoc->IsNegativePage( nTab ) )
370 : 0 : aPos.X() *= -1;
371 : :
372 : 54 : return aPos;
373 : : }
374 : :
375 : 14 : Rectangle ScDetectiveFunc::GetDrawRect( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 ) const
376 : : {
377 : : Rectangle aRect(
378 [ + - ][ + - ]: 14 : GetDrawPos( ::std::min( nCol1, nCol2 ), ::std::min( nRow1, nRow2 ), DRAWPOS_TOPLEFT ),
379 [ + - ][ + - ]: 28 : GetDrawPos( ::std::max( nCol1, nCol2 ), ::std::max( nRow1, nRow2 ), DRAWPOS_BOTTOMRIGHT ) );
380 : 14 : aRect.Justify(); // reorder left/right in RTL sheets
381 : 14 : return aRect;
382 : : }
383 : :
384 : 14 : Rectangle ScDetectiveFunc::GetDrawRect( SCCOL nCol, SCROW nRow ) const
385 : : {
386 : 14 : return GetDrawRect( nCol, nRow, nCol, nRow );
387 : : }
388 : :
389 : 0 : sal_Bool lcl_IsOtherTab( const basegfx::B2DPolyPolygon& rPolyPolygon )
390 : : {
391 : : // test if rPolygon is the line end for "other table" (rectangle)
392 [ # # ]: 0 : if(1L == rPolyPolygon.count())
393 : : {
394 [ # # ]: 0 : const basegfx::B2DPolygon aSubPoly(rPolyPolygon.getB2DPolygon(0L));
395 : :
396 : : // #i73305# circle consists of 4 segments, too, distinguishable from square by
397 : : // the use of control points
398 [ # # ][ # # ]: 0 : if(4L == aSubPoly.count() && aSubPoly.isClosed() && !aSubPoly.areControlPointsUsed())
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
399 : : {
400 : 0 : return true;
401 [ # # ][ # # ]: 0 : }
402 : : }
403 : :
404 : 0 : return false;
405 : : }
406 : :
407 : 13 : sal_Bool ScDetectiveFunc::HasArrow( const ScAddress& rStart,
408 : : SCCOL nEndCol, SCROW nEndRow, SCTAB nEndTab )
409 : : {
410 : 13 : sal_Bool bStartAlien = ( rStart.Tab() != nTab );
411 : 13 : sal_Bool bEndAlien = ( nEndTab != nTab );
412 : :
413 [ - + ][ + + ]: 13 : if (bStartAlien && bEndAlien)
414 : : {
415 : : OSL_FAIL("bStartAlien && bEndAlien");
416 : 0 : return true;
417 : : }
418 : :
419 [ + - ]: 13 : Rectangle aStartRect;
420 [ + - ]: 13 : Rectangle aEndRect;
421 [ + + ]: 13 : if (!bStartAlien)
422 [ + - ]: 1 : aStartRect = GetDrawRect( rStart.Col(), rStart.Row() );
423 [ + - ]: 13 : if (!bEndAlien)
424 [ + - ]: 13 : aEndRect = GetDrawRect( nEndCol, nEndRow );
425 : :
426 [ + - ]: 13 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
427 [ + - ]: 13 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
428 : : OSL_ENSURE(pPage,"Page ?");
429 : :
430 : 13 : sal_Bool bFound = false;
431 [ + - ]: 13 : SdrObjListIter aIter( *pPage, IM_FLAT );
432 [ + - ]: 13 : SdrObject* pObject = aIter.Next();
433 [ - + ][ # # ]: 13 : while (pObject && !bFound)
[ - + ]
434 : : {
435 [ # # ][ # # ]: 0 : if ( pObject->GetLayer()==SC_LAYER_INTERN &&
[ # # ][ # # ]
[ # # ]
436 [ # # ][ # # ]: 0 : pObject->IsPolyObj() && pObject->GetPointCount()==2 )
437 : : {
438 [ # # ]: 0 : const SfxItemSet& rSet = pObject->GetMergedItemSet();
439 : :
440 : : sal_Bool bObjStartAlien =
441 [ # # ][ # # ]: 0 : lcl_IsOtherTab( ((const XLineStartItem&)rSet.Get(XATTR_LINESTART)).GetLineStartValue() );
[ # # ][ # # ]
442 : : sal_Bool bObjEndAlien =
443 [ # # ][ # # ]: 0 : lcl_IsOtherTab( ((const XLineEndItem&)rSet.Get(XATTR_LINEEND)).GetLineEndValue() );
[ # # ][ # # ]
444 : :
445 : : sal_Bool bStartHit = bStartAlien ? bObjStartAlien :
446 [ # # ][ # # ]: 0 : ( !bObjStartAlien && aStartRect.IsInside(pObject->GetPoint(0)) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
447 : : sal_Bool bEndHit = bEndAlien ? bObjEndAlien :
448 [ # # ][ # # ]: 0 : ( !bObjEndAlien && aEndRect.IsInside(pObject->GetPoint(1)) );
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
449 : :
450 [ # # ][ # # ]: 0 : if ( bStartHit && bEndHit )
451 : 0 : bFound = sal_True;
452 : : }
453 [ # # ]: 0 : pObject = aIter.Next();
454 : : }
455 : :
456 : 13 : return bFound;
457 : : }
458 : :
459 : 0 : sal_Bool ScDetectiveFunc::IsNonAlienArrow( SdrObject* pObject )
460 : : {
461 [ # # # # : 0 : if ( pObject->GetLayer()==SC_LAYER_INTERN &&
# # ][ # # ]
462 : 0 : pObject->IsPolyObj() && pObject->GetPointCount()==2 )
463 : : {
464 : 0 : const SfxItemSet& rSet = pObject->GetMergedItemSet();
465 : :
466 : : sal_Bool bObjStartAlien =
467 [ # # ]: 0 : lcl_IsOtherTab( ((const XLineStartItem&)rSet.Get(XATTR_LINESTART)).GetLineStartValue() );
468 : : sal_Bool bObjEndAlien =
469 [ # # ]: 0 : lcl_IsOtherTab( ((const XLineEndItem&)rSet.Get(XATTR_LINEEND)).GetLineEndValue() );
470 : :
471 [ # # ][ # # ]: 0 : return !bObjStartAlien && !bObjEndAlien;
472 : : }
473 : :
474 : 0 : return false;
475 : : }
476 : :
477 : : //------------------------------------------------------------------------
478 : :
479 : : // InsertXXX: called from DrawEntry/DrawAlienEntry and InsertObject
480 : :
481 : 13 : sal_Bool ScDetectiveFunc::InsertArrow( SCCOL nCol, SCROW nRow,
482 : : SCCOL nRefStartCol, SCROW nRefStartRow,
483 : : SCCOL nRefEndCol, SCROW nRefEndRow,
484 : : sal_Bool bFromOtherTab, sal_Bool bRed,
485 : : ScDetectiveData& rData )
486 : : {
487 [ + - ]: 13 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
488 [ + - ]: 13 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
489 : :
490 [ + - ][ - + ]: 13 : sal_Bool bArea = ( nRefStartCol != nRefEndCol || nRefStartRow != nRefEndRow );
491 [ - + ][ # # ]: 13 : if (bArea && !bFromOtherTab)
492 : : {
493 : : // insert the rectangle before the arrow - this is relied on in FindFrameForObject
494 : :
495 [ # # ]: 0 : Rectangle aRect = GetDrawRect( nRefStartCol, nRefStartRow, nRefEndCol, nRefEndRow );
496 [ # # ][ # # ]: 0 : SdrRectObj* pBox = new SdrRectObj( aRect );
497 : :
498 [ # # ]: 0 : pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
499 : :
500 [ # # ]: 0 : pBox->SetLayer( SC_LAYER_INTERN );
501 [ # # ]: 0 : pPage->InsertObject( pBox );
502 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) );
[ # # ]
503 : :
504 [ # # ]: 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, sal_True );
505 : 0 : pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
506 : 0 : pData->maEnd.Set( nRefEndCol, nRefEndRow, nTab);
507 : : }
508 : :
509 [ + - ]: 13 : Point aStartPos = GetDrawPos( nRefStartCol, nRefStartRow, DRAWPOS_DETARROW );
510 [ + - ]: 13 : Point aEndPos = GetDrawPos( nCol, nRow, DRAWPOS_DETARROW );
511 : :
512 [ + + ]: 13 : if (bFromOtherTab)
513 : : {
514 [ + - ]: 12 : sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
515 [ - + ]: 12 : long nPageSign = bNegativePage ? -1 : 1;
516 : :
517 : 12 : aStartPos = Point( aEndPos.X() - 1000 * nPageSign, aEndPos.Y() - 1000 );
518 [ - + ]: 12 : if (aStartPos.X() * nPageSign < 0)
519 : 0 : aStartPos.X() += 2000 * nPageSign;
520 [ - + ]: 12 : if (aStartPos.Y() < 0)
521 : 0 : aStartPos.Y() += 2000;
522 : : }
523 : :
524 [ + + ]: 13 : SfxItemSet& rAttrSet = bFromOtherTab ? rData.GetFromTabSet() : rData.GetArrowSet();
525 : :
526 [ - + ][ # # ]: 13 : if (bArea && !bFromOtherTab)
527 [ # # ][ # # ]: 0 : rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich
[ # # ]
528 : : else
529 [ + - ][ + - ]: 13 : rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz
[ + - ]
530 : :
531 [ - + ][ # # ]: 13 : ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() );
[ + - ]
532 [ + - ][ + - ]: 13 : rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) );
[ + - ][ + - ]
[ + - ]
533 : :
534 [ + - ]: 13 : basegfx::B2DPolygon aTempPoly;
535 [ + - ]: 13 : aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
536 [ + - ]: 13 : aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
537 [ + - ][ + - ]: 13 : SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aTempPoly));
[ + - ][ + - ]
538 [ + - ][ + - ]: 13 : pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ???
539 [ + - ]: 13 : pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
540 : :
541 [ + - ]: 13 : pArrow->SetLayer( SC_LAYER_INTERN );
542 [ + - ]: 13 : pPage->InsertObject( pArrow );
543 [ + - ][ + - ]: 13 : pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) );
[ + - ]
544 : :
545 [ + - ]: 13 : ScDrawObjData* pData = ScDrawLayer::GetObjData(pArrow, true);
546 [ + + ]: 13 : if (bFromOtherTab)
547 : 12 : pData->maStart.SetInvalid();
548 : : else
549 : 1 : pData->maStart.Set( nRefStartCol, nRefStartRow, nTab);
550 : :
551 : 13 : pData->maEnd.Set( nCol, nRow, nTab);
552 : 13 : pData->meType = ScDrawObjData::DetectiveArrow;
553 : :
554 [ + - ]: 13 : Modified();
555 [ + - ]: 13 : return true;
556 : : }
557 : :
558 : 0 : sal_Bool ScDetectiveFunc::InsertToOtherTab( SCCOL nStartCol, SCROW nStartRow,
559 : : SCCOL nEndCol, SCROW nEndRow, sal_Bool bRed,
560 : : ScDetectiveData& rData )
561 : : {
562 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
563 [ # # ]: 0 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
564 : :
565 [ # # ][ # # ]: 0 : sal_Bool bArea = ( nStartCol != nEndCol || nStartRow != nEndRow );
566 [ # # ]: 0 : if (bArea)
567 : : {
568 [ # # ]: 0 : Rectangle aRect = GetDrawRect( nStartCol, nStartRow, nEndCol, nEndRow );
569 [ # # ][ # # ]: 0 : SdrRectObj* pBox = new SdrRectObj( aRect );
570 : :
571 [ # # ]: 0 : pBox->SetMergedItemSetAndBroadcast(rData.GetBoxSet());
572 : :
573 [ # # ]: 0 : pBox->SetLayer( SC_LAYER_INTERN );
574 [ # # ]: 0 : pPage->InsertObject( pBox );
575 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoInsertObj( *pBox ) );
[ # # ]
576 : :
577 [ # # ]: 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pBox, sal_True );
578 : 0 : pData->maStart.Set( nStartCol, nStartRow, nTab);
579 : 0 : pData->maEnd.Set( nEndCol, nEndRow, nTab);
580 : : }
581 : :
582 [ # # ]: 0 : sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
583 [ # # ]: 0 : long nPageSign = bNegativePage ? -1 : 1;
584 : :
585 [ # # ]: 0 : Point aStartPos = GetDrawPos( nStartCol, nStartRow, DRAWPOS_DETARROW );
586 : 0 : Point aEndPos = Point( aStartPos.X() + 1000 * nPageSign, aStartPos.Y() - 1000 );
587 [ # # ]: 0 : if (aEndPos.Y() < 0)
588 : 0 : aEndPos.Y() += 2000;
589 : :
590 : 0 : SfxItemSet& rAttrSet = rData.GetToTabSet();
591 [ # # ]: 0 : if (bArea)
592 [ # # ][ # # ]: 0 : rAttrSet.Put( XLineWidthItem( 50 ) ); // Bereich
[ # # ]
593 : : else
594 [ # # ][ # # ]: 0 : rAttrSet.Put( XLineWidthItem( 0 ) ); // einzelne Referenz
[ # # ]
595 : :
596 [ # # ][ # # ]: 0 : ColorData nColorData = ( bRed ? GetErrorColor() : GetArrowColor() );
[ # # ]
597 [ # # ][ # # ]: 0 : rAttrSet.Put( XLineColorItem( String(), Color( nColorData ) ) );
[ # # ][ # # ]
[ # # ]
598 : :
599 [ # # ]: 0 : basegfx::B2DPolygon aTempPoly;
600 [ # # ]: 0 : aTempPoly.append(basegfx::B2DPoint(aStartPos.X(), aStartPos.Y()));
601 [ # # ]: 0 : aTempPoly.append(basegfx::B2DPoint(aEndPos.X(), aEndPos.Y()));
602 [ # # ][ # # ]: 0 : SdrPathObj* pArrow = new SdrPathObj(OBJ_LINE, basegfx::B2DPolyPolygon(aTempPoly));
[ # # ][ # # ]
603 [ # # ][ # # ]: 0 : pArrow->NbcSetLogicRect(Rectangle(aStartPos,aEndPos)); //! noetig ???
604 : :
605 [ # # ]: 0 : pArrow->SetMergedItemSetAndBroadcast(rAttrSet);
606 : :
607 [ # # ]: 0 : pArrow->SetLayer( SC_LAYER_INTERN );
608 [ # # ]: 0 : pPage->InsertObject( pArrow );
609 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoInsertObj( *pArrow ) );
[ # # ]
610 : :
611 [ # # ]: 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pArrow, sal_True );
612 : 0 : pData->maStart.Set( nStartCol, nStartRow, nTab);
613 : 0 : pData->maEnd.SetInvalid();
614 : :
615 [ # # ]: 0 : Modified();
616 [ # # ]: 0 : return sal_True;
617 : : }
618 : :
619 : : //------------------------------------------------------------------------
620 : :
621 : : // DrawEntry: Formel auf dieser Tabelle,
622 : : // Referenz auf dieser oder anderer
623 : : // DrawAlienEntry: Formel auf anderer Tabelle,
624 : : // Referenz auf dieser
625 : :
626 : : // return FALSE: da war schon ein Pfeil
627 : :
628 : 13 : sal_Bool ScDetectiveFunc::DrawEntry( SCCOL nCol, SCROW nRow,
629 : : const ScRange& rRef,
630 : : ScDetectiveData& rData )
631 : : {
632 [ + - ][ - + ]: 13 : if ( HasArrow( rRef.aStart, nCol, nRow, nTab ) )
633 : 0 : return false;
634 : :
635 : 13 : ScAddress aErrorPos;
636 [ + - ]: 13 : sal_Bool bError = HasError( rRef, aErrorPos );
637 [ + + ][ - + ]: 13 : sal_Bool bAlien = ( rRef.aEnd.Tab() < nTab || rRef.aStart.Tab() > nTab );
638 : :
639 : : return InsertArrow( nCol, nRow,
640 : 13 : rRef.aStart.Col(), rRef.aStart.Row(),
641 : 13 : rRef.aEnd.Col(), rRef.aEnd.Row(),
642 [ + - ]: 39 : bAlien, bError, rData );
643 : : }
644 : :
645 : 0 : sal_Bool ScDetectiveFunc::DrawAlienEntry( const ScRange& rRef,
646 : : ScDetectiveData& rData )
647 : : {
648 [ # # ][ # # ]: 0 : if ( HasArrow( rRef.aStart, 0, 0, nTab+1 ) )
649 : 0 : return false;
650 : :
651 : 0 : ScAddress aErrorPos;
652 [ # # ]: 0 : sal_Bool bError = HasError( rRef, aErrorPos );
653 : :
654 : 0 : return InsertToOtherTab( rRef.aStart.Col(), rRef.aStart.Row(),
655 : 0 : rRef.aEnd.Col(), rRef.aEnd.Row(),
656 [ # # ]: 0 : bError, rData );
657 : : }
658 : :
659 : 0 : void ScDetectiveFunc::DrawCircle( SCCOL nCol, SCROW nRow, ScDetectiveData& rData )
660 : : {
661 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
662 [ # # ]: 0 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
663 : :
664 [ # # ]: 0 : Rectangle aRect = GetDrawRect( nCol, nRow );
665 : 0 : aRect.Left() -= 250;
666 : 0 : aRect.Right() += 250;
667 : 0 : aRect.Top() -= 70;
668 : 0 : aRect.Bottom() += 70;
669 : :
670 [ # # ][ # # ]: 0 : SdrCircObj* pCircle = new SdrCircObj( OBJ_CIRC, aRect );
671 : 0 : SfxItemSet& rAttrSet = rData.GetCircleSet();
672 : :
673 [ # # ]: 0 : pCircle->SetMergedItemSetAndBroadcast(rAttrSet);
674 : :
675 [ # # ]: 0 : pCircle->SetLayer( SC_LAYER_INTERN );
676 [ # # ]: 0 : pPage->InsertObject( pCircle );
677 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoInsertObj( *pCircle ) );
[ # # ]
678 : :
679 [ # # ]: 0 : ScDrawObjData* pData = ScDrawLayer::GetObjData( pCircle, sal_True );
680 : 0 : pData->maStart.Set( nCol, nRow, nTab);
681 : 0 : pData->maEnd.SetInvalid();
682 : 0 : pData->meType = ScDrawObjData::ValidationCircle;
683 : :
684 [ # # ]: 0 : Modified();
685 : 0 : }
686 : :
687 : 0 : void ScDetectiveFunc::DeleteArrowsAt( SCCOL nCol, SCROW nRow, sal_Bool bDestPnt )
688 : : {
689 [ # # ]: 0 : Rectangle aRect = GetDrawRect( nCol, nRow );
690 : :
691 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
692 [ # # ]: 0 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
693 : : OSL_ENSURE(pPage,"Page ?");
694 : :
695 [ # # ]: 0 : pPage->RecalcObjOrdNums();
696 : :
697 [ # # ]: 0 : sal_uLong nObjCount = pPage->GetObjCount();
698 [ # # ]: 0 : if (nObjCount)
699 : : {
700 : 0 : long nDelCount = 0;
701 [ # # ]: 0 : SdrObject** ppObj = new SdrObject*[nObjCount];
702 : :
703 [ # # ]: 0 : SdrObjListIter aIter( *pPage, IM_FLAT );
704 [ # # ]: 0 : SdrObject* pObject = aIter.Next();
705 [ # # ]: 0 : while (pObject)
706 : : {
707 [ # # ][ # # ]: 0 : if ( pObject->GetLayer()==SC_LAYER_INTERN &&
[ # # ][ # # ]
[ # # ]
708 [ # # ][ # # ]: 0 : pObject->IsPolyObj() && pObject->GetPointCount()==2 )
709 : : {
710 [ # # ][ # # ]: 0 : if (aRect.IsInside(pObject->GetPoint(bDestPnt))) // Start/Zielpunkt
[ # # ]
711 : 0 : ppObj[nDelCount++] = pObject;
712 : : }
713 : :
714 [ # # ]: 0 : pObject = aIter.Next();
715 : : }
716 : :
717 : : long i;
718 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
719 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
[ # # ]
720 : :
721 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
722 [ # # ][ # # ]: 0 : pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
723 : :
724 [ # # ]: 0 : delete[] ppObj;
725 : :
726 [ # # ]: 0 : Modified();
727 : : }
728 : 0 : }
729 : :
730 : : // Box um Referenz loeschen
731 : :
732 : : #define SC_DET_TOLERANCE 50
733 : :
734 : 0 : inline sal_Bool RectIsPoints( const Rectangle& rRect, const Point& rStart, const Point& rEnd )
735 : : {
736 : 0 : return rRect.Left() >= rStart.X() - SC_DET_TOLERANCE
737 : 0 : && rRect.Left() <= rStart.X() + SC_DET_TOLERANCE
738 : 0 : && rRect.Right() >= rEnd.X() - SC_DET_TOLERANCE
739 : 0 : && rRect.Right() <= rEnd.X() + SC_DET_TOLERANCE
740 : 0 : && rRect.Top() >= rStart.Y() - SC_DET_TOLERANCE
741 : 0 : && rRect.Top() <= rStart.Y() + SC_DET_TOLERANCE
742 : 0 : && rRect.Bottom() >= rEnd.Y() - SC_DET_TOLERANCE
743 [ # # ][ # # : 0 : && rRect.Bottom() <= rEnd.Y() + SC_DET_TOLERANCE;
# # # # #
# # # # #
# # ]
744 : : }
745 : :
746 : : #undef SC_DET_TOLERANCE
747 : :
748 : 0 : void ScDetectiveFunc::DeleteBox( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2 )
749 : : {
750 [ # # ]: 0 : Rectangle aCornerRect = GetDrawRect( nCol1, nRow1, nCol2, nRow2 );
751 : 0 : Point aStartCorner = aCornerRect.TopLeft();
752 [ # # ]: 0 : Point aEndCorner = aCornerRect.BottomRight();
753 [ # # ]: 0 : Rectangle aObjRect;
754 : :
755 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
756 [ # # ]: 0 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
757 : : OSL_ENSURE(pPage,"Page ?");
758 : :
759 [ # # ]: 0 : pPage->RecalcObjOrdNums();
760 : :
761 [ # # ]: 0 : sal_uLong nObjCount = pPage->GetObjCount();
762 [ # # ]: 0 : if (nObjCount)
763 : : {
764 : 0 : long nDelCount = 0;
765 [ # # ]: 0 : SdrObject** ppObj = new SdrObject*[nObjCount];
766 : :
767 [ # # ]: 0 : SdrObjListIter aIter( *pPage, IM_FLAT );
768 [ # # ]: 0 : SdrObject* pObject = aIter.Next();
769 [ # # ]: 0 : while (pObject)
770 : : {
771 [ # # ][ # # ]: 0 : if ( pObject->GetLayer() == SC_LAYER_INTERN &&
[ # # ][ # # ]
772 [ # # ][ # # ]: 0 : pObject->Type() == TYPE(SdrRectObj) )
773 : : {
774 [ # # ]: 0 : aObjRect = ((SdrRectObj*)pObject)->GetLogicRect();
775 [ # # ]: 0 : aObjRect.Justify();
776 [ # # ]: 0 : if ( RectIsPoints( aObjRect, aStartCorner, aEndCorner ) )
777 : 0 : ppObj[nDelCount++] = pObject;
778 : : }
779 : :
780 [ # # ]: 0 : pObject = aIter.Next();
781 : : }
782 : :
783 : : long i;
784 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
785 [ # # ][ # # ]: 0 : pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
[ # # ]
786 : :
787 [ # # ]: 0 : for (i=1; i<=nDelCount; i++)
788 [ # # ][ # # ]: 0 : pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
789 : :
790 [ # # ]: 0 : delete[] ppObj;
791 : :
792 [ # # ]: 0 : Modified();
793 : : }
794 : 0 : }
795 : :
796 : : //------------------------------------------------------------------------
797 : :
798 : 0 : sal_uInt16 ScDetectiveFunc::InsertPredLevelArea( const ScRange& rRef,
799 : : ScDetectiveData& rData, sal_uInt16 nLevel )
800 : : {
801 : 0 : sal_uInt16 nResult = DET_INS_EMPTY;
802 : :
803 [ # # ]: 0 : ScCellIterator aCellIter( pDoc, rRef);
804 [ # # ]: 0 : ScBaseCell* pCell = aCellIter.GetFirst();
805 [ # # ]: 0 : while (pCell)
806 : : {
807 [ # # ]: 0 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
808 [ # # ]: 0 : switch( InsertPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), rData, nLevel ) )
[ # # # # ]
809 : : {
810 : : case DET_INS_INSERTED:
811 : 0 : nResult = DET_INS_INSERTED;
812 : 0 : break;
813 : : case DET_INS_CONTINUE:
814 [ # # ]: 0 : if (nResult != DET_INS_INSERTED)
815 : 0 : nResult = DET_INS_CONTINUE;
816 : 0 : break;
817 : : case DET_INS_CIRCULAR:
818 [ # # ]: 0 : if (nResult == DET_INS_EMPTY)
819 : 0 : nResult = DET_INS_CIRCULAR;
820 : 0 : break;
821 : : }
822 : :
823 [ # # ]: 0 : pCell = aCellIter.GetNext();
824 : : }
825 : :
826 : 0 : return nResult;
827 : : }
828 : :
829 : 13 : sal_uInt16 ScDetectiveFunc::InsertPredLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
830 : : sal_uInt16 nLevel )
831 : : {
832 : : ScBaseCell* pCell;
833 [ + - ]: 13 : pDoc->GetCell( nCol, nRow, nTab, pCell );
834 [ - + ]: 13 : if (!pCell)
835 : 0 : return DET_INS_EMPTY;
836 [ - + ]: 13 : if (pCell->GetCellType() != CELLTYPE_FORMULA)
837 : 0 : return DET_INS_EMPTY;
838 : :
839 [ + - ]: 13 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
840 [ - + ]: 13 : if (pFCell->IsRunning())
841 : 0 : return DET_INS_CIRCULAR;
842 : :
843 [ + + ]: 13 : if (pFCell->GetDirty())
844 [ + - ]: 1 : pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
845 : 13 : pFCell->SetRunning(sal_True);
846 : :
847 : 13 : sal_uInt16 nResult = DET_INS_EMPTY;
848 : :
849 [ + - ][ + - ]: 13 : ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
850 : 13 : ScRange aRef;
851 [ + - ][ + + ]: 26 : while ( aIter.GetNextRef( aRef ) )
852 : : {
853 [ + - ][ + - ]: 13 : if (DrawEntry( nCol, nRow, aRef, rData ))
854 : : {
855 : 13 : nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen
856 : : }
857 : : else
858 : : {
859 : : // weiterverfolgen
860 : :
861 [ # # ]: 0 : if ( nLevel < rData.GetMaxLevel() )
862 : : {
863 : : sal_uInt16 nSubResult;
864 : 0 : sal_Bool bArea = (aRef.aStart != aRef.aEnd);
865 [ # # ]: 0 : if (bArea)
866 [ # # ]: 0 : nSubResult = InsertPredLevelArea( aRef, rData, nLevel+1 );
867 : : else
868 : 0 : nSubResult = InsertPredLevel( aRef.aStart.Col(), aRef.aStart.Row(),
869 [ # # ]: 0 : rData, nLevel+1 );
870 : :
871 [ # # # # ]: 0 : switch (nSubResult)
872 : : {
873 : : case DET_INS_INSERTED:
874 : 0 : nResult = DET_INS_INSERTED;
875 : 0 : break;
876 : : case DET_INS_CONTINUE:
877 [ # # ]: 0 : if (nResult != DET_INS_INSERTED)
878 : 0 : nResult = DET_INS_CONTINUE;
879 : 0 : break;
880 : : case DET_INS_CIRCULAR:
881 [ # # ]: 0 : if (nResult == DET_INS_EMPTY)
882 : 0 : nResult = DET_INS_CIRCULAR;
883 : 0 : break;
884 : : // DET_INS_EMPTY: unveraendert lassen
885 : : }
886 : : }
887 : : else // nMaxLevel erreicht
888 [ # # ]: 0 : if (nResult != DET_INS_INSERTED)
889 : 0 : nResult = DET_INS_CONTINUE;
890 : : }
891 : : }
892 : :
893 : 13 : pFCell->SetRunning(false);
894 : :
895 : 13 : return nResult;
896 : : }
897 : :
898 : 0 : sal_uInt16 ScDetectiveFunc::FindPredLevelArea( const ScRange& rRef,
899 : : sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
900 : : {
901 : 0 : sal_uInt16 nResult = nLevel;
902 : :
903 [ # # ]: 0 : ScCellIterator aCellIter( pDoc, rRef);
904 [ # # ]: 0 : ScBaseCell* pCell = aCellIter.GetFirst();
905 [ # # ]: 0 : while (pCell)
906 : : {
907 [ # # ]: 0 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
908 : : {
909 [ # # ]: 0 : sal_uInt16 nTemp = FindPredLevel( aCellIter.GetCol(), aCellIter.GetRow(), nLevel, nDeleteLevel );
910 [ # # ]: 0 : if (nTemp > nResult)
911 : 0 : nResult = nTemp;
912 : : }
913 [ # # ]: 0 : pCell = aCellIter.GetNext();
914 : : }
915 : :
916 : 0 : return nResult;
917 : : }
918 : :
919 : : // nDeleteLevel != 0 -> loeschen
920 : :
921 : 0 : sal_uInt16 ScDetectiveFunc::FindPredLevel( SCCOL nCol, SCROW nRow, sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
922 : : {
923 : : OSL_ENSURE( nLevel<1000, "Level" );
924 : :
925 : : ScBaseCell* pCell;
926 [ # # ]: 0 : pDoc->GetCell( nCol, nRow, nTab, pCell );
927 [ # # ]: 0 : if (!pCell)
928 : 0 : return nLevel;
929 [ # # ]: 0 : if (pCell->GetCellType() != CELLTYPE_FORMULA)
930 : 0 : return nLevel;
931 : :
932 [ # # ]: 0 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
933 [ # # ]: 0 : if (pFCell->IsRunning())
934 : 0 : return nLevel;
935 : :
936 [ # # ]: 0 : if (pFCell->GetDirty())
937 [ # # ]: 0 : pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
938 : 0 : pFCell->SetRunning(sal_True);
939 : :
940 : 0 : sal_uInt16 nResult = nLevel;
941 [ # # ][ # # ]: 0 : sal_Bool bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
942 : :
943 [ # # ]: 0 : if ( bDelete )
944 : : {
945 [ # # ]: 0 : DeleteArrowsAt( nCol, nRow, sal_True ); // Pfeile, die hierher zeigen
946 : : }
947 : :
948 [ # # ][ # # ]: 0 : ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
949 : 0 : ScRange aRef;
950 [ # # ][ # # ]: 0 : while ( aIter.GetNextRef( aRef) )
951 : : {
952 : 0 : sal_Bool bArea = ( aRef.aStart != aRef.aEnd );
953 : :
954 [ # # ]: 0 : if ( bDelete ) // Rahmen loeschen ?
955 : : {
956 [ # # ]: 0 : if (bArea)
957 : : {
958 [ # # ]: 0 : DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(), aRef.aEnd.Col(), aRef.aEnd.Row() );
959 : : }
960 : : }
961 : : else // weitersuchen
962 : : {
963 [ # # ][ # # ]: 0 : if ( HasArrow( aRef.aStart, nCol,nRow,nTab ) )
964 : : {
965 : : sal_uInt16 nTemp;
966 [ # # ]: 0 : if (bArea)
967 [ # # ]: 0 : nTemp = FindPredLevelArea( aRef, nLevel+1, nDeleteLevel );
968 : : else
969 : 0 : nTemp = FindPredLevel( aRef.aStart.Col(),aRef.aStart.Row(),
970 [ # # ]: 0 : nLevel+1, nDeleteLevel );
971 [ # # ]: 0 : if (nTemp > nResult)
972 : 0 : nResult = nTemp;
973 : : }
974 : : }
975 : : }
976 : :
977 : 0 : pFCell->SetRunning(false);
978 : :
979 : 0 : return nResult;
980 : : }
981 : :
982 : : //------------------------------------------------------------------------
983 : :
984 : 0 : sal_uInt16 ScDetectiveFunc::InsertErrorLevel( SCCOL nCol, SCROW nRow, ScDetectiveData& rData,
985 : : sal_uInt16 nLevel )
986 : : {
987 : : ScBaseCell* pCell;
988 [ # # ]: 0 : pDoc->GetCell( nCol, nRow, nTab, pCell );
989 [ # # ]: 0 : if (!pCell)
990 : 0 : return DET_INS_EMPTY;
991 [ # # ]: 0 : if (pCell->GetCellType() != CELLTYPE_FORMULA)
992 : 0 : return DET_INS_EMPTY;
993 : :
994 [ # # ]: 0 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
995 [ # # ]: 0 : if (pFCell->IsRunning())
996 : 0 : return DET_INS_CIRCULAR;
997 : :
998 [ # # ]: 0 : if (pFCell->GetDirty())
999 [ # # ]: 0 : pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
1000 : 0 : pFCell->SetRunning(sal_True);
1001 : :
1002 : 0 : sal_uInt16 nResult = DET_INS_EMPTY;
1003 : :
1004 [ # # ][ # # ]: 0 : ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
1005 : 0 : ScRange aRef;
1006 : 0 : ScAddress aErrorPos;
1007 : 0 : sal_Bool bHasError = false;
1008 [ # # ][ # # ]: 0 : while ( aIter.GetNextRef( aRef ) )
1009 : : {
1010 [ # # ][ # # ]: 0 : if (HasError( aRef, aErrorPos ))
1011 : : {
1012 : 0 : bHasError = sal_True;
1013 [ # # ][ # # ]: 0 : if (DrawEntry( nCol, nRow, ScRange( aErrorPos), rData ))
1014 : 0 : nResult = DET_INS_INSERTED;
1015 : :
1016 : : // und weiterverfolgen
1017 : :
1018 [ # # ]: 0 : if ( nLevel < rData.GetMaxLevel() ) // praktisch immer
1019 : : {
1020 [ # # ]: 0 : if (InsertErrorLevel( aErrorPos.Col(), aErrorPos.Row(),
1021 [ # # ]: 0 : rData, nLevel+1 ) == DET_INS_INSERTED)
1022 : 0 : nResult = DET_INS_INSERTED;
1023 : : }
1024 : : }
1025 : : }
1026 : :
1027 : 0 : pFCell->SetRunning(false);
1028 : :
1029 : : // Blaetter ?
1030 [ # # ]: 0 : if (!bHasError)
1031 [ # # ][ # # ]: 0 : if (InsertPredLevel( nCol, nRow, rData, rData.GetMaxLevel() ) == DET_INS_INSERTED)
1032 : 0 : nResult = DET_INS_INSERTED;
1033 : :
1034 : 0 : return nResult;
1035 : : }
1036 : :
1037 : : //------------------------------------------------------------------------
1038 : :
1039 : 0 : sal_uInt16 ScDetectiveFunc::InsertSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1040 : : ScDetectiveData& rData, sal_uInt16 nLevel )
1041 : : {
1042 : : // ueber ganzes Dokument
1043 : :
1044 : 0 : sal_uInt16 nResult = DET_INS_EMPTY;
1045 [ # # ]: 0 : ScCellIterator aCellIter( pDoc, 0,0,0, MAXCOL,MAXROW,MAXTAB ); // alle Tabellen
1046 [ # # ]: 0 : ScBaseCell* pCell = aCellIter.GetFirst();
1047 [ # # ]: 0 : while (pCell)
1048 : : {
1049 [ # # ]: 0 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
1050 : : {
1051 [ # # ]: 0 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1052 : 0 : sal_Bool bRunning = pFCell->IsRunning();
1053 : :
1054 [ # # ]: 0 : if (pFCell->GetDirty())
1055 [ # # ]: 0 : pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
1056 : 0 : pFCell->SetRunning(sal_True);
1057 : :
1058 [ # # ][ # # ]: 0 : ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
1059 : 0 : ScRange aRef;
1060 [ # # ][ # # ]: 0 : while ( aIter.GetNextRef( aRef) )
1061 : : {
1062 [ # # ][ # # ]: 0 : if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
[ # # ]
1063 : : {
1064 [ # # ]: 0 : if (Intersect( nCol1,nRow1,nCol2,nRow2,
1065 : 0 : aRef.aStart.Col(),aRef.aStart.Row(),
1066 : 0 : aRef.aEnd.Col(),aRef.aEnd.Row() ))
1067 : : {
1068 : 0 : sal_Bool bAlien = ( aCellIter.GetTab() != nTab );
1069 : : sal_Bool bDrawRet;
1070 [ # # ]: 0 : if (bAlien)
1071 [ # # ]: 0 : bDrawRet = DrawAlienEntry( aRef, rData );
1072 : : else
1073 : 0 : bDrawRet = DrawEntry( aCellIter.GetCol(), aCellIter.GetRow(),
1074 [ # # ]: 0 : aRef, rData );
1075 [ # # ]: 0 : if (bDrawRet)
1076 : : {
1077 : 0 : nResult = DET_INS_INSERTED; // neuer Pfeil eingetragen
1078 : : }
1079 : : else
1080 : : {
1081 [ # # ]: 0 : if (bRunning)
1082 : : {
1083 [ # # ]: 0 : if (nResult == DET_INS_EMPTY)
1084 : 0 : nResult = DET_INS_CIRCULAR;
1085 : : }
1086 : : else
1087 : : {
1088 : : // weiterverfolgen
1089 : :
1090 [ # # ]: 0 : if ( nLevel < rData.GetMaxLevel() )
1091 : : {
1092 : : sal_uInt16 nSubResult = InsertSuccLevel(
1093 : 0 : aCellIter.GetCol(), aCellIter.GetRow(),
1094 : 0 : aCellIter.GetCol(), aCellIter.GetRow(),
1095 [ # # ]: 0 : rData, nLevel+1 );
1096 [ # # # # ]: 0 : switch (nSubResult)
1097 : : {
1098 : : case DET_INS_INSERTED:
1099 : 0 : nResult = DET_INS_INSERTED;
1100 : 0 : break;
1101 : : case DET_INS_CONTINUE:
1102 [ # # ]: 0 : if (nResult != DET_INS_INSERTED)
1103 : 0 : nResult = DET_INS_CONTINUE;
1104 : 0 : break;
1105 : : case DET_INS_CIRCULAR:
1106 [ # # ]: 0 : if (nResult == DET_INS_EMPTY)
1107 : 0 : nResult = DET_INS_CIRCULAR;
1108 : 0 : break;
1109 : : // DET_INS_EMPTY: unveraendert lassen
1110 : : }
1111 : : }
1112 : : else // nMaxLevel erreicht
1113 [ # # ]: 0 : if (nResult != DET_INS_INSERTED)
1114 : 0 : nResult = DET_INS_CONTINUE;
1115 : : }
1116 : : }
1117 : : }
1118 : : }
1119 : : }
1120 : 0 : pFCell->SetRunning(bRunning);
1121 : : }
1122 [ # # ]: 0 : pCell = aCellIter.GetNext();
1123 : : }
1124 : :
1125 : 0 : return nResult;
1126 : : }
1127 : :
1128 : 0 : sal_uInt16 ScDetectiveFunc::FindSuccLevel( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1129 : : sal_uInt16 nLevel, sal_uInt16 nDeleteLevel )
1130 : : {
1131 : : OSL_ENSURE( nLevel<1000, "Level" );
1132 : :
1133 : 0 : sal_uInt16 nResult = nLevel;
1134 [ # # ][ # # ]: 0 : sal_Bool bDelete = ( nDeleteLevel && nLevel == nDeleteLevel-1 );
1135 : :
1136 [ # # ]: 0 : ScCellIterator aCellIter( pDoc, 0,0, nTab, MAXCOL,MAXROW, nTab );
1137 [ # # ]: 0 : ScBaseCell* pCell = aCellIter.GetFirst();
1138 [ # # ]: 0 : while (pCell)
1139 : : {
1140 [ # # ]: 0 : if (pCell->GetCellType() == CELLTYPE_FORMULA)
1141 : : {
1142 [ # # ]: 0 : ScFormulaCell* pFCell = (ScFormulaCell*)pCell;
1143 : 0 : sal_Bool bRunning = pFCell->IsRunning();
1144 : :
1145 [ # # ]: 0 : if (pFCell->GetDirty())
1146 [ # # ]: 0 : pFCell->Interpret(); // nach SetRunning geht's nicht mehr!
1147 : 0 : pFCell->SetRunning(sal_True);
1148 : :
1149 [ # # ][ # # ]: 0 : ScDetectiveRefIter aIter( (ScFormulaCell*) pCell );
1150 : 0 : ScRange aRef;
1151 [ # # ][ # # ]: 0 : while ( aIter.GetNextRef( aRef) )
1152 : : {
1153 [ # # ][ # # ]: 0 : if (aRef.aStart.Tab() <= nTab && aRef.aEnd.Tab() >= nTab)
[ # # ]
1154 : : {
1155 [ # # ]: 0 : if (Intersect( nCol1,nRow1,nCol2,nRow2,
1156 : 0 : aRef.aStart.Col(),aRef.aStart.Row(),
1157 : 0 : aRef.aEnd.Col(),aRef.aEnd.Row() ))
1158 : : {
1159 [ # # ]: 0 : if ( bDelete ) // Pfeile, die hier anfangen
1160 : : {
1161 [ # # ]: 0 : if (aRef.aStart != aRef.aEnd)
1162 : : {
1163 : 0 : DeleteBox( aRef.aStart.Col(), aRef.aStart.Row(),
1164 [ # # ]: 0 : aRef.aEnd.Col(), aRef.aEnd.Row() );
1165 : : }
1166 [ # # ]: 0 : DeleteArrowsAt( aRef.aStart.Col(), aRef.aStart.Row(), false );
1167 : : }
1168 [ # # ][ # # ]: 0 : else if ( !bRunning &&
[ # # ]
1169 : : HasArrow( aRef.aStart,
1170 [ # # ]: 0 : aCellIter.GetCol(),aCellIter.GetRow(),aCellIter.GetTab() ) )
1171 : : {
1172 : 0 : sal_uInt16 nTemp = FindSuccLevel( aCellIter.GetCol(), aCellIter.GetRow(),
1173 : 0 : aCellIter.GetCol(), aCellIter.GetRow(),
1174 [ # # ]: 0 : nLevel+1, nDeleteLevel );
1175 [ # # ]: 0 : if (nTemp > nResult)
1176 : 0 : nResult = nTemp;
1177 : : }
1178 : : }
1179 : : }
1180 : : }
1181 : :
1182 : 0 : pFCell->SetRunning(bRunning);
1183 : : }
1184 [ # # ]: 0 : pCell = aCellIter.GetNext();
1185 : : }
1186 : :
1187 : 0 : return nResult;
1188 : : }
1189 : :
1190 : :
1191 : : //
1192 : : // --------------------------------------------------------------------------------
1193 : : //
1194 : :
1195 : 13 : sal_Bool ScDetectiveFunc::ShowPred( SCCOL nCol, SCROW nRow )
1196 : : {
1197 [ + - ]: 13 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1198 [ - + ]: 13 : if (!pModel)
1199 : 0 : return false;
1200 : :
1201 [ + - ]: 13 : ScDetectiveData aData( pModel );
1202 : :
1203 : 13 : sal_uInt16 nMaxLevel = 0;
1204 : 13 : sal_uInt16 nResult = DET_INS_CONTINUE;
1205 [ + + ][ + - ]: 26 : while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
[ + + ]
1206 : : {
1207 : 13 : aData.SetMaxLevel( nMaxLevel );
1208 [ + - ]: 13 : nResult = InsertPredLevel( nCol, nRow, aData, 0 );
1209 : 13 : ++nMaxLevel;
1210 : : }
1211 : :
1212 [ + - ]: 13 : return ( nResult == DET_INS_INSERTED );
1213 : : }
1214 : :
1215 : 0 : sal_Bool ScDetectiveFunc::ShowSucc( SCCOL nCol, SCROW nRow )
1216 : : {
1217 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1218 [ # # ]: 0 : if (!pModel)
1219 : 0 : return false;
1220 : :
1221 [ # # ]: 0 : ScDetectiveData aData( pModel );
1222 : :
1223 : 0 : sal_uInt16 nMaxLevel = 0;
1224 : 0 : sal_uInt16 nResult = DET_INS_CONTINUE;
1225 [ # # ][ # # ]: 0 : while (nResult == DET_INS_CONTINUE && nMaxLevel < 1000)
[ # # ]
1226 : : {
1227 : 0 : aData.SetMaxLevel( nMaxLevel );
1228 [ # # ]: 0 : nResult = InsertSuccLevel( nCol, nRow, nCol, nRow, aData, 0 );
1229 : 0 : ++nMaxLevel;
1230 : : }
1231 : :
1232 [ # # ]: 0 : return ( nResult == DET_INS_INSERTED );
1233 : : }
1234 : :
1235 : 0 : sal_Bool ScDetectiveFunc::ShowError( SCCOL nCol, SCROW nRow )
1236 : : {
1237 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1238 [ # # ]: 0 : if (!pModel)
1239 : 0 : return false;
1240 : :
1241 : 0 : ScRange aRange( nCol, nRow, nTab );
1242 : 0 : ScAddress aErrPos;
1243 [ # # ][ # # ]: 0 : if ( !HasError( aRange,aErrPos ) )
1244 : 0 : return false;
1245 : :
1246 [ # # ]: 0 : ScDetectiveData aData( pModel );
1247 : :
1248 : 0 : aData.SetMaxLevel( 1000 );
1249 [ # # ]: 0 : sal_uInt16 nResult = InsertErrorLevel( nCol, nRow, aData, 0 );
1250 : :
1251 [ # # ]: 0 : return ( nResult == DET_INS_INSERTED );
1252 : : }
1253 : :
1254 : 0 : sal_Bool ScDetectiveFunc::DeleteSucc( SCCOL nCol, SCROW nRow )
1255 : : {
1256 : 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1257 [ # # ]: 0 : if (!pModel)
1258 : 0 : return false;
1259 : :
1260 : 0 : sal_uInt16 nLevelCount = FindSuccLevel( nCol, nRow, nCol, nRow, 0, 0 );
1261 [ # # ]: 0 : if ( nLevelCount )
1262 : 0 : FindSuccLevel( nCol, nRow, nCol, nRow, 0, nLevelCount ); // loeschen
1263 : :
1264 : 0 : return ( nLevelCount != 0 );
1265 : : }
1266 : :
1267 : 0 : sal_Bool ScDetectiveFunc::DeletePred( SCCOL nCol, SCROW nRow )
1268 : : {
1269 : 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1270 [ # # ]: 0 : if (!pModel)
1271 : 0 : return false;
1272 : :
1273 : 0 : sal_uInt16 nLevelCount = FindPredLevel( nCol, nRow, 0, 0 );
1274 [ # # ]: 0 : if ( nLevelCount )
1275 : 0 : FindPredLevel( nCol, nRow, 0, nLevelCount ); // loeschen
1276 : :
1277 : 0 : return ( nLevelCount != 0 );
1278 : : }
1279 : :
1280 : 24 : sal_Bool ScDetectiveFunc::DeleteAll( ScDetectiveDelete eWhat )
1281 : : {
1282 : 24 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1283 [ - + ]: 24 : if (!pModel)
1284 : 0 : return false;
1285 : :
1286 : 24 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
1287 : : OSL_ENSURE(pPage,"Page ?");
1288 : :
1289 : 24 : pPage->RecalcObjOrdNums();
1290 : :
1291 : 24 : long nDelCount = 0;
1292 : 24 : sal_uLong nObjCount = pPage->GetObjCount();
1293 [ + + ]: 24 : if (nObjCount)
1294 : : {
1295 [ + - ]: 12 : SdrObject** ppObj = new SdrObject*[nObjCount];
1296 : :
1297 [ + - ]: 12 : SdrObjListIter aIter( *pPage, IM_FLAT );
1298 [ + - ]: 12 : SdrObject* pObject = aIter.Next();
1299 [ + + ]: 24 : while (pObject)
1300 : : {
1301 [ + - ][ + - ]: 12 : if ( pObject->GetLayer() == SC_LAYER_INTERN )
1302 : : {
1303 : 12 : sal_Bool bDoThis = sal_True;
1304 [ + - ]: 12 : if ( eWhat != SC_DET_ALL )
1305 : : {
1306 [ + - ][ + - ]: 12 : sal_Bool bCircle = ( pObject->ISA(SdrCircObj) );
1307 [ + - ]: 12 : sal_Bool bCaption = ScDrawLayer::IsNoteCaption( pObject );
1308 [ - + ]: 12 : if ( eWhat == SC_DET_DETECTIVE ) // Detektiv, aus Menue
1309 : 0 : bDoThis = !bCaption; // auch Kreise
1310 [ - + ]: 12 : else if ( eWhat == SC_DET_CIRCLES ) // Kreise, wenn neue erzeugt werden
1311 : 0 : bDoThis = bCircle;
1312 [ + - ]: 12 : else if ( eWhat == SC_DET_ARROWS ) // DetectiveRefresh
1313 [ + - ][ + - ]: 12 : bDoThis = !bCaption && !bCircle; // don't include circles
1314 : : else
1315 : : {
1316 : : OSL_FAIL("wat?");
1317 : : }
1318 : : }
1319 [ + - ]: 12 : if ( bDoThis )
1320 : 12 : ppObj[nDelCount++] = pObject;
1321 : : }
1322 : :
1323 [ + - ]: 12 : pObject = aIter.Next();
1324 : : }
1325 : :
1326 : : long i;
1327 [ + + ]: 24 : for (i=1; i<=nDelCount; i++)
1328 [ + - ][ + - ]: 12 : pModel->AddCalcUndo( new SdrUndoRemoveObj( *ppObj[nDelCount-i] ) );
[ + - ]
1329 : :
1330 [ + + ]: 24 : for (i=1; i<=nDelCount; i++)
1331 [ + - ][ + - ]: 12 : pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1332 : :
1333 [ + - ]: 12 : delete[] ppObj;
1334 : :
1335 [ + - ]: 12 : Modified();
1336 : : }
1337 : :
1338 : 24 : return ( nDelCount != 0 );
1339 : : }
1340 : :
1341 : 0 : sal_Bool ScDetectiveFunc::MarkInvalid(sal_Bool& rOverflow)
1342 : : {
1343 : 0 : rOverflow = false;
1344 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1345 [ # # ]: 0 : if (!pModel)
1346 : 0 : return false;
1347 : :
1348 [ # # ]: 0 : sal_Bool bDeleted = DeleteAll( SC_DET_CIRCLES ); // nur die Kreise
1349 : :
1350 [ # # ]: 0 : ScDetectiveData aData( pModel );
1351 : 0 : long nInsCount = 0;
1352 : :
1353 : : // Stellen suchen, wo Gueltigkeit definiert ist
1354 : :
1355 [ # # ]: 0 : ScDocAttrIterator aAttrIter( pDoc, nTab, 0,0,MAXCOL,MAXROW );
1356 : : SCCOL nCol;
1357 : : SCROW nRow1;
1358 : : SCROW nRow2;
1359 [ # # ]: 0 : const ScPatternAttr* pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
1360 [ # # ][ # # ]: 0 : while ( pPattern && nInsCount < SC_DET_MAXCIRCLE )
[ # # ]
1361 : : {
1362 [ # # ]: 0 : sal_uLong nIndex = ((const SfxUInt32Item&)pPattern->GetItem(ATTR_VALIDDATA)).GetValue();
1363 [ # # ]: 0 : if (nIndex)
1364 : : {
1365 [ # # ]: 0 : const ScValidationData* pData = pDoc->GetValidationEntry( nIndex );
1366 [ # # ]: 0 : if ( pData )
1367 : : {
1368 : : // Zellen in dem Bereich durchgehen
1369 : :
1370 : 0 : sal_Bool bMarkEmpty = !pData->IsIgnoreBlank();
1371 : 0 : SCROW nNextRow = nRow1;
1372 : : SCROW nRow;
1373 [ # # ]: 0 : ScCellIterator aCellIter( pDoc, nCol,nRow1,nTab, nCol,nRow2,nTab );
1374 [ # # ]: 0 : ScBaseCell* pCell = aCellIter.GetFirst();
1375 [ # # ][ # # ]: 0 : while ( pCell && nInsCount < SC_DET_MAXCIRCLE )
[ # # ]
1376 : : {
1377 : 0 : SCROW nCellRow = aCellIter.GetRow();
1378 [ # # ]: 0 : if ( bMarkEmpty )
1379 [ # # ][ # # ]: 0 : for ( nRow = nNextRow; nRow < nCellRow && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
[ # # ]
1380 : : {
1381 [ # # ]: 0 : DrawCircle( nCol, nRow, aData );
1382 : 0 : ++nInsCount;
1383 : : }
1384 [ # # ][ # # ]: 0 : if ( !pData->IsDataValid( pCell, ScAddress( nCol, nCellRow, nTab ) ) )
1385 : : {
1386 [ # # ]: 0 : DrawCircle( nCol, nCellRow, aData );
1387 : 0 : ++nInsCount;
1388 : : }
1389 : 0 : nNextRow = nCellRow + 1;
1390 [ # # ]: 0 : pCell = aCellIter.GetNext();
1391 : : }
1392 [ # # ]: 0 : if ( bMarkEmpty )
1393 [ # # ][ # # ]: 0 : for ( nRow = nNextRow; nRow <= nRow2 && nInsCount < SC_DET_MAXCIRCLE; nRow++ )
[ # # ]
1394 : : {
1395 [ # # ]: 0 : DrawCircle( nCol, nRow, aData );
1396 : 0 : ++nInsCount;
1397 : : }
1398 : : }
1399 : : }
1400 : :
1401 [ # # ]: 0 : pPattern = aAttrIter.GetNext( nCol, nRow1, nRow2 );
1402 : : }
1403 : :
1404 [ # # ]: 0 : if ( nInsCount >= SC_DET_MAXCIRCLE )
1405 : 0 : rOverflow = sal_True;
1406 : :
1407 [ # # ][ # # ]: 0 : return ( bDeleted || nInsCount != 0 );
[ # # ][ # # ]
1408 : : }
1409 : :
1410 : 6 : void ScDetectiveFunc::GetAllPreds(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1411 : : vector<ScTokenRef>& rRefTokens)
1412 : : {
1413 [ + - ]: 6 : ScCellIterator aCellIter(pDoc, nCol1, nRow1, nTab, nCol2, nRow2, nTab);
1414 [ + - ][ + - ]: 12 : for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext())
[ + + ]
1415 : : {
1416 [ - + ]: 6 : if (pCell->GetCellType() != CELLTYPE_FORMULA)
1417 : 0 : continue;
1418 : :
1419 [ + - ]: 6 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
1420 [ + - ]: 6 : ScDetectiveRefIter aRefIter(pFCell);
1421 [ + - ][ + - ]: 18 : for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
[ + + ]
1422 : : {
1423 [ + - ]: 12 : ScTokenRef pRef(static_cast<ScToken*>(p->Clone()));
1424 [ + - ]: 12 : pRef->CalcAbsIfRel(aCellIter.GetPos());
1425 [ + - ]: 12 : ScRefTokenHelper::join(rRefTokens, pRef);
1426 [ + - ]: 12 : }
1427 : : }
1428 : 6 : }
1429 : :
1430 : 3 : void ScDetectiveFunc::GetAllSuccs(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
1431 : : vector<ScTokenRef>& rRefTokens)
1432 : : {
1433 [ + - ]: 3 : vector<ScTokenRef> aSrcRange;
1434 : : aSrcRange.push_back(
1435 [ + - ][ + - ]: 3 : ScRefTokenHelper::createRefToken(ScRange(nCol1, nRow1, nTab, nCol2, nRow2, nTab)));
[ + - ]
1436 : :
1437 [ + - ]: 3 : ScCellIterator aCellIter(pDoc, 0, 0, nTab, MAXCOL, MAXROW, nTab);
1438 [ + - ][ + - ]: 18 : for (ScBaseCell* pCell = aCellIter.GetFirst(); pCell; pCell = aCellIter.GetNext())
[ + + ]
1439 : : {
1440 [ + + ]: 15 : if (pCell->GetCellType() != CELLTYPE_FORMULA)
1441 : 9 : continue;
1442 : :
1443 [ + - ]: 6 : ScFormulaCell* pFCell = static_cast<ScFormulaCell*>(pCell);
1444 [ + - ]: 6 : ScDetectiveRefIter aRefIter(pFCell);
1445 [ + - ][ + - ]: 18 : for (ScToken* p = aRefIter.GetNextRefToken(); p; p = aRefIter.GetNextRefToken())
[ + + ]
1446 : : {
1447 : 12 : ScAddress aPos = aCellIter.GetPos();
1448 [ + - ]: 12 : ScTokenRef pRef(static_cast<ScToken*>(p->Clone()));
1449 [ + - ]: 12 : pRef->CalcAbsIfRel(aPos);
1450 [ + - ][ + + ]: 12 : if (ScRefTokenHelper::intersects(aSrcRange, pRef))
1451 : : {
1452 : : // This address is absolute.
1453 [ + - ][ + - ]: 6 : pRef = ScRefTokenHelper::createRefToken(aPos);
[ + - ]
1454 [ + - ]: 6 : ScRefTokenHelper::join(rRefTokens, pRef);
1455 : : }
1456 [ + - ]: 12 : }
1457 : 3 : }
1458 : 3 : }
1459 : :
1460 : 1794 : void ScDetectiveFunc::UpdateAllComments( ScDocument& rDoc )
1461 : : {
1462 : : // for all caption objects, update attributes and SpecialTextBoxShadow flag
1463 : : // (on all tables - nTab is ignored!)
1464 : :
1465 : : // no undo actions, this is refreshed after undo
1466 : :
1467 : 1794 : ScDrawLayer* pModel = rDoc.GetDrawLayer();
1468 [ + + ]: 1794 : if (!pModel)
1469 : 1794 : return;
1470 : :
1471 [ + + ]: 114 : for( SCTAB nObjTab = 0, nTabCount = rDoc.GetTableCount(); nObjTab < nTabCount; ++nObjTab )
1472 : : {
1473 : 57 : rDoc.InitializeNoteCaptions( nObjTab );
1474 : 57 : SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
1475 : : OSL_ENSURE( pPage, "Page ?" );
1476 [ + - ]: 57 : if( pPage )
1477 : : {
1478 [ + - ]: 57 : SdrObjListIter aIter( *pPage, IM_FLAT );
1479 [ + - ][ # # ]: 57 : for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
[ - + ]
1480 : : {
1481 [ # # ][ # # ]: 0 : if ( ScDrawObjData* pData = ScDrawLayer::GetNoteCaptionData( pObject, nObjTab ) )
1482 : : {
1483 [ # # ][ # # ]: 0 : ScPostIt* pNote = rDoc.GetNotes( pData->maStart.Tab() )->findByAddress( pData->maStart );
1484 : : // caption should exist, we iterate over drawing objects...
1485 : : OSL_ENSURE( pNote && (pNote->GetCaption() == pObject), "ScDetectiveFunc::UpdateAllComments - invalid cell note" );
1486 [ # # ]: 0 : if( pNote )
1487 : : {
1488 [ # # ]: 0 : ScCommentData aData( rDoc, pModel );
1489 [ # # ][ # # ]: 0 : SfxItemSet aAttrColorSet = pObject->GetMergedItemSet();
1490 [ # # ][ # # ]: 0 : aAttrColorSet.Put( XFillColorItem( String(), GetCommentColor() ) );
[ # # ][ # # ]
[ # # ][ # # ]
1491 [ # # ]: 0 : aData.UpdateCaptionSet( aAttrColorSet );
1492 [ # # ]: 0 : pObject->SetMergedItemSetAndBroadcast( aData.GetCaptionSet() );
1493 [ # # ][ # # ]: 0 : if( SdrCaptionObj* pCaption = dynamic_cast< SdrCaptionObj* >( pObject ) )
1494 : : {
1495 : 0 : pCaption->SetSpecialTextBoxShadow();
1496 : 0 : pCaption->SetFixedTail();
1497 [ # # ][ # # ]: 0 : }
1498 : : }
1499 : : }
1500 : 57 : }
1501 : : }
1502 : : }
1503 : : }
1504 : :
1505 : 0 : void ScDetectiveFunc::UpdateAllArrowColors()
1506 : : {
1507 : : // no undo actions necessary
1508 : :
1509 : 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1510 [ # # ]: 0 : if (!pModel)
1511 : 0 : return;
1512 : :
1513 [ # # ]: 0 : for( SCTAB nObjTab = 0, nTabCount = pDoc->GetTableCount(); nObjTab < nTabCount; ++nObjTab )
1514 : : {
1515 : 0 : SdrPage* pPage = pModel->GetPage( static_cast< sal_uInt16 >( nObjTab ) );
1516 : : OSL_ENSURE( pPage, "Page ?" );
1517 [ # # ]: 0 : if( pPage )
1518 : : {
1519 [ # # ]: 0 : SdrObjListIter aIter( *pPage, IM_FLAT );
1520 [ # # ][ # # ]: 0 : for( SdrObject* pObject = aIter.Next(); pObject; pObject = aIter.Next() )
[ # # ]
1521 : : {
1522 [ # # ][ # # ]: 0 : if ( pObject->GetLayer() == SC_LAYER_INTERN )
1523 : : {
1524 : 0 : sal_Bool bArrow = false;
1525 : 0 : sal_Bool bError = false;
1526 : :
1527 : 0 : ScAddress aPos;
1528 : 0 : ScRange aSource;
1529 : : bool bDummy;
1530 [ # # ]: 0 : ScDetectiveObjType eType = GetDetectiveObjectType( pObject, nObjTab, aPos, aSource, bDummy );
1531 [ # # ][ # # ]: 0 : if ( eType == SC_DETOBJ_ARROW || eType == SC_DETOBJ_TOOTHERTAB )
1532 : : {
1533 : : // source is valid, determine error flag from source range
1534 : :
1535 : 0 : ScAddress aErrPos;
1536 [ # # ][ # # ]: 0 : if ( HasError( aSource, aErrPos ) )
1537 : 0 : bError = sal_True;
1538 : : else
1539 : 0 : bArrow = sal_True;
1540 : : }
1541 [ # # ]: 0 : else if ( eType == SC_DETOBJ_FROMOTHERTAB )
1542 : : {
1543 : : // source range is no longer known, take error flag from formula itself
1544 : : // (this means, if the formula has an error, all references to other tables
1545 : : // are marked red)
1546 : :
1547 : 0 : ScAddress aErrPos;
1548 [ # # ][ # # ]: 0 : if ( HasError( ScRange( aPos), aErrPos ) )
1549 : 0 : bError = sal_True;
1550 : : else
1551 : 0 : bArrow = sal_True;
1552 : : }
1553 [ # # ]: 0 : else if ( eType == SC_DETOBJ_CIRCLE )
1554 : : {
1555 : : // circles (error marks) are always red
1556 : :
1557 : 0 : bError = sal_True;
1558 : : }
1559 [ # # ]: 0 : else if ( eType == SC_DETOBJ_NONE )
1560 : : {
1561 : : // frame for area reference has no ObjType, always gets arrow color
1562 : :
1563 [ # # ][ # # ]: 0 : if ( pObject->ISA( SdrRectObj ) && !pObject->ISA( SdrCaptionObj ) )
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
1564 : : {
1565 : 0 : bArrow = sal_True;
1566 : : }
1567 : : }
1568 : :
1569 [ # # ][ # # ]: 0 : if ( bArrow || bError )
1570 : : {
1571 [ # # ][ # # ]: 0 : ColorData nColorData = ( bError ? GetErrorColor() : GetArrowColor() );
[ # # ]
1572 [ # # ][ # # ]: 0 : pObject->SetMergedItem( XLineColorItem( String(), Color( nColorData ) ) );
[ # # ][ # # ]
[ # # ]
1573 : :
1574 : : // repaint only
1575 [ # # ]: 0 : pObject->ActionChanged();
1576 : : }
1577 : : }
1578 : 0 : }
1579 : : }
1580 : : }
1581 : : }
1582 : :
1583 : 0 : sal_Bool ScDetectiveFunc::FindFrameForObject( SdrObject* pObject, ScRange& rRange )
1584 : : {
1585 : : // find the rectangle for an arrow (always the object directly before the arrow)
1586 : : // rRange must be initialized to the source cell of the arrow (start of area)
1587 : :
1588 : 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1589 [ # # ]: 0 : if (!pModel) return false;
1590 : :
1591 : 0 : SdrPage* pPage = pModel->GetPage(static_cast<sal_uInt16>(nTab));
1592 : : OSL_ENSURE(pPage,"Page ?");
1593 [ # # ]: 0 : if (!pPage) return false;
1594 : :
1595 : : // test if the object is a direct page member
1596 [ # # ][ # # ]: 0 : if( pObject && pObject->GetPage() && (pObject->GetPage() == pObject->GetObjList()) )
[ # # ][ # # ]
1597 : : {
1598 : : // Is there a previous object?
1599 : 0 : const sal_uInt32 nOrdNum(pObject->GetOrdNum());
1600 : :
1601 [ # # ]: 0 : if(nOrdNum > 0)
1602 : : {
1603 : 0 : SdrObject* pPrevObj = pPage->GetObj(nOrdNum - 1);
1604 : :
1605 [ # # ][ # # ]: 0 : if ( pPrevObj && pPrevObj->GetLayer() == SC_LAYER_INTERN && pPrevObj->ISA(SdrRectObj) )
[ # # ][ # # ]
1606 : : {
1607 : 0 : ScDrawObjData* pPrevData = ScDrawLayer::GetObjDataTab( pPrevObj, rRange.aStart.Tab() );
1608 [ # # ][ # # ]: 0 : if ( pPrevData && pPrevData->maStart.IsValid() && pPrevData->maEnd.IsValid() && (pPrevData->maStart == rRange.aStart) )
[ # # ][ # # ]
[ # # ]
1609 : : {
1610 : 0 : rRange.aEnd = pPrevData->maEnd;
1611 : 0 : return sal_True;
1612 : : }
1613 : : }
1614 : : }
1615 : : }
1616 : 0 : return false;
1617 : : }
1618 : :
1619 : 0 : ScDetectiveObjType ScDetectiveFunc::GetDetectiveObjectType( SdrObject* pObject, SCTAB nObjTab,
1620 : : ScAddress& rPosition, ScRange& rSource, bool& rRedLine )
1621 : : {
1622 : 0 : rRedLine = false;
1623 : 0 : ScDetectiveObjType eType = SC_DETOBJ_NONE;
1624 : :
1625 [ # # ][ # # ]: 0 : if ( pObject && pObject->GetLayer() == SC_LAYER_INTERN )
[ # # ]
1626 : : {
1627 [ # # ]: 0 : if ( ScDrawObjData* pData = ScDrawLayer::GetObjDataTab( pObject, nObjTab ) )
1628 : : {
1629 : 0 : bool bValidStart = pData->maStart.IsValid();
1630 : 0 : bool bValidEnd = pData->maEnd.IsValid();
1631 : :
1632 [ # # ][ # # ]: 0 : if ( pObject->IsPolyObj() && pObject->GetPointCount() == 2 )
[ # # ]
1633 : : {
1634 : : // line object -> arrow
1635 : :
1636 [ # # ]: 0 : if ( bValidStart )
1637 [ # # ]: 0 : eType = bValidEnd ? SC_DETOBJ_ARROW : SC_DETOBJ_TOOTHERTAB;
1638 [ # # ]: 0 : else if ( bValidEnd )
1639 : 0 : eType = SC_DETOBJ_FROMOTHERTAB;
1640 : :
1641 [ # # ]: 0 : if ( bValidStart )
1642 : 0 : rSource = pData->maStart;
1643 [ # # ]: 0 : if ( bValidEnd )
1644 : 0 : rPosition = pData->maEnd;
1645 : :
1646 [ # # ][ # # ]: 0 : if ( bValidStart && lcl_HasThickLine( *pObject ) )
[ # # ]
1647 : : {
1648 : : // thick line -> look for frame before this object
1649 : :
1650 : 0 : FindFrameForObject( pObject, rSource ); // modifies rSource
1651 : : }
1652 : :
1653 : 0 : ColorData nObjColor = ((const XLineColorItem&)pObject->GetMergedItem(XATTR_LINECOLOR)).GetColorValue().GetColor();
1654 [ # # ][ # # ]: 0 : if ( nObjColor == GetErrorColor() && nObjColor != GetArrowColor() )
[ # # ]
1655 : 0 : rRedLine = true;
1656 : : }
1657 [ # # ]: 0 : else if ( pObject->ISA(SdrCircObj) )
1658 : : {
1659 [ # # ]: 0 : if ( bValidStart )
1660 : : {
1661 : : // cell position is returned in rPosition
1662 : :
1663 : 0 : rPosition = pData->maStart;
1664 : 0 : eType = SC_DETOBJ_CIRCLE;
1665 : : }
1666 : : }
1667 : : }
1668 : : }
1669 : :
1670 : 0 : return eType;
1671 : : }
1672 : :
1673 : 0 : void ScDetectiveFunc::InsertObject( ScDetectiveObjType eType,
1674 : : const ScAddress& rPosition, const ScRange& rSource,
1675 : : sal_Bool bRedLine )
1676 : : {
1677 [ # # ]: 0 : ScDrawLayer* pModel = pDoc->GetDrawLayer();
1678 [ # # ]: 0 : if (!pModel) return;
1679 [ # # ]: 0 : ScDetectiveData aData( pModel );
1680 : :
1681 [ # # # # ]: 0 : switch (eType)
1682 : : {
1683 : : case SC_DETOBJ_ARROW:
1684 : : case SC_DETOBJ_FROMOTHERTAB:
1685 : 0 : InsertArrow( rPosition.Col(), rPosition.Row(),
1686 : 0 : rSource.aStart.Col(), rSource.aStart.Row(),
1687 : 0 : rSource.aEnd.Col(), rSource.aEnd.Row(),
1688 [ # # ]: 0 : (eType == SC_DETOBJ_FROMOTHERTAB), bRedLine, aData );
1689 : 0 : break;
1690 : : case SC_DETOBJ_TOOTHERTAB:
1691 : 0 : InsertToOtherTab( rSource.aStart.Col(), rSource.aStart.Row(),
1692 : 0 : rSource.aEnd.Col(), rSource.aEnd.Row(),
1693 [ # # ]: 0 : bRedLine, aData );
1694 : 0 : break;
1695 : : case SC_DETOBJ_CIRCLE:
1696 [ # # ]: 0 : DrawCircle( rPosition.Col(), rPosition.Row(), aData );
1697 : 0 : break;
1698 : : default:
1699 : : {
1700 : : // added to avoid warnings
1701 : : }
1702 [ # # ]: 0 : }
1703 : : }
1704 : :
1705 : 26 : ColorData ScDetectiveFunc::GetArrowColor()
1706 : : {
1707 [ - + ]: 26 : if (!bColorsInitialized)
1708 : 0 : InitializeColors();
1709 : 26 : return nArrowColor;
1710 : : }
1711 : :
1712 : 13 : ColorData ScDetectiveFunc::GetErrorColor()
1713 : : {
1714 [ - + ]: 13 : if (!bColorsInitialized)
1715 : 0 : InitializeColors();
1716 : 13 : return nErrorColor;
1717 : : }
1718 : :
1719 : 10 : ColorData ScDetectiveFunc::GetCommentColor()
1720 : : {
1721 [ + + ]: 10 : if (!bColorsInitialized)
1722 : 4 : InitializeColors();
1723 : 10 : return nCommentColor;
1724 : : }
1725 : :
1726 : 4 : void ScDetectiveFunc::InitializeColors()
1727 : : {
1728 : : // may be called several times to update colors from configuration
1729 : :
1730 : 4 : const svtools::ColorConfig& rColorCfg = SC_MOD()->GetColorConfig();
1731 : 4 : nArrowColor = rColorCfg.GetColorValue(svtools::CALCDETECTIVE).nColor;
1732 : 4 : nErrorColor = rColorCfg.GetColorValue(svtools::CALCDETECTIVEERROR).nColor;
1733 : 4 : nCommentColor = rColorCfg.GetColorValue(svtools::CALCNOTESBACKGROUND).nColor;
1734 : :
1735 : 4 : bColorsInitialized = sal_True;
1736 : 4 : }
1737 : :
1738 : 0 : sal_Bool ScDetectiveFunc::IsColorsInitialized()
1739 : : {
1740 : 0 : return bColorsInitialized;
1741 : : }
1742 : :
1743 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|