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


Hi Kohei,

On 27/07/11 19:23, Kohei Yoshida wrote:
Hi Noel,

On Wed, 2011-07-27 at 11:50 +0100, Noel Power wrote:
I would really like to get this patch into 3.4,
[...]
Hmm... did you forget to attach your patch by any chance?
yes, ouch I did forget  :-) ( although it is attached to the bug )
   I tried to
cherry-pick the commits you referenced from master, but they don't apply
cleanly...
well, I didn't want the master fix going into 3.4 ( slightly nervous as it affects the core CopyToClip )

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..09a4e5c 100644
--- sc/source/ui/vba/vbarange.cxx
+++ sc/source/ui/vba/vbarange.cxx
@@ -2597,8 +2597,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 );
@@ -2616,11 +2614,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.