LCOV - code coverage report
Current view: top level - sc/source/core/data - drwlayer.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 735 1143 64.3 %
Date: 2015-06-13 12:38:46 Functions: 70 88 79.5 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.11