Hi Kohei
On 28/07/11 17:48, Kohei Yoshida wrote:
Hi Noel,
[...]
where these lines ScUnoConversion::FillScRange( aRange,
thisRange.getCellRangeAddressable()->getRangeAddress() );
uno::Reference< frame::XModel > xModel = excel::GetModelFromRange(
mxRange );and the line are flipped before and after in the 'else'
scope. Unless that's intentional, I would flip these lines back to
match the original code. Let me know what you think of this, and I'll
then push to the 3-4 branch with the above lines flipped back.
If I understand what you mean then I think it is the patch output is
confusing things, what has happened is the logic has changed from ( in
psuedo code )
if ( isMultiAreaRange() )
get out of here
if ( destination is specified )
do stuff
else
process single range
to....
if ( destination is specified )
do stuff
else
if ( isMultiAreaRange() )
process multiAreaRange
else
process single range
and I think you are referring to the apparent 'flipping' of the 'process
single range' code right? if so this is intentional ( but you had me
worried :-))) )
but one thing that I didn't think of ( 'till you made me look closer )
was the handling of the 'if ( destination is specified )' leg and that I
think I need to modify to be ( to avoid a possible core dump ) - will
attach newer patch for that
if ( destination is specified )
if ( isMultiAreaRange )
get out of here
do stuff
thanks
Noel
diff --git sc/source/ui/inc/viewfunc.hxx sc/source/ui/inc/viewfunc.hxx
index deca468..5c54d76 100644
--- sc/source/ui/inc/viewfunc.hxx
+++ 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 sc/source/ui/vba/excelvbahelper.cxx sc/source/ui/vba/excelvbahelper.cxx
index cbf30eb..cc2a768 100644
--- sc/source/ui/vba/excelvbahelper.cxx
+++ 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 sc/source/ui/vba/excelvbahelper.hxx sc/source/ui/vba/excelvbahelper.hxx
index eebeaff..a5ceb81 100644
--- sc/source/ui/vba/excelvbahelper.hxx
+++ 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 sc/source/ui/vba/vbarange.cxx sc/source/ui/vba/vbarange.cxx
index 1689b13..ec60b31 100644
--- sc/source/ui/vba/vbarange.cxx
+++ 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 );
+ uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRange );
+ ScUnoConversion::FillScRange( aRange,
thisRange.getCellRangeAddressable()->getRangeAddress() );
+ excel::implnCopyRange( xModel, aRange );
+ }
}
}
diff --git sc/source/ui/view/viewfun3.cxx sc/source/ui/view/viewfun3.cxx
index 5115ab0..8358b56 100644
--- sc/source/ui/view/viewfun3.cxx
+++ 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 )
{
Context
Privacy Policy |
Impressum (Legal Info) |
Copyright information: Unless otherwise specified, all text and images
on this website are licensed under the
Creative Commons Attribution-Share Alike 3.0 License.
This does not include the source code of LibreOffice, which is
licensed under the Mozilla Public License (
MPLv2).
"LibreOffice" and "The Document Foundation" are
registered trademarks of their corresponding registered owners or are
in actual use as trademarks in one or more countries. Their respective
logos and icons are also subject to international copyright laws. Use
thereof is explained in our
trademark policy.