diff options
-rw-r--r-- | sc/inc/document.hxx | 5 | ||||
-rw-r--r-- | sc/source/core/data/document.cxx | 56 | ||||
-rw-r--r-- | sc/source/ui/inc/viewfunc.hxx | 4 | ||||
-rw-r--r-- | sc/source/ui/vba/excelvbahelper.cxx | 13 | ||||
-rw-r--r-- | sc/source/ui/vba/excelvbahelper.hxx | 3 | ||||
-rw-r--r-- | sc/source/ui/vba/vbarange.cxx | 25 | ||||
-rw-r--r-- | sc/source/ui/view/viewfun3.cxx | 181 |
7 files changed, 118 insertions, 169 deletions
diff --git a/sc/inc/document.hxx b/sc/inc/document.hxx index 7dd81a6ed..4d1c3078e 100644 --- a/sc/inc/document.hxx +++ b/sc/inc/document.hxx @@ -1030,10 +1030,7 @@ public: void CopyToClip(const ScClipParam& rClipParam, ScDocument* pClipDoc, const ScMarkData* pMarks = NULL, bool bAllTabs = false, bool bKeepScenarioFlags = false, - bool bIncludeObjects = false, bool bCloneNoteCaptions = true); - - void CopyToClip4VBA(const ScClipParam& rClipParam, ScDocument* pClipDoc, bool bKeepScenarioFlags = false, - bool bIncludeObjects = false, bool bCloneNoteCaptions = true); + bool bIncludeObjects = false, bool bCloneNoteCaptions = true, bool bUseRangeForVBA = false ); void CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument* pClipDoc = NULL); diff --git a/sc/source/core/data/document.cxx b/sc/source/core/data/document.cxx index e21b87806..62e48c54d 100644 --- a/sc/source/core/data/document.cxx +++ b/sc/source/core/data/document.cxx @@ -1860,9 +1860,12 @@ void ScDocument::UndoToDocument(const ScRange& rRange, pDestDoc->SetAutoCalc( bOldAutoCalc ); } +// bUseRangeForVBA added for VBA api support to allow content of a specified +// range to be copied ( e.g. don't use marked data but the just the range +// specified by rClipParam void ScDocument::CopyToClip(const ScClipParam& rClipParam, ScDocument* pClipDoc, const ScMarkData* pMarks, - bool bAllTabs, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions) + bool bAllTabs, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions, bool bUseRangeForVBA ) { OSL_ENSURE( bAllTabs || pMarks, "CopyToClip: ScMarkData fails" ); @@ -1877,12 +1880,23 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, pClipDoc->aDocName = aDocName; pClipDoc->SetClipParam(rClipParam); - pClipDoc->ResetClip(this, pMarks); - ScRange aClipRange = rClipParam.getWholeRange(); + SCTAB nTab = aClipRange.aStart.Tab(); + SCTAB i = 0; + SCTAB nEndTab = static_cast<SCTAB>(maTabs.size()); + + if ( bUseRangeForVBA ) + { + pClipDoc->ResetClip( this, nTab ); + i = nTab; + nEndTab = nTab; + } + else + pClipDoc->ResetClip(this, pMarks); + CopyRangeNamesToClip(pClipDoc, aClipRange, pMarks, bAllTabs); - for (SCTAB i = 0; i < static_cast<SCTAB>(maTabs.size()); ++i) + for ( ; i < nTab; ++i) { if (!maTabs[i] || i >= static_cast<SCTAB>(pClipDoc->maTabs.size()) || !pClipDoc->maTabs[i]) continue; @@ -1905,40 +1919,6 @@ void ScDocument::CopyToClip(const ScClipParam& rClipParam, pClipDoc->ExtendMerge(aClipRange, true); } -// Copy the content of the Range into clipboard. Adding this method for VBA API: Range.Copy(). -void ScDocument::CopyToClip4VBA(const ScClipParam& rClipParam, ScDocument* pClipDoc, bool bKeepScenarioFlags, bool bIncludeObjects, bool bCloneNoteCaptions) -{ - if ( !bIsClip ) - { - pClipDoc = pClipDoc ? pClipDoc : SC_MOD()->GetClipDoc(); - if ( !pClipDoc ) - { - return; - } - ScRange aClipRange = rClipParam.getWholeRange(); - SCTAB nTab = aClipRange.aStart.Tab(); - pClipDoc->aDocName = aDocName; - pClipDoc->SetClipParam( rClipParam ); - pClipDoc->ResetClip( this, nTab ); - - CopyRangeNamesToClip( pClipDoc, aClipRange, nTab ); - if ( nTab < static_cast<SCTAB>(maTabs.size()) && nTab < static_cast<SCTAB>(pClipDoc->maTabs.size()) ) - if ( maTabs[nTab] && pClipDoc->maTabs[nTab] ) - { - maTabs[nTab]->CopyToClip( rClipParam.maRanges, pClipDoc->maTabs[nTab], bKeepScenarioFlags, bCloneNoteCaptions ); - if ( pDrawLayer && bIncludeObjects ) - { - // Also copy drawing objects. - Rectangle aObjRect = GetMMRect( aClipRange.aStart.Col(), aClipRange.aStart.Row(), aClipRange.aEnd.Col(), aClipRange.aEnd.Row(), nTab ); - pDrawLayer->CopyToClip( pClipDoc, nTab, aObjRect ); - } - } - - // Make sure to mark overlapped cells. - pClipDoc->ExtendMerge( aClipRange, true ); - } -} - void ScDocument::CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2, SCTAB nTab, ScDocument* pClipDoc) diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx index 090411843..40147db40 100644 --- a/sc/source/ui/inc/viewfunc.hxx +++ b/sc/source/ui/inc/viewfunc.hxx @@ -108,8 +108,8 @@ public: SC_DLLPUBLIC void CutToClip( ScDocument* pClipDoc = NULL, sal_Bool bIncludeObjects = false ); SC_DLLPUBLIC sal_Bool CopyToClip( ScDocument* pClipDoc = NULL, sal_Bool bCut = false, sal_Bool bApi = false, sal_Bool bIncludeObjects = false, sal_Bool bStopEdit = true ); - SC_DLLPUBLIC sal_Bool CopyToClip( ScDocument* pClipDoc, const ScRange& rRange, sal_Bool bCut = false, - sal_Bool bApi = false, sal_Bool bIncludeObjects = false, sal_Bool bStopEdit = true ); + SC_DLLPUBLIC sal_Bool CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRange, sal_Bool bCut = false, + sal_Bool bApi = false, sal_Bool bIncludeObjects = false, sal_Bool bStopEdit = true, sal_Bool bUseRangeForVBA = true ); ScTransferObj* CopyToTransferable(); SC_DLLPUBLIC sal_Bool PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc, sal_uInt16 nFunction = PASTE_NOFUNC, sal_Bool bSkipEmpty = false, diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx index bad9fdf53..027cfd90c 100644 --- a/sc/source/ui/vba/excelvbahelper.cxx +++ b/sc/source/ui/vba/excelvbahelper.cxx @@ -275,13 +275,22 @@ void implnPasteSpecial( const uno::Reference< frame::XModel>& xModel, sal_uInt16 } -void implnCopyRange( const uno::Reference< frame::XModel>& xModel, const ScRange& rRange ) +bool implnCopyRanges( const uno::Reference< frame::XModel>& xModel, ScRangeList& rRangeList ) { + bool bResult = false; ScTabViewShell* pViewShell = getBestViewShell( xModel ); if ( pViewShell ) { - pViewShell->CopyToClip( NULL, rRange, false, true, true ); + bResult = pViewShell->CopyToClip( NULL, rRangeList, false, true, true ); } + return bResult; +} + +bool implnCopyRange( const uno::Reference< frame::XModel>& xModel, const ScRange& rRange ) +{ + ScRangeList aRanges; + aRanges.Append( rRange ); + return implnCopyRanges( xModel, aRanges ); } ScDocShell* diff --git a/sc/source/ui/vba/excelvbahelper.hxx b/sc/source/ui/vba/excelvbahelper.hxx index af791040a..eb3e88e78 100644 --- a/sc/source/ui/vba/excelvbahelper.hxx +++ b/sc/source/ui/vba/excelvbahelper.hxx @@ -54,7 +54,8 @@ void implnCopy( const css::uno::Reference< css::frame::XModel>& xModel ); void implnPaste ( const css::uno::Reference< css::frame::XModel>& xModel ); void implnCut( const css::uno::Reference< css::frame::XModel>& xModel ); void implnPasteSpecial( const css::uno::Reference< css::frame::XModel>& xModel, sal_uInt16 nFlags,sal_uInt16 nFunction,sal_Bool bSkipEmpty, sal_Bool bTranspose); -void implnCopyRange( const css::uno::Reference< css::frame::XModel>& xModel, const ScRange& rRange ); +bool implnCopyRanges( const css::uno::Reference< css::frame::XModel>& xModel, ScRangeList& rRange ); +bool implnCopyRange( const css::uno::Reference< css::frame::XModel>& xModel, const ScRange& rRange ); ScTabViewShell* getBestViewShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; ScDocShell* getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) ; ScTabViewShell* getCurrentBestViewShell( const css::uno::Reference< css::uno::XComponentContext >& xContext ); diff --git a/sc/source/ui/vba/vbarange.cxx b/sc/source/ui/vba/vbarange.cxx index 4076ba874..5ecf30b23 100644 --- a/sc/source/ui/vba/vbarange.cxx +++ b/sc/source/ui/vba/vbarange.cxx @@ -2596,8 +2596,6 @@ ScVbaRange::getMergeCells() throw (script::BasicErrorException, uno::RuntimeExce void ScVbaRange::Copy(const ::uno::Any& Destination) throw (uno::RuntimeException) { - if ( m_Areas->getCount() > 1 ) - throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() ); if ( Destination.hasValue() ) { uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW ); @@ -2615,11 +2613,24 @@ ScVbaRange::Copy(const ::uno::Any& Destination) throw (uno::RuntimeException) } else { - ScRange aRange; - RangeHelper thisRange( mxRange ); - ScUnoConversion::FillScRange( aRange, thisRange.getCellRangeAddressable()->getRangeAddress() ); - uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRange ); - excel::implnCopyRange( xModel, aRange ); + if ( m_Areas->getCount() > 1 ) + { + uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRanges ); + ScCellRangesBase* pUnoRangesBase = getCellRangesBase(); + ScRangeList aList = pUnoRangesBase->GetRangeList(); + if ( !excel::implnCopyRanges( xModel, aList ) ) + { + throw uno::RuntimeException( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("That command cannot be used on multiple selections" ) ), uno::Reference< uno::XInterface >() ); + } + } + else + { + ScRange aRange; + RangeHelper thisRange( mxRange ); + uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRange ); + ScUnoConversion::FillScRange( aRange, thisRange.getCellRangeAddressable()->getRangeAddress() ); + excel::implnCopyRange( xModel, aRange ); + } } } diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx index 1853ab246..90e645e93 100644 --- a/sc/source/ui/view/viewfun3.cxx +++ b/sc/source/ui/view/viewfun3.cxx @@ -276,14 +276,11 @@ void ScViewFunc::CutToClip( ScDocument* pClipDoc, sal_Bool bIncludeObjects ) sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit ) { - sal_Bool bDone = false; - if ( bStopEdit ) - UpdateInputLine(); - ScRange aRange; ScMarkType eMarkType = GetViewData()->GetSimpleArea( aRange ); ScDocument* pDoc = GetViewData()->GetDocument(); ScMarkData& rMark = GetViewData()->GetMarkData(); + sal_Bool bDone = sal_False; if( !pClipDoc ) // System Copy - adjust the ranges. { @@ -305,37 +302,76 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b } if ( eMarkType == SC_MARK_SIMPLE || eMarkType == SC_MARK_SIMPLE_FILTERED ) { - if ( !pDoc->HasSelectedBlockMatrixFragment( - aRange.aStart.Col(), aRange.aStart.Row(), - aRange.aEnd.Col(), aRange.aEnd.Row(), - rMark ) ) + ScRangeList aRangeList; + aRangeList.Append( aRange ); + bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit, sal_False ); + } + else if (eMarkType == SC_MARK_MULTI) + { + ScRangeList aRangeList; + rMark.MarkToSimple(); + rMark.FillRangeListWithMarks(&aRangeList, false); + bDone = CopyToClip( pClipDoc, aRangeList, bCut, bApi, bIncludeObjects, bStopEdit, sal_False ); + } + else + { + if (!bApi) + ErrorMessage(STR_NOMULTISELECT); + } + + return bDone; +} + +// Copy the content of the Range into clipboard. Adding this method for VBA API: Range.Copy(). +// also combine the old content of CopyToClip method to share this implementation +sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit, sal_Bool bUseRangeForVBA ) +{ + if ( rRanges.empty() ) + return false; + sal_Bool bDone = false; + if ( bStopEdit ) + UpdateInputLine(); + + ScRange aRange = *rRanges[0]; + ScClipParam aClipParam( aRange, bCut ); + aClipParam.maRanges = rRanges; + + ScDocument* pDoc = GetViewData()->GetDocument(); + ScMarkData& rMark = GetViewData()->GetMarkData(); + + if ( !aClipParam.isMultiRange() ) + { + if ( pDoc && ( ( bUseRangeForVBA && !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ) ) || ( !bUseRangeForVBA && !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), rMark ) ) ) ) { sal_Bool bSysClip = false; if ( !pClipDoc ) // no clip doc specified { - pClipDoc = new ScDocument( SCDOCMODE_CLIP ); // create one (deleted by ScTransferObj) + // Create one (deleted by ScTransferObj). + pClipDoc = new ScDocument( SCDOCMODE_CLIP ); bSysClip = sal_True; // and copy into system } - if ( !bCut ) { ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); if ( pChangeTrack ) - pChangeTrack->ResetLastCut(); // kein CutMode mehr + pChangeTrack->ResetLastCut(); } if ( bSysClip && bIncludeObjects ) { - sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange, &rMark ); - // update ScGlobal::pDrawClipDocShellRef + sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange ); + // Update ScGlobal::pDrawClipDocShellRef. ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); } - ScClipParam aClipParam(aRange, bCut); - aClipParam.setSourceDocID( pDoc->GetDocumentID() ); - pDoc->CopyToClip(aClipParam, pClipDoc, &rMark, false, false, bIncludeObjects); + if ( !bUseRangeForVBA ) + // is this necessary?, will setting the doc id upset the + // following paste operation with range? would be nicer to just set this always + // and lose the 'if' above + aClipParam.setSourceDocID( pDoc->GetDocumentID() ); - if ( pDoc && pClipDoc ) + pDoc->CopyToClip( aClipParam, pClipDoc, &rMark, false, bIncludeObjects, bUseRangeForVBA ); + if ( !bUseRangeForVBA && pDoc && pClipDoc ) { ScDrawLayer* pDrawLayer = pClipDoc->GetDrawLayer(); if ( pDrawLayer ) @@ -354,15 +390,14 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b } } - if (bSysClip) + if ( bSysClip ) { ScDrawLayer::SetGlobalDrawPersist(NULL); - ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) ); } - pClipDoc->ExtendMerge( aRange, sal_True ); + pClipDoc->ExtendMerge( aRange, true ); - if (bSysClip) + if ( bSysClip ) { ScDocShell* pDocSh = GetViewData()->GetDocShell(); TransferableObjectDescriptor aObjDesc; @@ -372,32 +407,23 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); - if ( ScGlobal::pDrawClipDocShellRef ) { SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) ); - pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive - } + pTransferObj->SetDrawPersist( aPersistRef );// keep persist for ole objects alive - pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard - SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard + } + pTransferObj->CopyToClipboard( GetActiveWin() ); + SC_MOD()->SetClipObject( pTransferObj, NULL ); } - bDone = sal_True; - } - else - { - if (!bApi) - ErrorMessage(STR_MATRIXFRAGMENTERR); + bDone = true; } } - else if (eMarkType == SC_MARK_MULTI) + else { bool bSuccess = false; - ScClipParam aClipParam; aClipParam.mbCutMode = false; - rMark.MarkToSimple(); - rMark.FillRangeListWithMarks(&aClipParam.maRanges, false); do { @@ -423,8 +449,9 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b for ( size_t i = 1; i < aClipParam.maRanges.size(); ++i ) { p = aClipParam.maRanges[i]; - if (pDoc->HasSelectedBlockMatrixFragment( - p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark)) + if ( ( bUseRangeForVBA && pDoc->HasSelectedBlockMatrixFragment( + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), p->aStart.Tab() ) ) || ( !bUseRangeForVBA && pDoc->HasSelectedBlockMatrixFragment( + p->aStart.Col(), p->aStart.Row(), p->aEnd.Col(), p->aEnd.Row(), rMark) ) ) { if (!bApi) ErrorMessage(STR_MATRIXFRAGMENTERR); @@ -474,8 +501,7 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b } if (!bValidRanges) break; - - pDoc->CopyToClip(aClipParam, pDocClip.get(), &rMark, false, false, bIncludeObjects); + pDoc->CopyToClip(aClipParam, pDocClip.get(), &rMark, false, false, bIncludeObjects, bUseRangeForVBA ); ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); if ( pChangeTrack ) @@ -510,81 +536,6 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b bDone = bSuccess; } - else - { - if (!bApi) - ErrorMessage(STR_NOMULTISELECT); - } - - return bDone; -} - -// Copy the content of the Range into clipboard. Adding this method for VBA API: Range.Copy(). -sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRange& rRange, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit ) -{ - sal_Bool bDone = false; - if ( bStopEdit ) - UpdateInputLine(); - - ScRange aRange = rRange; - ScDocument* pDoc = GetViewData()->GetDocument(); - if ( pDoc && !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ) ) - { - sal_Bool bSysClip = false; - if ( !pClipDoc ) - { - // Create one (deleted by ScTransferObj). - pClipDoc = new ScDocument( SCDOCMODE_CLIP ); - bSysClip = true; - } - if ( !bCut ) - { - ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack(); - if ( pChangeTrack ) - pChangeTrack->ResetLastCut(); - } - - if ( bSysClip && bIncludeObjects ) - { - sal_Bool bAnyOle = pDoc->HasOLEObjectsInArea( aRange ); - // Update ScGlobal::pDrawClipDocShellRef. - ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) ); - } - - ScClipParam aClipParam( aRange, bCut ); - pDoc->CopyToClip4VBA( aClipParam, pClipDoc, false, bIncludeObjects ); - if ( bSysClip ) - { - ScDrawLayer::SetGlobalDrawPersist(NULL); - ScGlobal::SetClipDocName( pDoc->GetDocumentShell()->GetTitle( SFX_TITLE_FULLNAME ) ); - } - pClipDoc->ExtendMerge( aRange, true ); - - if ( bSysClip ) - { - ScDocShell* pDocSh = GetViewData()->GetDocShell(); - TransferableObjectDescriptor aObjDesc; - pDocSh->FillTransferableObjectDescriptor( aObjDesc ); - aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass(); - - ScTransferObj* pTransferObj = new ScTransferObj( pClipDoc, aObjDesc ); - uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj ); - if ( ScGlobal::pDrawClipDocShellRef ) - { - SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) ); - pTransferObj->SetDrawPersist( aPersistRef ); - } - pTransferObj->CopyToClipboard( GetActiveWin() ); - SC_MOD()->SetClipObject( pTransferObj, NULL ); - } - - bDone = true; - } - else - { - if ( !bApi ) - ErrorMessage(STR_MATRIXFRAGMENTERR); - } return bDone; } |