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

Generated by: LCOV version 1.10