xref: /aoo4110/main/sc/source/core/data/drwlayer.cxx (revision b1cdbd2c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_sc.hxx"
26 #include <com/sun/star/uno/Reference.hxx>
27 #include <com/sun/star/chart/XChartDocument.hpp>
28 #include <com/sun/star/embed/XEmbeddedObject.hpp>
29 #include <com/sun/star/embed/XVisualObject.hpp>
30 #include <com/sun/star/embed/XClassifiedObject.hpp>
31 #include <com/sun/star/embed/XComponentSupplier.hpp>
32 #include <com/sun/star/embed/EmbedStates.hpp>
33 #include <com/sun/star/embed/ElementModes.hpp>
34 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
35 #include <com/sun/star/datatransfer/XTransferable.hpp>
36 
37 // INCLUDE ---------------------------------------------------------------
38 
39 #include "scitems.hxx"
40 #include <editeng/eeitem.hxx>
41 #include <editeng/frmdiritem.hxx>
42 #include <sot/exchange.hxx>
43 #include <svx/objfac3d.hxx>
44 #include <svx/xtable.hxx>
45 #include <svx/svdoutl.hxx>
46 #include <svx/svditer.hxx>
47 #include <svx/svdocapt.hxx>
48 #include <svx/svdocirc.hxx>
49 #include <svx/svdoedge.hxx>
50 #include <svx/svdograf.hxx>
51 #include <svx/svdoole2.hxx>
52 #include <svx/svdundo.hxx>
53 #include <editeng/unolingu.hxx>
54 #include <svx/drawitem.hxx>
55 #include <editeng/fhgtitem.hxx>
56 #include <editeng/scriptspaceitem.hxx>
57 #include <svx/shapepropertynotifier.hxx>
58 #include <sfx2/viewsh.hxx>
59 #include <sfx2/docfile.hxx>
60 #include <sot/storage.hxx>
61 #include <unotools/pathoptions.hxx>
62 #include <svl/itempool.hxx>
63 #include <vcl/virdev.hxx>
64 #include <vcl/svapp.hxx>
65 #include <unotools/ucbstreamhelper.hxx>
66 
67 #include "drwlayer.hxx"
68 #include "drawpage.hxx"
69 #include "global.hxx"
70 #include "document.hxx"
71 #include "rechead.hxx"
72 #include "userdat.hxx"
73 #include "markdata.hxx"
74 #include "globstr.hrc"
75 #include "scmod.hxx"
76 #include "chartarr.hxx"
77 #include "postit.hxx"
78 #include "attrib.hxx"
79 #include "charthelper.hxx"
80 
81 #define DET_ARROW_OFFSET	1000
82 
83 //	Abstand zur naechsten Zelle beim Loeschen (bShrink), damit der Anker
84 //	immer an der richtigen Zelle angezeigt wird
85 //#define SHRINK_DIST		3
86 //	und noch etwas mehr, damit das Objekt auch sichtbar in der Zelle liegt
87 #define SHRINK_DIST		25
88 
89 #define SHRINK_DIST_TWIPS	15
90 
91 using namespace ::com::sun::star;
92 
93 // STATIC DATA -----------------------------------------------------------
94 
95 TYPEINIT1(ScTabDeletedHint, SfxHint);
96 TYPEINIT1(ScTabSizeChangedHint, SfxHint);
97 
98 static ScDrawObjFactory* pFac = NULL;
99 static E3dObjFactory* pF3d = NULL;
100 static sal_uInt16 nInst = 0;
101 
102 SfxObjectShell* ScDrawLayer::pGlobalDrawPersist = NULL;
103 //REMOVE	SvPersist* ScDrawLayer::pGlobalDrawPersist = NULL;
104 
105 sal_Bool bDrawIsInUndo = sal_False;			//! Member
106 
107 // -----------------------------------------------------------------------
108 
ScUndoObjData(SdrObject * pObjP,const ScAddress & rOS,const ScAddress & rOE,const ScAddress & rNS,const ScAddress & rNE)109 ScUndoObjData::ScUndoObjData( SdrObject* pObjP, const ScAddress& rOS, const ScAddress& rOE,
110 											   const ScAddress& rNS, const ScAddress& rNE ) :
111     SdrUndoObj( *pObjP ),
112 	aOldStt( rOS ),
113 	aOldEnd( rOE ),
114 	aNewStt( rNS ),
115 	aNewEnd( rNE )
116 {
117 }
118 
~ScUndoObjData()119 __EXPORT ScUndoObjData::~ScUndoObjData()
120 {
121 }
122 
Undo()123 void ScUndoObjData::Undo()
124 {
125 	ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
126 	DBG_ASSERT(pData,"ScUndoObjData: Daten nicht da");
127 	if (pData)
128 	{
129 		pData->maStart = aOldStt;
130 		pData->maEnd = aOldEnd;
131 	}
132 }
133 
Redo()134 void __EXPORT ScUndoObjData::Redo()
135 {
136 	ScDrawObjData* pData = ScDrawLayer::GetObjData( pObj );
137 	DBG_ASSERT(pData,"ScUndoObjData: Daten nicht da");
138 	if (pData)
139 	{
140 		pData->maStart = aNewStt;
141 		pData->maEnd = aNewEnd;
142 	}
143 }
144 
145 // -----------------------------------------------------------------------
146 
ScTabDeletedHint(SCTAB nTabNo)147 ScTabDeletedHint::ScTabDeletedHint( SCTAB nTabNo ) :
148 	nTab( nTabNo )
149 {
150 }
151 
~ScTabDeletedHint()152 __EXPORT ScTabDeletedHint::~ScTabDeletedHint()
153 {
154 }
155 
ScTabSizeChangedHint(SCTAB nTabNo)156 ScTabSizeChangedHint::ScTabSizeChangedHint( SCTAB nTabNo ) :
157 	nTab( nTabNo )
158 {
159 }
160 
~ScTabSizeChangedHint()161 __EXPORT ScTabSizeChangedHint::~ScTabSizeChangedHint()
162 {
163 }
164 
165 // -----------------------------------------------------------------------
166 
167 #define MAXMM	10000000
168 
TwipsToMM(long & nVal)169 inline void TwipsToMM( long& nVal )
170 {
171 	nVal = (long) ( nVal * HMM_PER_TWIPS );
172 }
173 
ReverseTwipsToMM(long & nVal)174 inline void ReverseTwipsToMM( long& nVal )
175 {
176 	//	reverse the effect of TwipsToMM - round up here (add 1)
177 
178 	nVal = ((long) ( nVal / HMM_PER_TWIPS )) + 1;
179 }
180 
lcl_TwipsToMM(Point & rPoint)181 void lcl_TwipsToMM( Point& rPoint )
182 {
183 	TwipsToMM( rPoint.X() );
184 	TwipsToMM( rPoint.Y() );
185 }
186 
lcl_ReverseTwipsToMM(Point & rPoint)187 void lcl_ReverseTwipsToMM( Point& rPoint )
188 {
189 	ReverseTwipsToMM( rPoint.X() );
190 	ReverseTwipsToMM( rPoint.Y() );
191 }
192 
lcl_ReverseTwipsToMM(Rectangle & rRect)193 void lcl_ReverseTwipsToMM( Rectangle& rRect )
194 {
195 	ReverseTwipsToMM( rRect.Left() );
196 	ReverseTwipsToMM( rRect.Right() );
197 	ReverseTwipsToMM( rRect.Top() );
198 	ReverseTwipsToMM( rRect.Bottom() );
199 }
200 
201 // -----------------------------------------------------------------------
202 
203 
ScDrawLayer(ScDocument * pDocument,const String & rName)204 ScDrawLayer::ScDrawLayer( ScDocument* pDocument, const String& rName ) :
205 	FmFormModel( SvtPathOptions().GetPalettePath(),
206 				 NULL, 							// SfxItemPool* Pool
207 				 pGlobalDrawPersist ?
208 				 	pGlobalDrawPersist :
209 				 	( pDocument ? pDocument->GetDocumentShell() : NULL )),
210 	aName( rName ),
211 	pDoc( pDocument ),
212 	pUndoGroup( NULL ),
213 	bRecording( sal_False ),
214 	bAdjustEnabled( sal_True ),
215 	bHyphenatorSet( sal_False ),
216         mbUndoAllowed( sal_True )
217 {
218 	pGlobalDrawPersist = NULL;			// nur einmal benutzen
219 
220 	SfxObjectShell* pObjSh = pDocument ? pDocument->GetDocumentShell() : NULL;
221 	if ( pObjSh )
222 	{
223 		SetObjectShell( pObjSh );
224 
225 		// set color table
226         const SvxColorTableItem* pColItem = static_cast< const SvxColorTableItem* >(pObjSh->GetItem( SID_COLOR_TABLE ));
227 		XColorListSharedPtr aXCol = pColItem ? pColItem->GetColorTable() : XColorList::GetStdColorList();
228 		SetColorTableAtSdrModel( aXCol );
229 	}
230 	else
231 		SetColorTableAtSdrModel( XColorList::GetStdColorList() );
232 
233 	SetSwapGraphics(sal_True);
234 //	SetSwapAsynchron(sal_True);		// an der View
235 
236 	SetScaleUnit(MAP_100TH_MM);
237 	SfxItemPool& rPool = GetItemPool();
238 	rPool.SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
239 	SvxFrameDirectionItem aModeItem( FRMDIR_ENVIRONMENT, EE_PARA_WRITINGDIR );
240 	rPool.SetPoolDefaultItem( aModeItem );
241 
242 	// #i33700#
243 	// Set shadow distance defaults as PoolDefaultItems. Details see bug.
244 	rPool.SetPoolDefaultItem(SdrShadowXDistItem(300));
245 	rPool.SetPoolDefaultItem(SdrShadowYDistItem(300));
246 
247 	// #111216# default for script spacing depends on locale, see SdDrawDocument ctor in sd
248 	LanguageType eOfficeLanguage = Application::GetSettings().GetLanguage();
249 	if ( eOfficeLanguage == LANGUAGE_KOREAN || eOfficeLanguage == LANGUAGE_KOREAN_JOHAB ||
250 		 eOfficeLanguage == LANGUAGE_JAPANESE )
251 	{
252 		// secondary is edit engine pool
253 		rPool.GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( sal_False, EE_PARA_ASIANCJKSPACING ) );
254 	}
255 
256 	rPool.FreezeIdRanges();							// the pool is also used directly
257 
258 	SdrLayerAdmin& rAdmin = GetLayerAdmin();
259 	rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("vorne")),    SC_LAYER_FRONT);
260 	rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hinten")),   SC_LAYER_BACK);
261 	rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("intern")),   SC_LAYER_INTERN);
262 	rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Controls")), SC_LAYER_CONTROLS);
263     rAdmin.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hidden")),   SC_LAYER_HIDDEN);
264 	// "Controls" is new - must also be created when loading
265 
266 	//	Link fuer URL-Fields setzen
267 	ScModule* pScMod = SC_MOD();
268 	Outliner& rOutliner = GetDrawOutliner();
269 	rOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
270 
271 	Outliner& rHitOutliner = GetHitTestOutliner();
272 	rHitOutliner.SetCalcFieldValueHdl( LINK( pScMod, ScModule, CalcFieldValueHdl ) );
273 
274     // #95129# SJ: set FontHeight pool defaults without changing static SdrEngineDefaults
275     SfxItemPool* pOutlinerPool = rOutliner.GetEditTextObjectPool();
276     if ( pOutlinerPool )
277     {
278  	    pItemPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ));           // 12Pt
279  	    pItemPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT_CJK ));           // 12Pt
280     }
281     SfxItemPool* pHitOutlinerPool = rHitOutliner.GetEditTextObjectPool();
282     if ( pHitOutlinerPool )
283     {
284  	    pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ));    // 12Pt
285  	    pHitOutlinerPool->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT_CJK ));    // 12Pt
286     }
287 
288     // initial undo mode as in Calc document
289     if( pDoc )
290         EnableUndo( pDoc->IsUndoEnabled() );
291 
292 	//	URL-Buttons haben keinen Handler mehr, machen alles selber
293 
294 	if( !nInst++ )
295 	{
296 		pFac = new ScDrawObjFactory;
297 		pF3d = new E3dObjFactory;
298 	}
299 }
300 
~ScDrawLayer()301 __EXPORT ScDrawLayer::~ScDrawLayer()
302 {
303 	Broadcast(SdrHint(HINT_MODELCLEARED));
304 
305 	// #116168#
306 	//Clear();
307 	ClearModel(sal_True);
308 
309 	delete pUndoGroup;
310 	if( !--nInst )
311 	{
312 		delete pFac, pFac = NULL;
313 		delete pF3d, pF3d = NULL;
314 	}
315 }
316 
UseHyphenator()317 void ScDrawLayer::UseHyphenator()
318 {
319 	if (!bHyphenatorSet)
320 	{
321 		com::sun::star::uno::Reference< com::sun::star::linguistic2::XHyphenator >
322 									xHyphenator = LinguMgr::GetHyphenator();
323 
324 		GetDrawOutliner().SetHyphenator( xHyphenator );
325 		GetHitTestOutliner().SetHyphenator( xHyphenator );
326 
327 		bHyphenatorSet = sal_True;
328 	}
329 }
330 
AllocPage(FASTBOOL bMasterPage)331 SdrPage* __EXPORT ScDrawLayer::AllocPage(FASTBOOL bMasterPage)
332 {
333 	//	don't create basic until it is needed
334 	StarBASIC* pBasic = NULL;
335     ScDrawPage* pPage = new ScDrawPage( *this, pBasic, sal::static_int_cast<sal_Bool>(bMasterPage) );
336 	return pPage;
337 }
338 
HasObjects() const339 sal_Bool ScDrawLayer::HasObjects() const
340 {
341 	sal_Bool bFound = sal_False;
342 
343 	sal_uInt16 nCount = GetPageCount();
344 	for (sal_uInt16 i=0; i<nCount && !bFound; i++)
345 		if (GetPage(i)->GetObjCount())
346 			bFound = sal_True;
347 
348 	return bFound;
349 }
350 
UpdateBasic()351 void ScDrawLayer::UpdateBasic()
352 {
353 	//	don't create basic until it is needed
354 	//!	remove this method?
355 }
356 
AllocModel() const357 SdrModel* __EXPORT ScDrawLayer::AllocModel() const
358 {
359 	//	#103849# Allocated model (for clipboard etc) must not have a pointer
360 	//	to the original model's document, pass NULL as document:
361 
362 	return new ScDrawLayer( NULL, aName );
363 }
364 
GetCurDocViewWin()365 Window* __EXPORT ScDrawLayer::GetCurDocViewWin()
366 {
367 	DBG_ASSERT( pDoc, "ScDrawLayer::GetCurDocViewWin without document" );
368 	if ( !pDoc )
369 		return NULL;
370 
371 	SfxViewShell* pViewSh = SfxViewShell::Current();
372 	SfxObjectShell* pObjSh = pDoc->GetDocumentShell();
373 
374 	if (pViewSh && pViewSh->GetObjectShell() == pObjSh)
375 		return pViewSh->GetWindow();
376 
377 	return NULL;
378 }
379 
ScAddPage(SCTAB nTab)380 sal_Bool ScDrawLayer::ScAddPage( SCTAB nTab )
381 {
382 	if (bDrawIsInUndo)
383         return sal_False;   // not inserted
384 
385 	ScDrawPage* pPage = (ScDrawPage*)AllocPage( sal_False );
386 	InsertPage(pPage, static_cast<sal_uInt16>(nTab));
387 	if (bRecording)
388 	        AddCalcUndo< SdrUndoNewPage >(*pPage);
389 
390     return sal_True;        // inserted
391 }
392 
ScRemovePage(SCTAB nTab)393 void ScDrawLayer::ScRemovePage( SCTAB nTab )
394 {
395 	if (bDrawIsInUndo)
396 		return;
397 
398 	Broadcast( ScTabDeletedHint( nTab ) );
399 	if (bRecording)
400 	{
401 		SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
402         AddCalcUndo< SdrUndoDelPage >(*pPage);		// Undo-Action wird Owner der Page
403 		RemovePage( static_cast<sal_uInt16>(nTab) );							// nur austragen, nicht loeschen
404 	}
405 	else
406 		DeletePage( static_cast<sal_uInt16>(nTab) );							// einfach weg damit
407 }
408 
ScRenamePage(SCTAB nTab,const String & rNewName)409 void ScDrawLayer::ScRenamePage( SCTAB nTab, const String& rNewName )
410 {
411 	ScDrawPage* pPage = (ScDrawPage*) GetPage(static_cast<sal_uInt16>(nTab));
412 	if (pPage)
413 		pPage->SetName(rNewName);
414 }
415 
ScMovePage(sal_uInt16 nOldPos,sal_uInt16 nNewPos)416 void ScDrawLayer::ScMovePage( sal_uInt16 nOldPos, sal_uInt16 nNewPos )
417 {
418 	MovePage( nOldPos, nNewPos );
419 }
420 
ScCopyPage(sal_uInt16 nOldPos,sal_uInt16 nNewPos,sal_Bool bAlloc)421 void ScDrawLayer::ScCopyPage( sal_uInt16 nOldPos, sal_uInt16 nNewPos, sal_Bool bAlloc )
422 {
423 	//!	remove argument bAlloc (always sal_False)
424 
425 	if (bDrawIsInUndo)
426 		return;
427 
428 	SdrPage* pOldPage = GetPage(nOldPos);
429 	SdrPage* pNewPage = bAlloc ? AllocPage(sal_False) : GetPage(nNewPos);
430 
431 	// kopieren
432 
433 	if (pOldPage && pNewPage)
434 	{
435 		SdrObjListIter aIter( *pOldPage, IM_FLAT );
436 		SdrObject* pOldObject = aIter.Next();
437 		while (pOldObject)
438 		{
439             // #i112034# do not copy internal objects (detective) and note captions
440             if ( pOldObject->GetLayer() != SC_LAYER_INTERN && !IsNoteCaption( pOldObject ) )
441             {
442                 // #116235#
443                 SdrObject* pNewObject = pOldObject->Clone();
444                 //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this );
445                 pNewObject->SetModel(this);
446                 pNewObject->SetPage(pNewPage);
447 
448                 pNewObject->NbcMove(Size(0,0));
449                 pNewPage->InsertObject( pNewObject );
450                 if (bRecording)
451 	                AddCalcUndo< SdrUndoInsertObj >( *pNewObject );
452             }
453 
454 			pOldObject = aIter.Next();
455 		}
456 	}
457 
458 	if (bAlloc)
459 		InsertPage(pNewPage, nNewPos);
460 }
461 
IsInBlock(const ScAddress & rPos,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)462 inline sal_Bool IsInBlock( const ScAddress& rPos, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2 )
463 {
464 	return rPos.Col() >= nCol1 && rPos.Col() <= nCol2 &&
465 		   rPos.Row() >= nRow1 && rPos.Row() <= nRow2;
466 }
467 
MoveCells(SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,SCsCOL nDx,SCsROW nDy,bool bUpdateNoteCaptionPos)468 void ScDrawLayer::MoveCells( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
469 								SCsCOL nDx,SCsROW nDy, bool bUpdateNoteCaptionPos )
470 {
471 	SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
472 	DBG_ASSERT(pPage,"Page nicht gefunden");
473 	if (!pPage)
474 		return;
475 
476 	sal_Bool bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
477 
478 	sal_uLong nCount = pPage->GetObjCount();
479 	for ( sal_uLong i = 0; i < nCount; i++ )
480 	{
481 		SdrObject* pObj = pPage->GetObj( i );
482 		ScDrawObjData* pData = GetObjDataTab( pObj, nTab );
483 		if( pData )
484 		{
485 			const ScAddress aOldStt = pData->maStart;
486 			const ScAddress aOldEnd = pData->maEnd;
487 			sal_Bool bChange = sal_False;
488 			if ( aOldStt.IsValid() && IsInBlock( aOldStt, nCol1,nRow1, nCol2,nRow2 ) )
489 			{
490                 pData->maStart.IncCol( nDx );
491 				pData->maStart.IncRow( nDy );
492 				bChange = sal_True;
493 			}
494 			if ( aOldEnd.IsValid() && IsInBlock( aOldEnd, nCol1,nRow1, nCol2,nRow2 ) )
495 			{
496 				pData->maEnd.IncCol( nDx );
497 				pData->maEnd.IncRow( nDy );
498 				bChange = sal_True;
499 			}
500 			if (bChange)
501 			{
502 				if ( pObj->ISA( SdrRectObj ) && pData->maStart.IsValid() && pData->maEnd.IsValid() )
503                     pData->maStart.PutInOrder( pData->maEnd );
504                 AddCalcUndo< ScUndoObjData >( pObj, aOldStt, aOldEnd, pData->maStart, pData->maEnd );
505                 RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
506 			}
507 		}
508 	}
509 }
510 
SetPageSize(sal_uInt16 nPageNo,const Size & rSize,bool bUpdateNoteCaptionPos)511 void ScDrawLayer::SetPageSize( sal_uInt16 nPageNo, const Size& rSize, bool bUpdateNoteCaptionPos )
512 {
513 	SdrPage* pPage = GetPage(nPageNo);
514 	if (pPage)
515 	{
516 		if ( rSize != pPage->GetSize() )
517 		{
518 			pPage->SetSize( rSize );
519 			Broadcast( ScTabSizeChangedHint( static_cast<SCTAB>(nPageNo) ) );	// SetWorkArea() an den Views
520 		}
521 
522 		// Detektivlinien umsetzen (an neue Hoehen/Breiten anpassen)
523 		//	auch wenn Groesse gleich geblieben ist
524 		//	(einzelne Zeilen/Spalten koennen geaendert sein)
525 
526 		sal_Bool bNegativePage = pDoc && pDoc->IsNegativePage( static_cast<SCTAB>(nPageNo) );
527 
528 		sal_uLong nCount = pPage->GetObjCount();
529 		for ( sal_uLong i = 0; i < nCount; i++ )
530 		{
531 			SdrObject* pObj = pPage->GetObj( i );
532 			ScDrawObjData* pData = GetObjDataTab( pObj, static_cast<SCTAB>(nPageNo) );
533 			if( pData )
534                 RecalcPos( pObj, *pData, bNegativePage, bUpdateNoteCaptionPos );
535 		}
536 	}
537 }
538 
RecalcPos(SdrObject * pObj,const ScDrawObjData & rData,bool bNegativePage,bool bUpdateNoteCaptionPos)539 void ScDrawLayer::RecalcPos( SdrObject* pObj, const ScDrawObjData& rData, bool bNegativePage, bool bUpdateNoteCaptionPos )
540 {
541 	DBG_ASSERT( pDoc, "ScDrawLayer::RecalcPos - missing document" );
542 	if( !pDoc )
543 		return;
544 
545 	if( rData.mbNote )
546 	{
547         DBG_ASSERT( rData.maStart.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
548         /*  #i109372# On insert/remove rows/columns/cells: Updating the caption
549             position must not be done, if the cell containing the note has not
550             been moved yet in the document. The calling code now passes an
551             additional boolean stating if the cells are already moved. */
552         if( bUpdateNoteCaptionPos )
553             /*  When inside an undo action, there may be pending note captions
554                 where cell note is already deleted (thus document cannot find
555                 the note object anymore). The caption will be deleted later
556                 with drawing undo. */
557             if( ScPostIt* pNote = pDoc->GetNote( rData.maStart ) )
558                 pNote->UpdateCaptionPos( rData.maStart );
559         return;
560 	}
561 
562     bool bValid1 = rData.maStart.IsValid();
563     SCCOL nCol1 = rData.maStart.Col();
564 	SCROW nRow1 = rData.maStart.Row();
565 	SCTAB nTab1 = rData.maStart.Tab();
566     bool bValid2 = rData.maEnd.IsValid();
567     SCCOL nCol2 = rData.maEnd.Col();
568 	SCROW nRow2 = rData.maEnd.Row();
569 	SCTAB nTab2 = rData.maEnd.Tab();
570 
571     // validation circle
572 	bool bCircle = pObj->ISA( SdrCircObj );
573     // detective arrow
574 	bool bArrow = pObj->IsPolyObj() && (pObj->GetPointCount() == 2);
575 
576 	if( bCircle )
577 	{
578 		Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
579 		TwipsToMM( aPos.X() );
580 		TwipsToMM( aPos.Y() );
581 
582 		//	Berechnung und Werte wie in detfunc.cxx
583 
584 		Size aSize( (long)(pDoc->GetColWidth( nCol1, nTab1 ) * HMM_PER_TWIPS),
585 					(long)(pDoc->GetRowHeight( nRow1, nTab1 ) * HMM_PER_TWIPS) );
586 		Rectangle aRect( aPos, aSize );
587 		aRect.Left()	-= 250;
588 		aRect.Right()	+= 250;
589 		aRect.Top()		-= 70;
590 		aRect.Bottom()	+= 70;
591 		if ( bNegativePage )
592 			MirrorRectRTL( aRect );
593 
594 		if ( pObj->GetLogicRect() != aRect )
595 		{
596 			if (bRecording)
597 		                AddCalcUndo<SdrUndoGeoObj>( *pObj );
598 			pObj->SetLogicRect(aRect);
599 		}
600 	}
601 	else if( bArrow )
602 	{
603 		//!	nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden)
604 
605         SCCOL nLastCol;
606         SCROW nLastRow;
607 		if( bValid1 )
608 		{
609 			Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
610             if (!pDoc->ColHidden(nCol1, nTab1, nLastCol))
611 				aPos.X() += pDoc->GetColWidth( nCol1, nTab1 ) / 4;
612             if (!pDoc->RowHidden(nRow1, nTab1, nLastRow))
613 				aPos.Y() += pDoc->GetRowHeight( nRow1, nTab1 ) / 2;
614 			TwipsToMM( aPos.X() );
615 			TwipsToMM( aPos.Y() );
616 			Point aStartPos = aPos;
617 			if ( bNegativePage )
618 				aStartPos.X() = -aStartPos.X();		// don't modify aPos - used below
619 			if ( pObj->GetPoint( 0 ) != aStartPos )
620 			{
621 				if (bRecording)
622 		                    AddCalcUndo< SdrUndoGeoObj> ( *pObj );
623 				pObj->SetPoint( aStartPos, 0 );
624 			}
625 
626 			if( !bValid2 )
627 			{
628 				Point aEndPos( aPos.X() + DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
629 				if (aEndPos.Y() < 0)
630 					aEndPos.Y() += (2 * DET_ARROW_OFFSET);
631 				if ( bNegativePage )
632 					aEndPos.X() = -aEndPos.X();
633 				if ( pObj->GetPoint( 1 ) != aEndPos )
634 				{
635 					if (bRecording)
636 		                        AddCalcUndo< SdrUndoGeoObj >( *pObj );
637 					pObj->SetPoint( aEndPos, 1 );
638 				}
639 			}
640 		}
641 		if( bValid2 )
642 		{
643 			Point aPos( pDoc->GetColOffset( nCol2, nTab2 ), pDoc->GetRowOffset( nRow2, nTab2 ) );
644             if (!pDoc->ColHidden(nCol2, nTab2, nLastCol))
645 				aPos.X() += pDoc->GetColWidth( nCol2, nTab2 ) / 4;
646             if (!pDoc->RowHidden(nRow2, nTab2, nLastRow))
647 				aPos.Y() += pDoc->GetRowHeight( nRow2, nTab2 ) / 2;
648 			TwipsToMM( aPos.X() );
649 			TwipsToMM( aPos.Y() );
650 			Point aEndPos = aPos;
651 			if ( bNegativePage )
652 				aEndPos.X() = -aEndPos.X();			// don't modify aPos - used below
653 			if ( pObj->GetPoint( 1 ) != aEndPos )
654 			{
655 				if (bRecording)
656 		                    AddCalcUndo< SdrUndoGeoObj> ( *pObj  );
657 				pObj->SetPoint( aEndPos, 1 );
658 			}
659 
660 			if( !bValid1 )
661 			{
662 				Point aStartPos( aPos.X() - DET_ARROW_OFFSET, aPos.Y() - DET_ARROW_OFFSET );
663 				if (aStartPos.X() < 0)
664 					aStartPos.X() += (2 * DET_ARROW_OFFSET);
665 				if (aStartPos.Y() < 0)
666 					aStartPos.Y() += (2 * DET_ARROW_OFFSET);
667 				if ( bNegativePage )
668 					aStartPos.X() = -aStartPos.X();
669 				if ( pObj->GetPoint( 0 ) != aStartPos )
670 				{
671 					if (bRecording)
672 			                        AddCalcUndo< SdrUndoGeoObj >( *pObj );
673 					pObj->SetPoint( aStartPos, 0 );
674 				}
675 			}
676 		}
677 	}
678 	else								// Referenz-Rahmen
679 	{
680 		DBG_ASSERT( bValid1, "ScDrawLayer::RecalcPos - invalid start position" );
681 		Point aPos( pDoc->GetColOffset( nCol1, nTab1 ), pDoc->GetRowOffset( nRow1, nTab1 ) );
682 		TwipsToMM( aPos.X() );
683 		TwipsToMM( aPos.Y() );
684 
685 		if( bValid2 )
686 		{
687 			Point aEnd( pDoc->GetColOffset( nCol2 + 1, nTab2 ), pDoc->GetRowOffset( nRow2 + 1, nTab2 ) );
688 			TwipsToMM( aEnd.X() );
689 			TwipsToMM( aEnd.Y() );
690 
691 			Rectangle aNew( aPos, aEnd );
692 			if ( bNegativePage )
693 				MirrorRectRTL( aNew );
694 			if ( pObj->GetLogicRect() != aNew )
695 			{
696 				if (bRecording)
697 		                    AddCalcUndo< SdrUndoGeoObj >( *pObj );
698 				pObj->SetLogicRect(aNew);
699 			}
700 		}
701 		else
702 		{
703 			if ( bNegativePage )
704 				aPos.X() = -aPos.X();
705 			if ( pObj->GetRelativePos() != aPos )
706 			{
707 				if (bRecording)
708 		                    AddCalcUndo< SdrUndoGeoObj >( *pObj );
709 				pObj->SetRelativePos( aPos );
710 			}
711 		}
712 	}
713 }
714 
GetPrintArea(ScRange & rRange,sal_Bool bSetHor,sal_Bool bSetVer) const715 sal_Bool ScDrawLayer::GetPrintArea( ScRange& rRange, sal_Bool bSetHor, sal_Bool bSetVer ) const
716 {
717 	DBG_ASSERT( pDoc, "ScDrawLayer::GetPrintArea without document" );
718 	if ( !pDoc )
719 		return sal_False;
720 
721 	SCTAB nTab = rRange.aStart.Tab();
722 	DBG_ASSERT( rRange.aEnd.Tab() == nTab, "GetPrintArea: Tab unterschiedlich" );
723 
724 	sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
725 
726 	sal_Bool bAny = sal_False;
727 	long nEndX = 0;
728 	long nEndY = 0;
729 	long nStartX = LONG_MAX;
730 	long nStartY = LONG_MAX;
731 
732 	// Grenzen ausrechnen
733 
734 	if (!bSetHor)
735 	{
736 		nStartX = 0;
737 		SCCOL nStartCol = rRange.aStart.Col();
738 	        SCCOL i;
739 		for (i=0; i<nStartCol; i++)
740 			nStartX +=pDoc->GetColWidth(i,nTab);
741 		nEndX = nStartX;
742 		SCCOL nEndCol = rRange.aEnd.Col();
743 		for (i=nStartCol; i<=nEndCol; i++)
744 			nEndX += pDoc->GetColWidth(i,nTab);
745 		nStartX = (long)(nStartX * HMM_PER_TWIPS);
746 		nEndX   = (long)(nEndX   * HMM_PER_TWIPS);
747 	}
748 	if (!bSetVer)
749 	{
750 		nStartY = pDoc->GetRowHeight( 0, rRange.aStart.Row()-1, nTab);
751         nEndY = nStartY + pDoc->GetRowHeight( rRange.aStart.Row(),
752                 rRange.aEnd.Row(), nTab);
753 		nStartY = (long)(nStartY * HMM_PER_TWIPS);
754 		nEndY   = (long)(nEndY   * HMM_PER_TWIPS);
755 	}
756 
757 	if ( bNegativePage )
758 	{
759 		nStartX = -nStartX;		// positions are negative, swap start/end so the same comparisons work
760 		nEndX   = -nEndX;
761 		::std::swap( nStartX, nEndX );
762 	}
763 
764 	const SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
765 	DBG_ASSERT(pPage,"Page nicht gefunden");
766 	if (pPage)
767 	{
768 		SdrObjListIter aIter( *pPage, IM_FLAT );
769 		SdrObject* pObject = aIter.Next();
770 		while (pObject)
771 		{
772 							//! Flags (ausgeblendet?) testen
773 
774 			Rectangle aObjRect = pObject->GetCurrentBoundRect();
775 			sal_Bool bFit = sal_True;
776 			if ( !bSetHor && ( aObjRect.Right() < nStartX || aObjRect.Left() > nEndX ) )
777 				bFit = sal_False;
778 			if ( !bSetVer && ( aObjRect.Bottom() < nStartY || aObjRect.Top() > nEndY ) )
779 				bFit = sal_False;
780             // #i104716# don't include hidden note objects
781             if ( bFit && pObject->GetLayer() != SC_LAYER_HIDDEN )
782 			{
783 				if (bSetHor)
784 				{
785 					if (aObjRect.Left() < nStartX) nStartX = aObjRect.Left();
786 					if (aObjRect.Right()  > nEndX) nEndX = aObjRect.Right();
787 				}
788 				if (bSetVer)
789 				{
790 					if (aObjRect.Top()  < nStartY) nStartY = aObjRect.Top();
791 					if (aObjRect.Bottom() > nEndY) nEndY = aObjRect.Bottom();
792 				}
793 				bAny = sal_True;
794 			}
795 
796 			pObject = aIter.Next();
797 		}
798 	}
799 
800 	if ( bNegativePage )
801 	{
802 		nStartX = -nStartX;		// reverse transformation, so the same cell address calculation works
803 		nEndX   = -nEndX;
804 		::std::swap( nStartX, nEndX );
805 	}
806 
807 	if (bAny)
808 	{
809 		DBG_ASSERT( nStartX<=nEndX && nStartY<=nEndY, "Start/End falsch in ScDrawLayer::GetPrintArea" );
810 
811 		if (bSetHor)
812 		{
813 			nStartX = (long) (nStartX / HMM_PER_TWIPS);
814 			nEndX = (long) (nEndX / HMM_PER_TWIPS);
815 			long nWidth;
816 	        SCCOL i;
817 
818 			nWidth = 0;
819 			for (i=0; i<=MAXCOL && nWidth<=nStartX; i++)
820 				nWidth += pDoc->GetColWidth(i,nTab);
821 			rRange.aStart.SetCol( i>0 ? (i-1) : 0 );
822 
823 			nWidth = 0;
824 			for (i=0; i<=MAXCOL && nWidth<=nEndX; i++)			//! bei Start anfangen
825 				nWidth += pDoc->GetColWidth(i,nTab);
826 			rRange.aEnd.SetCol( i>0 ? (i-1) : 0 );
827 		}
828 
829 		if (bSetVer)
830 		{
831 			nStartY = (long) (nStartY / HMM_PER_TWIPS);
832 			nEndY = (long) (nEndY / HMM_PER_TWIPS);
833             SCROW nRow = pDoc->GetRowForHeight( nTab, nStartY);
834 			rRange.aStart.SetRow( nRow>0 ? (nRow-1) : 0);
835             nRow = pDoc->GetRowForHeight( nTab, nEndY);
836 			rRange.aEnd.SetRow( nRow == MAXROW ? MAXROW :
837                     (nRow>0 ? (nRow-1) : 0));
838 		}
839 	}
840 	else
841 	{
842 		if (bSetHor)
843 		{
844 			rRange.aStart.SetCol(0);
845 			rRange.aEnd.SetCol(0);
846 		}
847 		if (bSetVer)
848 		{
849 			rRange.aStart.SetRow(0);
850 			rRange.aEnd.SetRow(0);
851 		}
852 	}
853 	return bAny;
854 }
855 
AddCalcUndo(SdrUndoAction * pUndo)856 void ScDrawLayer::AddCalcUndo( SdrUndoAction* pUndo )
857 {
858 	if (bRecording)
859 	{
860 		if (!pUndoGroup)
861 			pUndoGroup = new SdrUndoGroup(*this);
862 
863 		pUndoGroup->AddAction( pUndo );
864 	}
865 	else
866 		delete pUndo;
867 }
868 
BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)869 void ScDrawLayer::BeginCalcUndo(bool bDisableTextEditUsesCommonUndoManager)
870 {
871 //! DBG_ASSERT( !bRecording, "BeginCalcUndo ohne GetCalcUndo" );
872     SetDisableTextEditUsesCommonUndoManager(bDisableTextEditUsesCommonUndoManager);
873 	DELETEZ(pUndoGroup);
874 	bRecording = sal_True;
875 }
876 
GetCalcUndo()877 SdrUndoGroup* ScDrawLayer::GetCalcUndo()
878 {
879 //! DBG_ASSERT( bRecording, "GetCalcUndo ohne BeginCalcUndo" );
880 
881 	SdrUndoGroup* pRet = pUndoGroup;
882 	pUndoGroup = NULL;
883 	bRecording = sal_False;
884     SetDisableTextEditUsesCommonUndoManager(false);
885 	return pRet;
886 }
887 
888 //	MoveAreaTwips: all measures are kept in twips
MoveAreaTwips(SCTAB nTab,const Rectangle & rArea,const Point & rMove,const Point & rTopLeft)889 void ScDrawLayer::MoveAreaTwips( SCTAB nTab, const Rectangle& rArea,
890 		const Point& rMove, const Point& rTopLeft )
891 {
892 	if (!rMove.X() && !rMove.Y())
893 		return; 									// nix
894 
895 	SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
896 	DBG_ASSERT(pPage,"Page nicht gefunden");
897 	if (!pPage)
898 		return;
899 
900 	sal_Bool bNegativePage = pDoc && pDoc->IsNegativePage( nTab );
901 
902 	// fuer Shrinking!
903 	Rectangle aNew( rArea );
904 	sal_Bool bShrink = sal_False;
905 	if ( rMove.X() < 0 || rMove.Y() < 0 )		// verkleinern
906 	{
907 		if ( rTopLeft != rArea.TopLeft() )		// sind gleich beim Verschieben von Zellen
908 		{
909 			bShrink = sal_True;
910 			aNew.Left() = rTopLeft.X();
911 			aNew.Top() = rTopLeft.Y();
912 		}
913 	}
914 	SdrObjListIter aIter( *pPage, IM_FLAT );
915 	SdrObject* pObject = aIter.Next();
916 	while (pObject)
917 	{
918 		if( GetAnchor( pObject ) == SCA_CELL )
919 		{
920 			if ( GetObjData( pObject ) )					// Detektiv-Pfeil ?
921 			{
922 				// hier nichts
923 			}
924 			else if ( pObject->ISA( SdrEdgeObj ) )			// Verbinder?
925 			{
926 				//	hier auch nichts
927 				//!	nicht verbundene Enden wie bei Linien (s.u.) behandeln?
928 			}
929 			else if ( pObject->IsPolyObj() && pObject->GetPointCount()==2 )
930 			{
931 				for (sal_uInt16 i=0; i<2; i++)
932 				{
933 					sal_Bool bMoved = sal_False;
934 					Point aPoint = pObject->GetPoint(i);
935 					lcl_ReverseTwipsToMM( aPoint );
936 					if (rArea.IsInside(aPoint))
937 					{
938 						aPoint += rMove; bMoved = sal_True;
939 					}
940 					else if (bShrink && aNew.IsInside(aPoint))
941 					{
942 						//	Punkt ist in betroffener Zelle - Test auf geloeschten Bereich
943 						if ( rMove.X() && aPoint.X() >= rArea.Left() + rMove.X() )
944 						{
945 							aPoint.X() = rArea.Left() + rMove.X() - SHRINK_DIST_TWIPS;
946 							if ( aPoint.X() < 0 ) aPoint.X() = 0;
947 							bMoved = sal_True;
948 						}
949 						if ( rMove.Y() && aPoint.Y() >= rArea.Top() + rMove.Y() )
950 						{
951 							aPoint.Y() = rArea.Top() + rMove.Y() - SHRINK_DIST_TWIPS;
952 							if ( aPoint.Y() < 0 ) aPoint.Y() = 0;
953 							bMoved = sal_True;
954 						}
955 					}
956 					if( bMoved )
957 					{
958 			                        AddCalcUndo< SdrUndoGeoObj >( *pObject );
959 						lcl_TwipsToMM( aPoint );
960 						pObject->SetPoint( aPoint, i );
961 					}
962 				}
963 			}
964 			else
965 			{
966 				Rectangle aObjRect = pObject->GetLogicRect();
967 				// aOldMMPos: not converted, millimeters
968 				Point aOldMMPos = bNegativePage ? aObjRect.TopRight() : aObjRect.TopLeft();
969 				lcl_ReverseTwipsToMM( aObjRect );
970 				Point aTopLeft = bNegativePage ? aObjRect.TopRight() : aObjRect.TopLeft();	// logical left
971 				Size aMoveSize;
972 				sal_Bool bDoMove = sal_False;
973 				if (rArea.IsInside(aTopLeft))
974 				{
975 					aMoveSize = Size(rMove.X(),rMove.Y());
976 					bDoMove = sal_True;
977 				}
978 				else if (bShrink && aNew.IsInside(aTopLeft))
979 				{
980 					//	Position ist in betroffener Zelle - Test auf geloeschten Bereich
981 					if ( rMove.X() && aTopLeft.X() >= rArea.Left() + rMove.X() )
982 					{
983 						aMoveSize.Width() = rArea.Left() + rMove.X() - SHRINK_DIST - aTopLeft.X();
984 						bDoMove = sal_True;
985 					}
986 					if ( rMove.Y() && aTopLeft.Y() >= rArea.Top() + rMove.Y() )
987 					{
988 						aMoveSize.Height() = rArea.Top() + rMove.Y() - SHRINK_DIST - aTopLeft.Y();
989 						bDoMove = sal_True;
990 					}
991 				}
992 				if ( bDoMove )
993 				{
994 					if ( bNegativePage )
995 					{
996 						if ( aTopLeft.X() + aMoveSize.Width() > 0 )
997 							aMoveSize.Width() = -aTopLeft.X();
998 					}
999 					else
1000 					{
1001 						if ( aTopLeft.X() + aMoveSize.Width() < 0 )
1002 							aMoveSize.Width() = -aTopLeft.X();
1003 					}
1004 					if ( aTopLeft.Y() + aMoveSize.Height() < 0 )
1005 						aMoveSize.Height() = -aTopLeft.Y();
1006 
1007 					//	get corresponding move size in millimeters:
1008 					Point aNewPos( aTopLeft.X() + aMoveSize.Width(), aTopLeft.Y() + aMoveSize.Height() );
1009 					lcl_TwipsToMM( aNewPos );
1010 					aMoveSize = Size( aNewPos.X() - aOldMMPos.X(), aNewPos.Y() - aOldMMPos.Y() );	// millimeters
1011 
1012 			                    AddCalcUndo< SdrUndoMoveObj >( *pObject, aMoveSize );
1013 					pObject->Move( aMoveSize );
1014 				}
1015 				else if ( rArea.IsInside( bNegativePage ? aObjRect.BottomLeft() : aObjRect.BottomRight() ) &&
1016 							!pObject->IsResizeProtect() )
1017 				{
1018 					//	geschuetzte Groessen werden nicht veraendert
1019 					//	(Positionen schon, weil sie ja an der Zelle "verankert" sind)
1020 		                    AddCalcUndo< SdrUndoGeoObj >( *pObject );
1021 					long nOldSizeX = aObjRect.Right() - aObjRect.Left() + 1;
1022 					long nOldSizeY = aObjRect.Bottom() - aObjRect.Top() + 1;
1023 					long nLogMoveX = rMove.X() * ( bNegativePage ? -1 : 1 );	// logical direction
1024 					pObject->Resize( aOldMMPos, Fraction( nOldSizeX+nLogMoveX, nOldSizeX ),
1025 												Fraction( nOldSizeY+rMove.Y(), nOldSizeY ) );
1026 				}
1027 			}
1028 		}
1029 		pObject = aIter.Next();
1030 	}
1031 }
1032 
MoveArea(SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2,SCsCOL nDx,SCsROW nDy,sal_Bool bInsDel,bool bUpdateNoteCaptionPos)1033 void ScDrawLayer::MoveArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1, SCCOL nCol2,SCROW nRow2,
1034 							SCsCOL nDx,SCsROW nDy, sal_Bool bInsDel, bool bUpdateNoteCaptionPos )
1035 {
1036 	DBG_ASSERT( pDoc, "ScDrawLayer::MoveArea without document" );
1037 	if ( !pDoc )
1038 		return;
1039 
1040 	if (!bAdjustEnabled)
1041 		return;
1042 
1043 	sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1044 
1045 	Rectangle aRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1046 	lcl_ReverseTwipsToMM( aRect );
1047 	//!	use twips directly?
1048 
1049 	Point aMove;
1050 
1051 	if (nDx > 0)
1052 		for (SCsCOL s=0; s<nDx; s++)
1053 			aMove.X() += pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
1054 	else
1055 		for (SCsCOL s=-1; s>=nDx; s--)
1056 			aMove.X() -= pDoc->GetColWidth(s+(SCsCOL)nCol1,nTab);
1057 	if (nDy > 0)
1058         aMove.Y() += pDoc->GetRowHeight( nRow1, nRow1+nDy-1, nTab);
1059 	else
1060         aMove.Y() -= pDoc->GetRowHeight( nRow1+nDy, nRow1-1, nTab);
1061 
1062 	if ( bNegativePage )
1063 		aMove.X() = -aMove.X();
1064 
1065 	Point aTopLeft = aRect.TopLeft();		// Anfang beim Verkleinern
1066 	if (bInsDel)
1067 	{
1068 		if ( aMove.X() != 0 && nDx < 0 )	// nDx counts cells, sign is independent of RTL
1069 			aTopLeft.X() += aMove.X();
1070 		if ( aMove.Y() < 0 )
1071 			aTopLeft.Y() += aMove.Y();
1072 	}
1073 
1074 	//	drawing objects are now directly included in cut&paste
1075 	//	-> only update references when inserting/deleting (or changing widths or heights)
1076 	if ( bInsDel )
1077 		MoveAreaTwips( nTab, aRect, aMove, aTopLeft );
1078 
1079 		//
1080 		//		Detektiv-Pfeile: Zellpositionen anpassen
1081 		//
1082 
1083 	MoveCells( nTab, nCol1,nRow1, nCol2,nRow2, nDx,nDy, bUpdateNoteCaptionPos );
1084 }
1085 
WidthChanged(SCTAB nTab,SCCOL nCol,long nDifTwips)1086 void ScDrawLayer::WidthChanged( SCTAB nTab, SCCOL nCol, long nDifTwips )
1087 {
1088 	DBG_ASSERT( pDoc, "ScDrawLayer::WidthChanged without document" );
1089 	if ( !pDoc )
1090 		return;
1091 
1092 	if (!bAdjustEnabled)
1093 		return;
1094 
1095 	Rectangle aRect;
1096 	Point aTopLeft;
1097 
1098 	for (SCCOL i=0; i<nCol; i++)
1099 		aRect.Left() += pDoc->GetColWidth(i,nTab);
1100 	aTopLeft.X() = aRect.Left();
1101 	aRect.Left() += pDoc->GetColWidth(nCol,nTab);
1102 
1103 	aRect.Right() = MAXMM;
1104 	aRect.Top() = 0;
1105 	aRect.Bottom() = MAXMM;
1106 
1107 	//!	aTopLeft ist falsch, wenn mehrere Spalten auf einmal ausgeblendet werden
1108 
1109 	sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1110 	if ( bNegativePage )
1111 	{
1112 		MirrorRectRTL( aRect );
1113 		aTopLeft.X() = -aTopLeft.X();
1114 		nDifTwips = -nDifTwips;
1115 	}
1116 
1117 	MoveAreaTwips( nTab, aRect, Point( nDifTwips,0 ), aTopLeft );
1118 }
1119 
HeightChanged(SCTAB nTab,SCROW nRow,long nDifTwips)1120 void ScDrawLayer::HeightChanged( SCTAB nTab, SCROW nRow, long nDifTwips )
1121 {
1122 	DBG_ASSERT( pDoc, "ScDrawLayer::HeightChanged without document" );
1123 	if ( !pDoc )
1124 		return;
1125 
1126 	if (!bAdjustEnabled)
1127 		return;
1128 
1129     SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1130     DBG_ASSERT(pPage,"Page not found");
1131     if (!pPage)
1132         return;
1133 
1134     // for an empty page, there's no need to calculate the row heights
1135     if (!pPage->GetObjCount())
1136         return;
1137 
1138 	Rectangle aRect;
1139 	Point aTopLeft;
1140 
1141     aRect.Top() += pDoc->GetRowHeight( 0, nRow-1, nTab);
1142 	aTopLeft.Y() = aRect.Top();
1143 	aRect.Top() += pDoc->GetRowHeight(nRow, nTab);
1144 
1145 	aRect.Bottom() = MAXMM;
1146 	aRect.Left() = 0;
1147 	aRect.Right() = MAXMM;
1148 
1149 	//!	aTopLeft ist falsch, wenn mehrere Zeilen auf einmal ausgeblendet werden
1150 
1151 	sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1152 	if ( bNegativePage )
1153 	{
1154 		MirrorRectRTL( aRect );
1155 		aTopLeft.X() = -aTopLeft.X();
1156 	}
1157 
1158 	MoveAreaTwips( nTab, aRect, Point( 0,nDifTwips ), aTopLeft );
1159 }
1160 
HasObjectsInRows(SCTAB nTab,SCROW nStartRow,SCROW nEndRow,bool bIncludeNotes)1161 sal_Bool ScDrawLayer::HasObjectsInRows( SCTAB nTab, SCROW nStartRow, SCROW nEndRow, bool bIncludeNotes )
1162 {
1163 	DBG_ASSERT( pDoc, "ScDrawLayer::HasObjectsInRows without document" );
1164 	if ( !pDoc )
1165 		return sal_False;
1166 
1167     SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1168     DBG_ASSERT(pPage,"Page not found");
1169     if (!pPage)
1170         return sal_False;
1171 
1172     // for an empty page, there's no need to calculate the row heights
1173     if (!pPage->GetObjCount())
1174         return sal_False;
1175 
1176 	Rectangle aTestRect;
1177 
1178     aTestRect.Top() += pDoc->GetRowHeight( 0, nStartRow-1, nTab);
1179 
1180 	if (nEndRow==MAXROW)
1181 		aTestRect.Bottom() = MAXMM;
1182 	else
1183 	{
1184 		aTestRect.Bottom() = aTestRect.Top();
1185         aTestRect.Bottom() += pDoc->GetRowHeight( nStartRow, nEndRow, nTab);
1186 		TwipsToMM( aTestRect.Bottom() );
1187 	}
1188 
1189 	TwipsToMM( aTestRect.Top() );
1190 
1191 	aTestRect.Left()  = 0;
1192 	aTestRect.Right() = MAXMM;
1193 
1194 	sal_Bool bNegativePage = pDoc->IsNegativePage( nTab );
1195 	if ( bNegativePage )
1196 		MirrorRectRTL( aTestRect );
1197 
1198 	sal_Bool bFound = sal_False;
1199 
1200 	Rectangle aObjRect;
1201 	SdrObjListIter aIter( *pPage );
1202 	SdrObject* pObject = aIter.Next();
1203 	while ( pObject && !bFound )
1204 	{
1205 		aObjRect = pObject->GetSnapRect();	//! GetLogicRect ?
1206         // #i116164# note captions are handled separately, don't have to be included for each single row height change
1207         if ( (aTestRect.IsInside(aObjRect.TopLeft()) || aTestRect.IsInside(aObjRect.BottomLeft())) &&
1208              (bIncludeNotes || !IsNoteCaption(pObject)) )
1209 			bFound = sal_True;
1210 
1211 		pObject = aIter.Next();
1212 	}
1213 
1214 	return bFound;
1215 }
1216 
1217 #if 0
1218 void ScDrawLayer::DeleteObjects( SCTAB nTab )
1219 {
1220 	SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1221 	DBG_ASSERT(pPage,"Page ?");
1222 	if (!pPage)
1223 		return;
1224 
1225 	pPage->RecalcObjOrdNums();
1226 
1227 	long	nDelCount = 0;
1228 	sal_uLong	nObjCount = pPage->GetObjCount();
1229 	if (nObjCount)
1230 	{
1231 		SdrObject** ppObj = new SdrObject*[nObjCount];
1232 
1233 		SdrObjListIter aIter( *pPage, IM_FLAT );
1234 		SdrObject* pObject = aIter.Next();
1235 		while (pObject)
1236 		{
1237 			//	alle loeschen
1238 			ppObj[nDelCount++] = pObject;
1239 			pObject = aIter.Next();
1240 		}
1241 
1242 		long i;
1243 		if (bRecording)
1244 			for (i=1; i<=nDelCount; i++)
1245 		                AddCalcUndo< SdrUndoRemoveObj >( *ppObj[nDelCount-i] );
1246 
1247 		for (i=1; i<=nDelCount; i++)
1248 			pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1249 
1250 		delete[] ppObj;
1251 	}
1252 }
1253 #endif
1254 
DeleteObjectsInArea(SCTAB nTab,SCCOL nCol1,SCROW nRow1,SCCOL nCol2,SCROW nRow2)1255 void ScDrawLayer::DeleteObjectsInArea( SCTAB nTab, SCCOL nCol1,SCROW nRow1,
1256 											SCCOL nCol2,SCROW nRow2 )
1257 {
1258 	DBG_ASSERT( pDoc, "ScDrawLayer::DeleteObjectsInArea without document" );
1259 	if ( !pDoc )
1260 		return;
1261 
1262 	SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1263 	DBG_ASSERT(pPage,"Page ?");
1264 	if (!pPage)
1265 		return;
1266 
1267 	pPage->RecalcObjOrdNums();
1268 
1269 	long	nDelCount = 0;
1270 	sal_uLong	nObjCount = pPage->GetObjCount();
1271 	if (nObjCount)
1272 	{
1273 		Rectangle aDelRect = pDoc->GetMMRect( nCol1, nRow1, nCol2, nRow2, nTab );
1274 
1275 		SdrObject** ppObj = new SdrObject*[nObjCount];
1276 
1277 		SdrObjListIter aIter( *pPage, IM_FLAT );
1278 		SdrObject* pObject = aIter.Next();
1279 		while (pObject)
1280 		{
1281             // do not delete note caption, they are always handled by the cell note
1282             // TODO: detective objects are still deleted, is this desired?
1283             if (!IsNoteCaption( pObject ))
1284             {
1285                 Rectangle aObjRect = pObject->GetCurrentBoundRect();
1286                 if ( aDelRect.IsInside( aObjRect ) )
1287                     ppObj[nDelCount++] = pObject;
1288             }
1289 
1290 			pObject = aIter.Next();
1291 		}
1292 
1293 		long i;
1294 		if (bRecording)
1295 			for (i=1; i<=nDelCount; i++)
1296 		                AddCalcUndo< SdrUndoRemoveObj >( *ppObj[nDelCount-i] );
1297 
1298 		for (i=1; i<=nDelCount; i++)
1299 			pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1300 
1301 		delete[] ppObj;
1302 	}
1303 }
1304 
DeleteObjectsInSelection(const ScMarkData & rMark)1305 void ScDrawLayer::DeleteObjectsInSelection( const ScMarkData& rMark )
1306 {
1307 	DBG_ASSERT( pDoc, "ScDrawLayer::DeleteObjectsInSelection without document" );
1308 	if ( !pDoc )
1309 		return;
1310 
1311 	if ( !rMark.IsMultiMarked() )
1312 		return;
1313 
1314 	ScRange aMarkRange;
1315 	rMark.GetMultiMarkArea( aMarkRange );
1316 
1317 	SCTAB nTabCount = pDoc->GetTableCount();
1318 	for (SCTAB nTab=0; nTab<=nTabCount; nTab++)
1319 		if ( rMark.GetTableSelect( nTab ) )
1320 		{
1321 			SdrPage* pPage = GetPage(static_cast<sal_uInt16>(nTab));
1322 			if (pPage)
1323 			{
1324 				pPage->RecalcObjOrdNums();
1325 				long	nDelCount = 0;
1326 				sal_uLong	nObjCount = pPage->GetObjCount();
1327 				if (nObjCount)
1328 				{
1329 					//	Rechteck um die ganze Selektion
1330 					Rectangle aMarkBound = pDoc->GetMMRect(
1331 								aMarkRange.aStart.Col(), aMarkRange.aStart.Row(),
1332 								aMarkRange.aEnd.Col(), aMarkRange.aEnd.Row(), nTab );
1333 
1334 					SdrObject** ppObj = new SdrObject*[nObjCount];
1335 
1336 					SdrObjListIter aIter( *pPage, IM_FLAT );
1337 					SdrObject* pObject = aIter.Next();
1338 					while (pObject)
1339 					{
1340                         // do not delete note caption, they are always handled by the cell note
1341                         // TODO: detective objects are still deleted, is this desired?
1342                         if (!IsNoteCaption( pObject ))
1343                         {
1344                             Rectangle aObjRect = pObject->GetCurrentBoundRect();
1345                             if ( aMarkBound.IsInside( aObjRect ) )
1346                             {
1347                                 ScRange aRange = pDoc->GetRange( nTab, aObjRect );
1348                                 if (rMark.IsAllMarked(aRange))
1349                                     ppObj[nDelCount++] = pObject;
1350                             }
1351                         }
1352 
1353 						pObject = aIter.Next();
1354 					}
1355 
1356 					//	Objekte loeschen (rueckwaerts)
1357 
1358 					long i;
1359 					if (bRecording)
1360 						for (i=1; i<=nDelCount; i++)
1361 			                            AddCalcUndo< SdrUndoRemoveObj >( *ppObj[nDelCount-i] );
1362 
1363 					for (i=1; i<=nDelCount; i++)
1364 						pPage->RemoveObject( ppObj[nDelCount-i]->GetOrdNum() );
1365 
1366 					delete[] ppObj;
1367 				}
1368 			}
1369 			else
1370 			{
1371 				DBG_ERROR("pPage?");
1372 			}
1373 		}
1374 }
1375 
CopyToClip(ScDocument * pClipDoc,SCTAB nTab,const Rectangle & rRange)1376 void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& rRange )
1377 {
1378 	//	copy everything in the specified range into the same page (sheet) in the clipboard doc
1379 
1380 	SdrPage* pSrcPage = GetPage(static_cast<sal_uInt16>(nTab));
1381 	if (pSrcPage)
1382 	{
1383 		ScDrawLayer* pDestModel = NULL;
1384 		SdrPage* pDestPage = NULL;
1385 
1386 		SdrObjListIter aIter( *pSrcPage, IM_FLAT );
1387 		SdrObject* pOldObject = aIter.Next();
1388 		while (pOldObject)
1389 		{
1390 			Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1391             // do not copy internal objects (detective) and note captions
1392             if ( rRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
1393 			{
1394 				if ( !pDestModel )
1395 				{
1396 					pDestModel = pClipDoc->GetDrawLayer();		// does the document already have a drawing layer?
1397 					if ( !pDestModel )
1398 					{
1399 						//	allocate drawing layer in clipboard document only if there are objects to copy
1400 
1401 						pClipDoc->InitDrawLayer();					//!	create contiguous pages
1402 						pDestModel = pClipDoc->GetDrawLayer();
1403 					}
1404 					if (pDestModel)
1405 						pDestPage = pDestModel->GetPage( static_cast<sal_uInt16>(nTab) );
1406 				}
1407 
1408 				DBG_ASSERT( pDestPage, "no page" );
1409 				if (pDestPage)
1410 				{
1411 					// #116235#
1412 					SdrObject* pNewObject = pOldObject->Clone();
1413 					//SdrObject* pNewObject = pOldObject->Clone( pDestPage, pDestModel );
1414 					pNewObject->SetModel(pDestModel);
1415 					pNewObject->SetPage(pDestPage);
1416 
1417                     uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) );
1418                     if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise
1419                         pNewObject->NbcMove(Size(0,0));
1420 					pDestPage->InsertObject( pNewObject );
1421 
1422 					//	no undo needed in clipboard document
1423 					//	charts are not updated
1424 				}
1425 			}
1426 
1427 			pOldObject = aIter.Next();
1428 		}
1429 	}
1430 }
1431 
lcl_IsAllInRange(const::std::vector<ScRangeList> & rRangesVector,const ScRange & rClipRange)1432 sal_Bool lcl_IsAllInRange( const ::std::vector< ScRangeList >& rRangesVector, const ScRange& rClipRange )
1433 {
1434 	//	check if every range of rRangesVector is completely in rClipRange
1435 
1436     ::std::vector< ScRangeList >::const_iterator aIt = rRangesVector.begin();
1437     for( ;aIt!=rRangesVector.end(); ++aIt )
1438     {
1439         const ScRangeList& rRanges = *aIt;
1440 	    sal_uLong nCount = rRanges.Count();
1441 	    for (sal_uLong i=0; i<nCount; i++)
1442 	    {
1443 		    ScRange aRange = *rRanges.GetObject(i);
1444 		    if ( !rClipRange.In( aRange ) )
1445 		    {
1446 			    return sal_False;	// at least one range is not valid
1447 		    }
1448 	    }
1449     }
1450 
1451 	return sal_True;			// everything is fine
1452 }
1453 
lcl_MoveRanges(::std::vector<ScRangeList> & rRangesVector,const ScRange & rSourceRange,const ScAddress & rDestPos)1454 sal_Bool lcl_MoveRanges( ::std::vector< ScRangeList >& rRangesVector, const ScRange& rSourceRange, const ScAddress& rDestPos )
1455 {
1456 	sal_Bool bChanged = sal_False;
1457 
1458     ::std::vector< ScRangeList >::iterator aIt = rRangesVector.begin();
1459     for( ;aIt!=rRangesVector.end(); ++aIt )
1460     {
1461         ScRangeList& rRanges = *aIt;
1462         sal_uLong nCount = rRanges.Count();
1463 	    for (sal_uLong i=0; i<nCount; i++)
1464 	    {
1465 		    ScRange* pRange = rRanges.GetObject(i);
1466 		    if ( rSourceRange.In( *pRange ) )
1467 		    {
1468 			    SCsCOL nDiffX = rDestPos.Col() - (SCsCOL)rSourceRange.aStart.Col();
1469 			    SCsROW nDiffY = rDestPos.Row() - (SCsROW)rSourceRange.aStart.Row();
1470 			    SCsTAB nDiffZ = rDestPos.Tab() - (SCsTAB)rSourceRange.aStart.Tab();
1471 			    pRange->Move( nDiffX, nDiffY, nDiffZ );
1472 			    bChanged = sal_True;
1473 		    }
1474 	    }
1475     }
1476 
1477 	return bChanged;
1478 }
1479 
CopyFromClip(ScDrawLayer * pClipModel,SCTAB nSourceTab,const Rectangle & rSourceRange,const ScAddress & rDestPos,const Rectangle & rDestRange)1480 void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const Rectangle& rSourceRange,
1481 									const ScAddress& rDestPos, const Rectangle& rDestRange )
1482 {
1483 	DBG_ASSERT( pDoc, "ScDrawLayer::CopyFromClip without document" );
1484 	if ( !pDoc )
1485 		return;
1486 
1487 	if (!pClipModel)
1488 		return;
1489 
1490 	if (bDrawIsInUndo)		//! can this happen?
1491 	{
1492 		DBG_ERROR("CopyFromClip, bDrawIsInUndo");
1493 		return;
1494 	}
1495 
1496 	sal_Bool bMirrorObj = ( rSourceRange.Left() < 0 && rSourceRange.Right() < 0 &&
1497 						rDestRange.Left()   > 0 && rDestRange.Right()   > 0 ) ||
1498 					  ( rSourceRange.Left() > 0 && rSourceRange.Right() > 0 &&
1499 						rDestRange.Left()   < 0 && rDestRange.Right()   < 0 );
1500 	Rectangle aMirroredSource = rSourceRange;
1501 	if ( bMirrorObj )
1502 		MirrorRectRTL( aMirroredSource );
1503 
1504 	SCTAB nDestTab = rDestPos.Tab();
1505 
1506     SdrPage* pSrcPage = pClipModel->GetPage(static_cast<sal_uInt16>(nSourceTab));
1507     SdrPage* pDestPage = GetPage(static_cast<sal_uInt16>(nDestTab));
1508     DBG_ASSERT( pSrcPage && pDestPage, "draw page missing" );
1509     if ( !pSrcPage || !pDestPage )
1510         return;
1511 
1512     SdrObjListIter aIter( *pSrcPage, IM_FLAT );
1513     SdrObject* pOldObject = aIter.Next();
1514 
1515     ScDocument* pClipDoc = pClipModel->GetDocument();
1516     //  a clipboard document and its source share the same document item pool,
1517     //  so the pointers can be compared to see if this is copy&paste within
1518     //  the same document
1519     sal_Bool bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool();
1520     sal_Bool bDestClip = pDoc && pDoc->IsClipboard();
1521 
1522     //#i110034# charts need correct sheet names for xml range conversion during load
1523     //so the target sheet name is temporarily renamed (if we have any SdrObjects)
1524     String aDestTabName;
1525     sal_Bool bRestoreDestTabName = sal_False;
1526     if( pOldObject && !bSameDoc && !bDestClip )
1527     {
1528         if( pDoc && pClipDoc )
1529         {
1530             String aSourceTabName;
1531             if( pClipDoc->GetName( nSourceTab, aSourceTabName )
1532                 && pDoc->GetName( nDestTab, aDestTabName ) )
1533             {
1534                 if( !(aSourceTabName==aDestTabName) &&
1535                     pDoc->ValidNewTabName(aSourceTabName) )
1536                 {
1537                     bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //sal_Bool bUpdateRef = sal_True, sal_Bool bExternalDocument = sal_False
1538                 }
1539             }
1540         }
1541     }
1542 
1543 	// first mirror, then move
1544 	Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() );
1545 
1546 	long nDestWidth = rDestRange.GetWidth();
1547 	long nDestHeight = rDestRange.GetHeight();
1548 	long nSourceWidth = rSourceRange.GetWidth();
1549 	long nSourceHeight = rSourceRange.GetHeight();
1550 
1551 	long nWidthDiff = nDestWidth - nSourceWidth;
1552 	long nHeightDiff = nDestHeight - nSourceHeight;
1553 
1554 	Fraction aHorFract(1,1);
1555 	Fraction aVerFract(1,1);
1556 	sal_Bool bResize = sal_False;
1557 	// sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
1558 	// don't resize to empty size when pasting into hidden columns or rows
1559 	if ( Abs(nWidthDiff) > 1 && nDestWidth > 1 && nSourceWidth > 1 )
1560 	{
1561 		aHorFract = Fraction( nDestWidth, nSourceWidth );
1562 		bResize = sal_True;
1563 	}
1564 	if ( Abs(nHeightDiff) > 1 && nDestHeight > 1 && nSourceHeight > 1 )
1565 	{
1566 		aVerFract = Fraction( nDestHeight, nSourceHeight );
1567 		bResize = sal_True;
1568 	}
1569 	Point aRefPos = rDestRange.TopLeft();		// for resizing (after moving)
1570 
1571 	while (pOldObject)
1572 	{
1573 		Rectangle aObjRect = pOldObject->GetCurrentBoundRect();
1574         // do not copy internal objects (detective) and note captions
1575         if ( rSourceRange.IsInside( aObjRect ) && (pOldObject->GetLayer() != SC_LAYER_INTERN) && !IsNoteCaption( pOldObject ) )
1576 		{
1577 			// #116235#
1578 			SdrObject* pNewObject = pOldObject->Clone();
1579 			//SdrObject* pNewObject = pOldObject->Clone( pDestPage, this );
1580 			pNewObject->SetModel(this);
1581 			pNewObject->SetPage(pDestPage);
1582 
1583 			if ( bMirrorObj )
1584 				MirrorRTL( pNewObject );		// first mirror, then move
1585 
1586 			pNewObject->NbcMove( aMove );
1587 			if ( bResize )
1588 				pNewObject->NbcResize( aRefPos, aHorFract, aVerFract );
1589 
1590 			pDestPage->InsertObject( pNewObject );
1591 			if (bRecording)
1592 		                AddCalcUndo< SdrUndoInsertObj >( *pNewObject );
1593 
1594 			//#i110034#	handle chart data references (after InsertObject)
1595 
1596 			if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 )
1597 			{
1598 				uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pNewObject)->GetObjRef();
1599 				uno::Reference< embed::XClassifiedObject > xClassified( xIPObj, uno::UNO_QUERY );
1600 				SvGlobalName aObjectClassName;
1601 				if ( xClassified.is() )
1602 			    {
1603 					try {
1604 						aObjectClassName = SvGlobalName( xClassified->getClassID() );
1605 					} catch( uno::Exception& )
1606 					{
1607 						// TODO: handle error?
1608 					}
1609 				}
1610 
1611 				if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) )
1612 				{
1613                     uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) );
1614                     if( xNewChart.is() && !xNewChart->hasInternalDataProvider() )
1615                     {
1616                         String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName();
1617                         ::std::vector< ScRangeList > aRangesVector;
1618                         pDoc->GetChartRanges( aChartName, aRangesVector, pDoc );
1619                         if( !aRangesVector.empty() )
1620                         {
1621                             sal_Bool bInSourceRange = sal_False;
1622                             ScRange aClipRange;
1623                             if ( pClipDoc )
1624                             {
1625                                 SCCOL nClipStartX;
1626                                 SCROW nClipStartY;
1627                                 SCCOL nClipEndX;
1628                                 SCROW nClipEndY;
1629                                 pClipDoc->GetClipStart( nClipStartX, nClipStartY );
1630                                 pClipDoc->GetClipArea( nClipEndX, nClipEndY, sal_True );
1631                                 nClipEndX = nClipEndX + nClipStartX;
1632                                 nClipEndY += nClipStartY;   // GetClipArea returns the difference
1633 
1634                                 SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab;
1635                                 aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab,
1636                                                         nClipEndX, nClipEndY, nClipTab );
1637 
1638                                 bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange );
1639                             }
1640 
1641                             // always lose references when pasting into a clipboard document (transpose)
1642                             if ( ( bInSourceRange || bSameDoc ) && !bDestClip )
1643                             {
1644                                 if ( bInSourceRange )
1645                                 {
1646                                     if ( rDestPos != aClipRange.aStart )
1647                                     {
1648                                         //  update the data ranges to the new (copied) position
1649                                         if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) )
1650                                             pDoc->SetChartRanges( aChartName, aRangesVector );
1651                                     }
1652                                 }
1653                                 else
1654                                 {
1655                                     //  leave the ranges unchanged
1656                                 }
1657                             }
1658                             else
1659                             {
1660                                 //  pasting into a new document without the complete source data
1661                                 //  -> break connection to source data and switch to own data
1662 
1663                                 uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY );
1664                                 uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY );
1665                                 if( xOldChartDoc.is() && xNewChartDoc.is() )
1666                                     xNewChartDoc->attachData( xOldChartDoc->getData() );
1667 
1668                                 //  (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
1669                             }
1670 					    }
1671                     }
1672 				}
1673 			}
1674 		}
1675 
1676 		pOldObject = aIter.Next();
1677 	}
1678 
1679     if( bRestoreDestTabName )
1680         pDoc->RenameTab( nDestTab, aDestTabName );
1681 }
1682 
MirrorRTL(SdrObject * pObj)1683 void ScDrawLayer::MirrorRTL( SdrObject* pObj )
1684 {
1685 	sal_uInt16 nIdent = pObj->GetObjIdentifier();
1686 
1687 	//	don't mirror OLE or graphics, otherwise ask the object
1688 	//	if it can be mirrored
1689 	sal_Bool bCanMirror = ( nIdent != OBJ_GRAF && nIdent != OBJ_OLE2 );
1690 	if (bCanMirror)
1691 	{
1692 		SdrObjTransformInfoRec aInfo;
1693 		pObj->TakeObjInfo( aInfo );
1694 		bCanMirror = aInfo.bMirror90Allowed;
1695 	}
1696 
1697 	if (bCanMirror)
1698 	{
1699 		Point aRef1( 0, 0 );
1700 		Point aRef2( 0, 1 );
1701 		if (bRecording)
1702 		            AddCalcUndo< SdrUndoGeoObj >( *pObj );
1703 		pObj->Mirror( aRef1, aRef2 );
1704 	}
1705 	else
1706 	{
1707 		//	Move instead of mirroring:
1708 		//	New start position is negative of old end position
1709 		//	-> move by sum of start and end position
1710 		Rectangle aObjRect = pObj->GetLogicRect();
1711 		Size aMoveSize( -(aObjRect.Left() + aObjRect.Right()), 0 );
1712 		if (bRecording)
1713 		            AddCalcUndo< SdrUndoMoveObj >( *pObj, aMoveSize );
1714 		pObj->Move( aMoveSize );
1715 	}
1716 }
1717 
1718 // static
MirrorRectRTL(Rectangle & rRect)1719 void ScDrawLayer::MirrorRectRTL( Rectangle& rRect )
1720 {
1721 	//	mirror and swap left/right
1722 	long nTemp = rRect.Left();
1723 	rRect.Left() = -rRect.Right();
1724 	rRect.Right() = -nTemp;
1725 }
1726 
GetCellRect(ScDocument & rDoc,const ScAddress & rPos,bool bMergedCell)1727 Rectangle ScDrawLayer::GetCellRect( ScDocument& rDoc, const ScAddress& rPos, bool bMergedCell )
1728 {
1729     Rectangle aCellRect;
1730     DBG_ASSERT( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
1731     if( ValidColRowTab( rPos.Col(), rPos.Row(), rPos.Tab() ) )
1732     {
1733         // find top left position of passed cell address
1734         Point aTopLeft;
1735         for( SCCOL nCol = 0; nCol < rPos.Col(); ++nCol )
1736             aTopLeft.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
1737         if( rPos.Row() > 0 )
1738             aTopLeft.Y() += rDoc.GetRowHeight( 0, rPos.Row() - 1, rPos.Tab() );
1739 
1740         // find bottom-right position of passed cell address
1741         ScAddress aEndPos = rPos;
1742         if( bMergedCell )
1743         {
1744             const ScMergeAttr* pMerge = static_cast< const ScMergeAttr* >( rDoc.GetAttr( rPos.Col(), rPos.Row(), rPos.Tab(), ATTR_MERGE ) );
1745             if( pMerge->GetColMerge() > 1 )
1746                 aEndPos.IncCol( pMerge->GetColMerge() - 1 );
1747             if( pMerge->GetRowMerge() > 1 )
1748                 aEndPos.IncRow( pMerge->GetRowMerge() - 1 );
1749         }
1750         Point aBotRight = aTopLeft;
1751         for( SCCOL nCol = rPos.Col(); nCol <= aEndPos.Col(); ++nCol )
1752             aBotRight.X() += rDoc.GetColWidth( nCol, rPos.Tab() );
1753         aBotRight.Y() += rDoc.GetRowHeight( rPos.Row(), aEndPos.Row(), rPos.Tab() );
1754 
1755         // twips -> 1/100 mm
1756         aTopLeft.X() = static_cast< long >( aTopLeft.X() * HMM_PER_TWIPS );
1757         aTopLeft.Y() = static_cast< long >( aTopLeft.Y() * HMM_PER_TWIPS );
1758         aBotRight.X() = static_cast< long >( aBotRight.X() * HMM_PER_TWIPS );
1759         aBotRight.Y() = static_cast< long >( aBotRight.Y() * HMM_PER_TWIPS );
1760 
1761         aCellRect = Rectangle( aTopLeft, aBotRight );
1762         if( rDoc.IsNegativePage( rPos.Tab() ) )
1763             MirrorRectRTL( aCellRect );
1764     }
1765     return aCellRect;
1766 }
1767 
1768 // static
GetVisibleName(SdrObject * pObj)1769 String ScDrawLayer::GetVisibleName( SdrObject* pObj )
1770 {
1771 	String aName = pObj->GetName();
1772 	if ( pObj->GetObjIdentifier() == OBJ_OLE2 )
1773 	{
1774 		//	#95575# For OLE, the user defined name (GetName) is used
1775 		//	if it's not empty (accepting possibly duplicate names),
1776 		//	otherwise the persist name is used so every object appears
1777 		//	in the Navigator at all.
1778 
1779 		if ( !aName.Len() )
1780 			aName = static_cast<SdrOle2Obj*>(pObj)->GetPersistName();
1781 	}
1782 	return aName;
1783 }
1784 
IsNamedObject(SdrObject * pObj,const String & rName)1785 inline sal_Bool IsNamedObject( SdrObject* pObj, const String& rName )
1786 {
1787 	//	sal_True if rName is the object's Name or PersistName
1788 	//	(used to find a named object)
1789 
1790 	return ( pObj->GetName() == rName ||
1791 			( pObj->GetObjIdentifier() == OBJ_OLE2 &&
1792 			  static_cast<SdrOle2Obj*>(pObj)->GetPersistName() == rName ) );
1793 }
1794 
GetNamedObject(const String & rName,sal_uInt16 nId,SCTAB & rFoundTab) const1795 SdrObject* ScDrawLayer::GetNamedObject( const String& rName, sal_uInt16 nId, SCTAB& rFoundTab ) const
1796 {
1797 	sal_uInt16 nTabCount = GetPageCount();
1798 	for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1799 	{
1800 		const SdrPage* pPage = GetPage(nTab);
1801 		DBG_ASSERT(pPage,"Page ?");
1802 		if (pPage)
1803 		{
1804 			SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
1805 			SdrObject* pObject = aIter.Next();
1806 			while (pObject)
1807 			{
1808 				if ( nId == 0 || pObject->GetObjIdentifier() == nId )
1809 					if ( IsNamedObject( pObject, rName ) )
1810 					{
1811 						rFoundTab = static_cast<SCTAB>(nTab);
1812 						return pObject;
1813 					}
1814 
1815 				pObject = aIter.Next();
1816 			}
1817 		}
1818 	}
1819 
1820 	return NULL;
1821 }
1822 
GetNewGraphicName(long * pnCounter) const1823 String ScDrawLayer::GetNewGraphicName( long* pnCounter ) const
1824 {
1825 	String aBase = ScGlobal::GetRscString(STR_GRAPHICNAME);
1826 	aBase += ' ';
1827 
1828 	sal_Bool bThere = sal_True;
1829     String aGraphicName;
1830 	SCTAB nDummy;
1831     long nId = pnCounter ? *pnCounter : 0;
1832 	while (bThere)
1833 	{
1834 		++nId;
1835         aGraphicName = aBase;
1836         aGraphicName += String::CreateFromInt32( nId );
1837         bThere = ( GetNamedObject( aGraphicName, 0, nDummy ) != NULL );
1838 	}
1839 
1840     if ( pnCounter )
1841         *pnCounter = nId;
1842 
1843     return aGraphicName;
1844 }
1845 
EnsureGraphicNames()1846 void ScDrawLayer::EnsureGraphicNames()
1847 {
1848 	//	make sure all graphic objects have names (after Excel import etc.)
1849 
1850 	sal_uInt16 nTabCount = GetPageCount();
1851 	for (sal_uInt16 nTab=0; nTab<nTabCount; nTab++)
1852 	{
1853 		SdrPage* pPage = GetPage(nTab);
1854 		DBG_ASSERT(pPage,"Page ?");
1855 		if (pPage)
1856 		{
1857 			SdrObjListIter aIter( *pPage, IM_DEEPWITHGROUPS );
1858 			SdrObject* pObject = aIter.Next();
1859 
1860             /* #101799# The index passed to GetNewGraphicName() will be set to
1861                 the used index in each call. This prevents the repeated search
1862                 for all names from 1 to current index. */
1863             long nCounter = 0;
1864 
1865 			while (pObject)
1866 			{
1867 				if ( pObject->GetObjIdentifier() == OBJ_GRAF && pObject->GetName().Len() == 0 )
1868                     pObject->SetName( GetNewGraphicName( &nCounter ) );
1869 
1870 				pObject = aIter.Next();
1871 			}
1872 		}
1873 	}
1874 }
1875 
SetAnchor(SdrObject * pObj,ScAnchorType eType)1876 void ScDrawLayer::SetAnchor( SdrObject* pObj, ScAnchorType eType )
1877 {
1878     ScAnchorType eOldAnchorType = GetAnchor( pObj );
1879 
1880     // Ein an der Seite verankertes Objekt zeichnet sich durch eine Anker-Pos
1881 	// von (0,1) aus. Das ist ein shabby Trick, der aber funktioniert!
1882 	Point aAnchor( 0, eType == SCA_PAGE ? 1 : 0 );
1883 	pObj->SetAnchorPos( aAnchor );
1884 
1885     if ( eOldAnchorType != eType )
1886         pObj->notifyShapePropertyChange( ::svx::eSpreadsheetAnchor );
1887 }
1888 
GetAnchor(const SdrObject * pObj)1889 ScAnchorType ScDrawLayer::GetAnchor( const SdrObject* pObj )
1890 {
1891 	Point aAnchor( pObj->GetAnchorPos() );
1892 	return ( aAnchor.Y() != 0 ) ? SCA_PAGE : SCA_CELL;
1893 }
1894 
GetObjData(SdrObject * pObj,sal_Bool bCreate)1895 ScDrawObjData* ScDrawLayer::GetObjData( SdrObject* pObj, sal_Bool bCreate )		// static
1896 {
1897 	sal_uInt16 nCount = pObj ? pObj->GetUserDataCount() : 0;
1898 	for( sal_uInt16 i = 0; i < nCount; i++ )
1899 	{
1900 		SdrObjUserData* pData = pObj->GetUserData( i );
1901 		if( pData && pData->GetInventor() == SC_DRAWLAYER
1902 					&& pData->GetId() == SC_UD_OBJDATA )
1903 			return (ScDrawObjData*) pData;
1904 	}
1905 	if( pObj && bCreate )
1906 	{
1907 		ScDrawObjData* pData = new ScDrawObjData;
1908 		pObj->InsertUserData( pData, 0 );
1909 		return pData;
1910 	}
1911 	return 0;
1912 }
1913 
GetObjDataTab(SdrObject * pObj,SCTAB nTab)1914 ScDrawObjData* ScDrawLayer::GetObjDataTab( SdrObject* pObj, SCTAB nTab )    // static
1915 {
1916     ScDrawObjData* pData = GetObjData( pObj );
1917     if ( pData )
1918     {
1919         if ( pData->maStart.IsValid() )
1920             pData->maStart.SetTab( nTab );
1921         if ( pData->maEnd.IsValid() )
1922             pData->maEnd.SetTab( nTab );
1923     }
1924     return pData;
1925 }
1926 
IsNoteCaption(SdrObject * pObj)1927 bool ScDrawLayer::IsNoteCaption( SdrObject* pObj )
1928 {
1929     ScDrawObjData* pData = pObj ? GetObjData( pObj ) : 0;
1930     return pData && pData->mbNote;
1931 }
1932 
GetNoteCaptionData(SdrObject * pObj,SCTAB nTab)1933 ScDrawObjData* ScDrawLayer::GetNoteCaptionData( SdrObject* pObj, SCTAB nTab )
1934 {
1935     ScDrawObjData* pData = pObj ? GetObjDataTab( pObj, nTab ) : 0;
1936     return (pData && pData->mbNote) ? pData : 0;
1937 }
1938 
GetIMapInfo(SdrObject * pObj)1939 ScIMapInfo* ScDrawLayer::GetIMapInfo( SdrObject* pObj )				// static
1940 {
1941 	sal_uInt16 nCount = pObj->GetUserDataCount();
1942 	for( sal_uInt16 i = 0; i < nCount; i++ )
1943 	{
1944 		SdrObjUserData* pData = pObj->GetUserData( i );
1945 		if( pData && pData->GetInventor() == SC_DRAWLAYER
1946 					&& pData->GetId() == SC_UD_IMAPDATA )
1947 			return (ScIMapInfo*) pData;
1948 	}
1949 	return NULL;
1950 }
1951 
1952 // static:
GetHitIMapObject(SdrObject * pObj,const Point & rWinPoint,const Window & rCmpWnd)1953 IMapObject*	ScDrawLayer::GetHitIMapObject( SdrObject* pObj,
1954 										  const Point& rWinPoint, const Window& rCmpWnd )
1955 {
1956 	const MapMode		aMap100( MAP_100TH_MM );
1957 	MapMode				aWndMode = rCmpWnd.GetMapMode();
1958 	Point				aRelPoint( rCmpWnd.LogicToLogic( rWinPoint, &aWndMode, &aMap100 ) );
1959 	Rectangle			aLogRect = rCmpWnd.LogicToLogic( pObj->GetLogicRect(), &aWndMode, &aMap100 );
1960 	ScIMapInfo*			pIMapInfo = GetIMapInfo( pObj );
1961 	IMapObject*			pIMapObj = NULL;
1962 
1963 	if ( pIMapInfo )
1964 	{
1965 		Size		aGraphSize;
1966 		ImageMap&	rImageMap = (ImageMap&) pIMapInfo->GetImageMap();
1967 		Graphic		aGraphic;
1968 		sal_Bool		bObjSupported = sal_False;
1969 
1970 		if ( pObj->ISA( SdrGrafObj )  ) // einfaches Grafik-Objekt
1971 		{
1972 			const SdrGrafObj*	pGrafObj = (const SdrGrafObj*) pObj;
1973 			const GeoStat&		rGeo = pGrafObj->GetGeoStat();
1974 			const Graphic&		rGraphic = pGrafObj->GetGraphic();
1975 
1976 			// Drehung rueckgaengig
1977 			if ( rGeo.nDrehWink )
1978 				RotatePoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nSin, rGeo.nCos );
1979 
1980 			// Spiegelung rueckgaengig
1981 			if ( ( (const SdrGrafObjGeoData*) pGrafObj->GetGeoData() )->bMirrored )
1982 				aRelPoint.X() = aLogRect.Right() + aLogRect.Left() - aRelPoint.X();
1983 
1984 			// ggf. Unshear:
1985 			if ( rGeo.nShearWink )
1986 				ShearPoint( aRelPoint, aLogRect.TopLeft(), -rGeo.nTan );
1987 
1988 
1989 			if ( rGraphic.GetPrefMapMode().GetMapUnit() == MAP_PIXEL )
1990 				aGraphSize = rCmpWnd.PixelToLogic( rGraphic.GetPrefSize(),
1991 														 aMap100 );
1992 			else
1993 				aGraphSize = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(),
1994 														 rGraphic.GetPrefMapMode(),
1995 														 aMap100 );
1996 
1997 			bObjSupported = sal_True;
1998 		}
1999 		else if ( pObj->ISA( SdrOle2Obj ) ) // OLE-Objekt
2000 		{
2001             // TODO/LEAN: working with visual area needs running state
2002 			aGraphSize = ((SdrOle2Obj*)pObj)->GetOrigObjSize();
2003 			bObjSupported = sal_True;
2004 		}
2005 
2006 		// hat alles geklappt, dann HitTest ausfuehren
2007 		if ( bObjSupported )
2008 		{
2009 			// relativen Mauspunkt berechnen
2010 			aRelPoint -= aLogRect.TopLeft();
2011 			pIMapObj = rImageMap.GetHitIMapObject( aGraphSize, aLogRect.GetSize(), aRelPoint );
2012 		}
2013 	}
2014 
2015 	return pIMapObj;
2016 }
2017 
GetMacroInfo(SdrObject * pObj,sal_Bool bCreate)2018 ScMacroInfo* ScDrawLayer::GetMacroInfo( SdrObject* pObj, sal_Bool bCreate )             // static
2019 {
2020     sal_uInt16 nCount = pObj->GetUserDataCount();
2021     for( sal_uInt16 i = 0; i < nCount; i++ )
2022     {
2023         SdrObjUserData* pData = pObj->GetUserData( i );
2024         if( pData && pData->GetInventor() == SC_DRAWLAYER
2025                     && pData->GetId() == SC_UD_MACRODATA )
2026             return (ScMacroInfo*) pData;
2027     }
2028     if ( bCreate )
2029     {
2030         ScMacroInfo* pData = new ScMacroInfo;
2031         pObj->InsertUserData( pData, 0 );
2032         return pData;
2033     }
2034     return 0;
2035 }
GetImageMapForObject(SdrObject * pObj)2036 ImageMap* ScDrawLayer::GetImageMapForObject(SdrObject* pObj)
2037 {
2038 	ScIMapInfo* pIMapInfo = const_cast<ScIMapInfo*>( GetIMapInfo( pObj ) );
2039 	if ( pIMapInfo )
2040 	{
2041 		return const_cast<ImageMap*>( &(pIMapInfo->GetImageMap()) );
2042 	}
2043 	return NULL;
2044 }
2045 
GetHyperlinkCount(SdrObject * pObj)2046 sal_Int32 ScDrawLayer::GetHyperlinkCount(SdrObject* pObj)
2047 {
2048 	sal_Int32 nHLCount = 0;
2049 	ScMacroInfo* pMacroInfo = GetMacroInfo(pObj, sal_False);
2050 	if (pMacroInfo)
2051 		// MT IA2: GetHlink*( doesn|t exist in DEV300 anymore...
2052 		nHLCount = 0; // pMacroInfo->GetHlink().getLength() > 0 ? 1 : 0;
2053 	return nHLCount;
2054 }
SetGlobalDrawPersist(SfxObjectShell * pPersist)2055 void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell* pPersist)			// static
2056 {
2057 	DBG_ASSERT(!pGlobalDrawPersist,"SetGlobalDrawPersist mehrfach");
2058 	pGlobalDrawPersist = pPersist;
2059 }
2060 
SetChanged(sal_Bool bFlg)2061 void __EXPORT ScDrawLayer::SetChanged( sal_Bool bFlg /* = sal_True */ )
2062 {
2063 	if ( bFlg && pDoc )
2064 		pDoc->SetChartListenerCollectionNeedsUpdate( sal_True );
2065 	FmFormModel::SetChanged( bFlg );
2066 }
2067 
GetDocumentStream(SdrDocumentStreamInfo & rStreamInfo) const2068 SvStream* __EXPORT ScDrawLayer::GetDocumentStream(SdrDocumentStreamInfo& rStreamInfo) const
2069 {
2070 	DBG_ASSERT( pDoc, "ScDrawLayer::GetDocumentStream without document" );
2071 	if ( !pDoc )
2072 		return NULL;
2073 
2074 	uno::Reference< embed::XStorage > xStorage = pDoc->GetDocumentShell() ?
2075 														pDoc->GetDocumentShell()->GetStorage() :
2076 														NULL;
2077 	SvStream*	pRet = NULL;
2078 
2079 	if( xStorage.is() )
2080 	{
2081 		if( rStreamInfo.maUserData.Len() &&
2082 			( rStreamInfo.maUserData.GetToken( 0, ':' ) ==
2083 			  String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
2084 		{
2085 			const String aPicturePath( rStreamInfo.maUserData.GetToken( 1, ':' ) );
2086 
2087 			// graphic from picture stream in picture storage in XML package
2088 			if( aPicturePath.GetTokenCount( '/' ) == 2 )
2089 			{
2090 				const String aPictureStreamName( aPicturePath.GetToken( 1, '/' ) );
2091 				const String aPictureStorageName( aPicturePath.GetToken( 0, '/' ) );
2092 
2093 				try {
2094 					if ( xStorage->isStorageElement( aPictureStorageName ) )
2095 					{
2096 						uno::Reference< embed::XStorage > xPictureStorage =
2097                                     xStorage->openStorageElement( aPictureStorageName, embed::ElementModes::READ );
2098 
2099 						if( xPictureStorage.is() &&
2100 							xPictureStorage->isStreamElement( aPictureStreamName ) )
2101 						{
2102 							uno::Reference< io::XStream > xStream =
2103                                 xPictureStorage->openStreamElement( aPictureStreamName, embed::ElementModes::READ );
2104 							if ( xStream.is() )
2105 								pRet = ::utl::UcbStreamHelper::CreateStream( xStream );
2106 						}
2107 					}
2108 				}
2109 				catch( uno::Exception& )
2110 				{
2111 					// TODO: error handling
2112 				}
2113 			}
2114 		}
2115 		// the following code seems to be related to binary format
2116 //REMOVE			else
2117 //REMOVE			{
2118 //REMOVE				pRet = pStor->OpenStream( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_SCSTREAM)),
2119 //REMOVE										  STREAM_READ | STREAM_WRITE | STREAM_TRUNC );
2120 //REMOVE
2121 //REMOVE				if( pRet )
2122 //REMOVE				{
2123 //REMOVE					pRet->SetVersion( pStor->GetVersion() );
2124 //REMOVE					pRet->SetKey( pStor->GetKey() );
2125 //REMOVE				}
2126 //REMOVE			}
2127 
2128 		rStreamInfo.mbDeleteAfterUse = ( pRet != NULL );
2129 	}
2130 
2131 	return pRet;
2132 }
2133 
2134 //REMOVE	void ScDrawLayer::ReleasePictureStorage()
2135 //REMOVE	{
2136 //REMOVE		xPictureStorage.Clear();
2137 //REMOVE	}
2138 
GetControlExportLayerId(const SdrObject &) const2139 SdrLayerID __EXPORT ScDrawLayer::GetControlExportLayerId( const SdrObject & ) const
2140 {
2141 	//	Layer fuer Export von Form-Controls in Versionen vor 5.0 - immer SC_LAYER_FRONT
2142 	return SC_LAYER_FRONT;
2143 }
2144 
createUnoModel()2145 ::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > ScDrawLayer::createUnoModel()
2146 {
2147 	::com::sun::star::uno::Reference< ::com::sun::star::uno::XInterface > xRet;
2148 	if( pDoc && pDoc->GetDocumentShell() )
2149 		xRet = pDoc->GetDocumentShell()->GetModel();
2150 
2151 	return xRet;
2152 }
2153