Date: prev next · Thread: first prev next last
2011 Archives by date, by thread · List index


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.