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)
617 Point
aPos( pDoc
->GetColOffset( nCol1
, nTab1
), pDoc
->GetRowOffset( nRow1
, nTab1
) );
618 if (!pDoc
->ColHidden(nCol1
, nTab1
, nLastCol
))
619 aPos
.X() += pDoc
->GetColWidth( nCol1
, nTab1
) / 4;
620 if (!pDoc
->RowHidden(nRow1
, nTab1
, nLastRow
))
621 aPos
.Y() += pDoc
->GetRowHeight( nRow1
, nTab1
) / 2;
622 TwipsToMM( aPos
.X() );
623 TwipsToMM( aPos
.Y() );
624 Point aStartPos
= aPos
;
626 aStartPos
.X() = -aStartPos
.X(); // don't modify aPos - used below
627 if ( pObj
->GetPoint( 0 ) != aStartPos
)
630 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
631 pObj
->SetPoint( aStartPos
, 0 );
636 Point
aEndPos( aPos
.X() + DET_ARROW_OFFSET
, aPos
.Y() - DET_ARROW_OFFSET
);
638 aEndPos
.Y() += (2 * DET_ARROW_OFFSET
);
640 aEndPos
.X() = -aEndPos
.X();
641 if ( pObj
->GetPoint( 1 ) != aEndPos
)
644 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
645 pObj
->SetPoint( aEndPos
, 1 );
651 Point
aPos( pDoc
->GetColOffset( nCol2
, nTab2
), pDoc
->GetRowOffset( nRow2
, nTab2
) );
652 if (!pDoc
->ColHidden(nCol2
, nTab2
, nLastCol
))
653 aPos
.X() += pDoc
->GetColWidth( nCol2
, nTab2
) / 4;
654 if (!pDoc
->RowHidden(nRow2
, nTab2
, nLastRow
))
655 aPos
.Y() += pDoc
->GetRowHeight( nRow2
, nTab2
) / 2;
656 TwipsToMM( aPos
.X() );
657 TwipsToMM( aPos
.Y() );
658 Point aEndPos
= aPos
;
660 aEndPos
.X() = -aEndPos
.X(); // don't modify aPos - used below
661 if ( pObj
->GetPoint( 1 ) != aEndPos
)
664 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
665 pObj
->SetPoint( aEndPos
, 1 );
670 Point
aStartPos( aPos
.X() - DET_ARROW_OFFSET
, aPos
.Y() - DET_ARROW_OFFSET
);
671 if (aStartPos
.X() < 0)
672 aStartPos
.X() += (2 * DET_ARROW_OFFSET
);
673 if (aStartPos
.Y() < 0)
674 aStartPos
.Y() += (2 * DET_ARROW_OFFSET
);
676 aStartPos
.X() = -aStartPos
.X();
677 if ( pObj
->GetPoint( 0 ) != aStartPos
)
680 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
681 pObj
->SetPoint( aStartPos
, 0 );
686 else // Referenz-Rahmen
688 DBG_ASSERT( bValid1
, "ScDrawLayer::RecalcPos - invalid start position" );
689 Point
aPos( pDoc
->GetColOffset( nCol1
, nTab1
), pDoc
->GetRowOffset( nRow1
, nTab1
) );
690 TwipsToMM( aPos
.X() );
691 TwipsToMM( aPos
.Y() );
695 Point
aEnd( pDoc
->GetColOffset( nCol2
+ 1, nTab2
), pDoc
->GetRowOffset( nRow2
+ 1, nTab2
) );
696 TwipsToMM( aEnd
.X() );
697 TwipsToMM( aEnd
.Y() );
699 Rectangle
aNew( aPos
, aEnd
);
701 MirrorRectRTL( aNew
);
702 if ( pObj
->GetLogicRect() != aNew
)
705 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
706 pObj
->SetLogicRect(aNew
);
712 aPos
.X() = -aPos
.X();
713 if ( pObj
->GetRelativePos() != aPos
)
716 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
717 pObj
->SetRelativePos( aPos
);
723 BOOL
ScDrawLayer::GetPrintArea( ScRange
& rRange
, BOOL bSetHor
, BOOL bSetVer
) const
725 DBG_ASSERT( pDoc
, "ScDrawLayer::GetPrintArea without document" );
729 SCTAB nTab
= rRange
.aStart
.Tab();
730 DBG_ASSERT( rRange
.aEnd
.Tab() == nTab
, "GetPrintArea: Tab unterschiedlich" );
732 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
737 long nStartX
= LONG_MAX
;
738 long nStartY
= LONG_MAX
;
740 // Grenzen ausrechnen
745 SCCOL nStartCol
= rRange
.aStart
.Col();
747 for (i
=0; i
<nStartCol
; i
++)
748 nStartX
+=pDoc
->GetColWidth(i
,nTab
);
750 SCCOL nEndCol
= rRange
.aEnd
.Col();
751 for (i
=nStartCol
; i
<=nEndCol
; i
++)
752 nEndX
+= pDoc
->GetColWidth(i
,nTab
);
753 nStartX
= TwipsToHmm( nStartX
);
754 nEndX
= TwipsToHmm( nEndX
);
758 nStartY
= pDoc
->FastGetRowHeight( 0, rRange
.aStart
.Row()-1, nTab
);
759 nEndY
= nStartY
+ pDoc
->FastGetRowHeight( rRange
.aStart
.Row(),
760 rRange
.aEnd
.Row(), nTab
);
761 nStartY
= TwipsToHmm( nStartY
);
762 nEndY
= TwipsToHmm( nEndY
);
767 nStartX
= -nStartX
; // positions are negative, swap start/end so the same comparisons work
769 ::std::swap( nStartX
, nEndX
);
772 const SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
773 DBG_ASSERT(pPage
,"Page nicht gefunden");
776 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
777 SdrObject
* pObject
= aIter
.Next();
780 //! Flags (ausgeblendet?) testen
782 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
784 if ( !bSetHor
&& ( aObjRect
.Right() < nStartX
|| aObjRect
.Left() > nEndX
) )
786 if ( !bSetVer
&& ( aObjRect
.Bottom() < nStartY
|| aObjRect
.Top() > nEndY
) )
792 if (aObjRect
.Left() < nStartX
) nStartX
= aObjRect
.Left();
793 if (aObjRect
.Right() > nEndX
) nEndX
= aObjRect
.Right();
797 if (aObjRect
.Top() < nStartY
) nStartY
= aObjRect
.Top();
798 if (aObjRect
.Bottom() > nEndY
) nEndY
= aObjRect
.Bottom();
803 pObject
= aIter
.Next();
809 nStartX
= -nStartX
; // reverse transformation, so the same cell address calculation works
811 ::std::swap( nStartX
, nEndX
);
816 DBG_ASSERT( nStartX
<=nEndX
&& nStartY
<=nEndY
, "Start/End falsch in ScDrawLayer::GetPrintArea" );
820 nStartX
= HmmToTwips( nStartX
);
821 nEndX
= HmmToTwips( nEndX
);
826 for (i
=0; i
<=MAXCOL
&& nWidth
<=nStartX
; i
++)
827 nWidth
+= pDoc
->GetColWidth(i
,nTab
);
828 rRange
.aStart
.SetCol( i
>0 ? (i
-1) : 0 );
831 for (i
=0; i
<=MAXCOL
&& nWidth
<=nEndX
; i
++) //! bei Start anfangen
832 nWidth
+= pDoc
->GetColWidth(i
,nTab
);
833 rRange
.aEnd
.SetCol( i
>0 ? (i
-1) : 0 );
838 nStartY
= HmmToTwips( nStartY
);
839 nEndY
= HmmToTwips( nEndY
);
840 SCROW nRow
= pDoc
->FastGetRowForHeight( nTab
, nStartY
);
841 rRange
.aStart
.SetRow( nRow
>0 ? (nRow
-1) : 0);
842 nRow
= pDoc
->FastGetRowForHeight( nTab
, nEndY
);
843 rRange
.aEnd
.SetRow( nRow
== MAXROW
? MAXROW
:
844 (nRow
>0 ? (nRow
-1) : 0));
851 rRange
.aStart
.SetCol(0);
852 rRange
.aEnd
.SetCol(0);
856 rRange
.aStart
.SetRow(0);
857 rRange
.aEnd
.SetRow(0);
863 void ScDrawLayer::AddCalcUndo( SdrUndoAction
* pUndo
)
868 pUndoGroup
= new SdrUndoGroup(*this);
870 pUndoGroup
->AddAction( pUndo
);
876 void ScDrawLayer::BeginCalcUndo()
878 //! DBG_ASSERT( !bRecording, "BeginCalcUndo ohne GetCalcUndo" );
884 SdrUndoGroup
* ScDrawLayer::GetCalcUndo()
886 //! DBG_ASSERT( bRecording, "GetCalcUndo ohne BeginCalcUndo" );
888 SdrUndoGroup
* pRet
= pUndoGroup
;
894 // MoveAreaTwips: all measures are kept in twips
895 void ScDrawLayer::MoveAreaTwips( SCTAB nTab
, const Rectangle
& rArea
,
896 const Point
& rMove
, const Point
& rTopLeft
)
898 if (!rMove
.X() && !rMove
.Y())
901 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
902 DBG_ASSERT(pPage
,"Page nicht gefunden");
906 BOOL bNegativePage
= pDoc
&& pDoc
->IsNegativePage( nTab
);
909 Rectangle
aNew( rArea
);
910 BOOL bShrink
= FALSE
;
911 if ( rMove
.X() < 0 || rMove
.Y() < 0 ) // verkleinern
913 if ( rTopLeft
!= rArea
.TopLeft() ) // sind gleich beim Verschieben von Zellen
916 aNew
.Left() = rTopLeft
.X();
917 aNew
.Top() = rTopLeft
.Y();
920 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
921 SdrObject
* pObject
= aIter
.Next();
924 if( GetAnchor( pObject
) == SCA_CELL
)
926 if ( GetObjData( pObject
) ) // Detektiv-Pfeil ?
930 else if ( pObject
->ISA( SdrEdgeObj
) ) // Verbinder?
933 //! nicht verbundene Enden wie bei Linien (s.u.) behandeln?
935 else if ( pObject
->IsPolyObj() && pObject
->GetPointCount()==2 )
937 for (USHORT i
=0; i
<2; i
++)
940 Point aPoint
= pObject
->GetPoint(i
);
941 lcl_ReverseTwipsToMM( aPoint
);
942 if (rArea
.IsInside(aPoint
))
944 aPoint
+= rMove
; bMoved
= TRUE
;
946 else if (bShrink
&& aNew
.IsInside(aPoint
))
948 // Punkt ist in betroffener Zelle - Test auf geloeschten Bereich
949 if ( rMove
.X() && aPoint
.X() >= rArea
.Left() + rMove
.X() )
951 aPoint
.X() = rArea
.Left() + rMove
.X() - SHRINK_DIST_TWIPS
;
952 if ( aPoint
.X() < 0 ) aPoint
.X() = 0;
955 if ( rMove
.Y() && aPoint
.Y() >= rArea
.Top() + rMove
.Y() )
957 aPoint
.Y() = rArea
.Top() + rMove
.Y() - SHRINK_DIST_TWIPS
;
958 if ( aPoint
.Y() < 0 ) aPoint
.Y() = 0;
964 AddCalcUndo( new SdrUndoGeoObj( *pObject
) );
965 lcl_TwipsToMM( aPoint
);
966 pObject
->SetPoint( aPoint
, i
);
972 Rectangle aObjRect
= pObject
->GetLogicRect();
973 // aOldMMPos: not converted, millimeters
974 Point aOldMMPos
= bNegativePage
? aObjRect
.TopRight() : aObjRect
.TopLeft();
975 lcl_ReverseTwipsToMM( aObjRect
);
976 Point aTopLeft
= bNegativePage
? aObjRect
.TopRight() : aObjRect
.TopLeft(); // logical left
978 BOOL bDoMove
= FALSE
;
979 if (rArea
.IsInside(aTopLeft
))
981 aMoveSize
= Size(rMove
.X(),rMove
.Y());
984 else if (bShrink
&& aNew
.IsInside(aTopLeft
))
986 // Position ist in betroffener Zelle - Test auf geloeschten Bereich
987 if ( rMove
.X() && aTopLeft
.X() >= rArea
.Left() + rMove
.X() )
989 aMoveSize
.Width() = rArea
.Left() + rMove
.X() - SHRINK_DIST
- aTopLeft
.X();
992 if ( rMove
.Y() && aTopLeft
.Y() >= rArea
.Top() + rMove
.Y() )
994 aMoveSize
.Height() = rArea
.Top() + rMove
.Y() - SHRINK_DIST
- aTopLeft
.Y();
1000 if ( bNegativePage
)
1002 if ( aTopLeft
.X() + aMoveSize
.Width() > 0 )
1003 aMoveSize
.Width() = -aTopLeft
.X();
1007 if ( aTopLeft
.X() + aMoveSize
.Width() < 0 )
1008 aMoveSize
.Width() = -aTopLeft
.X();
1010 if ( aTopLeft
.Y() + aMoveSize
.Height() < 0 )
1011 aMoveSize
.Height() = -aTopLeft
.Y();
1013 // get corresponding move size in millimeters:
1014 Point
aNewPos( aTopLeft
.X() + aMoveSize
.Width(), aTopLeft
.Y() + aMoveSize
.Height() );
1015 lcl_TwipsToMM( aNewPos
);
1016 aMoveSize
= Size( aNewPos
.X() - aOldMMPos
.X(), aNewPos
.Y() - aOldMMPos
.Y() ); // millimeters
1018 AddCalcUndo( new SdrUndoMoveObj( *pObject
, aMoveSize
) );
1019 pObject
->Move( aMoveSize
);
1021 else if ( rArea
.IsInside( bNegativePage
? aObjRect
.BottomLeft() : aObjRect
.BottomRight() ) &&
1022 !pObject
->IsResizeProtect() )
1024 // geschuetzte Groessen werden nicht veraendert
1025 // (Positionen schon, weil sie ja an der Zelle "verankert" sind)
1026 AddCalcUndo( new SdrUndoGeoObj( *pObject
) );
1027 long nOldSizeX
= aObjRect
.Right() - aObjRect
.Left() + 1;
1028 long nOldSizeY
= aObjRect
.Bottom() - aObjRect
.Top() + 1;
1029 long nLogMoveX
= rMove
.X() * ( bNegativePage
? -1 : 1 ); // logical direction
1030 pObject
->Resize( aOldMMPos
, Fraction( nOldSizeX
+nLogMoveX
, nOldSizeX
),
1031 Fraction( nOldSizeY
+rMove
.Y(), nOldSizeY
) );
1035 pObject
= aIter
.Next();
1039 void ScDrawLayer::MoveArea( SCTAB nTab
, SCCOL nCol1
,SCROW nRow1
, SCCOL nCol2
,SCROW nRow2
,
1040 SCsCOL nDx
,SCsROW nDy
, BOOL bInsDel
)
1042 DBG_ASSERT( pDoc
, "ScDrawLayer::MoveArea without document" );
1046 if (!bAdjustEnabled
)
1049 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1051 Rectangle aRect
= pDoc
->GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, nTab
);
1052 lcl_ReverseTwipsToMM( aRect
);
1053 //! use twips directly?
1058 for (SCsCOL s
=0; s
<nDx
; s
++)
1059 aMove
.X() += pDoc
->GetColWidth(s
+(SCsCOL
)nCol1
,nTab
);
1061 for (SCsCOL s
=-1; s
>=nDx
; s
--)
1062 aMove
.X() -= pDoc
->GetColWidth(s
+(SCsCOL
)nCol1
,nTab
);
1064 aMove
.Y() += pDoc
->FastGetRowHeight( nRow1
, nRow1
+nDy
-1, nTab
);
1066 aMove
.Y() -= pDoc
->FastGetRowHeight( nRow1
+nDy
, nRow1
-1, nTab
);
1068 if ( bNegativePage
)
1069 aMove
.X() = -aMove
.X();
1071 Point aTopLeft
= aRect
.TopLeft(); // Anfang beim Verkleinern
1074 if ( aMove
.X() != 0 && nDx
< 0 ) // nDx counts cells, sign is independent of RTL
1075 aTopLeft
.X() += aMove
.X();
1076 if ( aMove
.Y() < 0 )
1077 aTopLeft
.Y() += aMove
.Y();
1080 // drawing objects are now directly included in cut&paste
1081 // -> only update references when inserting/deleting (or changing widths or heights)
1083 MoveAreaTwips( nTab
, aRect
, aMove
, aTopLeft
);
1086 // Detektiv-Pfeile: Zellpositionen anpassen
1089 MoveCells( nTab
, nCol1
,nRow1
, nCol2
,nRow2
, nDx
,nDy
);
1092 void ScDrawLayer::WidthChanged( SCTAB nTab
, SCCOL nCol
, long nDifTwips
)
1094 DBG_ASSERT( pDoc
, "ScDrawLayer::WidthChanged without document" );
1098 if (!bAdjustEnabled
)
1104 for (SCCOL i
=0; i
<nCol
; i
++)
1105 aRect
.Left() += pDoc
->GetColWidth(i
,nTab
);
1106 aTopLeft
.X() = aRect
.Left();
1107 aRect
.Left() += pDoc
->GetColWidth(nCol
,nTab
);
1109 aRect
.Right() = MAXMM
;
1111 aRect
.Bottom() = MAXMM
;
1113 //! aTopLeft ist falsch, wenn mehrere Spalten auf einmal ausgeblendet werden
1115 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1116 if ( bNegativePage
)
1118 MirrorRectRTL( aRect
);
1119 aTopLeft
.X() = -aTopLeft
.X();
1120 nDifTwips
= -nDifTwips
;
1123 MoveAreaTwips( nTab
, aRect
, Point( nDifTwips
,0 ), aTopLeft
);
1126 void ScDrawLayer::HeightChanged( SCTAB nTab
, SCROW nRow
, long nDifTwips
)
1128 DBG_ASSERT( pDoc
, "ScDrawLayer::HeightChanged without document" );
1132 if (!bAdjustEnabled
)
1138 aRect
.Top() += pDoc
->FastGetRowHeight( 0, nRow
-1, nTab
);
1139 aTopLeft
.Y() = aRect
.Top();
1140 aRect
.Top() += pDoc
->FastGetRowHeight(nRow
,nTab
);
1142 aRect
.Bottom() = MAXMM
;
1144 aRect
.Right() = MAXMM
;
1146 //! aTopLeft ist falsch, wenn mehrere Zeilen auf einmal ausgeblendet werden
1148 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1149 if ( bNegativePage
)
1151 MirrorRectRTL( aRect
);
1152 aTopLeft
.X() = -aTopLeft
.X();
1155 MoveAreaTwips( nTab
, aRect
, Point( 0,nDifTwips
), aTopLeft
);
1158 BOOL
ScDrawLayer::HasObjectsInRows( SCTAB nTab
, SCROW nStartRow
, SCROW nEndRow
)
1160 DBG_ASSERT( pDoc
, "ScDrawLayer::HasObjectsInRows without document" );
1164 Rectangle aTestRect
;
1166 aTestRect
.Top() += pDoc
->FastGetRowHeight( 0, nStartRow
-1, nTab
);
1168 if (nEndRow
==MAXROW
)
1169 aTestRect
.Bottom() = MAXMM
;
1172 aTestRect
.Bottom() = aTestRect
.Top();
1173 aTestRect
.Bottom() += pDoc
->FastGetRowHeight( nStartRow
, nEndRow
, nTab
);
1174 TwipsToMM( aTestRect
.Bottom() );
1177 TwipsToMM( aTestRect
.Top() );
1179 aTestRect
.Left() = 0;
1180 aTestRect
.Right() = MAXMM
;
1182 BOOL bNegativePage
= pDoc
->IsNegativePage( nTab
);
1183 if ( bNegativePage
)
1184 MirrorRectRTL( aTestRect
);
1186 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1187 DBG_ASSERT(pPage
,"Page nicht gefunden");
1191 BOOL bFound
= FALSE
;
1194 SdrObjListIter
aIter( *pPage
);
1195 SdrObject
* pObject
= aIter
.Next();
1196 while ( pObject
&& !bFound
)
1198 aObjRect
= pObject
->GetSnapRect(); //! GetLogicRect ?
1199 if (aTestRect
.IsInside(aObjRect
.TopLeft()) || aTestRect
.IsInside(aObjRect
.BottomLeft()))
1202 pObject
= aIter
.Next();
1209 void ScDrawLayer::DeleteObjects( SCTAB nTab
)
1211 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1212 DBG_ASSERT(pPage
,"Page ?");
1216 pPage
->RecalcObjOrdNums();
1219 ULONG nObjCount
= pPage
->GetObjCount();
1222 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1224 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1225 SdrObject
* pObject
= aIter
.Next();
1229 ppObj
[nDelCount
++] = pObject
;
1230 pObject
= aIter
.Next();
1235 for (i
=1; i
<=nDelCount
; i
++)
1236 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1238 for (i
=1; i
<=nDelCount
; i
++)
1239 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1246 void ScDrawLayer::DeleteObjectsInArea( SCTAB nTab
, SCCOL nCol1
,SCROW nRow1
,
1247 SCCOL nCol2
,SCROW nRow2
)
1249 DBG_ASSERT( pDoc
, "ScDrawLayer::DeleteObjectsInArea without document" );
1253 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1254 DBG_ASSERT(pPage
,"Page ?");
1258 pPage
->RecalcObjOrdNums();
1261 ULONG nObjCount
= pPage
->GetObjCount();
1264 Rectangle aDelRect
= pDoc
->GetMMRect( nCol1
, nRow1
, nCol2
, nRow2
, nTab
);
1266 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1268 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1269 SdrObject
* pObject
= aIter
.Next();
1272 // do not delete note caption, they are always handled by the cell note
1273 // TODO: detective objects are still deleted, is this desired?
1274 if (!IsNoteCaption( pObject
))
1276 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
1277 if ( aDelRect
.IsInside( aObjRect
) )
1278 ppObj
[nDelCount
++] = pObject
;
1281 pObject
= aIter
.Next();
1286 for (i
=1; i
<=nDelCount
; i
++)
1287 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1289 for (i
=1; i
<=nDelCount
; i
++)
1290 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1296 void ScDrawLayer::DeleteObjectsInSelection( const ScMarkData
& rMark
)
1298 DBG_ASSERT( pDoc
, "ScDrawLayer::DeleteObjectsInSelection without document" );
1302 if ( !rMark
.IsMultiMarked() )
1306 rMark
.GetMultiMarkArea( aMarkRange
);
1308 SCTAB nTabCount
= pDoc
->GetTableCount();
1309 for (SCTAB nTab
=0; nTab
<=nTabCount
; nTab
++)
1310 if ( rMark
.GetTableSelect( nTab
) )
1312 SdrPage
* pPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1315 pPage
->RecalcObjOrdNums();
1317 ULONG nObjCount
= pPage
->GetObjCount();
1320 // Rechteck um die ganze Selektion
1321 Rectangle aMarkBound
= pDoc
->GetMMRect(
1322 aMarkRange
.aStart
.Col(), aMarkRange
.aStart
.Row(),
1323 aMarkRange
.aEnd
.Col(), aMarkRange
.aEnd
.Row(), nTab
);
1325 SdrObject
** ppObj
= new SdrObject
*[nObjCount
];
1327 SdrObjListIter
aIter( *pPage
, IM_FLAT
);
1328 SdrObject
* pObject
= aIter
.Next();
1331 // do not delete note caption, they are always handled by the cell note
1332 // TODO: detective objects are still deleted, is this desired?
1333 if (!IsNoteCaption( pObject
))
1335 Rectangle aObjRect
= pObject
->GetCurrentBoundRect();
1336 if ( aMarkBound
.IsInside( aObjRect
) )
1338 ScRange aRange
= pDoc
->GetRange( nTab
, aObjRect
);
1339 if (rMark
.IsAllMarked(aRange
))
1340 ppObj
[nDelCount
++] = pObject
;
1344 pObject
= aIter
.Next();
1347 // Objekte loeschen (rueckwaerts)
1351 for (i
=1; i
<=nDelCount
; i
++)
1352 AddCalcUndo( new SdrUndoRemoveObj( *ppObj
[nDelCount
-i
] ) );
1354 for (i
=1; i
<=nDelCount
; i
++)
1355 pPage
->RemoveObject( ppObj
[nDelCount
-i
]->GetOrdNum() );
1362 DBG_ERROR("pPage?");
1367 void ScDrawLayer::CopyToClip( ScDocument
* pClipDoc
, SCTAB nTab
, const Rectangle
& rRange
)
1369 // copy everything in the specified range into the same page (sheet) in the clipboard doc
1371 SdrPage
* pSrcPage
= GetPage(static_cast<sal_uInt16
>(nTab
));
1374 ScDrawLayer
* pDestModel
= NULL
;
1375 SdrPage
* pDestPage
= NULL
;
1377 SdrObjListIter
aIter( *pSrcPage
, IM_FLAT
);
1378 SdrObject
* pOldObject
= aIter
.Next();
1381 Rectangle aObjRect
= pOldObject
->GetCurrentBoundRect();
1382 // do not copy internal objects (detective) and note captions
1383 if ( rRange
.IsInside( aObjRect
) && (pOldObject
->GetLayer() != SC_LAYER_INTERN
) && !IsNoteCaption( pOldObject
) )
1387 pDestModel
= pClipDoc
->GetDrawLayer(); // does the document already have a drawing layer?
1390 // allocate drawing layer in clipboard document only if there are objects to copy
1392 pClipDoc
->InitDrawLayer(); //! create contiguous pages
1393 pDestModel
= pClipDoc
->GetDrawLayer();
1396 pDestPage
= pDestModel
->GetPage( static_cast<sal_uInt16
>(nTab
) );
1399 DBG_ASSERT( pDestPage
, "no page" );
1403 SdrObject
* pNewObject
= pOldObject
->Clone();
1404 //SdrObject* pNewObject = pOldObject->Clone( pDestPage, pDestModel );
1405 pNewObject
->SetModel(pDestModel
);
1406 pNewObject
->SetPage(pDestPage
);
1408 pNewObject
->NbcMove(Size(0,0));
1409 pDestPage
->InsertObject( pNewObject
);
1411 // no undo needed in clipboard document
1412 // charts are not updated
1416 pOldObject
= aIter
.Next();
1421 BOOL
lcl_IsAllInRange( const ScRangeList
& rRanges
, const ScRange
& rClipRange
)
1423 // check if every range of rRanges is completely in rClipRange
1425 ULONG nCount
= rRanges
.Count();
1426 for (ULONG i
=0; i
<nCount
; i
++)
1428 ScRange aRange
= *rRanges
.GetObject(i
);
1429 if ( !rClipRange
.In( aRange
) )
1431 return FALSE
; // at least one range is not valid
1435 return TRUE
; // everything is fine
1438 BOOL
lcl_MoveRanges( ScRangeList
& rRanges
, const ScRange
& rSourceRange
, const ScAddress
& rDestPos
)
1440 BOOL bChanged
= FALSE
;
1442 ULONG nCount
= rRanges
.Count();
1443 for (ULONG i
=0; i
<nCount
; i
++)
1445 ScRange
* pRange
= rRanges
.GetObject(i
);
1446 if ( rSourceRange
.In( *pRange
) )
1448 SCsCOL nDiffX
= rDestPos
.Col() - (SCsCOL
)rSourceRange
.aStart
.Col();
1449 SCsROW nDiffY
= rDestPos
.Row() - (SCsROW
)rSourceRange
.aStart
.Row();
1450 SCsTAB nDiffZ
= rDestPos
.Tab() - (SCsTAB
)rSourceRange
.aStart
.Tab();
1451 pRange
->Move( nDiffX
, nDiffY
, nDiffZ
);
1459 void ScDrawLayer::CopyFromClip( ScDrawLayer
* pClipModel
, SCTAB nSourceTab
, const Rectangle
& rSourceRange
,
1460 const ScAddress
& rDestPos
, const Rectangle
& rDestRange
)
1462 DBG_ASSERT( pDoc
, "ScDrawLayer::CopyFromClip without document" );
1469 if (bDrawIsInUndo
) //! can this happen?
1471 DBG_ERROR("CopyFromClip, bDrawIsInUndo");
1475 BOOL bMirrorObj
= ( rSourceRange
.Left() < 0 && rSourceRange
.Right() < 0 &&
1476 rDestRange
.Left() > 0 && rDestRange
.Right() > 0 ) ||
1477 ( rSourceRange
.Left() > 0 && rSourceRange
.Right() > 0 &&
1478 rDestRange
.Left() < 0 && rDestRange
.Right() < 0 );
1479 Rectangle aMirroredSource
= rSourceRange
;
1481 MirrorRectRTL( aMirroredSource
);
1483 SCTAB nDestTab
= rDestPos
.Tab();
1485 SdrPage
* pSrcPage
= pClipModel
->GetPage(static_cast<sal_uInt16
>(nSourceTab
));
1486 SdrPage
* pDestPage
= GetPage(static_cast<sal_uInt16
>(nDestTab
));
1487 DBG_ASSERT( pSrcPage
&& pDestPage
, "draw page missing" );
1488 if ( !pSrcPage
|| !pDestPage
)
1491 // first mirror, then move
1492 Size
aMove( rDestRange
.Left() - aMirroredSource
.Left(), rDestRange
.Top() - aMirroredSource
.Top() );
1494 long nDestWidth
= rDestRange
.GetWidth();
1495 long nDestHeight
= rDestRange
.GetHeight();
1496 long nSourceWidth
= rSourceRange
.GetWidth();
1497 long nSourceHeight
= rSourceRange
.GetHeight();
1499 long nWidthDiff
= nDestWidth
- nSourceWidth
;
1500 long nHeightDiff
= nDestHeight
- nSourceHeight
;
1502 Fraction
aHorFract(1,1);
1503 Fraction
aVerFract(1,1);
1504 BOOL bResize
= FALSE
;
1505 // sizes can differ by 1 from twips->1/100mm conversion for equal cell sizes,
1506 // don't resize to empty size when pasting into hidden columns or rows
1507 if ( Abs(nWidthDiff
) > 1 && nDestWidth
> 1 && nSourceWidth
> 1 )
1509 aHorFract
= Fraction( nDestWidth
, nSourceWidth
);
1512 if ( Abs(nHeightDiff
) > 1 && nDestHeight
> 1 && nSourceHeight
> 1 )
1514 aVerFract
= Fraction( nDestHeight
, nSourceHeight
);
1517 Point aRefPos
= rDestRange
.TopLeft(); // for resizing (after moving)
1519 SdrObjListIter
aIter( *pSrcPage
, IM_FLAT
);
1520 SdrObject
* pOldObject
= aIter
.Next();
1523 Rectangle aObjRect
= pOldObject
->GetCurrentBoundRect();
1524 // do not copy internal objects (detective) and note captions
1525 if ( rSourceRange
.IsInside( aObjRect
) && (pOldObject
->GetLayer() != SC_LAYER_INTERN
) && !IsNoteCaption( pOldObject
) )
1528 SdrObject
* pNewObject
= pOldObject
->Clone();
1529 //SdrObject* pNewObject = pOldObject->Clone( pDestPage, this );
1530 pNewObject
->SetModel(this);
1531 pNewObject
->SetPage(pDestPage
);
1534 MirrorRTL( pNewObject
); // first mirror, then move
1536 pNewObject
->NbcMove( aMove
);
1538 pNewObject
->NbcResize( aRefPos
, aHorFract
, aVerFract
);
1540 pDestPage
->InsertObject( pNewObject
);
1542 AddCalcUndo( new SdrUndoInsertObj( *pNewObject
) );
1544 // handle chart data references (after InsertObject)
1546 if ( pNewObject
->GetObjIdentifier() == OBJ_OLE2
)
1548 uno::Reference
< embed::XEmbeddedObject
> xIPObj
= ((SdrOle2Obj
*)pNewObject
)->GetObjRef();
1549 uno::Reference
< embed::XClassifiedObject
> xClassified( xIPObj
, uno::UNO_QUERY
);
1550 SvGlobalName aObjectClassName
;
1551 if ( xClassified
.is() )
1554 aObjectClassName
= SvGlobalName( xClassified
->getClassID() );
1555 } catch( uno::Exception
& )
1557 // TODO: handle error?
1561 if ( xIPObj
.is() && SotExchange::IsChart( aObjectClassName
) )
1563 String aNewName
= ((SdrOle2Obj
*)pNewObject
)->GetPersistName();
1565 //! need to set new DataProvider, or does Chart handle this itself?
1567 ScRangeListRef
xRanges( new ScRangeList
);
1568 BOOL bColHeaders
= FALSE
;
1569 BOOL bRowHeaders
= FALSE
;
1570 pDoc
->GetOldChartParameters( aNewName
, *xRanges
, bColHeaders
, bRowHeaders
);
1572 if ( xRanges
->Count() > 0 )
1574 ScDocument
* pClipDoc
= pClipModel
->GetDocument();
1576 // a clipboard document and its source share the same document item pool,
1577 // so the pointers can be compared to see if this is copy&paste within
1578 // the same document
1579 BOOL bSameDoc
= pDoc
&& pClipDoc
&& pDoc
->GetPool() == pClipDoc
->GetPool();
1581 BOOL bDestClip
= pDoc
&& pDoc
->IsClipboard();
1583 BOOL bInSourceRange
= FALSE
;
1591 pClipDoc
->GetClipStart( nClipStartX
, nClipStartY
);
1592 pClipDoc
->GetClipArea( nClipEndX
, nClipEndY
, TRUE
);
1593 nClipEndX
= nClipEndX
+ nClipStartX
;
1594 nClipEndY
+= nClipStartY
; // GetClipArea returns the difference
1596 aClipRange
= ScRange( nClipStartX
, nClipStartY
, nSourceTab
,
1597 nClipEndX
, nClipEndY
, nSourceTab
);
1599 bInSourceRange
= lcl_IsAllInRange( *xRanges
, aClipRange
);
1602 // always lose references when pasting into a clipboard document (transpose)
1603 if ( ( bInSourceRange
|| bSameDoc
) && !bDestClip
)
1605 if ( bInSourceRange
)
1607 if ( rDestPos
!= aClipRange
.aStart
)
1609 // update the data ranges to the new (copied) position
1610 ScRangeListRef xNewRanges
= new ScRangeList( *xRanges
);
1611 if ( lcl_MoveRanges( *xNewRanges
, aClipRange
, rDestPos
) )
1613 pDoc
->UpdateChartArea( aNewName
, xNewRanges
, bColHeaders
, bRowHeaders
, FALSE
);
1619 // leave the ranges unchanged
1624 // pasting into a new document without the complete source data
1625 // -> break connection to source data
1627 // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc)
1629 //! need chart interface to switch to own data
1636 pOldObject
= aIter
.Next();
1640 void ScDrawLayer::MirrorRTL( SdrObject
* pObj
)
1642 UINT16 nIdent
= pObj
->GetObjIdentifier();
1644 // don't mirror OLE or graphics, otherwise ask the object
1645 // if it can be mirrored
1646 BOOL bCanMirror
= ( nIdent
!= OBJ_GRAF
&& nIdent
!= OBJ_OLE2
);
1649 SdrObjTransformInfoRec aInfo
;
1650 pObj
->TakeObjInfo( aInfo
);
1651 bCanMirror
= aInfo
.bMirror90Allowed
;
1656 Point
aRef1( 0, 0 );
1657 Point
aRef2( 0, 1 );
1659 AddCalcUndo( new SdrUndoGeoObj( *pObj
) );
1660 pObj
->Mirror( aRef1
, aRef2
);
1664 // Move instead of mirroring:
1665 // New start position is negative of old end position
1666 // -> move by sum of start and end position
1667 Rectangle aObjRect
= pObj
->GetLogicRect();
1668 Size
aMoveSize( -(aObjRect
.Left() + aObjRect
.Right()), 0 );
1670 AddCalcUndo( new SdrUndoMoveObj( *pObj
, aMoveSize
) );
1671 pObj
->Move( aMoveSize
);
1676 void ScDrawLayer::MirrorRectRTL( Rectangle
& rRect
)
1678 // mirror and swap left/right
1679 long nTemp
= rRect
.Left();
1680 rRect
.Left() = -rRect
.Right();
1681 rRect
.Right() = -nTemp
;
1684 Rectangle
ScDrawLayer::GetCellRect( ScDocument
& rDoc
, const ScAddress
& rPos
, bool bMergedCell
)
1686 Rectangle aCellRect
;
1687 DBG_ASSERT( ValidColRowTab( rPos
.Col(), rPos
.Row(), rPos
.Tab() ), "ScDrawLayer::GetCellRect - invalid cell address" );
1688 if( ValidColRowTab( rPos
.Col(), rPos
.Row(), rPos
.Tab() ) )
1690 // find top left position of passed cell address
1692 for( SCCOL nCol
= 0; nCol
< rPos
.Col(); ++nCol
)
1693 aTopLeft
.X() += rDoc
.GetColWidth( nCol
, rPos
.Tab() );
1694 if( rPos
.Row() > 0 )
1695 aTopLeft
.Y() += rDoc
.FastGetRowHeight( 0, rPos
.Row() - 1, rPos
.Tab() );
1697 // find bottom-right position of passed cell address
1698 ScAddress aEndPos
= rPos
;
1701 const ScMergeAttr
* pMerge
= static_cast< const ScMergeAttr
* >( rDoc
.GetAttr( rPos
.Col(), rPos
.Row(), rPos
.Tab(), ATTR_MERGE
) );
1702 if( pMerge
->GetColMerge() > 1 )
1703 aEndPos
.IncCol( pMerge
->GetColMerge() - 1 );
1704 if( pMerge
->GetRowMerge() > 1 )
1705 aEndPos
.IncRow( pMerge
->GetRowMerge() - 1 );
1707 Point aBotRight
= aTopLeft
;
1708 for( SCCOL nCol
= rPos
.Col(); nCol
<= aEndPos
.Col(); ++nCol
)
1709 aBotRight
.X() += rDoc
.GetColWidth( nCol
, rPos
.Tab() );
1710 aBotRight
.Y() += rDoc
.FastGetRowHeight( rPos
.Row(), aEndPos
.Row(), rPos
.Tab() );
1712 // twips -> 1/100 mm
1713 aTopLeft
.X() = static_cast< long >( aTopLeft
.X() * HMM_PER_TWIPS
);
1714 aTopLeft
.Y() = static_cast< long >( aTopLeft
.Y() * HMM_PER_TWIPS
);
1715 aBotRight
.X() = static_cast< long >( aBotRight
.X() * HMM_PER_TWIPS
);
1716 aBotRight
.Y() = static_cast< long >( aBotRight
.Y() * HMM_PER_TWIPS
);
1718 aCellRect
= Rectangle( aTopLeft
, aBotRight
);
1719 if( rDoc
.IsNegativePage( rPos
.Tab() ) )
1720 MirrorRectRTL( aCellRect
);
1726 String
ScDrawLayer::GetVisibleName( SdrObject
* pObj
)
1728 String aName
= pObj
->GetName();
1729 if ( pObj
->GetObjIdentifier() == OBJ_OLE2
)
1731 // #95575# For OLE, the user defined name (GetName) is used
1732 // if it's not empty (accepting possibly duplicate names),
1733 // otherwise the persist name is used so every object appears
1734 // in the Navigator at all.
1737 aName
= static_cast<SdrOle2Obj
*>(pObj
)->GetPersistName();
1742 inline sal_Bool
IsNamedObject( SdrObject
* pObj
, const String
& rName
)
1744 // TRUE if rName is the object's Name or PersistName
1745 // (used to find a named object)
1747 return ( pObj
->GetName() == rName
||
1748 ( pObj
->GetObjIdentifier() == OBJ_OLE2
&&
1749 static_cast<SdrOle2Obj
*>(pObj
)->GetPersistName() == rName
) );
1752 SdrObject
* ScDrawLayer::GetNamedObject( const String
& rName
, USHORT nId
, SCTAB
& rFoundTab
) const
1754 sal_uInt16 nTabCount
= GetPageCount();
1755 for (sal_uInt16 nTab
=0; nTab
<nTabCount
; nTab
++)
1757 const SdrPage
* pPage
= GetPage(nTab
);
1758 DBG_ASSERT(pPage
,"Page ?");
1761 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
1762 SdrObject
* pObject
= aIter
.Next();
1765 if ( nId
== 0 || pObject
->GetObjIdentifier() == nId
)
1766 if ( IsNamedObject( pObject
, rName
) )
1768 rFoundTab
= static_cast<SCTAB
>(nTab
);
1772 pObject
= aIter
.Next();
1780 String
ScDrawLayer::GetNewGraphicName( long* pnCounter
) const
1782 String aBase
= ScGlobal::GetRscString(STR_GRAPHICNAME
);
1786 String aGraphicName
;
1788 long nId
= pnCounter
? *pnCounter
: 0;
1792 aGraphicName
= aBase
;
1793 aGraphicName
+= String::CreateFromInt32( nId
);
1794 bThere
= ( GetNamedObject( aGraphicName
, 0, nDummy
) != NULL
);
1800 return aGraphicName
;
1803 void ScDrawLayer::EnsureGraphicNames()
1805 // make sure all graphic objects have names (after Excel import etc.)
1807 sal_uInt16 nTabCount
= GetPageCount();
1808 for (sal_uInt16 nTab
=0; nTab
<nTabCount
; nTab
++)
1810 SdrPage
* pPage
= GetPage(nTab
);
1811 DBG_ASSERT(pPage
,"Page ?");
1814 SdrObjListIter
aIter( *pPage
, IM_DEEPWITHGROUPS
);
1815 SdrObject
* pObject
= aIter
.Next();
1817 /* #101799# The index passed to GetNewGraphicName() will be set to
1818 the used index in each call. This prevents the repeated search
1819 for all names from 1 to current index. */
1824 if ( pObject
->GetObjIdentifier() == OBJ_GRAF
&& pObject
->GetName().Len() == 0 )
1825 pObject
->SetName( GetNewGraphicName( &nCounter
) );
1827 pObject
= aIter
.Next();
1833 void ScDrawLayer::SetAnchor( SdrObject
* pObj
, ScAnchorType eType
)
1835 ScAnchorType eOldAnchorType
= GetAnchor( pObj
);
1837 // Ein an der Seite verankertes Objekt zeichnet sich durch eine Anker-Pos
1838 // von (0,1) aus. Das ist ein shabby Trick, der aber funktioniert!
1839 Point
aAnchor( 0, eType
== SCA_PAGE
? 1 : 0 );
1840 pObj
->SetAnchorPos( aAnchor
);
1842 if ( eOldAnchorType
!= eType
)
1843 pObj
->notifyShapePropertyChange( ::svx::eSpreadsheetAnchor
);
1846 ScAnchorType
ScDrawLayer::GetAnchor( const SdrObject
* pObj
)
1848 Point
aAnchor( pObj
->GetAnchorPos() );
1849 return ( aAnchor
.Y() != 0 ) ? SCA_PAGE
: SCA_CELL
;
1852 ScDrawObjData
* ScDrawLayer::GetObjData( SdrObject
* pObj
, BOOL bCreate
) // static
1854 USHORT nCount
= pObj
? pObj
->GetUserDataCount() : 0;
1855 for( USHORT i
= 0; i
< nCount
; i
++ )
1857 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1858 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1859 && pData
->GetId() == SC_UD_OBJDATA
)
1860 return (ScDrawObjData
*) pData
;
1862 if( pObj
&& bCreate
)
1864 ScDrawObjData
* pData
= new ScDrawObjData
;
1865 pObj
->InsertUserData( pData
, 0 );
1871 ScDrawObjData
* ScDrawLayer::GetObjDataTab( SdrObject
* pObj
, SCTAB nTab
) // static
1873 ScDrawObjData
* pData
= GetObjData( pObj
);
1876 if ( pData
->maStart
.IsValid() )
1877 pData
->maStart
.SetTab( nTab
);
1878 if ( pData
->maEnd
.IsValid() )
1879 pData
->maEnd
.SetTab( nTab
);
1884 bool ScDrawLayer::IsNoteCaption( SdrObject
* pObj
)
1886 ScDrawObjData
* pData
= pObj
? GetObjData( pObj
) : 0;
1887 return pData
&& pData
->mbNote
;
1890 ScDrawObjData
* ScDrawLayer::GetNoteCaptionData( SdrObject
* pObj
, SCTAB nTab
)
1892 ScDrawObjData
* pData
= pObj
? GetObjDataTab( pObj
, nTab
) : 0;
1893 return (pData
&& pData
->mbNote
) ? pData
: 0;
1896 ScIMapInfo
* ScDrawLayer::GetIMapInfo( SdrObject
* pObj
) // static
1898 USHORT nCount
= pObj
->GetUserDataCount();
1899 for( USHORT i
= 0; i
< nCount
; i
++ )
1901 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1902 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1903 && pData
->GetId() == SC_UD_IMAPDATA
)
1904 return (ScIMapInfo
*) pData
;
1910 IMapObject
* ScDrawLayer::GetHitIMapObject( SdrObject
* pObj
,
1911 const Point
& rWinPoint
, const Window
& rCmpWnd
)
1913 const MapMode
aMap100( MAP_100TH_MM
);
1914 MapMode aWndMode
= rCmpWnd
.GetMapMode();
1915 Point
aRelPoint( rCmpWnd
.LogicToLogic( rWinPoint
, &aWndMode
, &aMap100
) );
1916 Rectangle aLogRect
= rCmpWnd
.LogicToLogic( pObj
->GetLogicRect(), &aWndMode
, &aMap100
);
1917 ScIMapInfo
* pIMapInfo
= GetIMapInfo( pObj
);
1918 IMapObject
* pIMapObj
= NULL
;
1923 ImageMap
& rImageMap
= (ImageMap
&) pIMapInfo
->GetImageMap();
1925 BOOL bObjSupported
= FALSE
;
1927 if ( pObj
->ISA( SdrGrafObj
) ) // einfaches Grafik-Objekt
1929 const SdrGrafObj
* pGrafObj
= (const SdrGrafObj
*) pObj
;
1930 const GeoStat
& rGeo
= pGrafObj
->GetGeoStat();
1931 const Graphic
& rGraphic
= pGrafObj
->GetGraphic();
1933 // Drehung rueckgaengig
1934 if ( rGeo
.nDrehWink
)
1935 RotatePoint( aRelPoint
, aLogRect
.TopLeft(), -rGeo
.nSin
, rGeo
.nCos
);
1937 // Spiegelung rueckgaengig
1938 if ( ( (const SdrGrafObjGeoData
*) pGrafObj
->GetGeoData() )->bMirrored
)
1939 aRelPoint
.X() = aLogRect
.Right() + aLogRect
.Left() - aRelPoint
.X();
1942 if ( rGeo
.nShearWink
)
1943 ShearPoint( aRelPoint
, aLogRect
.TopLeft(), -rGeo
.nTan
);
1946 if ( rGraphic
.GetPrefMapMode().GetMapUnit() == MAP_PIXEL
)
1947 aGraphSize
= rCmpWnd
.PixelToLogic( rGraphic
.GetPrefSize(),
1950 aGraphSize
= OutputDevice::LogicToLogic( rGraphic
.GetPrefSize(),
1951 rGraphic
.GetPrefMapMode(),
1954 bObjSupported
= TRUE
;
1956 else if ( pObj
->ISA( SdrOle2Obj
) ) // OLE-Objekt
1958 // TODO/LEAN: working with visual area needs running state
1959 aGraphSize
= ((SdrOle2Obj
*)pObj
)->GetOrigObjSize();
1960 bObjSupported
= TRUE
;
1963 // hat alles geklappt, dann HitTest ausfuehren
1964 if ( bObjSupported
)
1966 // relativen Mauspunkt berechnen
1967 aRelPoint
-= aLogRect
.TopLeft();
1968 pIMapObj
= rImageMap
.GetHitIMapObject( aGraphSize
, aLogRect
.GetSize(), aRelPoint
);
1975 ScMacroInfo
* ScDrawLayer::GetMacroInfo( SdrObject
* pObj
, BOOL bCreate
) // static
1977 USHORT nCount
= pObj
->GetUserDataCount();
1978 for( USHORT i
= 0; i
< nCount
; i
++ )
1980 SdrObjUserData
* pData
= pObj
->GetUserData( i
);
1981 if( pData
&& pData
->GetInventor() == SC_DRAWLAYER
1982 && pData
->GetId() == SC_UD_MACRODATA
)
1983 return (ScMacroInfo
*) pData
;
1987 ScMacroInfo
* pData
= new ScMacroInfo
;
1988 pObj
->InsertUserData( pData
, 0 );
1994 void ScDrawLayer::SetGlobalDrawPersist(SfxObjectShell
* pPersist
) // static
1996 DBG_ASSERT(!pGlobalDrawPersist
,"SetGlobalDrawPersist mehrfach");
1997 pGlobalDrawPersist
= pPersist
;
2000 void __EXPORT
ScDrawLayer::SetChanged( sal_Bool bFlg
/* = sal_True */ )
2003 pDoc
->SetChartListenerCollectionNeedsUpdate( TRUE
);
2004 FmFormModel::SetChanged( bFlg
);
2007 SvStream
* __EXPORT
ScDrawLayer::GetDocumentStream(SdrDocumentStreamInfo
& rStreamInfo
) const
2009 DBG_ASSERT( pDoc
, "ScDrawLayer::GetDocumentStream without document" );
2013 uno::Reference
< embed::XStorage
> xStorage
= pDoc
->GetDocumentShell() ?
2014 pDoc
->GetDocumentShell()->GetStorage() :
2016 SvStream
* pRet
= NULL
;
2020 if( rStreamInfo
.maUserData
.Len() &&
2021 ( rStreamInfo
.maUserData
.GetToken( 0, ':' ) ==
2022 String( RTL_CONSTASCII_USTRINGPARAM( "vnd.sun.star.Package" ) ) ) )
2024 const String
aPicturePath( rStreamInfo
.maUserData
.GetToken( 1, ':' ) );
2026 // graphic from picture stream in picture storage in XML package
2027 if( aPicturePath
.GetTokenCount( '/' ) == 2 )
2029 const String
aPictureStreamName( aPicturePath
.GetToken( 1, '/' ) );
2030 const String
aPictureStorageName( aPicturePath
.GetToken( 0, '/' ) );
2033 if ( xStorage
->isStorageElement( aPictureStorageName
) )
2035 uno::Reference
< embed::XStorage
> xPictureStorage
=
2036 xStorage
->openStorageElement( aPictureStorageName
, embed::ElementModes::READ
);
2038 if( xPictureStorage
.is() &&
2039 xPictureStorage
->isStreamElement( aPictureStreamName
) )
2041 uno::Reference
< io::XStream
> xStream
=
2042 xPictureStorage
->openStreamElement( aPictureStreamName
, embed::ElementModes::READ
);
2044 pRet
= ::utl::UcbStreamHelper::CreateStream( xStream
);
2048 catch( uno::Exception
& )
2050 // TODO: error handling
2054 // the following code seems to be related to binary format
2057 //REMOVE pRet = pStor->OpenStream( String::CreateFromAscii(RTL_CONSTASCII_STRINGPARAM(STRING_SCSTREAM)),
2058 //REMOVE STREAM_READ | STREAM_WRITE | STREAM_TRUNC );
2062 //REMOVE pRet->SetVersion( pStor->GetVersion() );
2063 //REMOVE pRet->SetKey( pStor->GetKey() );
2067 rStreamInfo
.mbDeleteAfterUse
= ( pRet
!= NULL
);
2073 //REMOVE void ScDrawLayer::ReleasePictureStorage()
2075 //REMOVE xPictureStorage.Clear();
2078 SdrLayerID __EXPORT
ScDrawLayer::GetControlExportLayerId( const SdrObject
& ) const
2080 // Layer fuer Export von Form-Controls in Versionen vor 5.0 - immer SC_LAYER_FRONT
2081 return SC_LAYER_FRONT
;
2084 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> ScDrawLayer::createUnoModel()
2086 ::com::sun::star::uno::Reference
< ::com::sun::star::uno::XInterface
> xRet
;
2087 if( pDoc
&& pDoc
->GetDocumentShell() )
2088 xRet
= pDoc
->GetDocumentShell()->GetModel();