[Libreoffice-commits] .: Branch 'libreoffice-3-4' - sc/source
Kohei Yoshida
kohei at kemper.freedesktop.org
Fri Jul 29 08:59:55 PDT 2011
sc/source/ui/inc/viewfunc.hxx | 2
sc/source/ui/vba/excelvbahelper.cxx | 13 +++
sc/source/ui/vba/excelvbahelper.hxx | 3
sc/source/ui/vba/vbarange.cxx | 26 +++++--
sc/source/ui/view/viewfun3.cxx | 129 ++++++++++++++++++++++++++++++++++--
5 files changed, 158 insertions(+), 15 deletions(-)
New commits:
commit 66e69633b4de68663859e481a15bbc8be628f6ba
Author: Noel Power <nopower at novell.com>
Date: Fri Jul 29 10:47:53 2011 -0400
bnc#707486: Allow multi-range copy from VBA.
Signed-off-by: Kohei Yoshida <kyoshida at novell.com>
diff --git a/sc/source/ui/inc/viewfunc.hxx b/sc/source/ui/inc/viewfunc.hxx
index deca468..5c54d76 100644
--- a/sc/source/ui/inc/viewfunc.hxx
+++ b/sc/source/ui/inc/viewfunc.hxx
@@ -108,7 +108,7 @@ 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,
+ 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 );
ScTransferObj* CopyToTransferable();
SC_DLLPUBLIC sal_Bool PasteFromClip( sal_uInt16 nFlags, ScDocument* pClipDoc,
diff --git a/sc/source/ui/vba/excelvbahelper.cxx b/sc/source/ui/vba/excelvbahelper.cxx
index cbf30eb..cc2a768 100644
--- a/sc/source/ui/vba/excelvbahelper.cxx
+++ b/sc/source/ui/vba/excelvbahelper.cxx
@@ -286,13 +286,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 eebeaff..a5ceb81 100644
--- a/sc/source/ui/vba/excelvbahelper.hxx
+++ b/sc/source/ui/vba/excelvbahelper.hxx
@@ -55,7 +55,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 1689b13..a5670d7 100644
--- a/sc/source/ui/vba/vbarange.cxx
+++ b/sc/source/ui/vba/vbarange.cxx
@@ -2597,10 +2597,11 @@ 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() )
{
+ // #TODO support ( if necessary ) multi-area range in this scenario
+ 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 >() );
uno::Reference< excel::XRange > xRange( Destination, uno::UNO_QUERY_THROW );
uno::Any aRange = xRange->getCellRange();
uno::Reference< table::XCellRange > xCellRange;
@@ -2616,11 +2617,22 @@ 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 );
+ ScUnoConversion::FillScRange( aRange, thisRange.getCellRangeAddressable()->getRangeAddress() );
+ uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRange );
+ excel::implnCopyRange( xModel, aRange );
+ }
}
}
diff --git a/sc/source/ui/view/viewfun3.cxx b/sc/source/ui/view/viewfun3.cxx
index 5115ab0..8358b56 100644
--- a/sc/source/ui/view/viewfun3.cxx
+++ b/sc/source/ui/view/viewfun3.cxx
@@ -501,15 +501,137 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, sal_Bool bCut, sal_Bool b
}
// 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 ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRangeList& rRanges, sal_Bool bCut, sal_Bool bApi, sal_Bool bIncludeObjects, sal_Bool bStopEdit )
{
+ if ( rRanges.empty() )
+ return false;
sal_Bool bDone = false;
if ( bStopEdit )
UpdateInputLine();
- ScRange aRange = rRange;
+ ScRange aRange = *rRanges[0];
+ ScClipParam aClipParam( aRange, bCut );
+ aClipParam.maRanges = rRanges;
+
ScDocument* pDoc = GetViewData()->GetDocument();
- if ( pDoc && !pDoc->HasSelectedBlockMatrixFragment( aRange.aStart.Col(), aRange.aStart.Row(), aRange.aEnd.Col(), aRange.aEnd.Row(), aRange.aStart.Tab() ) )
+
+ if ( aClipParam.isMultiRange() )
+ {
+ bool bSuccess = false;
+ aClipParam.mbCutMode = false;
+
+ do
+ {
+ if (bCut)
+ // We con't support cutting of multi-selections.
+ break;
+
+ if (pClipDoc)
+ // TODO: What's this for?
+ break;
+
+ ::std::auto_ptr<ScDocument> pDocClip(new ScDocument(SCDOCMODE_CLIP));
+
+ // Check for geometrical feasibility of the ranges.
+ bool bValidRanges = true;
+ ScRange* p = aClipParam.maRanges.front();
+ SCCOL nPrevColDelta = 0;
+ SCROW nPrevRowDelta = 0;
+ SCCOL nPrevCol = p->aStart.Col();
+ SCROW nPrevRow = p->aStart.Row();
+ SCCOL nPrevColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nPrevRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+ 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(), p->aStart.Tab() ))
+ {
+ if (!bApi)
+ ErrorMessage(STR_MATRIXFRAGMENTERR);
+ return false;
+ }
+
+ SCCOL nColDelta = p->aStart.Col() - nPrevCol;
+ SCROW nRowDelta = p->aStart.Row() - nPrevRow;
+
+ if ((nColDelta && nRowDelta) || (nPrevColDelta && nRowDelta) || (nPrevRowDelta && nColDelta))
+ {
+ bValidRanges = false;
+ break;
+ }
+
+ if (aClipParam.meDirection == ScClipParam::Unspecified)
+ {
+ if (nColDelta)
+ aClipParam.meDirection = ScClipParam::Column;
+ if (nRowDelta)
+ aClipParam.meDirection = ScClipParam::Row;
+ }
+
+ SCCOL nColSize = p->aEnd.Col() - p->aStart.Col() + 1;
+ SCROW nRowSize = p->aEnd.Row() - p->aStart.Row() + 1;
+
+ if (aClipParam.meDirection == ScClipParam::Column && nRowSize != nPrevRowSize)
+ {
+ // column-oriented ranges must have identical row size.
+ bValidRanges = false;
+ break;
+ }
+ if (aClipParam.meDirection == ScClipParam::Row && nColSize != nPrevColSize)
+ {
+ // likewise, row-oriented ranges must have identical
+ // column size.
+ bValidRanges = false;
+ break;
+ }
+
+ nPrevCol = p->aStart.Col();
+ nPrevRow = p->aStart.Row();
+ nPrevColDelta = nColDelta;
+ nPrevRowDelta = nRowDelta;
+ nPrevColSize = nColSize;
+ nPrevRowSize = nRowSize;
+ }
+ if (!bValidRanges)
+ break;
+
+ pDoc->CopyToClip4VBA( aClipParam, pClipDoc, false, bIncludeObjects );
+
+ ScChangeTrack* pChangeTrack = pDoc->GetChangeTrack();
+ if ( pChangeTrack )
+ pChangeTrack->ResetLastCut(); // kein CutMode mehr
+
+ {
+ ScDocShell* pDocSh = GetViewData()->GetDocShell();
+ TransferableObjectDescriptor aObjDesc;
+ pDocSh->FillTransferableObjectDescriptor( aObjDesc );
+ aObjDesc.maDisplayName = pDocSh->GetMedium()->GetURLObject().GetURLNoPass();
+ // maSize is set in ScTransferObj ctor
+
+ ScTransferObj* pTransferObj = new ScTransferObj( pDocClip.release(), aObjDesc );
+ uno::Reference<datatransfer::XTransferable> xTransferable( pTransferObj );
+
+ if ( ScGlobal::pDrawClipDocShellRef )
+ {
+ SfxObjectShellRef aPersistRef( &(*ScGlobal::pDrawClipDocShellRef) );
+ pTransferObj->SetDrawPersist( aPersistRef ); // keep persist for ole objects alive
+ }
+
+ pTransferObj->CopyToClipboard( GetActiveWin() ); // system clipboard
+ SC_MOD()->SetClipObject( pTransferObj, NULL ); // internal clipboard
+ }
+
+ bSuccess = true;
+ }
+ while (false);
+
+ if (!bSuccess && !bApi)
+ ErrorMessage(STR_NOMULTISELECT);
+
+ bDone = bSuccess;
+ }
+ else 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 )
@@ -532,7 +654,6 @@ sal_Bool ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRange& rRange, sa
ScDrawLayer::SetGlobalDrawPersist( ScTransferObj::SetDrawClipDoc( bAnyOle ) );
}
- ScClipParam aClipParam( aRange, bCut );
pDoc->CopyToClip4VBA( aClipParam, pClipDoc, false, bIncludeObjects );
if ( bSysClip )
{
More information about the Libreoffice-commits
mailing list