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

Generated by: LCOV version 1.10