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