1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: drwlayer.cxx,v $
10 * $Revision: 1.55.128.8 $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sc.hxx"
33 #include <com/sun/star/uno/Reference.hxx>
34 #include <com/sun/star/embed/XEmbeddedObject.hpp>
35 #include <com/sun/star/embed/XVisualObject.hpp>
36 #include <com/sun/star/embed/XClassifiedObject.hpp>
37 #include <com/sun/star/embed/XComponentSupplier.hpp>
38 #include <com/sun/star/embed/EmbedStates.hpp>
39 #include <com/sun/star/embed/ElementModes.hpp>
40 #include <com/sun/star/embed/NoVisualAreaSizeException.hpp>
41 #include <com/sun/star/datatransfer/XTransferable.hpp>
43 // INCLUDE ---------------------------------------------------------------
45 #include "scitems.hxx"
46 #include <svx/eeitem.hxx>
47 #include <svx/frmdiritem.hxx>
48 #include <sot/exchange.hxx>
49 #include <svx/objfac3d.hxx>
50 #include <svx/xtable.hxx>
51 #include <svx/svdoutl.hxx>
52 #include <svx/svditer.hxx>
53 #include <svx/svdocapt.hxx>
54 #include <svx/svdocirc.hxx>
55 #include <svx/svdoedge.hxx>
56 #include <svx/svdograf.hxx>
57 #include <svx/svdoole2.hxx>
58 #include <svx/svdundo.hxx>
59 #include <svx/unolingu.hxx>
60 #include <svx/drawitem.hxx>
61 #include <svx/fhgtitem.hxx>
62 #include <svx/scriptspaceitem.hxx>
63 #include <svx/shapepropertynotifier.hxx>
64 #include <sfx2/viewsh.hxx>
65 #include <sfx2/docfile.hxx>
66 #include <sot/storage.hxx>
67 #include <svtools/pathoptions.hxx>
68 #include <svtools/itempool.hxx>
69 #include <vcl/virdev.hxx>
70 #include <vcl/svapp.hxx>
71 #include <unotools/ucbstreamhelper.hxx>
73 #include "drwlayer.hxx"
74 #include "drawpage.hxx"
76 #include "document.hxx"
77 #include "rechead.hxx"
78 #include "userdat.hxx"
79 #include "markdata.hxx"
80 #include "globstr.hrc"
82 #include "chartarr.hxx"
86 #ifndef _SV_FIELD_HXX //autogen
87 #include <vcl/field.hxx>
90 #define DET_ARROW_OFFSET 1000
92 // Abstand zur naechsten Zelle beim Loeschen (bShrink), damit der Anker
93 // immer an der richtigen Zelle angezeigt wird
94 //#define SHRINK_DIST 3
95 // und noch etwas mehr, damit das Objekt auch sichtbar in der Zelle liegt
96 #define SHRINK_DIST 25
98 #define SHRINK_DIST_TWIPS 15
100 using namespace ::com::sun::star
;
102 // STATIC DATA -----------------------------------------------------------
104 TYPEINIT1(ScTabDeletedHint
, SfxHint
);
105 TYPEINIT1(ScTabSizeChangedHint
, SfxHint
);
107 static ScDrawObjFactory
* pFac
= NULL
;
108 static E3dObjFactory
* pF3d
= NULL
;
109 static USHORT nInst
= 0;
111 SfxObjectShell
* ScDrawLayer::pGlobalDrawPersist
= NULL
;
112 //REMOVE SvPersist* ScDrawLayer::pGlobalDrawPersist = NULL;
114 BOOL bDrawIsInUndo
= FALSE
; //! Member
116 // -----------------------------------------------------------------------
118 ScUndoObjData::ScUndoObjData( SdrObject
* pObjP
, const ScAddress
& rOS
, const ScAddress
& rOE
,
119 const ScAddress
& rNS
, const ScAddress
& rNE
) :
120 SdrUndoObj( *pObjP
),
128 __EXPORT
ScUndoObjData::~ScUndoObjData()
132 void ScUndoObjData::Undo()
134 ScDrawObjData
* pData
= ScDrawLayer::GetObjData( pObj
);
135 DBG_ASSERT(pData
,"ScUndoObjData: Daten nicht da");
138 pData
->maStart
= aOldStt
;
139 pData
->maEnd
= aOldEnd
;
143 void __EXPORT
ScUndoObjData::Redo()
145 ScDrawObjData
* pData
= ScDrawLayer::GetObjData( pObj
);
146 DBG_ASSERT(pData
,"ScUndoObjData: Daten nicht da");
149 pData
->maStart
= aNewStt
;
150 pData
->maEnd
= aNewEnd
;
154 // -----------------------------------------------------------------------
156 ScTabDeletedHint::ScTabDeletedHint( SCTAB nTabNo
) :
161 __EXPORT
ScTabDeletedHint::~ScTabDeletedHint()
165 ScTabSizeChangedHint::ScTabSizeChangedHint( SCTAB nTabNo
) :
170 __EXPORT
ScTabSizeChangedHint::~ScTabSizeChangedHint()
174 // -----------------------------------------------------------------------
176 #define MAXMM 10000000
178 inline long TwipsToHmm (long nVal
)
180 return static_cast< long >( MetricField::ConvertDoubleValue (static_cast<sal_Int64
>(nVal
), 0, 0,
181 FUNIT_TWIP
, FUNIT_100TH_MM
) );
184 inline long HmmToTwips (long nVal
)
186 return static_cast< long > ( MetricField::ConvertDoubleValue (static_cast<sal_Int64
>(nVal
), 0, 0,
187 FUNIT_100TH_MM
, FUNIT_TWIP
) );
190 inline void TwipsToMM( long& nVal
)
192 nVal
= TwipsToHmm (nVal
);
195 inline void ReverseTwipsToMM( long& nVal
)
197 nVal
= HmmToTwips (nVal
);
200 void lcl_TwipsToMM( Point
& rPoint
)
202 TwipsToMM( rPoint
.X() );
203 TwipsToMM( rPoint
.Y() );
206 void lcl_ReverseTwipsToMM( Point
& rPoint
)
208 ReverseTwipsToMM( rPoint
.X() );
209 ReverseTwipsToMM( rPoint
.Y() );
212 void lcl_ReverseTwipsToMM( Rectangle
& rRect
)
214 ReverseTwipsToMM( rRect
.Left() );
215 ReverseTwipsToMM( rRect
.Right() );
216 ReverseTwipsToMM( rRect
.Top() );
217 ReverseTwipsToMM( rRect
.Bottom() );
220 // -----------------------------------------------------------------------
223 ScDrawLayer::ScDrawLayer( ScDocument
* pDocument
, const String
& rName
) :
224 FmFormModel( SvtPathOptions().GetPalettePath(),
225 NULL
, // SfxItemPool* Pool
228 ( pDocument
? pDocument
->GetDocumentShell() : NULL
),
229 TRUE
), // bUseExtColorTable (is set below)
234 bAdjustEnabled( TRUE
),
235 bHyphenatorSet( FALSE
)
237 pGlobalDrawPersist
= NULL
; // nur einmal benutzen
239 SfxObjectShell
* pObjSh
= pDocument
? pDocument
->GetDocumentShell() : NULL
;
242 SetObjectShell( pObjSh
);
245 SvxColorTableItem
* pColItem
= (SvxColorTableItem
*) pObjSh
->GetItem( SID_COLOR_TABLE
);
246 XColorTable
* pXCol
= pColItem
? pColItem
->GetColorTable() : XColorTable::GetStdColorTable();
247 SetColorTable( pXCol
);
250 SetColorTable( XColorTable::GetStdColorTable() );
252 SetSwapGraphics(TRUE
);
253 // SetSwapAsynchron(TRUE); // an der View
255 SetScaleUnit(MAP_100TH_MM
);
256 SfxItemPool
& rPool
= GetItemPool();
257 rPool
.SetDefaultMetric(SFX_MAPUNIT_100TH_MM
);
258 SvxFrameDirectionItem
aModeItem( FRMDIR_ENVIRONMENT
, EE_PARA_WRITINGDIR
);
259 rPool
.SetPoolDefaultItem( aModeItem
);
262 // Set shadow distance defaults as PoolDefaultItems. Details see bug.
263 rPool
.SetPoolDefaultItem(SdrShadowXDistItem(300));
264 rPool
.SetPoolDefaultItem(SdrShadowYDistItem(300));
266 // #111216# default for script spacing depends on locale, see SdDrawDocument ctor in sd
267 LanguageType eOfficeLanguage
= Application::GetSettings().GetLanguage();
268 if ( eOfficeLanguage
== LANGUAGE_KOREAN
|| eOfficeLanguage
== LANGUAGE_KOREAN_JOHAB
||
269 eOfficeLanguage
== LANGUAGE_JAPANESE
)
271 // secondary is edit engine pool
272 rPool
.GetSecondaryPool()->SetPoolDefaultItem( SvxScriptSpaceItem( FALSE
, EE_PARA_ASIANCJKSPACING
) );
275 rPool
.FreezeIdRanges(); // the pool is also used directly
277 SdrLayerAdmin
& rAdmin
= GetLayerAdmin();
278 rAdmin
.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("vorne")), SC_LAYER_FRONT
);
279 rAdmin
.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hinten")), SC_LAYER_BACK
);
280 rAdmin
.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("intern")), SC_LAYER_INTERN
);
281 rAdmin
.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("Controls")), SC_LAYER_CONTROLS
);
282 rAdmin
.NewLayer(String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM("hidden")), SC_LAYER_HIDDEN
);
283 // "Controls" is new - must also be created when loading
285 // Link fuer URL-Fields setzen
286 ScModule
* pScMod
= SC_MOD();
287 Outliner
& rOutliner
= GetDrawOutliner();
288 rOutliner
.SetCalcFieldValueHdl( LINK( pScMod
, ScModule
, CalcFieldValueHdl
) );
290 Outliner
& rHitOutliner
= GetHitTestOutliner();
291 rHitOutliner
.SetCalcFieldValueHdl( LINK( pScMod
, ScModule
, CalcFieldValueHdl
) );
293 // #95129# SJ: set FontHeight pool defaults without changing static SdrEngineDefaults
294 SfxItemPool
* pOutlinerPool
= rOutliner
.GetEditTextObjectPool();
296 pItemPool
->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT
)); // 12Pt
297 SfxItemPool
* pHitOutlinerPool
= rHitOutliner
.GetEditTextObjectPool();
298 if ( pHitOutlinerPool
)
299 pHitOutlinerPool
->SetPoolDefaultItem(SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT
)); // 12Pt
301 // URL-Buttons haben keinen Handler mehr, machen alles selber
305 pFac
= new ScDrawObjFactory
;
306 pF3d
= new E3dObjFactory
;
310 __EXPORT
ScDrawLayer::~ScDrawLayer()
312 Broadcast(SdrHint(HINT_MODELCLEARED
));
316 ClearModel(sal_True
);
321 delete pFac
, pFac
= NULL
;
322 delete pF3d
, pF3d
= NULL
;
326 void ScDrawLayer::UseHyphenator()
330 com::sun::star::uno::Reference
< com::sun::star::linguistic2::XHyphenator
>
331 xHyphenator
= LinguMgr::GetHyphenator();
333 GetDrawOutliner().SetHyphenator( xHyphenator
);
334 GetHitTestOutliner().SetHyphenator( xHyphenator
);
336 bHyphenatorSet
= TRUE
;
340 SdrPage
* __EXPORT
ScDrawLayer::AllocPage(FASTBOOL bMasterPage
)
342 // don't create basic until it is needed
343 StarBASIC
* pBasic
= NULL
;
344 ScDrawPage
* pPage
= new ScDrawPage( *this, pBasic
, sal::static_int_cast
<BOOL
>(bMasterPage
) );
348 BOOL
ScDrawLayer::HasObjects() const
352 USHORT nCount
= GetPageCount();
353 for (USHORT i
=0; i
<nCount
&& !bFound
; i
++)
354 if (GetPage(i
)->GetObjCount())
360 void ScDrawLayer::UpdateBasic()
362 // don't create basic until it is needed
363 //! remove this method?
366 SdrModel
* __EXPORT
ScDrawLayer::AllocModel() const
368 // #103849# Allocated model (for clipboard etc) must not have a pointer
369 // to the original model's document, pass NULL as document:
371 return new ScDrawLayer( NULL
, aName
);
374 Window
* __EXPORT
ScDrawLayer::GetCurDocViewWin()
376 DBG_ASSERT( pDoc
, "ScDrawLayer::GetCurDocViewWin without document" );
380 SfxViewShell
* pViewSh
= SfxViewShell::Current();
381 SfxObjectShell
* pObjSh
= pDoc
->GetDocumentShell();
383 if (pViewSh
&& pViewSh
->GetObjectShell() == pObjSh
)
384 return pViewSh
->GetWindow();
389 BOOL
ScDrawLayer::ScAddPage( SCTAB nTab
)
392 return FALSE
; // not inserted
394 ScDrawPage
* pPage
= (ScDrawPage
*)AllocPage( FALSE
);
395 InsertPage(pPage
, static_cast<sal_uInt16
>(nTab
));
397 AddCalcUndo(new SdrUndoNewPage(*pPage
));
399 return TRUE
; // inserted
402 void ScDrawLayer::ScRemovePage( SCTAB nTab
)
407 Broadcast( ScTabDeletedHint( nTab
) );
410 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
411 AddCalcUndo(new SdrUndoDelPage(*pPage
)); // Undo-Action wird Owner der Page
412 RemovePage( static_cast<sal_uInt16
>(nTab
) ); // nur austragen, nicht loeschen
415 DeletePage( static_cast<sal_uInt16
>(nTab
) ); // einfach weg damit
418 void ScDrawLayer::ScRenamePage( SCTAB nTab
, const String
& rNewName
)
420 ScDrawPage
* pPage
= (ScDrawPage
*) GetPage(static_cast<sal_uInt16
>(nTab
));
422 pPage
->SetName(rNewName
);
425 void ScDrawLayer::ScMovePage( USHORT nOldPos
, USHORT nNewPos
)
427 MovePage( nOldPos
, nNewPos
);
430 void ScDrawLayer::ScCopyPage( USHORT nOldPos
, USHORT nNewPos
, BOOL bAlloc
)
432 //! remove argument bAlloc (always FALSE)
437 SdrPage
* pOldPage
= GetPage(nOldPos
);
438 SdrPage
* pNewPage
= bAlloc
? AllocPage(FALSE
) : GetPage(nNewPos
);
442 if (pOldPage
&& pNewPage
)
444 SdrObjListIter
aIter( *pOldPage
, IM_FLAT
);
445 SdrObject
* pOldObject
= aIter
.Next();
449 SdrObject
* pNewObject
= pOldObject
->Clone();
450 //SdrObject* pNewObject = pOldObject->Clone( pNewPage, this );
451 pNewObject
->SetModel(this);
452 pNewObject
->SetPage(pNewPage
);
454 pNewObject
->NbcMove(Size(0,0));
455 pNewPage
->InsertObject( pNewObject
);
457 AddCalcUndo( new SdrUndoInsertObj( *pNewObject
) );
459 pOldObject
= aIter
.Next();
464 InsertPage(pNewPage
, nNewPos
);
467 inline BOOL
IsInBlock( const ScAddress
& rPos
, SCCOL nCol1
,SCROW nRow1
, SCCOL nCol2
,SCROW nRow2
)
469 return rPos
.Col() >= nCol1
&& rPos
.Col() <= nCol2
&&
470 rPos
.Row() >= nRow1
&& rPos
.Row() <= nRow2
;
473 void ScDrawLayer::MoveCells( SCTAB nTab
, SCCOL nCol1
,SCROW nRow1
, SCCOL nCol2
,SCROW nRow2
,
474 SCsCOL nDx
,SCsROW nDy
)
476 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
477 DBG_ASSERT(pPage
,"Page nicht gefunden");
481 BOOL bNegativePage
= pDoc
&& pDoc
->IsNegativePage( nTab
);
483 ULONG nCount
= pPage
->GetObjCount();
484 for ( ULONG i
= 0; i
< nCount
; i
++ )
486 SdrObject
* pObj
= pPage
->GetObj( i
);
487 ScDrawObjData
* pData
= GetObjDataTab( pObj
, nTab
);
490 const ScAddress aOldStt
= pData
->maStart
;
491 const ScAddress aOldEnd
= pData
->maEnd
;
492 BOOL bChange
= FALSE
;
493 if ( aOldStt
.IsValid() && IsInBlock( aOldStt
, nCol1
,nRow1
, nCol2
,nRow2
) )
495 pData
->maStart
.IncCol( nDx
);
496 pData
->maStart
.IncRow( nDy
);
499 if ( aOldEnd
.IsValid() && IsInBlock( aOldEnd
, nCol1
,nRow1
, nCol2
,nRow2
) )
501 pData
->maEnd
.IncCol( nDx
);
502 pData
->maEnd
.IncRow( nDy
);
507 if ( pObj
->ISA( SdrRectObj
) && pData
->maStart
.IsValid() && pData
->maEnd
.IsValid() )
508 pData
->maStart
.PutInOrder( pData
->maEnd
);
509 AddCalcUndo( new ScUndoObjData( pObj
, aOldStt
, aOldEnd
, pData
->maStart
, pData
->maEnd
) );
510 RecalcPos( pObj
, *pData
, bNegativePage
);
516 void ScDrawLayer::SetPageSize( USHORT nPageNo
, const Size
& rSize
)
518 SdrPage
* pPage
= GetPage(nPageNo
);
521 if ( rSize
!= pPage
->GetSize() )
523 pPage
->SetSize( rSize
);
524 Broadcast( ScTabSizeChangedHint( static_cast<SCTAB
>(nPageNo
) ) ); // SetWorkArea() an den Views
527 // Detektivlinien umsetzen (an neue Hoehen/Breiten anpassen)
528 // auch wenn Groesse gleich geblieben ist
529 // (einzelne Zeilen/Spalten koennen geaendert sein)
531 BOOL bNegativePage
= pDoc
&& pDoc
->IsNegativePage( static_cast<SCTAB
>(nPageNo
) );
533 ULONG nCount
= pPage
->GetObjCount();
534 for ( ULONG i
= 0; i
< nCount
; i
++ )
536 SdrObject
* pObj
= pPage
->GetObj( i
);
537 ScDrawObjData
* pData
= GetObjDataTab( pObj
, static_cast<SCTAB
>(nPageNo
) );
539 RecalcPos( pObj
, *pData
, bNegativePage
);
544 void ScDrawLayer::RecalcPos( SdrObject
* pObj
, const ScDrawObjData
& rData
, bool bNegativePage
)
546 DBG_ASSERT( pDoc
, "ScDrawLayer::RecalcPos - missing document" );
550 /* TODO CleanUp: Updating note position works just by chance currently...
551 When inserting rows/columns, this function is called after the
552 insertion, and the note is located at the new position contained in the
553 passed ScDrawObjData already. But when deleting rows/columns, this
554 function is called *before* the deletion, so the note is still at the
555 old cell position, and ScDocument::GetNote() will fail to get the note
556 or will get another note. But after the rows/columns are deleted, a
557 call to ScDrawLayer::SetPageSize() will call this function again, and
558 now the note is at the expected position in the document. */
561 DBG_ASSERT( rData
.maStart
.IsValid(), "ScDrawLayer::RecalcPos - invalid position for cell note" );
562 /* When inside an undo action, there may be pending note captions
563 where cell note is already deleted. The caption will be deleted
564 later with drawing undo. */
565 if( ScPostIt
* pNote
= pDoc
->GetNote( rData
.maStart
) )
566 pNote
->UpdateCaptionPos( rData
.maStart
);
570 bool bValid1
= rData
.maStart
.IsValid();
571 SCCOL nCol1
= rData
.maStart
.Col();
572 SCROW nRow1
= rData
.maStart
.Row();
573 SCTAB nTab1
= rData
.maStart
.Tab();
574 bool bValid2
= rData
.maEnd
.IsValid();
575 SCCOL nCol2
= rData
.maEnd
.Col();
576 SCROW nRow2
= rData
.maEnd
.Row();
577 SCTAB nTab2
= rData
.maEnd
.Tab();
580 bool bCircle
= pObj
->ISA( SdrCircObj
);
582 bool bArrow
= pObj
->IsPolyObj() && (pObj
->GetPointCount() == 2);
586 Point
aPos( pDoc
->GetColOffset( nCol1
, nTab1
), pDoc
->GetRowOffset( nRow1
, nTab1
) );
587 TwipsToMM( aPos
.X() );
588 TwipsToMM( aPos
.Y() );
590 // Berechnung und Werte wie in detfunc.cxx
592 Size
aSize( (long)( TwipsToHmm( pDoc
->GetColWidth( nCol1
, nTab1
) ) ),
593 (long)( TwipsToHmm( pDoc
->GetRowHeight( nRow1
, nTab1
) ) ) );
594 Rectangle
aRect( aPos
, aSize
);
596 aRect
.Right() += 250;
598 aRect
.Bottom() += 70;
600 MirrorRectRTL( aRect
);
602 if ( pObj
->GetLogicRect() != aRect
)
605 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
606 pObj
->SetLogicRect(aRect
);
611 //! nicht mehrere Undos fuer ein Objekt erzeugen (hinteres kann dann weggelassen werden)
615 Point
aPos( pDoc
->GetColOffset( nCol1
, nTab1
), pDoc
->GetRowOffset( nRow1
, nTab1
) );
616 if( (pDoc
->GetColFlags( nCol1
, nTab1
) & CR_HIDDEN
) == 0 )
617 aPos
.X() += pDoc
->GetColWidth( nCol1
, nTab1
) / 4;
618 if( (pDoc
->GetRowFlags( nRow1
, nTab1
) & CR_HIDDEN
) == 0 )
619 aPos
.Y() += pDoc
->GetRowHeight( nRow1
, nTab1
) / 2;
620 TwipsToMM( aPos
.X() );
621 TwipsToMM( aPos
.Y() );
622 Point aStartPos
= aPos
;
624 aStartPos
.X() = -aStartPos
.X(); // don't modify aPos - used below
625 if ( pObj
->GetPoint( 0 ) != aStartPos
)
628 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
629 pObj
->SetPoint( aStartPos
, 0 );
634 Point
aEndPos( aPos
.X() + DET_ARROW_OFFSET
, aPos
.Y() - DET_ARROW_OFFSET
);
636 aEndPos
.Y() += (2 * DET_ARROW_OFFSET
);
638 aEndPos
.X() = -aEndPos
.X();
639 if ( pObj
->GetPoint( 1 ) != aEndPos
)
642 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
643 pObj
->SetPoint( aEndPos
, 1 );
649 Point
aPos( pDoc
->GetColOffset( nCol2
, nTab2
), pDoc
->GetRowOffset( nRow2
, nTab2
) );
650 if( (pDoc
->GetColFlags( nCol2
, nTab2
) & CR_HIDDEN
) == 0 )
651 aPos
.X() += pDoc
->GetColWidth( nCol2
, nTab2
) / 4;
652 if( (pDoc
->GetRowFlags( nRow2
, nTab2
) & CR_HIDDEN
) == 0 )
653 aPos
.Y() += pDoc
->GetRowHeight( nRow2
, nTab2
) / 2;
654 TwipsToMM( aPos
.X() );
655 TwipsToMM( aPos
.Y() );
656 Point aEndPos
= aPos
;
658 aEndPos
.X() = -aEndPos
.X(); // don't modify aPos - used below
659 if ( pObj
->GetPoint( 1 ) != aEndPos
)
662 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
663 pObj
->SetPoint( aEndPos
, 1 );
668 Point
aStartPos( aPos
.X() - DET_ARROW_OFFSET
, aPos
.Y() - DET_ARROW_OFFSET
);
669 if (aStartPos
.X() < 0)
670 aStartPos
.X() += (2 * DET_ARROW_OFFSET
);
671 if (aStartPos
.Y() < 0)
672 aStartPos
.Y() += (2 * DET_ARROW_OFFSET
);
674 aStartPos
.X() = -aStartPos
.X();
675 if ( pObj
->GetPoint( 0 ) != aStartPos
)
678 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
679 pObj
->SetPoint( aStartPos
, 0 );
684 else // Referenz-Rahmen
686 DBG_ASSERT( bValid1
, "ScDrawLayer::RecalcPos - invalid start position" );
687 Point
aPos( pDoc
->GetColOffset( nCol1
, nTab1
), pDoc
->GetRowOffset( nRow1
, nTab1
) );
688 TwipsToMM( aPos
.X() );
689 TwipsToMM( aPos
.Y() );
693 Point
aEnd( pDoc
->GetColOffset( nCol2
+ 1, nTab2
), pDoc
->GetRowOffset( nRow2
+ 1, nTab2
) );
694 TwipsToMM( aEnd
.X() );
695 TwipsToMM( aEnd
.Y() );
697 Rectangle
aNew( aPos
, aEnd
);
699 MirrorRectRTL( aNew
);
700 if ( pObj
->GetLogicRect() != aNew
)
703 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
704 pObj
->SetLogicRect(aNew
);
710 aPos
.X() = -aPos
.X();
711 if ( pObj
->GetRelativePos() != aPos
)
714 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
715 pObj
->SetRelativePos( aPos
);
721 BOOL
ScDrawLayer::GetPrintArea( ScRange
& rRange
, BOOL bSetHor
, BOOL bSetVer
) const
723 DBG_ASSERT( pDoc
, "ScDrawLayer::GetPrintArea without document" );
727 SCTAB nTab
= rRange
.aStart
.Tab();
728 DBG_ASSERT( rRange
.aEnd
.Tab() == nTab
, "GetPrintArea: Tab unterschiedlich" );
730 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
735 long nStartX
= LONG_MAX
;
736 long nStartY
= LONG_MAX
;
738 // Grenzen ausrechnen
743 SCCOL nStartCol
= rRange
.aStart
.Col();
745 for (i
=0; i
<nStartCol
; i
++)
746 nStartX
+=pDoc
->GetColWidth(i
,nTab
);
748 SCCOL nEndCol
= rRange
.aEnd
.Col();
749 for (i
=nStartCol
; i
<=nEndCol
; i
++)
750 nEndX
+= pDoc
->GetColWidth(i
,nTab
);
751 nStartX
= TwipsToHmm( nStartX
);
752 nEndX
= TwipsToHmm( nEndX
);
756 nStartY
= pDoc
->FastGetRowHeight( 0, rRange
.aStart
.Row()-1, nTab
);
757 nEndY
= nStartY
+ pDoc
->FastGetRowHeight( rRange
.aStart
.Row(),
758 rRange
.aEnd
.Row(), nTab
);
759 nStartY
= TwipsToHmm( nStartY
);
760 nEndY
= TwipsToHmm( nEndY
);
765 nStartX
= -nStartX
; // positions are negative, swap start/end so the same comparisons work
767 ::std::swap( nStartX
, nEndX
);
770 const SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
771 DBG_ASSERT(pPage
,"Page nicht gefunden");
774 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
775 SdrObject
* pObject
= aIter
.Next();
778 //! Flags (ausgeblendet?) testen
780 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
782 if ( !bSetHor
&& ( aObjRect
.Right() < nStartX
|| aObjRect
.Left() > nEndX
) )
784 if ( !bSetVer
&& ( aObjRect
.Bottom() < nStartY
|| aObjRect
.Top() > nEndY
) )
790 if (aObjRect
.Left() < nStartX
) nStartX
= aObjRect
.Left();
791 if (aObjRect
.Right() > nEndX
) nEndX
= aObjRect
.Right();
795 if (aObjRect
.Top() < nStartY
) nStartY
= aObjRect
.Top();
796 if (aObjRect
.Bottom() > nEndY
) nEndY
= aObjRect
.Bottom();
801 pObject
= aIter
.Next();
807 nStartX
= -nStartX
; // reverse transformation, so the same cell address calculation works
809 ::std::swap( nStartX
, nEndX
);
814 DBG_ASSERT( nStartX
<=nEndX
&& nStartY
<=nEndY
, "Start/End falsch in ScDrawLayer::GetPrintArea" );
818 nStartX
= HmmToTwips( nStartX
);
819 nEndX
= HmmToTwips( nEndX
);
824 for (i
=0; i
<=MAXCOL
&& nWidth
<=nStartX
; i
++)
825 nWidth
+= pDoc
->GetColWidth(i
,nTab
);
826 rRange
.aStart
.SetCol( i
>0 ? (i
-1) : 0 );
829 for (i
=0; i
<=MAXCOL
&& nWidth
<=nEndX
; i
++) //! bei Start anfangen
830 nWidth
+= pDoc
->GetColWidth(i
,nTab
);
831 rRange
.aEnd
.SetCol( i
>0 ? (i
-1) : 0 );
836 nStartY
= HmmToTwips( nStartY
);
837 nEndY
= HmmToTwips( nEndY
);
838 SCROW nRow
= pDoc
->FastGetRowForHeight( nTab
, nStartY
);
839 rRange
.aStart
.SetRow( nRow
>0 ? (nRow
-1) : 0);
840 nRow
= pDoc
->FastGetRowForHeight( nTab
, nEndY
);
841 rRange
.aEnd
.SetRow( nRow
== MAXROW
? MAXROW
:
842 (nRow
>0 ? (nRow
-1) : 0));
849 rRange
.aStart
.SetCol(0);
850 rRange
.aEnd
.SetCol(0);
854 rRange
.aStart
.SetRow(0);
855 rRange
.aEnd
.SetRow(0);
861 void ScDrawLayer::AddCalcUndo( SdrUndoAction
* pUndo
)
866 pUndoGroup
= new SdrUndoGroup(*this);
868 pUndoGroup
->AddAction( pUndo
);
874 void ScDrawLayer::BeginCalcUndo()
876 //! DBG_ASSERT( !bRecording, "BeginCalcUndo ohne GetCalcUndo" );
882 SdrUndoGroup
* ScDrawLayer::GetCalcUndo()
884 //! DBG_ASSERT( bRecording, "GetCalcUndo ohne BeginCalcUndo" );
886 SdrUndoGroup
* pRet
= pUndoGroup
;
892 // MoveAreaTwips: all measures are kept in twips
893 void ScDrawLayer::MoveAreaTwips( SCTAB nTab
, const Rectangle
& rArea
,
894 const Point
& rMove
, const Point
& rTopLeft
)
896 if (!rMove
.X() && !rMove
.Y())
899 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
900 DBG_ASSERT(pPage
,"Page nicht gefunden");
904 BOOL bNegativePage
= pDoc
&& pDoc
->IsNegativePage( nTab
);
907 Rectangle
aNew( rArea
);
908 BOOL bShrink
= FALSE
;
909 if ( rMove
.X() < 0 || rMove
.Y() < 0 ) // verkleinern
911 if ( rTopLeft
!= rArea
.TopLeft() ) // sind gleich beim Verschieben von Zellen
914 aNew
.Left() = rTopLeft
.X();
915 aNew
.Top() = rTopLeft
.Y();
918 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
919 SdrObject
* pObject
= aIter
.Next();
922 if( GetAnchor( pObject
) == SCA_CELL
)
924 if ( GetObjData( pObject
) ) // Detektiv-Pfeil ?
928 else if ( pObject
->ISA( SdrEdgeObj
) ) // Verbinder?
931 //! nicht verbundene Enden wie bei Linien (s.u.) behandeln?
933 else if ( pObject
->IsPolyObj() && pObject
->GetPointCount()==2 )
935 for (USHORT i
=0; i
<2; i
++)
938 Point aPoint
= pObject
->GetPoint(i
);
939 lcl_ReverseTwipsToMM( aPoint
);
940 if (rArea
.IsInside(aPoint
))
942 aPoint
+= rMove
; bMoved
= TRUE
;
944 else if (bShrink
&& aNew
.IsInside(aPoint
))
946 // Punkt ist in betroffener Zelle - Test auf geloeschten Bereich
947 if ( rMove
.X() && aPoint
.X() >= rArea
.Left() + rMove
.X() )
949 aPoint
.X() = rArea
.Left() + rMove
.X() - SHRINK_DIST_TWIPS
;
950 if ( aPoint
.X() < 0 ) aPoint
.X() = 0;
953 if ( rMove
.Y() && aPoint
.Y() >= rArea
.Top() + rMove
.Y() )
955 aPoint
.Y() = rArea
.Top() + rMove
.Y() - SHRINK_DIST_TWIPS
;
956 if ( aPoint
.Y() < 0 ) aPoint
.Y() = 0;
962 AddCalcUndo( new SdrUndoGeoObj( *pObject
) );
963 lcl_TwipsToMM( aPoint
);
964 pObject
->SetPoint( aPoint
, i
);
970 Rectangle aObjRect
= pObject
->GetLogicRect();
971 // aOldMMPos: not converted, millimeters
972 Point aOldMMPos
= bNegativePage
? aObjRect
.TopRight() : aObjRect
.TopLeft();
973 lcl_ReverseTwipsToMM( aObjRect
);
974 Point aTopLeft
= bNegativePage
? aObjRect
.TopRight() : aObjRect
.TopLeft(); // logical left
976 BOOL bDoMove
= FALSE
;
977 if (rArea
.IsInside(aTopLeft
))
979 aMoveSize
= Size(rMove
.X(),rMove
.Y());
982 else if (bShrink
&& aNew
.IsInside(aTopLeft
))
984 // Position ist in betroffener Zelle - Test auf geloeschten Bereich
985 if ( rMove
.X() && aTopLeft
.X() >= rArea
.Left() + rMove
.X() )
987 aMoveSize
.Width() = rArea
.Left() + rMove
.X() - SHRINK_DIST
- aTopLeft
.X();
990 if ( rMove
.Y() && aTopLeft
.Y() >= rArea
.Top() + rMove
.Y() )
992 aMoveSize
.Height() = rArea
.Top() + rMove
.Y() - SHRINK_DIST
- aTopLeft
.Y();
1000 if ( aTopLeft
.X() + aMoveSize
.Width() > 0 )
1001 aMoveSize
.Width() = -aTopLeft
.X();
1005 if ( aTopLeft
.X() + aMoveSize
.Width() < 0 )
1006 aMoveSize
.Width() = -aTopLeft
.X();
1008 if ( aTopLeft
.Y() + aMoveSize
.Height() < 0 )
1009 aMoveSize
.Height() = -aTopLeft
.Y();
1011 // get corresponding move size in millimeters:
1012 Point
aNewPos( aTopLeft
.X() + aMoveSize
.Width(), aTopLeft
.Y() + aMoveSize
.Height() );
1013 lcl_TwipsToMM( aNewPos
);
1014 aMoveSize
= Size( aNewPos
.X() - aOldMMPos
.X(), aNewPos
.Y() - aOldMMPos
.Y() ); // millimeters
1016 AddCalcUndo( new SdrUndoMoveObj( *pObject
, aMoveSize
) );
1017 pObject
->Move( aMoveSize
);
1019 else if ( rArea
.IsInside( bNegativePage
? aObjRect
.BottomLeft() : aObjRect
.BottomRight() ) &&
1020 !pObject
->IsResizeProtect() )
1022 // geschuetzte Groessen werden nicht veraendert
1023 // (Positionen schon, weil sie ja an der Zelle "verankert" sind)
1024 AddCalcUndo( new SdrUndoGeoObj( *pObject
) );
1025 long nOldSizeX
= aObjRect
.Right() - aObjRect
.Left() + 1;
1026 long nOldSizeY
= aObjRect
.Bottom() - aObjRect
.Top() + 1;
1027 long nLogMoveX
= rMove
.X() * ( bNegativePage
? -1 : 1 ); // logical direction
1028 pObject
->Resize( aOldMMPos
, Fraction( nOldSizeX
+nLogMoveX
, nOldSizeX
),
1029 Fraction( nOldSizeY
+rMove
.Y(), nOldSizeY
) );
1033 pObject
= aIter
.Next();
1037 void ScDrawLayer::MoveArea( SCTAB nTab
, SCCOL nCol1
,SCROW nRow1
, SCCOL nCol2
,SCROW nRow2
,
1038 SCsCOL nDx
,SCsROW nDy
, BOOL bInsDel
)
1040 DBG_ASSERT( pDoc
, "ScDrawLayer::MoveArea without document" );
1044 if (!bAdjustEnabled
)
1047 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1049 Rectangle aRect
= pDoc
->GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, nTab
);
1050 lcl_ReverseTwipsToMM( aRect
);
1051 //! use twips directly?
1056 for (SCsCOL s
=0; s
<nDx
; s
++)
1057 aMove
.X() += pDoc
->GetColWidth(s
+(SCsCOL
)nCol1
,nTab
);
1059 for (SCsCOL s
=-1; s
>=nDx
; s
--)
1060 aMove
.X() -= pDoc
->GetColWidth(s
+(SCsCOL
)nCol1
,nTab
);
1062 aMove
.Y() += pDoc
->FastGetRowHeight( nRow1
, nRow1
+nDy
-1, nTab
);
1064 aMove
.Y() -= pDoc
->FastGetRowHeight( nRow1
+nDy
, nRow1
-1, nTab
);
1066 if ( bNegativePage
)
1067 aMove
.X() = -aMove
.X();
1069 Point aTopLeft
= aRect
.TopLeft(); // Anfang beim Verkleinern
1072 if ( aMove
.X() != 0 && nDx
< 0 ) // nDx counts cells, sign is independent of RTL
1073 aTopLeft
.X() += aMove
.X();
1074 if ( aMove
.Y() < 0 )
1075 aTopLeft
.Y() += aMove
.Y();
1078 // drawing objects are now directly included in cut&paste
1079 // -> only update references when inserting/deleting (or changing widths or heights)
1081 MoveAreaTwips( nTab
, aRect
, aMove
, aTopLeft
);
1084 // Detektiv-Pfeile: Zellpositionen anpassen
1087 MoveCells( nTab
, nCol1
,nRow1
, nCol2
,nRow2
, nDx
,nDy
);
1090 void ScDrawLayer::WidthChanged( SCTAB nTab
, SCCOL nCol
, long nDifTwips
)
1092 DBG_ASSERT( pDoc
, "ScDrawLayer::WidthChanged without document" );
1096 if (!bAdjustEnabled
)
1102 for (SCCOL i
=0; i
<nCol
; i
++)
1103 aRect
.Left() += pDoc
->GetColWidth(i
,nTab
);
1104 aTopLeft
.X() = aRect
.Left();
1105 aRect
.Left() += pDoc
->GetColWidth(nCol
,nTab
);
1107 aRect
.Right() = MAXMM
;
1109 aRect
.Bottom() = MAXMM
;
1111 //! aTopLeft ist falsch, wenn mehrere Spalten auf einmal ausgeblendet werden
1113 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1114 if ( bNegativePage
)
1116 MirrorRectRTL( aRect
);
1117 aTopLeft
.X() = -aTopLeft
.X();
1118 nDifTwips
= -nDifTwips
;
1121 MoveAreaTwips( nTab
, aRect
, Point( nDifTwips
,0 ), aTopLeft
);
1124 void ScDrawLayer::HeightChanged( SCTAB nTab
, SCROW nRow
, long nDifTwips
)
1126 DBG_ASSERT( pDoc
, "ScDrawLayer::HeightChanged without document" );
1130 if (!bAdjustEnabled
)
1136 aRect
.Top() += pDoc
->FastGetRowHeight( 0, nRow
-1, nTab
);
1137 aTopLeft
.Y() = aRect
.Top();
1138 aRect
.Top() += pDoc
->FastGetRowHeight(nRow
,nTab
);
1140 aRect
.Bottom() = MAXMM
;
1142 aRect
.Right() = MAXMM
;
1144 //! aTopLeft ist falsch, wenn mehrere Zeilen auf einmal ausgeblendet werden
1146 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1147 if ( bNegativePage
)
1149 MirrorRectRTL( aRect
);
1150 aTopLeft
.X() = -aTopLeft
.X();
1153 MoveAreaTwips( nTab
, aRect
, Point( 0,nDifTwips
), aTopLeft
);
1156 BOOL
ScDrawLayer::HasObjectsInRows( SCTAB nTab
, SCROW nStartRow
, SCROW nEndRow
)
1158 DBG_ASSERT( pDoc
, "ScDrawLayer::HasObjectsInRows without document" );
1162 Rectangle aTestRect
;
1164 aTestRect
.Top() += pDoc
->FastGetRowHeight( 0, nStartRow
-1, nTab
);
1166 if (nEndRow
==MAXROW
)
1167 aTestRect
.Bottom() = MAXMM
;
1170 aTestRect
.Bottom() = aTestRect
.Top();
1171 aTestRect
.Bottom() += pDoc
->FastGetRowHeight( nStartRow
, nEndRow
, nTab
);
1172 TwipsToMM( aTestRect
.Bottom() );
1175 TwipsToMM( aTestRect
.Top() );
1177 aTestRect
.Left() = 0;
1178 aTestRect
.Right() = MAXMM
;
1180 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1181 if ( bNegativePage
)
1182 MirrorRectRTL( aTestRect
);
1184 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1185 DBG_ASSERT(pPage
,"Page nicht gefunden");
1189 BOOL bFound
= FALSE
;
1192 SdrObjListIter
aIter( *pPage
);
1193 SdrObject
* pObject
= aIter
.Next();
1194 while ( pObject
&& !bFound
)
1196 aObjRect
= pObject
->GetSnapRect(); //! GetLogicRect ?
1197 if (aTestRect
.IsInside(aObjRect
.TopLeft()) || aTestRect
.IsInside(aObjRect
.BottomLeft()))
1200 pObject
= aIter
.Next();
1207 void ScDrawLayer::DeleteObjects( SCTAB nTab
)
1209 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1210 DBG_ASSERT(pPage
,"Page ?");
1214 pPage
->RecalcObjOrdNums();
1217 ULONG nObjCount
= pPage
->GetObjCount();
1220 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1222 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1223 SdrObject
* pObject
= aIter
.Next();
1227 ppObj
[nDelCount
++] = pObject
;
1228 pObject
= aIter
.Next();
1233 for (i
=1; i
<=nDelCount
; i
++)
1234 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1236 for (i
=1; i
<=nDelCount
; i
++)
1237 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1244 void ScDrawLayer::DeleteObjectsInArea( SCTAB nTab
, SCCOL nCol1
,SCROW nRow1
,
1245 SCCOL nCol2
,SCROW nRow2
)
1247 DBG_ASSERT( pDoc
, "ScDrawLayer::DeleteObjectsInArea without document" );
1251 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1252 DBG_ASSERT(pPage
,"Page ?");
1256 pPage
->RecalcObjOrdNums();
1259 ULONG nObjCount
= pPage
->GetObjCount();
1262 Rectangle aDelRect
= pDoc
->GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, nTab
);
1264 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1266 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1267 SdrObject
* pObject
= aIter
.Next();
1270 // do not delete note caption, they are always handled by the cell note
1271 // TODO: detective objects are still deleted, is this desired?
1272 if (!IsNoteCaption( pObject
))
1274 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
1275 if ( aDelRect
.IsInside( aObjRect
) )
1276 ppObj
[nDelCount
++] = pObject
;
1279 pObject
= aIter
.Next();
1284 for (i
=1; i
<=nDelCount
; i
++)
1285 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1287 for (i
=1; i
<=nDelCount
; i
++)
1288 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1294 void ScDrawLayer::DeleteObjectsInSelection( const ScMarkData
& rMark
)
1296 DBG_ASSERT( pDoc
, "ScDrawLayer::DeleteObjectsInSelection without document" );
1300 if ( !rMark
.IsMultiMarked() )
1304 rMark
.GetMultiMarkArea( aMarkRange
);
1306 SCTAB nTabCount
= pDoc
->GetTableCount();
1307 for (SCTAB nTab
=0; nTab
<=nTabCount
; nTab
++)
1308 if ( rMark
.GetTableSelect( nTab
) )
1310 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1313 pPage
->RecalcObjOrdNums();
1315 ULONG nObjCount
= pPage
->GetObjCount();
1318 // Rechteck um die ganze Selektion
1319 Rectangle aMarkBound
= pDoc
->GetMMRect(
1320 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
1321 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(), nTab
);
1323 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1325 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1326 SdrObject
* pObject
= aIter
.Next();
1329 // do not delete note caption, they are always handled by the cell note
1330 // TODO: detective objects are still deleted, is this desired?
1331 if (!IsNoteCaption( pObject
))
1333 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
1334 if ( aMarkBound
.IsInside( aObjRect
) )
1336 ScRange aRange
= pDoc
->GetRange( nTab
, aObjRect
);
1337 if (rMark
.IsAllMarked(aRange
))
1338 ppObj
[nDelCount
++] = pObject
;
1342 pObject
= aIter
.Next();
1345 // Objekte loeschen (rueckwaerts)
1349 for (i
=1; i
<=nDelCount
; i
++)
1350 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1352 for (i
=1; i
<=nDelCount
; i
++)
1353 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1360 DBG_ERROR("pPage?");
1365 void ScDrawLayer::CopyToClip( ScDocument
* pClipDoc
, SCTAB nTab
, const Rectangle
& rRange
)
1367 // copy everything in the specified range into the same page (sheet) in the clipboard doc
1369 SdrPage
* pSrcPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1372 ScDrawLayer
* pDestModel
= NULL
;
1373 SdrPage
* pDestPage
= NULL
;
1375 SdrObjListIter
aIter( *pSrcPage
, IM_FLAT
);
1376 SdrObject
* pOldObject
= aIter
.Next();
1379 Rectangle aObjRect
= pOldObject
->GetCurrentBoundRect();
1380 // do not copy internal objects (detective) and note captions
1381 if ( rRange
.IsInside( aObjRect
) && (pOldObject
->GetLayer() != SC_LAYER_INTERN
) && !IsNoteCaption( pOldObject
) )
1385 pDestModel
= pClipDoc
->GetDrawLayer(); // does the document already have a drawing layer?
1388 // allocate drawing layer in clipboard document only if there are objects to copy
1390 pClipDoc
->InitDrawLayer(); //! create contiguous pages
1391 pDestModel
= pClipDoc
->GetDrawLayer();
1394 pDestPage
= pDestModel
->GetPage( static_cast<sal_uInt16
>(nTab
) );
1397 DBG_ASSERT( pDestPage
, "no page" );
1401 SdrObject
* pNewObject
= pOldObject
->Clone();
1402 //SdrObject* pNewObject = pOldObject->Clone( pDestPage, pDestModel );
1403 pNewObject
->SetModel(pDestModel
);
1404 pNewObject
->SetPage(pDestPage
);
1406 pNewObject
->NbcMove(Size(0,0));
1407 pDestPage
->InsertObject( pNewObject
);
1409 // no undo needed in clipboard document
1410 // charts are not updated
1414 pOldObject
= aIter
.Next();
1419 BOOL
lcl_IsAllInRange( const ScRangeList
& rRanges
, const ScRange
& rClipRange
)
1421 // check if every range of rRanges is completely in rClipRange
1423 ULONG nCount
= rRanges
.Count();
1424 for (ULONG i
=0; i
<nCount
; i
++)
1426 ScRange aRange
= *rRanges
.GetObject(i
);
1427 if ( !rClipRange
.In( aRange
) )
1429 return FALSE
; // at least one range is not valid
1433 return TRUE
; // everything is fine
1436 BOOL
lcl_MoveRanges( ScRangeList
& rRanges
, const ScRange
& rSourceRange
, const ScAddress
& rDestPos
)
1438 BOOL bChanged
= FALSE
;
1440 ULONG nCount
= rRanges
.Count();
1441 for (ULONG i
=0; i
<nCount
; i
++)
1443 ScRange
* pRange
= rRanges
.GetObject(i
);
1444 if ( rSourceRange
.In( *pRange
) )
1446 SCsCOL nDiffX
= rDestPos
.Col() - (SCsCOL
)rSourceRange
.aStart
.Col();
1447 SCsROW nDiffY
= rDestPos
.Row() - (SCsROW
)rSourceRange
.aStart
.Row();
1448 SCsTAB nDiffZ
= rDestPos
.Tab() - (SCsTAB
)rSourceRange
.aStart
.Tab();
1449 pRange
->Move( nDiffX
, nDiffY
, nDiffZ
);
1457 void ScDrawLayer::CopyFromClip( ScDrawLayer
* pClipModel
, SCTAB nSourceTab
, const Rectangle
& rSourceRange
,
1458 const ScAddress
& rDestPos
, const Rectangle
& rDestRange
)
1460 DBG_ASSERT( pDoc
, "ScDrawLayer::CopyFromClip without document" );
1467 if (bDrawIsInUndo
) //! can this happen?
1469 DBG_ERROR("CopyFromClip, bDrawIsInUndo");
1473 BOOL bMirrorObj
= ( rSourceRange
.Left() < 0 && rSourceRange
.Right() < 0 &&
1474 rDestRange
.Left() > 0 && rDestRange
.Right() > 0 ) ||
1475 ( rSourceRange
.Left() > 0 && rSourceRange
.Right() > 0 &&
1476 rDestRange
.Left() < 0 && rDestRange
.Right() < 0 );
1477 Rectangle aMirroredSource
= rSourceRange
;
1479 MirrorRectRTL( aMirroredSource
);
1481 SCTAB nDestTab
= rDestPos
.Tab();
1483 SdrPage
* pSrcPage
= pClipModel
->GetPage(static_cast<sal_uInt16
>(nSourceTab
));
1484 SdrPage
* pDestPage
= GetPage(static_cast<sal_uInt16
>(nDestTab
));
1485 DBG_ASSERT( pSrcPage
&& pDestPage
, "draw page missing" );
1486 if ( !pSrcPage
|| !pDestPage
)
1489 // first mirror, then move
1490 Size
aMove( rDestRange
.Left() - aMirroredSource
.Left(), rDestRange
.Top() - aMirroredSource
.Top() );
1492 long nDestWidth
= rDestRange
.GetWidth();
1493 long nDestHeight
= rDestRange
.GetHeight();
1494 long nSourceWidth
= rSourceRange
.GetWidth();
1495 long nSourceHeight
= rSourceRange
.GetHeight();
1497 long nWidthDiff
= nDestWidth
- nSourceWidth
;
1498 long nHeightDiff
= nDestHeight
- nSourceHeight
;
1500 Fraction
aHorFract(1,1);
1501 Fraction
aVerFract(1,1);
1502 BOOL bResize
= FALSE
;
1503 // sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
1504 // don't resize to empty size when pasting into hidden columns or rows
1505 if ( Abs(nWidthDiff
) > 1 && nDestWidth
> 1 && nSourceWidth
> 1 )
1507 aHorFract
= Fraction( nDestWidth
, nSourceWidth
);
1510 if ( Abs(nHeightDiff
) > 1 && nDestHeight
> 1 && nSourceHeight
> 1 )
1512 aVerFract
= Fraction( nDestHeight
, nSourceHeight
);
1515 Point aRefPos
= rDestRange
.TopLeft(); // for resizing (after moving)
1517 SdrObjListIter
aIter( *pSrcPage
, IM_FLAT
);
1518 SdrObject
* pOldObject
= aIter
.Next();
1521 Rectangle aObjRect
= pOldObject
->GetCurrentBoundRect();
1522 // do not copy internal objects (detective) and note captions
1523 if ( rSourceRange
.IsInside( aObjRect
) && (pOldObject
->GetLayer() != SC_LAYER_INTERN
) && !IsNoteCaption( pOldObject
) )
1526 SdrObject
* pNewObject
= pOldObject
->Clone();
1527 //SdrObject* pNewObject = pOldObject->Clone( pDestPage, this );
1528 pNewObject
->SetModel(this);
1529 pNewObject
->SetPage(pDestPage
);
1532 MirrorRTL( pNewObject
); // first mirror, then move
1534 pNewObject
->NbcMove( aMove
);
1536 pNewObject
->NbcResize( aRefPos
, aHorFract
, aVerFract
);
1538 pDestPage
->InsertObject( pNewObject
);
1540 AddCalcUndo( new SdrUndoInsertObj( *pNewObject
) );
1542 // handle chart data references (after InsertObject)
1544 if ( pNewObject
->GetObjIdentifier() == OBJ_OLE2
)
1546 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pNewObject
)->GetObjRef();
1547 uno::Reference
< embed::XClassifiedObject
> xClassified( xIPObj
, uno::UNO_QUERY
);
1548 SvGlobalName aObjectClassName
;
1549 if ( xClassified
.is() )
1552 aObjectClassName
= SvGlobalName( xClassified
->getClassID() );
1553 } catch( uno::Exception
& )
1555 // TODO: handle error?
1559 if ( xIPObj
.is() && SotExchange::IsChart( aObjectClassName
) )
1561 String aNewName
= ((SdrOle2Obj
*)pNewObject
)->GetPersistName();
1563 //! need to set new DataProvider, or does Chart handle this itself?
1565 ScRangeListRef
xRanges( new ScRangeList
);
1566 BOOL bColHeaders
= FALSE
;
1567 BOOL bRowHeaders
= FALSE
;
1568 pDoc
->GetOldChartParameters( aNewName
, *xRanges
, bColHeaders
, bRowHeaders
);
1570 if ( xRanges
->Count() > 0 )
1572 ScDocument
* pClipDoc
= pClipModel
->GetDocument();
1574 // a clipboard document and its source share the same document item pool,
1575 // so the pointers can be compared to see if this is copy&paste within
1576 // the same document
1577 BOOL bSameDoc
= pDoc
&& pClipDoc
&& pDoc
->GetPool() == pClipDoc
->GetPool();
1579 BOOL bDestClip
= pDoc
&& pDoc
->IsClipboard();
1581 BOOL bInSourceRange
= FALSE
;
1589 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
1590 pClipDoc
->GetClipArea( nClipEndX
, nClipEndY
, TRUE
);
1591 nClipEndX
= nClipEndX
+ nClipStartX
;
1592 nClipEndY
+= nClipStartY
; // GetClipArea returns the difference
1594 aClipRange
= ScRange( nClipStartX
, nClipStartY
, nSourceTab
,
1595 nClipEndX
, nClipEndY
, nSourceTab
);
1597 bInSourceRange
= lcl_IsAllInRange( *xRanges
, aClipRange
);
1600 // always lose references when pasting into a clipboard document (transpose)
1601 if ( ( bInSourceRange
|| bSameDoc
) && !bDestClip
)
1603 if ( bInSourceRange
)
1605 if ( rDestPos
!= aClipRange
.aStart
)
1607 // update the data ranges to the new (copied) position
1608 ScRangeListRef xNewRanges
= new ScRangeList( *xRanges
);
1609 if ( lcl_MoveRanges( *xNewRanges
, aClipRange
, rDestPos
) )
1611 pDoc
->UpdateChartArea( aNewName
, xNewRanges
, bColHeaders
, bRowHeaders
, FALSE
);
1617 // leave the ranges unchanged
1622 // pasting into a new document without the complete source data
1623 // -> break connection to source data
1625 // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
1627 //! need chart interface to switch to own data
1634 pOldObject
= aIter
.Next();
1638 void ScDrawLayer::MirrorRTL( SdrObject
* pObj
)
1640 UINT16 nIdent
= pObj
->GetObjIdentifier();
1642 // don't mirror OLE or graphics, otherwise ask the object
1643 // if it can be mirrored
1644 BOOL bCanMirror
= ( nIdent
!= OBJ_GRAF
&& nIdent
!= OBJ_OLE2
);
1647 SdrObjTransformInfoRec aInfo
;
1648 pObj
->TakeObjInfo( aInfo
);
1649 bCanMirror
= aInfo
.bMirror90Allowed
;
1654 Point
aRef1( 0, 0 );
1655 Point
aRef2( 0, 1 );
1657 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
1658 pObj
->Mirror( aRef1
, aRef2
);
1662 // Move instead of mirroring:
1663 // New start position is negative of old end position
1664 // -> move by sum of start and end position
1665 Rectangle aObjRect
= pObj
->GetLogicRect();
1666 Size
aMoveSize( -(aObjRect
.Left() + aObjRect
.Right()), 0 );
1668 AddCalcUndo( new SdrUndoMoveObj( *pObj
, aMoveSize
) );
1669 pObj
->Move( aMoveSize
);
1674 void ScDrawLayer::MirrorRectRTL( Rectangle
& rRect
)
1676 // mirror and swap left/right
1677 long nTemp
= rRect
.Left();
1678 rRect
.Left() = -rRect
.Right();
1679 rRect
.Right() = -nTemp
;
1682 Rectangle
ScDrawLayer::GetCellRect( ScDocument
& rDoc
, const ScAddress
& rPos
, bool bMergedCell
)
1684 Rectangle aCellRect
;
1685 DBG_ASSERT( ValidColRowTab( rPos
.Col(), rPos
.Row(), rPos
.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
1686 if( ValidColRowTab( rPos
.Col(), rPos
.Row(), rPos
.Tab() ) )
1688 // find top left position of passed cell address
1690 for( SCCOL nCol
= 0; nCol
< rPos
.Col(); ++nCol
)
1691 aTopLeft
.X() += rDoc
.GetColWidth( nCol
, rPos
.Tab() );
1692 if( rPos
.Row() > 0 )
1693 aTopLeft
.Y() += rDoc
.FastGetRowHeight( 0, rPos
.Row() - 1, rPos
.Tab() );
1695 // find bottom-right position of passed cell address
1696 ScAddress aEndPos
= rPos
;
1699 const ScMergeAttr
* pMerge
= static_cast< const ScMergeAttr
* >( rDoc
.GetAttr( rPos
.Col(), rPos
.Row(), rPos
.Tab(), ATTR_MERGE
) );
1700 if( pMerge
->GetColMerge() > 1 )
1701 aEndPos
.IncCol( pMerge
->GetColMerge() - 1 );
1702 if( pMerge
->GetRowMerge() > 1 )
1703 aEndPos
.IncRow( pMerge
->GetRowMerge() - 1 );
1705 Point aBotRight
= aTopLeft
;
1706 for( SCCOL nCol
= rPos
.Col(); nCol
<= aEndPos
.Col(); ++nCol
)
1707 aBotRight
.X() += rDoc
.GetColWidth( nCol
, rPos
.Tab() );
1708 aBotRight
.Y() += rDoc
.FastGetRowHeight( rPos
.Row(), aEndPos
.Row(), rPos
.Tab() );
1710 // twips -> 1/100 mm
1711 aTopLeft
.X() = static_cast< long >( aTopLeft
.X() * HMM_PER_TWIPS
);
1712 aTopLeft
.Y() = static_cast< long >( aTopLeft
.Y() * HMM_PER_TWIPS
);
1713 aBotRight
.X() = static_cast< long >( aBotRight
.X() * HMM_PER_TWIPS
);
1714 aBotRight
.Y() = static_cast< long >( aBotRight
.Y() * HMM_PER_TWIPS
);
1716 aCellRect
= Rectangle( aTopLeft
, aBotRight
);
1717 if( rDoc
.IsNegativePage( rPos
.Tab() ) )
1718 MirrorRectRTL( aCellRect
);
1724 String
ScDrawLayer::GetVisibleName( SdrObject
* pObj
)
1726 String aName
= pObj
->GetName();
1727 if ( pObj
->GetObjIdentifier() == OBJ_OLE2
)
1729 // #95575# For OLE, the user defined name (GetName) is used
1730 // if it's not empty (accepting possibly duplicate names),
1731 // otherwise the persist name is used so every object appears
1732 // in the Navigator at all.
1735 aName
= static_cast<SdrOle2Obj
*>(pObj
)->GetPersistName();
1740 inline sal_Bool
IsNamedObject( SdrObject
* pObj
, const String
& rName
)
1742 // TRUE if rName is the object's Name or PersistName
1743 // (used to find a named object)
1745 return ( pObj
->GetName() == rName
||
1746 ( pObj
->GetObjIdentifier() == OBJ_OLE2
&&
1747 static_cast<SdrOle2Obj
*>(pObj
)->GetPersistName() == rName
) );
1750 SdrObject
* ScDrawLayer::GetNamedObject( const String
& rName
, USHORT nId
, SCTAB
& rFoundTab
) const
1752 sal_uInt16 nTabCount
= GetPageCount();
1753 for (sal_uInt16 nTab
=0; nTab
<nTabCount
; nTab
++)
1755 const SdrPage
* pPage
= GetPage(nTab
);
1756 DBG_ASSERT(pPage
,"Page ?");
1759 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
1760 SdrObject
* pObject
= aIter
.Next();
1763 if ( nId
== 0 || pObject
->GetObjIdentifier() == nId
)
1764 if ( IsNamedObject( pObject
, rName
) )
1766 rFoundTab
= static_cast<SCTAB
>(nTab
);
1770 pObject
= aIter
.Next();
1778 String
ScDrawLayer::GetNewGraphicName( long* pnCounter
) const
1780 String aBase
= ScGlobal::GetRscString(STR_GRAPHICNAME
);
1784 String aGraphicName
;
1786 long nId
= pnCounter
? *pnCounter
: 0;
1790 aGraphicName
= aBase
;
1791 aGraphicName
+= String::CreateFromInt32( nId
);
1792 bThere
= ( GetNamedObject( aGraphicName
, 0, nDummy
) != NULL
);
1798 return aGraphicName
;
1801 void ScDrawLayer::EnsureGraphicNames()
1803 // make sure all graphic objects have names (after Excel import etc.)
1805 sal_uInt16 nTabCount
= GetPageCount();
1806 for (sal_uInt16 nTab
=0; nTab
<nTabCount
; nTab
++)
1808 SdrPage
* pPage
= GetPage(nTab
);
1809 DBG_ASSERT(pPage
,"Page ?");
1812 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
1813 SdrObject
* pObject
= aIter
.Next();
1815 /* #101799# The index passed to GetNewGraphicName() will be set to
1816 the used index in each call. This prevents the repeated search
1817 for all names from 1 to current index. */
1822 if ( pObject
->GetObjIdentifier() == OBJ_GRAF
&& pObject
->GetName().Len() == 0 )
1823 pObject
->SetName( GetNewGraphicName( &nCounter
) );
1825 pObject
= aIter
.Next();
1831 void ScDrawLayer::SetAnchor( SdrObject
* pObj
, ScAnchorType eType
)
1833 ScAnchorType eOldAnchorType
= GetAnchor( pObj
);
1835 // Ein an der Seite verankertes Objekt zeichnet sich durch eine Anker-Pos
1836 // von (0,1) aus. Das ist ein shabby Trick, der aber funktioniert!
1837 Point
aAnchor( 0, eType
== SCA_PAGE
? 1 : 0 );
1838 pObj
->SetAnchorPos( aAnchor
);
1840 if ( eOldAnchorType
!= eType
)
1841 pObj
->notifyShapePropertyChange( ::svx::eSpreadsheetAnchor
);
1844 ScAnchorType
ScDrawLayer::GetAnchor( const SdrObject
* pObj
)
1846 Point
aAnchor( pObj
->GetAnchorPos() );
1847 return ( aAnchor
.Y() != 0 ) ? SCA_PAGE
: SCA_CELL
;
1850 ScDrawObjData
* ScDrawLayer::GetObjData( SdrObject
* pObj
, BOOL bCreate
) // static
1852 USHORT nCount
= pObj
? pObj
->GetUserDataCount() : 0;
1853 for( USHORT i
= 0; i
< nCount
; i
++ )
1855 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1856 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1857 && pData
->GetId() == SC_UD_OBJDATA
)
1858 return (ScDrawObjData
*) pData
;
1860 if( pObj
&& bCreate
)
1862 ScDrawObjData
* pData
= new ScDrawObjData
;
1863 pObj
->InsertUserData( pData
, 0 );
1869 ScDrawObjData
* ScDrawLayer::GetObjDataTab( SdrObject
* pObj
, SCTAB nTab
) // static
1871 ScDrawObjData
* pData
= GetObjData( pObj
);
1874 if ( pData
->maStart
.IsValid() )
1875 pData
->maStart
.SetTab( nTab
);
1876 if ( pData
->maEnd
.IsValid() )
1877 pData
->maEnd
.SetTab( nTab
);
1882 bool ScDrawLayer::IsNoteCaption( SdrObject
* pObj
)
1884 ScDrawObjData
* pData
= pObj
? GetObjData( pObj
) : 0;
1885 return pData
&& pData
->mbNote
;
1888 ScDrawObjData
* ScDrawLayer::GetNoteCaptionData( SdrObject
* pObj
, SCTAB nTab
)
1890 ScDrawObjData
* pData
= pObj
? GetObjDataTab( pObj
, nTab
) : 0;
1891 return (pData
&& pData
->mbNote
) ? pData
: 0;
1894 ScIMapInfo
* ScDrawLayer::GetIMapInfo( SdrObject
* pObj
) // static
1896 USHORT nCount
= pObj
->GetUserDataCount();
1897 for( USHORT i
= 0; i
< nCount
; i
++ )
1899 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1900 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1901 && pData
->GetId() == SC_UD_IMAPDATA
)
1902 return (ScIMapInfo
*) pData
;
1908 IMapObject
* ScDrawLayer::GetHitIMapObject( SdrObject
* pObj
,
1909 const Point
& rWinPoint
, const Window
& rCmpWnd
)
1911 const MapMode
aMap100( MAP_100TH_MM
);
1912 MapMode aWndMode
= rCmpWnd
.GetMapMode();
1913 Point
aRelPoint( rCmpWnd
.LogicToLogic( rWinPoint
, &aWndMode
, &aMap100
) );
1914 Rectangle aLogRect
= rCmpWnd
.LogicToLogic( pObj
->GetLogicRect(), &aWndMode
, &aMap100
);
1915 ScIMapInfo
* pIMapInfo
= GetIMapInfo( pObj
);
1916 IMapObject
* pIMapObj
= NULL
;
1921 ImageMap
& rImageMap
= (ImageMap
&) pIMapInfo
->GetImageMap();
1923 BOOL bObjSupported
= FALSE
;
1925 if ( pObj
->ISA( SdrGrafObj
) ) // einfaches Grafik-Objekt
1927 const SdrGrafObj
* pGrafObj
= (const SdrGrafObj
*) pObj
;
1928 const GeoStat
& rGeo
= pGrafObj
->GetGeoStat();
1929 const Graphic
& rGraphic
= pGrafObj
->GetGraphic();
1931 // Drehung rueckgaengig
1932 if ( rGeo
.nDrehWink
)
1933 RotatePoint( aRelPoint
, aLogRect
.TopLeft(), -rGeo
.nSin
, rGeo
.nCos
);
1935 // Spiegelung rueckgaengig
1936 if ( ( (const SdrGrafObjGeoData
*) pGrafObj
->GetGeoData() )->bMirrored
)
1937 aRelPoint
.X() = aLogRect
.Right() + aLogRect
.Left() - aRelPoint
.X();
1940 if ( rGeo
.nShearWink
)
1941 ShearPoint( aRelPoint
, aLogRect
.TopLeft(), -rGeo
.nTan
);
1944 if ( rGraphic
.GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
1945 aGraphSize
= rCmpWnd
.PixelToLogic( rGraphic
.GetPrefSize(),
1948 aGraphSize
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(),
1949 rGraphic
.GetPrefMapMode(),
1952 bObjSupported
= TRUE
;
1954 else if ( pObj
->ISA( SdrOle2Obj
) ) // OLE-Objekt
1956 // TODO/LEAN: working with visual area needs running state
1957 aGraphSize
= ((SdrOle2Obj
*)pObj
)->GetOrigObjSize();
1958 bObjSupported
= TRUE
;
1961 // hat alles geklappt, dann HitTest ausfuehren
1962 if ( bObjSupported
)
1964 // relativen Mauspunkt berechnen
1965 aRelPoint
-= aLogRect
.TopLeft();
1966 pIMapObj
= rImageMap
.GetHitIMapObject( aGraphSize
, aLogRect
.GetSize(), aRelPoint
);
1973 ScMacroInfo
* ScDrawLayer::GetMacroInfo( SdrObject
* pObj
, BOOL bCreate
) // static
1975 USHORT nCount
= pObj
->GetUserDataCount();
1976 for( USHORT i
= 0; i
< nCount
; i
++ )
1978 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1979 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1980 && pData
->GetId() == SC_UD_MACRODATA
)
1981 return (ScMacroInfo
*) pData
;
1985 ScMacroInfo
* pData
= new ScMacroInfo
;
1986 pObj
->InsertUserData( pData
, 0 );
1992 void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell
* pPersist
) // static
1994 DBG_ASSERT(!pGlobalDrawPersist
,"SetGlobalDrawPersist mehrfach");
1995 pGlobalDrawPersist
= pPersist
;
1998 void __EXPORT
ScDrawLayer::SetChanged( sal_Bool bFlg
/* = sal_True */ )
2001 pDoc
->SetChartListenerCollectionNeedsUpdate( TRUE
);
2002 FmFormModel::SetChanged( bFlg
);
2005 SvStream
* __EXPORT
ScDrawLayer::GetDocumentStream(SdrDocumentStreamInfo
& rStreamInfo
) const
2007 DBG_ASSERT( pDoc
, "ScDrawLayer::GetDocumentStream without document" );
2011 uno::Reference
< embed::XStorage
> xStorage
= pDoc
->GetDocumentShell() ?
2012 pDoc
->GetDocumentShell()->GetStorage() :
2014 SvStream
* pRet
= NULL
;
2018 if( rStreamInfo
.maUserData
.Len() &&
2019 ( rStreamInfo
.maUserData
.GetToken( 0, ':' ) ==
2020 String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
2022 const String
aPicturePath( rStreamInfo
.maUserData
.GetToken( 1, ':' ) );
2024 // graphic from picture stream in picture storage in XML package
2025 if( aPicturePath
.GetTokenCount( '/' ) == 2 )
2027 const String
aPictureStreamName( aPicturePath
.GetToken( 1, '/' ) );
2028 const String
aPictureStorageName( aPicturePath
.GetToken( 0, '/' ) );
2031 if ( xStorage
->isStorageElement( aPictureStorageName
) )
2033 uno::Reference
< embed::XStorage
> xPictureStorage
=
2034 xStorage
->openStorageElement( aPictureStorageName
, embed::ElementModes::READ
);
2036 if( xPictureStorage
.is() &&
2037 xPictureStorage
->isStreamElement( aPictureStreamName
) )
2039 uno::Reference
< io::XStream
> xStream
=
2040 xPictureStorage
->openStreamElement( aPictureStreamName
, embed::ElementModes::READ
);
2042 pRet
= ::utl::UcbStreamHelper::CreateStream( xStream
);
2046 catch( uno::Exception
& )
2048 // TODO: error handling
2052 // the following code seems to be related to binary format
2055 //REMOVE pRet = pStor->OpenStream( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_SCSTREAM)),
2056 //REMOVE STREAM_READ | STREAM_WRITE | STREAM_TRUNC );
2060 //REMOVE pRet->SetVersion( pStor->GetVersion() );
2061 //REMOVE pRet->SetKey( pStor->GetKey() );
2065 rStreamInfo
.mbDeleteAfterUse
= ( pRet
!= NULL
);
2071 //REMOVE void ScDrawLayer::ReleasePictureStorage()
2073 //REMOVE xPictureStorage.Clear();
2076 SdrLayerID __EXPORT
ScDrawLayer::GetControlExportLayerId( const SdrObject
& ) const
2078 // Layer fuer Export von Form-Controls in Versionen vor 5.0 - immer SC_LAYER_FRONT
2079 return SC_LAYER_FRONT
;
2082 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> ScDrawLayer::createUnoModel()
2084 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> xRet
;
2085 if( pDoc
&& pDoc
->GetDocumentShell() )
2086 xRet
= pDoc
->GetDocumentShell()->GetModel();