summaryrefslogtreecommitdiff
path: root/sc
diff options
context:
space:
mode:
authorIngrid Halama <iha@openoffice.org>2010-03-10 19:46:41 +0100
committerIngrid Halama <iha@openoffice.org>2010-03-10 19:46:41 +0100
commitab2bbad3c25a9c3b370d75153104ce8bfb760240 (patch)
tree9abd433ae26171c946a8783287f7ffffab28f94a /sc
parent121ce9b7bc3ca740d8a53177f40d19237bc13e95 (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.cxx129
-rwxr-xr-xsc/source/core/data/drwlayer.cxx139
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 )