1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sc.hxx" 26 27 #include "charthelper.hxx" 28 #include "document.hxx" 29 #include "drwlayer.hxx" 30 #include "rangelst.hxx" 31 #include "chartlis.hxx" 32 #include "docuno.hxx" 33 34 //#include <vcl/svapp.hxx> 35 #include <svx/svditer.hxx> 36 #include <svx/svdoole2.hxx> 37 #include <svx/svdpage.hxx> 38 39 #include <com/sun/star/chart2/data/XDataReceiver.hpp> 40 41 using namespace com::sun::star; 42 using ::com::sun::star::uno::Reference; 43 44 45 // ==================================================================== 46 47 namespace 48 { 49 50 51 sal_uInt16 lcl_DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc, sal_Bool bAllCharts ) 52 { 53 ScDrawLayer* pModel = pDoc->GetDrawLayer(); 54 if (!pModel) 55 return 0; 56 57 sal_uInt16 nFound = 0; 58 59 sal_uInt16 nPageCount = pModel->GetPageCount(); 60 for (sal_uInt16 nPageNo=0; nPageNo<nPageCount; nPageNo++) 61 { 62 SdrPage* pPage = pModel->GetPage(nPageNo); 63 DBG_ASSERT(pPage,"Page ?"); 64 65 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 66 SdrObject* pObject = aIter.Next(); 67 while (pObject) 68 { 69 if ( pObject->GetObjIdentifier() == OBJ_OLE2 && pDoc->IsChart( pObject ) ) 70 { 71 String aName = ((SdrOle2Obj*)pObject)->GetPersistName(); 72 sal_Bool bHit = sal_True; 73 if ( !bAllCharts ) 74 { 75 ScRangeList aRanges; 76 sal_Bool bColHeaders = sal_False; 77 sal_Bool bRowHeaders = sal_False; 78 pDoc->GetOldChartParameters( aName, aRanges, bColHeaders, bRowHeaders ); 79 bHit = aRanges.In( rPos ); 80 } 81 if ( bHit ) 82 { 83 pDoc->UpdateChart( aName ); 84 ++nFound; 85 } 86 } 87 pObject = aIter.Next(); 88 } 89 } 90 return nFound; 91 } 92 93 sal_Bool lcl_AdjustRanges( ScRangeList& rRanges, SCTAB nSourceTab, SCTAB nDestTab, SCTAB nTabCount ) 94 { 95 //! if multiple sheets are copied, update references into the other copied sheets? 96 97 sal_Bool bChanged = sal_False; 98 99 sal_uLong nCount = rRanges.Count(); 100 for (sal_uLong i=0; i<nCount; i++) 101 { 102 ScRange* pRange = rRanges.GetObject(i); 103 if ( pRange->aStart.Tab() == nSourceTab && pRange->aEnd.Tab() == nSourceTab ) 104 { 105 pRange->aStart.SetTab( nDestTab ); 106 pRange->aEnd.SetTab( nDestTab ); 107 bChanged = sal_True; 108 } 109 if ( pRange->aStart.Tab() >= nTabCount ) 110 { 111 pRange->aStart.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); 112 bChanged = sal_True; 113 } 114 if ( pRange->aEnd.Tab() >= nTabCount ) 115 { 116 pRange->aEnd.SetTab( nTabCount > 0 ? ( nTabCount - 1 ) : 0 ); 117 bChanged = sal_True; 118 } 119 } 120 121 return bChanged; 122 } 123 124 }//end anonymous namespace 125 126 // === ScChartHelper ====================================== 127 128 //static 129 sal_uInt16 ScChartHelper::DoUpdateCharts( const ScAddress& rPos, ScDocument* pDoc ) 130 { 131 return lcl_DoUpdateCharts( rPos, pDoc, sal_False ); 132 } 133 134 //static 135 sal_uInt16 ScChartHelper::DoUpdateAllCharts( ScDocument* pDoc ) 136 { 137 return lcl_DoUpdateCharts( ScAddress(), pDoc, sal_True ); 138 } 139 140 //static 141 void ScChartHelper::AdjustRangesOfChartsOnDestinationPage( ScDocument* pSrcDoc, ScDocument* pDestDoc, const SCTAB nSrcTab, const SCTAB nDestTab ) 142 { 143 if( !pSrcDoc || !pDestDoc ) 144 return; 145 ScDrawLayer* pDrawLayer = pDestDoc->GetDrawLayer(); 146 if( !pDrawLayer ) 147 return; 148 149 SdrPage* pDestPage = pDrawLayer->GetPage(static_cast<sal_uInt16>(nDestTab)); 150 if( pDestPage ) 151 { 152 SdrObjListIter aIter( *pDestPage, IM_FLAT ); 153 SdrObject* pObject = aIter.Next(); 154 while( pObject ) 155 { 156 if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) 157 { 158 String aChartName = ((SdrOle2Obj*)pObject)->GetPersistName(); 159 160 Reference< chart2::XChartDocument > xChartDoc( pDestDoc->GetChartByName( aChartName ) ); 161 Reference< chart2::data::XDataReceiver > xReceiver( xChartDoc, uno::UNO_QUERY ); 162 if( xChartDoc.is() && xReceiver.is() && !xChartDoc->hasInternalDataProvider() ) 163 { 164 ::std::vector< ScRangeList > aRangesVector; 165 pDestDoc->GetChartRanges( aChartName, aRangesVector, pSrcDoc ); 166 167 ::std::vector< ScRangeList >::iterator aIt( aRangesVector.begin() ); 168 for( ; aIt!=aRangesVector.end(); aIt++ ) 169 { 170 ScRangeList& rScRangeList( *aIt ); 171 lcl_AdjustRanges( rScRangeList, nSrcTab, nDestTab, pDestDoc->GetTableCount() ); 172 } 173 pDestDoc->SetChartRanges( aChartName, aRangesVector ); 174 } 175 } 176 pObject = aIter.Next(); 177 } 178 } 179 } 180 181 //static 182 uno::Reference< chart2::XChartDocument > ScChartHelper::GetChartFromSdrObject( SdrObject* pObject ) 183 { 184 uno::Reference< chart2::XChartDocument > xReturn; 185 if( pObject ) 186 { 187 if( pObject->GetObjIdentifier() == OBJ_OLE2 && ((SdrOle2Obj*)pObject)->IsChart() ) 188 { 189 uno::Reference< embed::XEmbeddedObject > xIPObj = ((SdrOle2Obj*)pObject)->GetObjRef(); 190 if( xIPObj.is() ) 191 { 192 svt::EmbeddedObjectRef::TryRunningState( xIPObj ); 193 uno::Reference< util::XCloseable > xComponent = xIPObj->getComponent(); 194 xReturn.set( uno::Reference< chart2::XChartDocument >( xComponent, uno::UNO_QUERY ) ); 195 } 196 } 197 } 198 return xReturn; 199 } 200 201 void ScChartHelper::GetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, 202 uno::Sequence< rtl::OUString >& rRanges ) 203 { 204 rRanges.realloc(0); 205 uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); 206 if( !xDataSource.is() ) 207 return; 208 //uno::Reference< chart2::data::XDataProvider > xProvider = xChartDoc->getDataProvider(); 209 210 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); 211 rRanges.realloc(2*aLabeledDataSequences.getLength()); 212 sal_Int32 nRealCount=0; 213 for( sal_Int32 nN=0;nN<aLabeledDataSequences.getLength();nN++) 214 { 215 uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); 216 if(!xLabeledSequence.is()) 217 continue; 218 uno::Reference< chart2::data::XDataSequence > xLabel( xLabeledSequence->getLabel()); 219 uno::Reference< chart2::data::XDataSequence > xValues( xLabeledSequence->getValues()); 220 221 if( xLabel.is()) 222 rRanges[nRealCount++] = xLabel->getSourceRangeRepresentation(); 223 if( xValues.is()) 224 rRanges[nRealCount++] = xValues->getSourceRangeRepresentation(); 225 } 226 rRanges.realloc(nRealCount); 227 } 228 229 void ScChartHelper::SetChartRanges( const uno::Reference< chart2::XChartDocument >& xChartDoc, 230 const uno::Sequence< rtl::OUString >& rRanges ) 231 { 232 uno::Reference< chart2::data::XDataSource > xDataSource( xChartDoc, uno::UNO_QUERY ); 233 if( !xDataSource.is() ) 234 return; 235 uno::Reference< chart2::data::XDataProvider > xDataProvider = xChartDoc->getDataProvider(); 236 if( !xDataProvider.is() ) 237 return; 238 239 uno::Reference< frame::XModel > xModel( xChartDoc, uno::UNO_QUERY ); 240 if( xModel.is() ) 241 xModel->lockControllers(); 242 243 try 244 { 245 rtl::OUString aPropertyNameRole( ::rtl::OUString::createFromAscii("Role") ); 246 247 uno::Sequence< uno::Reference< chart2::data::XLabeledDataSequence > > aLabeledDataSequences( xDataSource->getDataSequences() ); 248 sal_Int32 nRange=0; 249 for( sal_Int32 nN=0; (nN<aLabeledDataSequences.getLength()) && (nRange<rRanges.getLength()); nN++ ) 250 { 251 uno::Reference< chart2::data::XLabeledDataSequence > xLabeledSequence( aLabeledDataSequences[nN] ); 252 if(!xLabeledSequence.is()) 253 continue; 254 uno::Reference< beans::XPropertySet > xLabel( xLabeledSequence->getLabel(), uno::UNO_QUERY ); 255 uno::Reference< beans::XPropertySet > xValues( xLabeledSequence->getValues(), uno::UNO_QUERY ); 256 257 if( xLabel.is()) 258 { 259 // the range string must be in Calc A1 format. 260 uno::Reference< chart2::data::XDataSequence > xNewSeq( 261 xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); 262 263 uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); 264 if( xNewProps.is() ) 265 xNewProps->setPropertyValue( aPropertyNameRole, xLabel->getPropertyValue( aPropertyNameRole ) ); 266 267 xLabeledSequence->setLabel( xNewSeq ); 268 } 269 270 if( !(nRange<rRanges.getLength()) ) 271 break; 272 273 if( xValues.is()) 274 { 275 // the range string must be in Calc A1 format. 276 uno::Reference< chart2::data::XDataSequence > xNewSeq( 277 xDataProvider->createDataSequenceByRangeRepresentation( rRanges[nRange++] )); 278 279 uno::Reference< beans::XPropertySet > xNewProps( xNewSeq, uno::UNO_QUERY ); 280 if( xNewProps.is() ) 281 xNewProps->setPropertyValue( aPropertyNameRole, xValues->getPropertyValue( aPropertyNameRole ) ); 282 283 xLabeledSequence->setValues( xNewSeq ); 284 } 285 } 286 } 287 catch ( uno::Exception& ex ) 288 { 289 (void)ex; 290 DBG_ERROR("Exception in ScChartHelper::SetChartRanges - invalid range string?"); 291 } 292 293 if( xModel.is() ) 294 xModel->unlockControllers(); 295 } 296 297 void ScChartHelper::AddRangesIfProtectedChart( ScRangeListVector& rRangesVector, ScDocument* pDocument, SdrObject* pObject ) 298 { 299 if ( pDocument && pObject && ( pObject->GetObjIdentifier() == OBJ_OLE2 ) ) 300 { 301 SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); 302 if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) 303 { 304 uno::Reference< embed::XEmbeddedObject > xEmbeddedObj = pSdrOle2Obj->GetObjRef(); 305 if ( xEmbeddedObj.is() ) 306 { 307 bool bDisableDataTableDialog = false; 308 sal_Int32 nOldState = xEmbeddedObj->getCurrentState(); 309 svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); 310 uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); 311 if ( xProps.is() && 312 ( xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bDisableDataTableDialog ) && 313 bDisableDataTableDialog ) 314 { 315 ::rtl::OUString aChartName = pSdrOle2Obj->GetPersistName(); 316 ScRange aEmptyRange; 317 ScChartListener aSearcher( aChartName, pDocument, aEmptyRange ); 318 sal_uInt16 nIndex = 0; 319 ScChartListenerCollection* pCollection = pDocument->GetChartListenerCollection(); 320 if ( pCollection && pCollection->Search( &aSearcher, nIndex ) ) 321 { 322 ScChartListener* pListener = static_cast< ScChartListener* >( pCollection->At( nIndex ) ); 323 if ( pListener ) 324 { 325 const ScRangeListRef& rRangeList = pListener->GetRangeList(); 326 if ( rRangeList.Is() ) 327 { 328 rRangesVector.push_back( *rRangeList ); 329 } 330 } 331 } 332 } 333 if ( xEmbeddedObj->getCurrentState() != nOldState ) 334 { 335 xEmbeddedObj->changeState( nOldState ); 336 } 337 } 338 } 339 } 340 } 341 342 void ScChartHelper::FillProtectedChartRangesVector( ScRangeListVector& rRangesVector, ScDocument* pDocument, SdrPage* pPage ) 343 { 344 if ( pDocument && pPage ) 345 { 346 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 347 SdrObject* pObject = aIter.Next(); 348 while ( pObject ) 349 { 350 AddRangesIfProtectedChart( rRangesVector, pDocument, pObject ); 351 pObject = aIter.Next(); 352 } 353 } 354 } 355 356 void ScChartHelper::GetChartNames( ::std::vector< ::rtl::OUString >& rChartNames, SdrPage* pPage ) 357 { 358 if ( pPage ) 359 { 360 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 361 SdrObject* pObject = aIter.Next(); 362 while ( pObject ) 363 { 364 if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) 365 { 366 SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); 367 if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) 368 { 369 rChartNames.push_back( pSdrOle2Obj->GetPersistName() ); 370 } 371 } 372 pObject = aIter.Next(); 373 } 374 } 375 } 376 377 void ScChartHelper::CreateProtectedChartListenersAndNotify( ScDocument* pDoc, SdrPage* pPage, ScModelObj* pModelObj, SCTAB nTab, 378 const ScRangeListVector& rRangesVector, const ::std::vector< ::rtl::OUString >& rExcludedChartNames, bool bSameDoc ) 379 { 380 if ( pDoc && pPage && pModelObj ) 381 { 382 size_t nRangeListCount = rRangesVector.size(); 383 size_t nRangeList = 0; 384 SdrObjListIter aIter( *pPage, IM_DEEPNOGROUPS ); 385 SdrObject* pObject = aIter.Next(); 386 while ( pObject ) 387 { 388 if ( pObject->GetObjIdentifier() == OBJ_OLE2 ) 389 { 390 SdrOle2Obj* pSdrOle2Obj = dynamic_cast< SdrOle2Obj* >( pObject ); 391 if ( pSdrOle2Obj && pSdrOle2Obj->IsChart() ) 392 { 393 ::rtl::OUString aChartName = pSdrOle2Obj->GetPersistName(); 394 ::std::vector< ::rtl::OUString >::const_iterator aEnd = rExcludedChartNames.end(); 395 ::std::vector< ::rtl::OUString >::const_iterator aFound = ::std::find( rExcludedChartNames.begin(), aEnd, aChartName ); 396 if ( aFound == aEnd ) 397 { 398 uno::Reference< embed::XEmbeddedObject > xEmbeddedObj = pSdrOle2Obj->GetObjRef(); 399 if ( xEmbeddedObj.is() && ( nRangeList < nRangeListCount ) ) 400 { 401 bool bDisableDataTableDialog = false; 402 svt::EmbeddedObjectRef::TryRunningState( xEmbeddedObj ); 403 uno::Reference< beans::XPropertySet > xProps( xEmbeddedObj->getComponent(), uno::UNO_QUERY ); 404 if ( xProps.is() && 405 ( xProps->getPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ) ) >>= bDisableDataTableDialog ) && 406 bDisableDataTableDialog ) 407 { 408 if ( bSameDoc ) 409 { 410 ScRange aEmptyRange; 411 ScChartListener aSearcher( aChartName, pDoc, aEmptyRange ); 412 sal_uInt16 nIndex = 0; 413 ScChartListenerCollection* pCollection = pDoc->GetChartListenerCollection(); 414 if ( pCollection && !pCollection->Search( &aSearcher, nIndex ) ) 415 { 416 ScRangeList aRangeList( rRangesVector[ nRangeList++ ] ); 417 ScRangeListRef rRangeList( new ScRangeList( aRangeList ) ); 418 ScChartListener* pChartListener = new ScChartListener( aChartName, pDoc, rRangeList ); 419 pCollection->Insert( pChartListener ); 420 pChartListener->StartListeningTo(); 421 } 422 } 423 else 424 { 425 xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableDataTableDialog" ) ), 426 uno::makeAny( sal_False ) ); 427 xProps->setPropertyValue( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "DisableComplexChartTypes" ) ), 428 uno::makeAny( sal_False ) ); 429 } 430 } 431 } 432 433 if ( pModelObj && pModelObj->HasChangesListeners() ) 434 { 435 Rectangle aRectangle = pSdrOle2Obj->GetSnapRect(); 436 ScRange aRange( pDoc->GetRange( nTab, aRectangle ) ); 437 ScRangeList aChangeRanges; 438 aChangeRanges.Append( aRange ); 439 440 uno::Sequence< beans::PropertyValue > aProperties( 1 ); 441 aProperties[ 0 ].Name = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "Name" ) ); 442 aProperties[ 0 ].Value <<= aChartName; 443 444 pModelObj->NotifyChanges( ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "insert-chart" ) ), aChangeRanges, aProperties ); 445 } 446 } 447 } 448 } 449 pObject = aIter.Next(); 450 } 451 } 452 } 453