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

Generated by: LCOV version 1.10