diff options
author | Ingrid Halama <iha@openoffice.org> | 2010-03-10 19:46:41 +0100 |
---|---|---|
committer | Ingrid Halama <iha@openoffice.org> | 2010-03-10 19:46:41 +0100 |
commit | ab2bbad3c25a9c3b370d75153104ce8bfb760240 (patch) | |
tree | 9abd433ae26171c946a8783287f7ffffab28f94a /sc | |
parent | 121ce9b7bc3ca740d8a53177f40d19237bc13e95 (diff) |
#i110034# while copy-paste of chart and cell ranges the chart looses its data references
Diffstat (limited to 'sc')
-rw-r--r-- | sc/source/core/data/documen5.cxx | 129 | ||||
-rwxr-xr-x | sc/source/core/data/drwlayer.cxx | 139 |
2 files changed, 101 insertions, 167 deletions
diff --git a/sc/source/core/data/documen5.cxx b/sc/source/core/data/documen5.cxx index 23951d2e6..3fd47ccb5 100644 --- a/sc/source/core/data/documen5.cxx +++ b/sc/source/core/data/documen5.cxx @@ -453,124 +453,25 @@ void ScDocument::UpdateChart( const String& rChartName ) { if (!pDrawLayer || bInDtorClear) return; - - for (SCTAB nTab=0; nTab<=MAXTAB && pTab[nTab]; nTab++) + uno::Reference< chart2::XChartDocument > xChartDoc( GetChartByName( rChartName ) ); + if( xChartDoc.is() ) { - SdrPage* pPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nTab)); - DBG_ASSERT(pPage,"Page ?"); - - SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); - SdrObject* pObject = aIter.Next(); - while (pObject) + try + { + uno::Reference< util::XModifiable > xModif( xChartDoc, uno::UNO_QUERY_THROW ); + if( apTemporaryChartLock.get() ) + apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); + xModif->setModified( sal_True ); + } + catch ( uno::Exception& ) { - if ( pObject->GetObjIdentifier() == OBJ_OLE2 && - ((SdrOle2Obj*)pObject)->GetPersistName() == rChartName ) - { - //@todo?: maybe we need a notification - //from the calc to the chart in future - //that calc content has changed - // ((SdrOle2Obj*)pObject)->GetNewReplacement(); - - // Load the object and set modified - - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - svt::EmbeddedObjectRef::TryRunningState( xIPObj ); - - try - { - uno::Reference< util::XModifiable > xModif( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - if( apTemporaryChartLock.get() ) - apTemporaryChartLock->AlsoLockThisChart( uno::Reference< frame::XModel >( xModif, uno::UNO_QUERY ) ); - xModif->setModified( sal_True ); - } - catch ( uno::Exception& ) - { - } - } - - // repaint - - pObject->ActionChanged(); - - // After the update, chart keeps track of its own data source ranges, - // the listener doesn't need to listen anymore. - - pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); - - return; - - /* old chart: - uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); - if ( xIPObj.is() ) - { - const SchMemChart* pChartData = SchDLL::GetChartData(xIPObj); - if ( pChartData ) - { - ScChartArray aArray( this, *pChartData ); - - SchMemChart* pMemChart = aArray.CreateMemChart(); - ScChartArray::CopySettings( *pMemChart, *pChartData ); - - // #57655# Chart-Update ohne geaenderte Einstellungen (MemChart) - // soll das Dokument nicht auf modified setzen (z.B. in frisch - // geladenem Dokument durch initiales Recalc) - - // #72576# disable SetModified for readonly documents only - - sal_Bool bEnabled = ( (pShell && pShell->IsReadOnly()) || IsImportingXML() ); - sal_Bool bModified = sal_False; - uno::Reference< util::XModifiable > xModif; - - if ( bEnabled ) - { - try - { - xModif = - uno::Reference< util::XModifiable >( xIPObj->getComponent(), uno::UNO_QUERY_THROW ); - bModified = xModif->isModified(); - } - catch( uno::Exception& ) - { - bEnabled = sal_False; - } - } - - SchDLL::Update( xIPObj, pMemChart, pWindow ); - ((SdrOle2Obj*)pObject)->GetNewReplacement(); - delete pMemChart; - - // Dies veranlaesst Chart zum sofortigen Update - //SvData aEmpty; - //aIPObj->SendDataChanged( aEmpty ); - - // the method below did nothing in SO7 -//REMOVE aIPObj->SendViewChanged(); - - // redraw only - pObject->ActionChanged(); - // pObject->SendRepaintBroadcast(); - - if ( bEnabled && xModif.is() ) - { - try - { - if ( xModif->isModified() != bModified ) - xModif->setModified( bModified ); - } - catch ( uno::Exception& ) - {} - } - - return; // nicht weitersuchen - } - } - */ - } - pObject = aIter.Next(); } } + + // After the update, chart keeps track of its own data source ranges, + // the listener doesn't need to listen anymore. + if(pChartListenerCollection) + pChartListenerCollection->ChangeListening( rChartName, new ScRangeList ); } void ScDocument::RestoreChartListener( const String& rName ) diff --git a/sc/source/core/data/drwlayer.cxx b/sc/source/core/data/drwlayer.cxx index ec8fc20e0..0b02376ca 100755 --- a/sc/source/core/data/drwlayer.cxx +++ b/sc/source/core/data/drwlayer.cxx @@ -28,6 +28,7 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_sc.hxx" #include <com/sun/star/uno/Reference.hxx> +#include <com/sun/star/chart/XChartDocument.hpp> #include <com/sun/star/embed/XEmbeddedObject.hpp> #include <com/sun/star/embed/XVisualObject.hpp> #include <com/sun/star/embed/XClassifiedObject.hpp> @@ -1387,7 +1388,9 @@ void ScDrawLayer::CopyToClip( ScDocument* pClipDoc, SCTAB nTab, const Rectangle& pNewObject->SetModel(pDestModel); pNewObject->SetPage(pDestPage); - pNewObject->NbcMove(Size(0,0)); + uno::Reference< chart2::XChartDocument > xOldChart( ScChartHelper::GetChartFromSdrObject( pOldObject ) ); + if(!xOldChart.is())//#i110034# do not move charts as they loose all their data references otherwise + pNewObject->NbcMove(Size(0,0)); pDestPage->InsertObject( pNewObject ); // no undo needed in clipboard document @@ -1480,6 +1483,37 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( !pSrcPage || !pDestPage ) return; + SdrObjListIter aIter( *pSrcPage, IM_FLAT ); + SdrObject* pOldObject = aIter.Next(); + + ScDocument* pClipDoc = pClipModel->GetDocument(); + // a clipboard document and its source share the same document item pool, + // so the pointers can be compared to see if this is copy&paste within + // the same document + BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); + BOOL bDestClip = pDoc && pDoc->IsClipboard(); + + //#i110034# charts need correct sheet names for xml range conversion during load + //so the target sheet name is temporarily renamed (if we have any SdrObjects) + String aDestTabName; + BOOL bRestoreDestTabName = FALSE; + if( pOldObject && !bSameDoc && !bDestClip ) + { + if( pDoc && pClipDoc ) + { + String aSourceTabName; + if( pClipDoc->GetName( nSourceTab, aSourceTabName ) + && pDoc->GetName( nDestTab, aDestTabName ) ) + { + if( !(aSourceTabName==aDestTabName) && + pDoc->ValidNewTabName(aSourceTabName) ) + { + bRestoreDestTabName = pDoc->RenameTab( nDestTab, aSourceTabName ); //BOOL bUpdateRef = TRUE, BOOL bExternalDocument = FALSE + } + } + } + } + // first mirror, then move Size aMove( rDestRange.Left() - aMirroredSource.Left(), rDestRange.Top() - aMirroredSource.Top() ); @@ -1508,8 +1542,6 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const } Point aRefPos = rDestRange.TopLeft(); // for resizing (after moving) - SdrObjListIter aIter( *pSrcPage, IM_FLAT ); - SdrObject* pOldObject = aIter.Next(); while (pOldObject) { Rectangle aObjRect = pOldObject->GetCurrentBoundRect(); @@ -1533,7 +1565,7 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if (bRecording) AddCalcUndo( new SdrUndoInsertObj( *pNewObject ) ); - // handle chart data references (after InsertObject) + //#i110034# handle chart data references (after InsertObject) if ( pNewObject->GetObjIdentifier() == OBJ_OLE2 ) { @@ -1552,66 +1584,64 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const if ( xIPObj.is() && SotExchange::IsChart( aObjectClassName ) ) { - String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); - - ::std::vector< ScRangeList > aRangesVector; - pDoc->GetChartRanges( aChartName, aRangesVector, pDoc ); - if( !aRangesVector.empty() ) + uno::Reference< chart2::XChartDocument > xNewChart( ScChartHelper::GetChartFromSdrObject( pNewObject ) ); + if( xNewChart.is() && !xNewChart->hasInternalDataProvider() ) { - ScDocument* pClipDoc = pClipModel->GetDocument(); - - // a clipboard document and its source share the same document item pool, - // so the pointers can be compared to see if this is copy&paste within - // the same document - BOOL bSameDoc = pDoc && pClipDoc && pDoc->GetPool() == pClipDoc->GetPool(); - - BOOL bDestClip = pDoc && pDoc->IsClipboard(); - - BOOL bInSourceRange = FALSE; - ScRange aClipRange; - if ( pClipDoc ) + String aChartName = ((SdrOle2Obj*)pNewObject)->GetPersistName(); + ::std::vector< ScRangeList > aRangesVector; + pDoc->GetChartRanges( aChartName, aRangesVector, pDoc ); + if( !aRangesVector.empty() ) { - SCCOL nClipStartX; - SCROW nClipStartY; - SCCOL nClipEndX; - SCROW nClipEndY; - pClipDoc->GetClipStart( nClipStartX, nClipStartY ); - pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); - nClipEndX = nClipEndX + nClipStartX; - nClipEndY += nClipStartY; // GetClipArea returns the difference - - aClipRange = ScRange( nClipStartX, nClipStartY, nSourceTab, - nClipEndX, nClipEndY, nSourceTab ); - - bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange ); - } + BOOL bInSourceRange = FALSE; + ScRange aClipRange; + if ( pClipDoc ) + { + SCCOL nClipStartX; + SCROW nClipStartY; + SCCOL nClipEndX; + SCROW nClipEndY; + pClipDoc->GetClipStart( nClipStartX, nClipStartY ); + pClipDoc->GetClipArea( nClipEndX, nClipEndY, TRUE ); + nClipEndX = nClipEndX + nClipStartX; + nClipEndY += nClipStartY; // GetClipArea returns the difference + + SCTAB nClipTab = bRestoreDestTabName ? nDestTab : nSourceTab; + aClipRange = ScRange( nClipStartX, nClipStartY, nClipTab, + nClipEndX, nClipEndY, nClipTab ); + + bInSourceRange = lcl_IsAllInRange( aRangesVector, aClipRange ); + } - // always lose references when pasting into a clipboard document (transpose) - if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) - { - if ( bInSourceRange ) + // always lose references when pasting into a clipboard document (transpose) + if ( ( bInSourceRange || bSameDoc ) && !bDestClip ) { - if ( rDestPos != aClipRange.aStart ) + if ( bInSourceRange ) { - // update the data ranges to the new (copied) position - if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) ) - pDoc->SetChartRanges( aChartName, aRangesVector ); + if ( rDestPos != aClipRange.aStart ) + { + // update the data ranges to the new (copied) position + if ( lcl_MoveRanges( aRangesVector, aClipRange, rDestPos ) ) + pDoc->SetChartRanges( aChartName, aRangesVector ); + } + } + else + { + // leave the ranges unchanged } } else { - // leave the ranges unchanged + // pasting into a new document without the complete source data + // -> break connection to source data and switch to own data + + uno::Reference< chart::XChartDocument > xOldChartDoc( ScChartHelper::GetChartFromSdrObject( pOldObject ), uno::UNO_QUERY ); + uno::Reference< chart::XChartDocument > xNewChartDoc( xNewChart, uno::UNO_QUERY ); + if( xOldChartDoc.is() && xNewChartDoc.is() ) + xNewChartDoc->attachData( xOldChartDoc->getData() ); + + // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) } } - else - { - // pasting into a new document without the complete source data - // -> break connection to source data - - // (see ScDocument::UpdateChartListenerCollection, PastingDrawFromOtherDoc) - - //! need chart interface to switch to own data - } } } } @@ -1619,6 +1649,9 @@ void ScDrawLayer::CopyFromClip( ScDrawLayer* pClipModel, SCTAB nSourceTab, const pOldObject = aIter.Next(); } + + if( bRestoreDestTabName ) + pDoc->RenameTab( nDestTab, aDestTabName ); } void ScDrawLayer::MirrorRTL( SdrObject* pObj ) |