1. mst
  2. ooo340

Commits

lihui  committed 3d93a35

Fix for issue: 112998

  • Participants
  • Parent commits 7111298
  • Branches default

Comments (0)

Files changed (7)

File sc/inc/document.hxx

View file
 	BOOL			HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow,
 											SCCOL nEndCol, SCROW nEndRow,
 											const ScMarkData& rMark ) const;
+	BOOL			HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTAB ) const;
 
 	BOOL			GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix );
 
                                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);
+
     void			CopyTabToClip(SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
                                 SCTAB nTab, ScDocument* pClipDoc = NULL);
 	void 			CopyBlockFromClip( SCCOL nCol1, SCROW nRow1, SCCOL nCol2, SCROW nRow2,
 							 const ScRange& r, SCsCOL nDx, SCsROW nDy, SCsTAB nDz );
 
     void    CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, const ScMarkData* pMarks, bool bAllTabs);
+    void    CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, SCTAB nTab);
     void    CopyRangeNamesFromClip(ScDocument* pClipDoc, ScClipRangeNameData& rRangeNames);
     void    UpdateRangeNamesInFormulas(
         ScClipRangeNameData& rRangeNames, const ScRangeList& rDestRanges, const ScMarkData& rMark,

File sc/source/core/data/document.cxx

View file
     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 ( pTab[nTab] && pClipDoc->pTab[nTab] )
+		{
+			pTab[nTab]->CopyToClip( rClipParam.maRanges, pClipDoc->pTab[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)
     }
 }
 
+void ScDocument::CopyRangeNamesToClip(ScDocument* pClipDoc, const ScRange& rClipRange, SCTAB nTab)
+{
+	// Indexes of named ranges that are used in the copied cells
+	std::set<USHORT> aUsedNames;
+	if ( pTab[nTab] && pClipDoc->pTab[nTab] )
+	{
+		pTab[nTab]->FindRangeNamesInUse( rClipRange.aStart.Col(), rClipRange.aStart.Row(), rClipRange.aEnd.Col(), rClipRange.aEnd.Row(), aUsedNames );
+	}
+
+	pClipDoc->pRangeName->FreeAll();
+	for ( USHORT i = 0; i < pRangeName->GetCount(); i++ )
+	{
+		USHORT nIndex = ((ScRangeData*)((*pRangeName)[i]))->GetIndex();
+		bool bInUse = ( aUsedNames.find(nIndex) != aUsedNames.end() );
+		if ( bInUse )
+		{
+			ScRangeData* pData = new ScRangeData(*((*pRangeName)[i]));
+			if ( !pClipDoc->pRangeName->Insert(pData) )
+				delete pData;
+			else
+				pData->SetIndex(nIndex);
+		}
+	}
+}
+
 ScDocument::NumFmtMergeHandler::NumFmtMergeHandler(ScDocument* pDoc, ScDocument* pSrcDoc) :
         mpDoc(pDoc)
 {
 	return !bOk;
 }
 
+BOOL ScDocument::HasSelectedBlockMatrixFragment( SCCOL nStartCol, SCROW nStartRow, SCCOL nEndCol, SCROW nEndRow, SCTAB nTab ) const
+{
+	BOOL bOk = TRUE;
+	if ( pTab[nTab] && pTab[nTab]->HasBlockMatrixFragment( nStartCol, nStartRow, nEndCol, nEndRow ) )
+	{
+		bOk = FALSE;
+	}
+	return !bOk;
+}
 
 BOOL ScDocument::GetMatrixFormulaRange( const ScAddress& rCellPos, ScRange& rMatrix )
 {

File sc/source/ui/inc/viewfunc.hxx

View file
 	SC_DLLPUBLIC void			CutToClip( ScDocument* pClipDoc = NULL, BOOL bIncludeObjects = FALSE );
 	SC_DLLPUBLIC BOOL			CopyToClip( ScDocument* pClipDoc = NULL, BOOL bCut = FALSE, BOOL bApi = FALSE,
 								BOOL bIncludeObjects = FALSE, BOOL bStopEdit = TRUE );
+	SC_DLLPUBLIC BOOL			CopyToClip( ScDocument* pClipDoc, const ScRange& rRange, BOOL bCut = FALSE, 
+								BOOL bApi = FALSE, BOOL bIncludeObjects = FALSE, BOOL bStopEdit = TRUE );
     ScTransferObj*              CopyToTransferable();
 	SC_DLLPUBLIC BOOL			PasteFromClip( USHORT nFlags, ScDocument* pClipDoc,
 									USHORT nFunction = PASTE_NOFUNC, BOOL bSkipEmpty = FALSE,

File sc/source/ui/vba/excelvbahelper.cxx

View file
 
 }
 
+void implnCopyRange( const uno::Reference< frame::XModel>& xModel, const ScRange& rRange )
+{
+	ScTabViewShell* pViewShell = getBestViewShell( xModel );
+	if ( pViewShell )
+	{
+		pViewShell->CopyToClip( NULL, rRange, FALSE, TRUE, TRUE );
+	}
+}
+
 ScDocShell* 
 getDocShell( const css::uno::Reference< css::frame::XModel>& xModel ) 
 {

File sc/source/ui/vba/excelvbahelper.hxx

View file
             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 );
             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 );

File sc/source/ui/vba/vbarange.cxx

View file
 	}
 	else
 	{
+		ScRange aRange;
+		RangeHelper thisRange( mxRange );
+		ScUnoConversion::FillScRange( aRange, thisRange.getCellRangeAddressable()->getRangeAddress() );
 		uno::Reference< frame::XModel > xModel = excel::GetModelFromRange( mxRange );
-		Select();
-		excel::implnCopy( xModel );
+		excel::implnCopyRange( xModel, aRange );
 	}
 }
 

File sc/source/ui/view/viewfun3.cxx

View file
 	return bDone;
 }
 
+// Copy the content of the Range into clipboard. Adding this method for VBA API: Range.Copy().
+BOOL ScViewFunc::CopyToClip( ScDocument* pClipDoc, const ScRange& rRange, BOOL bCut, BOOL bApi, BOOL bIncludeObjects, BOOL bStopEdit )
+{
+	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() ) )
+	{
+		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 )
+		{
+			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;
+}
+
 ScTransferObj* ScViewFunc::CopyToTransferable()
 {
 	ScRange aRange;