LCOV - code coverage report
Current view: top level - sc/source/ui/app - transobj.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 45 422 10.7 %
Date: 2015-06-13 12:38:46 Functions: 7 28 25.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 "scitems.hxx"
      21             : #include <editeng/eeitem.hxx>
      22             : #include <editeng/justifyitem.hxx>
      23             : 
      24             : #include <com/sun/star/uno/Sequence.hxx>
      25             : #include <com/sun/star/embed/XTransactedObject.hpp>
      26             : 
      27             : #include <unotools/tempfile.hxx>
      28             : #include <unotools/ucbstreamhelper.hxx>
      29             : #include <comphelper/storagehelper.hxx>
      30             : #include <comphelper/servicehelper.hxx>
      31             : #include <sot/storage.hxx>
      32             : #include <vcl/svapp.hxx>
      33             : #include <vcl/virdev.hxx>
      34             : #include <osl/mutex.hxx>
      35             : #include <sfx2/app.hxx>
      36             : #include <sfx2/docfile.hxx>
      37             : 
      38             : #include "transobj.hxx"
      39             : #include "document.hxx"
      40             : #include "viewopti.hxx"
      41             : #include "editutil.hxx"
      42             : #include "impex.hxx"
      43             : #include "formulacell.hxx"
      44             : #include "printfun.hxx"
      45             : #include "docfunc.hxx"
      46             : #include "scmod.hxx"
      47             : #include "dragdata.hxx"
      48             : #include "clipdata.hxx"
      49             : #include "clipparam.hxx"
      50             : 
      51             : #include <editeng/paperinf.hxx>
      52             : #include <editeng/sizeitem.hxx>
      53             : #include <svx/algitem.hxx>
      54             : #include <svl/intitem.hxx>
      55             : #include <svl/zforlist.hxx>
      56             : #include "docsh.hxx"
      57             : #include "markdata.hxx"
      58             : #include "stlpool.hxx"
      59             : #include "viewdata.hxx"
      60             : #include "dociter.hxx"
      61             : #include "cellsuno.hxx"
      62             : #include "stringutil.hxx"
      63             : #include "formulaiter.hxx"
      64             : #include <gridwin.hxx>
      65             : 
      66             : using namespace com::sun::star;
      67             : 
      68             : #define SCTRANS_TYPE_IMPEX          SotClipboardFormatId::STRING
      69             : #define SCTRANS_TYPE_EDIT_RTF       SotClipboardFormatId::BITMAP
      70             : #define SCTRANS_TYPE_EDIT_BIN       SotClipboardFormatId::GDIMETAFILE
      71             : #define SCTRANS_TYPE_EMBOBJ         SotClipboardFormatId::PRIVATE
      72             : 
      73           0 : void ScTransferObj::GetAreaSize( ScDocument* pDoc, SCTAB nTab1, SCTAB nTab2, SCROW& nRow, SCCOL& nCol )
      74             : {
      75           0 :     SCCOL nMaxCol = 0;
      76           0 :     SCROW nMaxRow = 0;
      77           0 :     for( SCTAB nTab = nTab1; nTab <= nTab2; nTab++ )
      78             :     {
      79           0 :         SCCOL nLastCol = 0;
      80           0 :         SCROW nLastRow = 0;
      81             :         // GetPrintArea instead of GetCellArea - include drawing objects
      82           0 :         if( pDoc->GetPrintArea( nTab, nLastCol, nLastRow ) )
      83             :         {
      84           0 :             if( nLastCol > nMaxCol )
      85           0 :                 nMaxCol = nLastCol;
      86           0 :             if( nLastRow > nMaxRow  )
      87           0 :                 nMaxRow = nLastRow;
      88             :         }
      89             :     }
      90           0 :     nRow = nMaxRow;
      91           0 :     nCol = nMaxCol;
      92           0 : }
      93             : 
      94           0 : void ScTransferObj::PaintToDev( OutputDevice* pDev, ScDocument* pDoc, double nPrintFactor,
      95             :                                 const ScRange& rBlock, bool bMetaFile )
      96             : {
      97           0 :     if (!pDoc)
      98           0 :         return;
      99             : 
     100           0 :     Point aPoint;
     101           0 :     Rectangle aBound( aPoint, pDev->GetOutputSize() );      //! use size from clip area?
     102             : 
     103           0 :     ScViewData aViewData(NULL,NULL);
     104           0 :     aViewData.InitData( pDoc );
     105             : 
     106           0 :     aViewData.SetTabNo( rBlock.aEnd.Tab() );
     107           0 :     aViewData.SetScreen( rBlock.aStart.Col(), rBlock.aStart.Row(),
     108           0 :                             rBlock.aEnd.Col(), rBlock.aEnd.Row() );
     109             : 
     110           0 :     ScPrintFunc::DrawToDev( pDoc, pDev, nPrintFactor, aBound, &aViewData, bMetaFile );
     111             : }
     112             : 
     113          11 : ScTransferObj::ScTransferObj( ScDocument* pClipDoc, const TransferableObjectDescriptor& rDesc ) :
     114             :     pDoc( pClipDoc ),
     115             :     nNonFiltered(0),
     116             :     aObjDesc( rDesc ),
     117             :     nDragHandleX( 0 ),
     118             :     nDragHandleY( 0 ),
     119             :     nDragSourceFlags( 0 ),
     120             :     bDragWasInternal( false ),
     121             :     bUsedForLink( false ),
     122          11 :     bUseInApi( false )
     123             : {
     124             :     OSL_ENSURE(pDoc->IsClipboard(), "wrong document");
     125             : 
     126             :     // get aBlock from clipboard doc
     127             : 
     128             :     SCCOL nCol1;
     129             :     SCROW nRow1;
     130             :     SCCOL nCol2;
     131             :     SCROW nRow2;
     132          11 :     pDoc->GetClipStart( nCol1, nRow1 );
     133          11 :     pDoc->GetClipArea( nCol2, nRow2, true );    // real source area - include filtered rows
     134          11 :     nCol2 = sal::static_int_cast<SCCOL>( nCol2 + nCol1 );
     135          11 :     nRow2 = sal::static_int_cast<SCROW>( nRow2 + nRow1 );
     136             : 
     137             :     SCCOL nDummy;
     138          11 :     pDoc->GetClipArea( nDummy, nNonFiltered, false );
     139          11 :     bHasFiltered = (nNonFiltered < (nRow2 - nRow1));
     140          11 :     ++nNonFiltered;     // to get count instead of diff
     141             : 
     142          11 :     SCTAB nTab1=0;
     143          11 :     SCTAB nTab2=0;
     144          11 :     bool bFirst = true;
     145          22 :     for (SCTAB i=0; i< pDoc->GetTableCount(); i++)
     146          11 :         if (pDoc->HasTable(i))
     147             :         {
     148          11 :             if (bFirst)
     149          11 :                 nTab1 = i;
     150          11 :             nTab2 = i;
     151          11 :             bFirst = false;
     152             :         }
     153             :     OSL_ENSURE(!bFirst, "no sheet selected");
     154             : 
     155             :     //  only limit to used cells if whole sheet was marked
     156             :     //  (so empty cell areas can be copied)
     157          11 :     if ( nCol2>=MAXCOL && nRow2>=MAXROW )
     158             :     {
     159             :         SCROW nMaxRow;
     160             :         SCCOL nMaxCol;
     161           0 :         GetAreaSize( pDoc, nTab1, nTab2, nMaxRow, nMaxCol );
     162           0 :         if( nMaxRow < nRow2 )
     163           0 :             nRow2 = nMaxRow;
     164           0 :         if( nMaxCol < nCol2 )
     165           0 :             nCol2 = nMaxCol;
     166             :     }
     167             : 
     168          11 :     aBlock = ScRange( nCol1, nRow1, nTab1, nCol2, nRow2, nTab2 );
     169          11 :     nVisibleTab = nTab1;    // valid table as default
     170             : 
     171          11 :     Rectangle aMMRect = pDoc->GetMMRect( nCol1,nRow1, nCol2,nRow2, nTab1 );
     172          11 :     aObjDesc.maSize = aMMRect.GetSize();
     173          11 :     PrepareOLE( aObjDesc );
     174          11 : }
     175             : 
     176          33 : ScTransferObj::~ScTransferObj()
     177             : {
     178          11 :     SolarMutexGuard aSolarGuard;
     179             : 
     180          11 :     ScModule* pScMod = SC_MOD();
     181          11 :     if ( pScMod->GetClipData().pCellClipboard == this )
     182             :     {
     183             :         OSL_FAIL("ScTransferObj wasn't released");
     184          11 :         pScMod->SetClipObject( NULL, NULL );
     185             :     }
     186          11 :     if ( pScMod->GetDragData().pCellTransfer == this )
     187             :     {
     188             :         OSL_FAIL("ScTransferObj wasn't released");
     189           0 :         pScMod->ResetDragObject();
     190             :     }
     191             : 
     192          11 :     delete pDoc;        // ScTransferObj is owner of clipboard document
     193             : 
     194          11 :     aDocShellRef.Clear();   // before releasing the mutex
     195             : 
     196          11 :     aDrawPersistRef.Clear();                    // after the model
     197             : 
     198          22 : }
     199             : 
     200        1499 : ScTransferObj* ScTransferObj::GetOwnClipboard( vcl::Window* pUIWin )
     201             : {
     202        1499 :     ScTransferObj* pObj = SC_MOD()->GetClipData().pCellClipboard;
     203        1499 :     if ( pObj && pUIWin )
     204             :     {
     205             :         //  check formats to see if pObj is really in the system clipboard
     206             : 
     207             :         //  pUIWin is NULL when called from core (IsClipboardSource),
     208             :         //  in that case don't access the system clipboard, because the call
     209             :         //  may be from other clipboard operations (like flushing, #86059#)
     210             : 
     211           0 :         TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pUIWin ) );
     212           0 :         if ( !aDataHelper.HasFormat( SotClipboardFormatId::DIF ) )
     213             :         {
     214             : //          OSL_FAIL("ScTransferObj wasn't released");
     215           0 :             pObj = NULL;
     216           0 :         }
     217             :     }
     218        1499 :     return pObj;
     219             : }
     220             : 
     221           0 : void ScTransferObj::AddSupportedFormats()
     222             : {
     223           0 :     AddFormat( SotClipboardFormatId::EMBED_SOURCE );
     224           0 :     AddFormat( SotClipboardFormatId::OBJECTDESCRIPTOR );
     225           0 :     AddFormat( SotClipboardFormatId::GDIMETAFILE );
     226           0 :     AddFormat( SotClipboardFormatId::PNG );
     227           0 :     AddFormat( SotClipboardFormatId::BITMAP );
     228             : 
     229             :     // ScImportExport formats
     230           0 :     AddFormat( SotClipboardFormatId::HTML );
     231           0 :     AddFormat( SotClipboardFormatId::SYLK );
     232           0 :     AddFormat( SotClipboardFormatId::LINK );
     233           0 :     AddFormat( SotClipboardFormatId::DIF );
     234           0 :     AddFormat( SotClipboardFormatId::STRING );
     235             : 
     236           0 :     AddFormat( SotClipboardFormatId::RTF );
     237           0 :     if ( aBlock.aStart == aBlock.aEnd )
     238           0 :         AddFormat( SotClipboardFormatId::EDITENGINE );
     239           0 : }
     240             : 
     241           0 : bool ScTransferObj::GetData( const datatransfer::DataFlavor& rFlavor, const OUString& /*rDestDoc*/ )
     242             : {
     243           0 :     SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
     244           0 :     bool        bOK = false;
     245             : 
     246           0 :     if( HasFormat( nFormat ) )
     247             :     {
     248           0 :         if ( nFormat == SotClipboardFormatId::LINKSRCDESCRIPTOR || nFormat == SotClipboardFormatId::OBJECTDESCRIPTOR )
     249             :         {
     250           0 :             bOK = SetTransferableObjectDescriptor( aObjDesc, rFlavor );
     251             :         }
     252           0 :         else if ( ( nFormat == SotClipboardFormatId::RTF || nFormat == SotClipboardFormatId::EDITENGINE ) &&
     253           0 :                         aBlock.aStart == aBlock.aEnd )
     254             :         {
     255             :             //  RTF from a single cell is handled by EditEngine
     256             : 
     257           0 :             SCCOL nCol = aBlock.aStart.Col();
     258           0 :             SCROW nRow = aBlock.aStart.Row();
     259           0 :             SCTAB nTab = aBlock.aStart.Tab();
     260           0 :             ScAddress aPos(nCol, nRow, nTab);
     261             : 
     262           0 :             const ScPatternAttr* pPattern = pDoc->GetPattern( nCol, nRow, nTab );
     263           0 :             ScTabEditEngine aEngine( *pPattern, pDoc->GetEditPool() );
     264           0 :             if (pDoc->GetCellType(aPos) == CELLTYPE_EDIT)
     265             :             {
     266           0 :                 const EditTextObject* pObj = pDoc->GetEditText(aPos);
     267           0 :                 if (pObj)
     268           0 :                     aEngine.SetText(*pObj);
     269             :             }
     270             :             else
     271             :             {
     272           0 :                 OUString aText = pDoc->GetString(nCol, nRow, nTab);
     273           0 :                 if (!aText.isEmpty())
     274           0 :                     aEngine.SetText(aText);
     275             :             }
     276             : 
     277             :             bOK = SetObject( &aEngine,
     278             :                             (nFormat == SotClipboardFormatId::RTF) ? SCTRANS_TYPE_EDIT_RTF : SCTRANS_TYPE_EDIT_BIN,
     279           0 :                             rFlavor );
     280             :         }
     281           0 :         else if ( ScImportExport::IsFormatSupported( nFormat ) || nFormat == SotClipboardFormatId::RTF )
     282             :         {
     283             :             //  if this transfer object was used to create a DDE link, filtered rows
     284             :             //  have to be included for subsequent calls (to be consistent with link data)
     285           0 :             if ( nFormat == SotClipboardFormatId::LINK )
     286           0 :                 bUsedForLink = true;
     287             : 
     288           0 :             bool bIncludeFiltered = pDoc->IsCutMode() || bUsedForLink;
     289             : 
     290           0 :             bool bReduceBlockFormat = nFormat == SotClipboardFormatId::HTML || nFormat == SotClipboardFormatId::RTF;
     291           0 :             ScRange aReducedBlock = aBlock;
     292           0 :             if (bReduceBlockFormat && (aBlock.aEnd.Col() == MAXCOL || aBlock.aEnd.Row() == MAXROW) && aBlock.aStart.Tab() == aBlock.aEnd.Tab())
     293             :             {
     294           0 :                 bool bShrunk = false;
     295             :                 //shrink the area to allow pasting to external applications
     296           0 :                 SCCOL aStartCol = aReducedBlock.aStart.Col();
     297           0 :                 SCROW aStartRow = aReducedBlock.aStart.Row();
     298           0 :                 SCCOL aEndCol = aReducedBlock.aEnd.Col();
     299           0 :                 SCROW aEndRow = aReducedBlock.aEnd.Row();
     300           0 :                 pDoc->ShrinkToUsedDataArea( bShrunk, aReducedBlock.aStart.Tab(), aStartCol, aStartRow, aEndCol, aEndRow, false);
     301           0 :                 aReducedBlock = ScRange(aStartCol, aStartRow, aReducedBlock.aStart.Tab(), aEndCol, aEndRow, aReducedBlock.aEnd.Tab());
     302             :             }
     303             : 
     304           0 :             ScImportExport aObj( pDoc, aReducedBlock );
     305           0 :             ScExportTextOptions aTextOptions(ScExportTextOptions::None, 0, true);
     306           0 :             if ( bUsedForLink )
     307             :             {
     308             :                 // For a DDE link, convert line breaks and separators to space.
     309           0 :                 aTextOptions.meNewlineConversion = ScExportTextOptions::ToSpace;
     310           0 :                 aTextOptions.mcSeparatorConvertTo = ' ';
     311           0 :                 aTextOptions.mbAddQuotes = false;
     312             :             }
     313           0 :             aObj.SetExportTextOptions(aTextOptions);
     314           0 :             aObj.SetFormulas( pDoc->GetViewOptions().GetOption( VOPT_FORMULAS ) );
     315           0 :             aObj.SetIncludeFiltered( bIncludeFiltered );
     316             : 
     317             :             //  DataType depends on format type:
     318             : 
     319           0 :             if ( rFlavor.DataType.equals( ::cppu::UnoType<OUString>::get() ) )
     320             :             {
     321           0 :                 OUString aString;
     322           0 :                 if ( aObj.ExportString( aString, nFormat ) )
     323           0 :                     bOK = SetString( aString, rFlavor );
     324             :             }
     325           0 :             else if ( rFlavor.DataType.equals( cppu::UnoType<uno::Sequence< sal_Int8 >>::get() ) )
     326             :             {
     327             :                 //  SetObject converts a stream into a Int8-Sequence
     328           0 :                 bOK = SetObject( &aObj, SCTRANS_TYPE_IMPEX, rFlavor );
     329             :             }
     330             :             else
     331             :             {
     332             :                 OSL_FAIL("unknown DataType");
     333           0 :             }
     334             :         }
     335           0 :         else if ( nFormat == SotClipboardFormatId::BITMAP || nFormat == SotClipboardFormatId::PNG )
     336             :         {
     337           0 :             Rectangle aMMRect = pDoc->GetMMRect( aBlock.aStart.Col(), aBlock.aStart.Row(),
     338           0 :                                                  aBlock.aEnd.Col(), aBlock.aEnd.Row(),
     339           0 :                                                  aBlock.aStart.Tab() );
     340           0 :             ScopedVclPtrInstance< VirtualDevice > pVirtDev;
     341           0 :             pVirtDev->SetOutputSizePixel( pVirtDev->LogicToPixel( aMMRect.GetSize(), MAP_100TH_MM ) );
     342             : 
     343           0 :             PaintToDev( pVirtDev, pDoc, 1.0, aBlock, false );
     344             : 
     345           0 :             pVirtDev->SetMapMode( MapMode( MAP_PIXEL ) );
     346           0 :             Bitmap aBmp = pVirtDev->GetBitmap( Point(), pVirtDev->GetOutputSize() );
     347           0 :             bOK = SetBitmapEx( aBmp, rFlavor );
     348             :         }
     349           0 :         else if ( nFormat == SotClipboardFormatId::GDIMETAFILE )
     350             :         {
     351             :             // #i123405# Do not limit visual size calculation for metafile creation.
     352             :             // It seems unlikely that removing the limitation causes problems since
     353             :             // metafile creation means that no real pixel device in the needed size is
     354             :             // created.
     355           0 :             InitDocShell(false);
     356             : 
     357           0 :             SfxObjectShell* pEmbObj = aDocShellRef;
     358             : 
     359             :             // like SvEmbeddedTransfer::GetData:
     360           0 :             GDIMetaFile     aMtf;
     361           0 :             ScopedVclPtrInstance< VirtualDevice > pVDev;
     362           0 :             MapMode         aMapMode( pEmbObj->GetMapUnit() );
     363           0 :             Rectangle       aVisArea( pEmbObj->GetVisArea( ASPECT_CONTENT ) );
     364             : 
     365           0 :             pVDev->EnableOutput( false );
     366           0 :             pVDev->SetMapMode( aMapMode );
     367           0 :             aMtf.SetPrefSize( aVisArea.GetSize() );
     368           0 :             aMtf.SetPrefMapMode( aMapMode );
     369           0 :             aMtf.Record( pVDev );
     370             : 
     371           0 :             pEmbObj->DoDraw( pVDev, Point(), aVisArea.GetSize(), JobSetup(), ASPECT_CONTENT );
     372             : 
     373           0 :             aMtf.Stop();
     374           0 :             aMtf.WindStart();
     375             : 
     376           0 :             bOK = SetGDIMetaFile( aMtf, rFlavor );
     377             :         }
     378           0 :         else if ( nFormat == SotClipboardFormatId::EMBED_SOURCE )
     379             :         {
     380             :             //TODO/LATER: differentiate between formats?!
     381             :             // #i123405# Do limit visual size calculation to PageSize
     382           0 :             InitDocShell(true);         // set aDocShellRef
     383             : 
     384           0 :             SfxObjectShell* pEmbObj = aDocShellRef;
     385           0 :             bOK = SetObject( pEmbObj, SCTRANS_TYPE_EMBOBJ, rFlavor );
     386             :         }
     387             :     }
     388           0 :     return bOK;
     389             : }
     390             : 
     391           0 : bool ScTransferObj::WriteObject( tools::SvRef<SotStorageStream>& rxOStm, void* pUserObject, SotClipboardFormatId nUserObjectId,
     392             :                                         const datatransfer::DataFlavor& rFlavor )
     393             : {
     394             :     // called from SetObject, put data into stream
     395             : 
     396           0 :     bool bRet = false;
     397           0 :     switch (nUserObjectId)
     398             :     {
     399             :         case SCTRANS_TYPE_IMPEX:
     400             :             {
     401           0 :                 ScImportExport* pImpEx = static_cast<ScImportExport*>(pUserObject);
     402             : 
     403           0 :                 SotClipboardFormatId nFormat = SotExchange::GetFormat( rFlavor );
     404             :                 // mba: no BaseURL for data exchange
     405           0 :                 if ( pImpEx->ExportStream( *rxOStm, OUString(), nFormat ) )
     406           0 :                     bRet = ( rxOStm->GetError() == ERRCODE_NONE );
     407             :             }
     408           0 :             break;
     409             : 
     410             :         case SCTRANS_TYPE_EDIT_RTF:
     411             :         case SCTRANS_TYPE_EDIT_BIN:
     412             :             {
     413           0 :                 ScTabEditEngine* pEngine = static_cast<ScTabEditEngine*>(pUserObject);
     414           0 :                 if ( nUserObjectId == SCTRANS_TYPE_EDIT_RTF )
     415             :                 {
     416           0 :                     pEngine->Write( *rxOStm, EE_FORMAT_RTF );
     417           0 :                     bRet = ( rxOStm->GetError() == ERRCODE_NONE );
     418             :                 }
     419             :                 else
     420             :                 {
     421             :                     //  can't use Write for EditEngine format because that would
     422             :                     //  write old format without support for unicode characters.
     423             :                     //  Get the data from the EditEngine's transferable instead.
     424             : 
     425           0 :                     sal_Int32 nParCnt = pEngine->GetParagraphCount();
     426           0 :                     if ( nParCnt == 0 )
     427           0 :                         nParCnt = 1;
     428           0 :                     ESelection aSel( 0, 0, nParCnt-1, pEngine->GetTextLen(nParCnt-1) );
     429             : 
     430           0 :                     uno::Reference<datatransfer::XTransferable> xEditTrans = pEngine->CreateTransferable( aSel );
     431           0 :                     TransferableDataHelper aEditHelper( xEditTrans );
     432             : 
     433           0 :                     bRet = aEditHelper.GetSotStorageStream( rFlavor, rxOStm );
     434             :                 }
     435             :             }
     436           0 :             break;
     437             : 
     438             :         case SCTRANS_TYPE_EMBOBJ:
     439             :             {
     440             :                 // TODO/MBA: testing
     441           0 :                 SfxObjectShell*   pEmbObj = static_cast<SfxObjectShell*>(pUserObject);
     442           0 :                 ::utl::TempFile     aTempFile;
     443           0 :                 aTempFile.EnableKillingFile();
     444             :                 uno::Reference< embed::XStorage > xWorkStore =
     445           0 :                     ::comphelper::OStorageHelper::GetStorageFromURL( aTempFile.GetURL(), embed::ElementModes::READWRITE );
     446             : 
     447             :                 // write document storage
     448           0 :                 pEmbObj->SetupStorage( xWorkStore, SOFFICE_FILEFORMAT_CURRENT, false, false );
     449             : 
     450             :                 // mba: no relative URLs for clipboard!
     451           0 :                 SfxMedium aMedium( xWorkStore, OUString() );
     452           0 :                 bRet = pEmbObj->DoSaveObjectAs( aMedium, false );
     453           0 :                 pEmbObj->DoSaveCompleted();
     454             : 
     455           0 :                 uno::Reference< embed::XTransactedObject > xTransact( xWorkStore, uno::UNO_QUERY );
     456           0 :                 if ( xTransact.is() )
     457           0 :                     xTransact->commit();
     458             : 
     459           0 :                 SvStream* pSrcStm = ::utl::UcbStreamHelper::CreateStream( aTempFile.GetURL(), StreamMode::READ );
     460           0 :                 if( pSrcStm )
     461             :                 {
     462           0 :                     rxOStm->SetBufferSize( 0xff00 );
     463           0 :                     rxOStm->WriteStream( *pSrcStm );
     464           0 :                     delete pSrcStm;
     465             :                 }
     466             : 
     467           0 :                 bRet = true;
     468             : 
     469           0 :                 xWorkStore->dispose();
     470           0 :                 xWorkStore = uno::Reference < embed::XStorage >();
     471           0 :                 rxOStm->Commit();
     472             :             }
     473           0 :             break;
     474             : 
     475             :         default:
     476             :             OSL_FAIL("unknown object id");
     477             :     }
     478           0 :     return bRet;
     479             : }
     480             : 
     481           0 : void ScTransferObj::ObjectReleased()
     482             : {
     483           0 :     ScModule* pScMod = SC_MOD();
     484           0 :     if ( pScMod->GetClipData().pCellClipboard == this )
     485           0 :         pScMod->SetClipObject( NULL, NULL );
     486             : 
     487           0 :     TransferableHelper::ObjectReleased();
     488           0 : }
     489             : 
     490           0 : void ScTransferObj::DragFinished( sal_Int8 nDropAction )
     491             : {
     492           0 :     if ( nDropAction == DND_ACTION_MOVE && !bDragWasInternal && !(nDragSourceFlags & SC_DROP_NAVIGATOR) )
     493             :     {
     494             :         //  move: delete source data
     495           0 :         ScDocShell* pSourceSh = GetSourceDocShell();
     496           0 :         if (pSourceSh)
     497             :         {
     498           0 :             ScMarkData aMarkData = GetSourceMarkData();
     499             :             //  external drag&drop doesn't copy objects, so they also aren't deleted:
     500             :             //  bApi=TRUE, don't show error messages from drag&drop
     501           0 :             pSourceSh->GetDocFunc().DeleteContents( aMarkData, IDF_ALL & ~IDF_OBJECTS, true, true );
     502             :         }
     503             :     }
     504             : 
     505           0 :     ScModule* pScMod = SC_MOD();
     506           0 :     if ( pScMod->GetDragData().pCellTransfer == this )
     507           0 :         pScMod->ResetDragObject();
     508             : 
     509           0 :     xDragSourceRanges = NULL;       // don't keep source after dropping
     510             : 
     511           0 :     TransferableHelper::DragFinished( nDropAction );
     512           0 : }
     513             : 
     514           0 : void ScTransferObj::SetDragHandlePos( SCCOL nX, SCROW nY )
     515             : {
     516           0 :     nDragHandleX = nX;
     517           0 :     nDragHandleY = nY;
     518           0 : }
     519             : 
     520           0 : void ScTransferObj::SetVisibleTab( SCTAB nNew )
     521             : {
     522           0 :     nVisibleTab = nNew;
     523           0 : }
     524             : 
     525           0 : void ScTransferObj::SetDrawPersist( const SfxObjectShellRef& rRef )
     526             : {
     527           0 :     aDrawPersistRef = rRef;
     528           0 : }
     529             : 
     530           0 : void ScTransferObj::SetDragSource( ScDocShell* pSourceShell, const ScMarkData& rMark )
     531             : {
     532           0 :     ScRangeList aRanges;
     533           0 :     rMark.FillRangeListWithMarks( &aRanges, false );
     534           0 :     xDragSourceRanges = new ScCellRangesObj( pSourceShell, aRanges );
     535           0 : }
     536             : 
     537           0 : void ScTransferObj::SetDragSourceFlags( sal_uInt16 nFlags )
     538             : {
     539           0 :     nDragSourceFlags = nFlags;
     540           0 : }
     541             : 
     542           0 : void ScTransferObj::SetDragWasInternal()
     543             : {
     544           0 :     bDragWasInternal = true;
     545           0 : }
     546             : 
     547           0 : void ScTransferObj::SetUseInApi( bool bSet )
     548             : {
     549           0 :     bUseInApi = bSet;
     550           0 : }
     551             : 
     552           0 : ScDocument* ScTransferObj::GetSourceDocument()
     553             : {
     554           0 :     ScDocShell* pSourceDocSh = GetSourceDocShell();
     555           0 :     if (pSourceDocSh)
     556           0 :         return &pSourceDocSh->GetDocument();
     557           0 :     return NULL;
     558             : }
     559             : 
     560           0 : ScDocShell* ScTransferObj::GetSourceDocShell()
     561             : {
     562           0 :     ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
     563           0 :     if (pRangesObj)
     564           0 :         return pRangesObj->GetDocShell();
     565             : 
     566           0 :     return NULL;    // none set
     567             : }
     568             : 
     569           0 : ScMarkData ScTransferObj::GetSourceMarkData()
     570             : {
     571           0 :     ScMarkData aMarkData;
     572           0 :     ScCellRangesBase* pRangesObj = ScCellRangesBase::getImplementation( xDragSourceRanges );
     573           0 :     if (pRangesObj)
     574             :     {
     575           0 :         const ScRangeList& rRanges = pRangesObj->GetRangeList();
     576           0 :         aMarkData.MarkFromRangeList( rRanges, false );
     577             :     }
     578           0 :     return aMarkData;
     579             : }
     580             : 
     581             : //  initialize aDocShellRef with a live document from the ClipDoc
     582             : 
     583             : // #i123405# added parameter to allow size calculation without limitation
     584             : // to PageSize, e.g. used for Metafile creation for clipboard.
     585             : 
     586           0 : void ScTransferObj::InitDocShell(bool bLimitToPageSize)
     587             : {
     588           0 :     if ( !aDocShellRef.Is() )
     589             :     {
     590           0 :         ScDocShell* pDocSh = new ScDocShell;
     591           0 :         aDocShellRef = pDocSh;      // ref must be there before InitNew
     592             : 
     593           0 :         pDocSh->DoInitNew(NULL);
     594             : 
     595           0 :         ScDocument& rDestDoc = pDocSh->GetDocument();
     596           0 :         ScMarkData aDestMark;
     597           0 :         aDestMark.SelectTable( 0, true );
     598             : 
     599           0 :         rDestDoc.SetDocOptions( pDoc->GetDocOptions() );   // #i42666#
     600             : 
     601           0 :         OUString aTabName;
     602           0 :         pDoc->GetName( aBlock.aStart.Tab(), aTabName );
     603           0 :         rDestDoc.RenameTab( 0, aTabName, false );          // no UpdateRef (empty)
     604             : 
     605           0 :         rDestDoc.CopyStdStylesFrom( pDoc );
     606             : 
     607           0 :         SCCOL nStartX = aBlock.aStart.Col();
     608           0 :         SCROW nStartY = aBlock.aStart.Row();
     609           0 :         SCCOL nEndX = aBlock.aEnd.Col();
     610           0 :         SCROW nEndY = aBlock.aEnd.Row();
     611             : 
     612             :         //  widths / heights
     613             :         //  (must be copied before CopyFromClip, for drawing objects)
     614             : 
     615             :         SCCOL nCol;
     616           0 :         SCTAB nSrcTab = aBlock.aStart.Tab();
     617           0 :         rDestDoc.SetLayoutRTL(0, pDoc->IsLayoutRTL(nSrcTab));
     618           0 :         for (nCol=nStartX; nCol<=nEndX; nCol++)
     619           0 :             if ( pDoc->ColHidden(nCol, nSrcTab) )
     620           0 :                 rDestDoc.ShowCol( nCol, 0, false );
     621             :             else
     622           0 :                 rDestDoc.SetColWidth( nCol, 0, pDoc->GetColWidth( nCol, nSrcTab ) );
     623             : 
     624           0 :         for (SCROW nRow = nStartY; nRow <= nEndY; ++nRow)
     625             :         {
     626           0 :             if ( pDoc->RowHidden(nRow, nSrcTab) )
     627           0 :                 rDestDoc.ShowRow( nRow, 0, false );
     628             :             else
     629             :             {
     630           0 :                 rDestDoc.SetRowHeight( nRow, 0, pDoc->GetOriginalHeight( nRow, nSrcTab ) );
     631             : 
     632             :                 //  if height was set manually, that flag has to be copied, too
     633           0 :                 bool bManual = pDoc->IsManualRowHeight(nRow, nSrcTab);
     634           0 :                 rDestDoc.SetManualHeight(nRow, nRow, 0, bManual);
     635             :             }
     636             :         }
     637             : 
     638           0 :         if (pDoc->GetDrawLayer() || pDoc->HasNotes())
     639           0 :             pDocSh->MakeDrawLayer();
     640             : 
     641             :         //  cell range is copied to the original position, but on the first sheet
     642             :         //  -> bCutMode must be set
     643             :         //  pDoc is always a Clipboard-document
     644             : 
     645           0 :         ScRange aDestRange( nStartX,nStartY,0, nEndX,nEndY,0 );
     646           0 :         bool bWasCut = pDoc->IsCutMode();
     647           0 :         if (!bWasCut)
     648           0 :             pDoc->SetClipArea( aDestRange, true );          // Cut
     649           0 :         rDestDoc.CopyFromClip( aDestRange, aDestMark, IDF_ALL, NULL, pDoc, false );
     650           0 :         pDoc->SetClipArea( aDestRange, bWasCut );
     651             : 
     652           0 :         StripRefs( pDoc, nStartX,nStartY, nEndX,nEndY, &rDestDoc, 0,0 );
     653             : 
     654           0 :         ScRange aMergeRange = aDestRange;
     655           0 :         rDestDoc.ExtendMerge( aMergeRange, true );
     656             : 
     657           0 :         pDoc->CopyDdeLinks( &rDestDoc );         // copy values of DDE Links
     658             : 
     659             :         //  page format (grid etc) and page size (maximum size for ole object)
     660             : 
     661           0 :         Size aPaperSize = SvxPaperInfo::GetPaperSize( PAPER_A4 );       // Twips
     662           0 :         ScStyleSheetPool* pStylePool = pDoc->GetStyleSheetPool();
     663           0 :         OUString aStyleName = pDoc->GetPageStyle( aBlock.aStart.Tab() );
     664           0 :         SfxStyleSheetBase* pStyleSheet = pStylePool->Find( aStyleName, SFX_STYLE_FAMILY_PAGE );
     665           0 :         if (pStyleSheet)
     666             :         {
     667           0 :             const SfxItemSet& rSourceSet = pStyleSheet->GetItemSet();
     668           0 :             aPaperSize = static_cast<const SvxSizeItem&>( rSourceSet.Get(ATTR_PAGE_SIZE)).GetSize();
     669             : 
     670             :             //  CopyStyleFrom kopiert SetItems mit richtigem Pool
     671           0 :             ScStyleSheetPool* pDestPool = rDestDoc.GetStyleSheetPool();
     672           0 :             pDestPool->CopyStyleFrom( pStylePool, aStyleName, SFX_STYLE_FAMILY_PAGE );
     673             :         }
     674             : 
     675           0 :         ScViewData aViewData( pDocSh, NULL );
     676           0 :         aViewData.SetScreen( nStartX,nStartY, nEndX,nEndY );
     677           0 :         aViewData.SetCurX( nStartX );
     678           0 :         aViewData.SetCurY( nStartY );
     679             : 
     680           0 :         rDestDoc.SetViewOptions( pDoc->GetViewOptions() );
     681             : 
     682             :         //      Size
     683             :         //! get while copying sizes
     684             : 
     685           0 :         long nPosX = 0;
     686           0 :         long nPosY = 0;
     687             : 
     688           0 :         for (nCol=0; nCol<nStartX; nCol++)
     689           0 :             nPosX += rDestDoc.GetColWidth( nCol, 0 );
     690           0 :         nPosY += rDestDoc.GetRowHeight( 0, nStartY-1, 0 );
     691           0 :         nPosX = (long) ( nPosX * HMM_PER_TWIPS );
     692           0 :         nPosY = (long) ( nPosY * HMM_PER_TWIPS );
     693             : 
     694           0 :         aPaperSize.Width()  *= 2;       // limit OLE object to double of page size
     695           0 :         aPaperSize.Height() *= 2;
     696             : 
     697           0 :         long nSizeX = 0;
     698           0 :         long nSizeY = 0;
     699           0 :         for (nCol=nStartX; nCol<=nEndX; nCol++)
     700             :         {
     701           0 :             long nAdd = rDestDoc.GetColWidth( nCol, 0 );
     702           0 :             if ( bLimitToPageSize && nSizeX+nAdd > aPaperSize.Width() && nSizeX )   // above limit?
     703           0 :                 break;
     704           0 :             nSizeX += nAdd;
     705             :         }
     706           0 :         for (SCROW nRow=nStartY; nRow<=nEndY; nRow++)
     707             :         {
     708           0 :             long nAdd = rDestDoc.GetRowHeight( nRow, 0 );
     709           0 :             if ( bLimitToPageSize && nSizeY+nAdd > aPaperSize.Height() && nSizeY )  // above limit?
     710           0 :                 break;
     711           0 :             nSizeY += nAdd;
     712             :         }
     713           0 :         nSizeX = (long) ( nSizeX * HMM_PER_TWIPS );
     714           0 :         nSizeY = (long) ( nSizeY * HMM_PER_TWIPS );
     715             : 
     716             : //      pDocSh->SetVisAreaSize( Size(nSizeX,nSizeY) );
     717             : 
     718           0 :         Rectangle aNewArea( Point(nPosX,nPosY), Size(nSizeX,nSizeY) );
     719             :         //TODO/LATER: why twice?!
     720             :         //pDocSh->SvInPlaceObject::SetVisArea( aNewArea );
     721           0 :         pDocSh->SetVisArea( aNewArea );
     722             : 
     723           0 :         pDocSh->UpdateOle(&aViewData, true);
     724             : 
     725             :         //! SetDocumentModified?
     726           0 :         if ( rDestDoc.IsChartListenerCollectionNeedsUpdate() )
     727           0 :             rDestDoc.UpdateChartListenerCollection();
     728             :     }
     729           0 : }
     730             : 
     731          11 : SfxObjectShell* ScTransferObj::SetDrawClipDoc( bool bAnyOle )
     732             : {
     733             :     // update ScGlobal::pDrawClipDocShellRef
     734             : 
     735          11 :     delete ScGlobal::pDrawClipDocShellRef;
     736          11 :     if (bAnyOle)
     737             :     {
     738             :         ScGlobal::pDrawClipDocShellRef =
     739           0 :                         new ScDocShellRef(new ScDocShell(SfxModelFlags::EMBEDDED_OBJECT | SfxModelFlags::DISABLE_EMBEDDED_SCRIPTS));      // there must be a ref
     740           0 :         (*ScGlobal::pDrawClipDocShellRef)->DoInitNew(NULL);
     741           0 :         return *ScGlobal::pDrawClipDocShellRef;
     742             :     }
     743             :     else
     744             :     {
     745          11 :         ScGlobal::pDrawClipDocShellRef = NULL;
     746          11 :         return NULL;
     747             :     }
     748             : }
     749             : 
     750           0 : void ScTransferObj::StripRefs( ScDocument* pDoc,
     751             :                     SCCOL nStartX, SCROW nStartY, SCCOL nEndX, SCROW nEndY,
     752             :                     ScDocument* pDestDoc, SCCOL nSubX, SCROW nSubY )
     753             : {
     754           0 :     if (!pDestDoc)
     755             :     {
     756           0 :         pDestDoc = pDoc;
     757             :         OSL_ENSURE(nSubX==0&&nSubY==0, "can't move within the document");
     758             :     }
     759             : 
     760             :     //  In a clipboard doc the data don't have to be on the first sheet
     761             : 
     762           0 :     SCTAB nSrcTab = 0;
     763           0 :     while (nSrcTab<pDoc->GetTableCount() && !pDoc->HasTable(nSrcTab))
     764           0 :         ++nSrcTab;
     765           0 :     SCTAB nDestTab = 0;
     766           0 :     while (nDestTab<pDestDoc->GetTableCount() && !pDestDoc->HasTable(nDestTab))
     767           0 :         ++nDestTab;
     768             : 
     769           0 :     if (!pDoc->HasTable(nSrcTab) || !pDestDoc->HasTable(nDestTab))
     770             :     {
     771             :         OSL_FAIL("Sheet not found in ScTransferObj::StripRefs");
     772           0 :         return;
     773             :     }
     774             : 
     775           0 :     ScRange aRef;
     776             : 
     777           0 :     ScCellIterator aIter( pDoc, ScRange(nStartX, nStartY, nSrcTab, nEndX, nEndY, nSrcTab) );
     778           0 :     for (bool bHas = aIter.first(); bHas; bHas = aIter.next())
     779             :     {
     780           0 :         if (aIter.getType() != CELLTYPE_FORMULA)
     781           0 :             continue;
     782             : 
     783           0 :         ScFormulaCell* pFCell = aIter.getFormulaCell();
     784           0 :         bool bOut = false;
     785           0 :         ScDetectiveRefIter aRefIter( pFCell );
     786           0 :         while ( !bOut && aRefIter.GetNextRef( aRef ) )
     787             :         {
     788           0 :             if ( aRef.aStart.Tab() != nSrcTab || aRef.aEnd.Tab() != nSrcTab ||
     789           0 :                     aRef.aStart.Col() < nStartX || aRef.aEnd.Col() > nEndX ||
     790           0 :                     aRef.aStart.Row() < nStartY || aRef.aEnd.Row() > nEndY )
     791           0 :                 bOut = true;
     792             :         }
     793           0 :         if (bOut)
     794             :         {
     795           0 :             SCCOL nCol = aIter.GetPos().Col() - nSubX;
     796           0 :             SCROW nRow = aIter.GetPos().Row() - nSubY;
     797             : 
     798           0 :             sal_uInt16 nErrCode = pFCell->GetErrCode();
     799           0 :             ScAddress aPos(nCol, nRow, nDestTab);
     800           0 :             if (nErrCode)
     801             :             {
     802           0 :                 if ( static_cast<const SvxHorJustifyItem*>(pDestDoc->GetAttr(
     803           0 :                         nCol,nRow,nDestTab, ATTR_HOR_JUSTIFY))->GetValue() ==
     804             :                         SVX_HOR_JUSTIFY_STANDARD )
     805             :                     pDestDoc->ApplyAttr( nCol,nRow,nDestTab,
     806           0 :                             SvxHorJustifyItem(SVX_HOR_JUSTIFY_RIGHT, ATTR_HOR_JUSTIFY) );
     807             : 
     808           0 :                 ScSetStringParam aParam;
     809           0 :                 aParam.setTextInput();
     810           0 :                 pDestDoc->SetString(aPos, ScGlobal::GetErrorString(nErrCode), &aParam);
     811             :             }
     812           0 :             else if (pFCell->IsValue())
     813             :             {
     814           0 :                 pDestDoc->SetValue(aPos, pFCell->GetValue());
     815             :             }
     816             :             else
     817             :             {
     818           0 :                 OUString aStr = pFCell->GetString().getString();
     819           0 :                 if ( pFCell->IsMultilineResult() )
     820             :                 {
     821           0 :                     ScFieldEditEngine& rEngine = pDestDoc->GetEditEngine();
     822           0 :                     rEngine.SetText(aStr);
     823           0 :                     pDestDoc->SetEditText(ScAddress(nCol,nRow,nDestTab), rEngine.CreateTextObject());
     824             :                 }
     825             :                 else
     826             :                 {
     827           0 :                     ScSetStringParam aParam;
     828           0 :                     aParam.setTextInput();
     829           0 :                     pDestDoc->SetString(aPos, aStr, &aParam);
     830           0 :                 }
     831             :             }
     832             :         }
     833           0 :     }
     834             : }
     835             : 
     836             : namespace
     837             : {
     838             :     class theScTransferUnoTunnelId : public rtl::Static< UnoTunnelIdInit, theScTransferUnoTunnelId> {};
     839             : }
     840             : 
     841           0 : const com::sun::star::uno::Sequence< sal_Int8 >& ScTransferObj::getUnoTunnelId()
     842             : {
     843           0 :     return theScTransferUnoTunnelId::get().getSeq();
     844             : }
     845             : 
     846           0 : sal_Int64 SAL_CALL ScTransferObj::getSomething( const com::sun::star::uno::Sequence< sal_Int8 >& rId ) throw( com::sun::star::uno::RuntimeException, std::exception )
     847             : {
     848             :     sal_Int64 nRet;
     849           0 :     if( ( rId.getLength() == 16 ) &&
     850           0 :         ( 0 == memcmp( getUnoTunnelId().getConstArray(), rId.getConstArray(), 16 ) ) )
     851             :     {
     852           0 :         nRet = reinterpret_cast< sal_Int64 >( this );
     853             :     }
     854             :     else
     855           0 :         nRet = TransferableHelper::getSomething(rId);
     856           0 :     return nRet;
     857         156 : }
     858             : 
     859             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11