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_chart2.hxx" 26 27 #include "chartview/DrawModelWrapper.hxx" 28 #include "macros.hxx" 29 #include "ShapeFactory.hxx" 30 #include "ChartItemPool.hxx" 31 #include "ObjectIdentifier.hxx" 32 #include <svx/unomodel.hxx> 33 #include <svl/itempool.hxx> 34 // header for class SfxBoolItem 35 #include <svl/eitem.hxx> 36 // header for define EE_PARA_HYPHENATE 37 #include <editeng/eeitem.hxx> 38 // header for class Svx3DPercentDiagonalItem 39 #include <svx/svx3ditems.hxx> 40 // header for class SvtPathOptions 41 #include <unotools/pathoptions.hxx> 42 // header E3dObjFactory 43 #include <svx/objfac3d.hxx> 44 // header for class SdrObjList 45 #include <svx/svdpage.hxx> 46 // header for SvxUnoXDashTable_createInstance 47 #include <svx/XPropertyTable.hxx> 48 // header for class XDashList 49 #include <svx/xtable.hxx> 50 // header for class SdrOutliner 51 #include <svx/svdoutl.hxx> 52 // header for class LinguMgr 53 #include <editeng/unolingu.hxx> 54 // header for class Application 55 #include <vcl/svapp.hxx> 56 // header for class VirtualDevice 57 #include <vcl/virdev.hxx> 58 59 #include <com/sun/star/container/XChild.hpp> 60 #include <com/sun/star/lang/XUnoTunnel.hpp> 61 62 #include <sfx2/objsh.hxx> 63 #include <com/sun/star/linguistic2/XHyphenator.hpp> 64 #include <com/sun/star/linguistic2/XSpellChecker1.hpp> 65 66 using namespace ::com::sun::star; 67 68 //............................................................................. 69 namespace 70 { 71 // this code is copied from sfx2/source/doc/objembed.cxx 72 SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel ) 73 { 74 SfxObjectShell* pResult = NULL; 75 76 try 77 { 78 uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY ); 79 if ( xChildModel.is() ) 80 { 81 uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY ); 82 if ( xParentTunnel.is() ) 83 { 84 SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID ); 85 pResult = reinterpret_cast< SfxObjectShell * >( 86 xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) ); 87 } 88 } 89 } 90 catch( uno::Exception& ) 91 { 92 // TODO: error handling 93 } 94 95 return pResult; 96 } 97 98 // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to 99 // get the reference device (e.g. printer) fromthe parent document 100 OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel ) 101 { 102 SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel ); 103 if ( pParent ) 104 return pParent->GetDocumentRefDev(); 105 return NULL; 106 } 107 108 } // anonymous namespace 109 110 //.. ........................................................................... 111 namespace chart 112 { 113 //............................................................................. 114 115 DrawModelWrapper::DrawModelWrapper( 116 uno::Reference<uno::XComponentContext> const & xContext ) 117 : SdrModel( SvtPathOptions().GetPalettePath() ) 118 , m_xMCF(0) 119 , m_pChartItemPool(0) 120 , m_xMainDrawPage(0) 121 , m_xHiddenDrawPage(0) 122 , m_apRefDevice(0) 123 { 124 m_pChartItemPool = ChartItemPool::CreateChartItemPool(); 125 126 m_xMCF = xContext->getServiceManager(); 127 128 SetScaleUnit(MAP_100TH_MM); 129 SetScaleFraction(Fraction(1, 1)); 130 SetDefaultFontHeight(423); // 12pt 131 132 SfxItemPool* pMasterPool = &GetItemPool(); 133 pMasterPool->SetDefaultMetric(SFX_MAPUNIT_100TH_MM); 134 pMasterPool->SetPoolDefaultItem(SfxBoolItem(EE_PARA_HYPHENATE, sal_True) ); 135 pMasterPool->SetPoolDefaultItem(Svx3DPercentDiagonalItem (5)); 136 137 SfxItemPool* pPool = pMasterPool; 138 // append chart pool to end of pool chain 139 for (;;) 140 { 141 SfxItemPool* pSecondary = pPool->GetSecondaryPool(); 142 if (!pSecondary) 143 break; 144 145 pPool = pSecondary; 146 } 147 pPool->SetSecondaryPool(m_pChartItemPool); 148 pMasterPool->FreezeIdRanges(); 149 150 //this factory needs to be created before first use of 3D scenes once upon an office runtime 151 //@todo in future this should be done by drawing engine itself on demand 152 static bool b3dFactoryInitialized = false; 153 if(!b3dFactoryInitialized) 154 { 155 E3dObjFactory aObjFactory; 156 b3dFactoryInitialized = true; 157 } 158 159 //Hyphenyation and spellchecking 160 SdrOutliner& rOutliner = GetDrawOutliner(); 161 try 162 { 163 uno::Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() ); 164 if( xHyphenator.is() ) 165 rOutliner.SetHyphenator( xHyphenator ); 166 167 uno::Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() ); 168 if ( xSpellChecker.is() ) 169 rOutliner.SetSpeller( xSpellChecker ); 170 } 171 catch(...) 172 { 173 DBG_ERROR("Can't get Hyphenator or SpellChecker for chart"); 174 } 175 176 //ref device for font rendering 177 OutputDevice* pDefaultDevice = rOutliner.GetRefDevice(); 178 if( !pDefaultDevice ) 179 pDefaultDevice = Application::GetDefaultDevice(); 180 m_apRefDevice = std::auto_ptr< OutputDevice >( new VirtualDevice( *pDefaultDevice ) ); 181 MapMode aMapMode = m_apRefDevice->GetMapMode(); 182 aMapMode.SetMapUnit(MAP_100TH_MM); 183 m_apRefDevice->SetMapMode(aMapMode); 184 SetRefDevice(m_apRefDevice.get()); 185 rOutliner.SetRefDevice(m_apRefDevice.get()); 186 } 187 188 DrawModelWrapper::~DrawModelWrapper() 189 { 190 //remove m_pChartItemPool from pool chain 191 if(m_pChartItemPool) 192 { 193 SfxItemPool* pPool = &GetItemPool(); 194 for (;;) 195 { 196 SfxItemPool* pSecondary = pPool->GetSecondaryPool(); 197 if(pSecondary == m_pChartItemPool) 198 { 199 pPool->SetSecondaryPool (NULL); 200 break; 201 } 202 pPool = pSecondary; 203 } 204 SfxItemPool::Free(m_pChartItemPool); 205 } 206 } 207 208 uno::Reference< uno::XInterface > DrawModelWrapper 209 ::createUnoModel() 210 { 211 uno::Reference< lang::XComponent > xComponent = new SvxUnoDrawingModel( this ); //tell Andreas Schluens if SvxUnoDrawingModel is not needed anymore -> remove export from svx to avoid link problems in writer 212 return uno::Reference< uno::XInterface >::query( xComponent ); 213 } 214 215 uno::Reference< frame::XModel > DrawModelWrapper::getUnoModel() 216 { 217 uno::Reference< uno::XInterface > xI = this->SdrModel::getUnoModel(); 218 return uno::Reference<frame::XModel>::query( xI ); 219 } 220 221 SdrModel& DrawModelWrapper::getSdrModel() 222 { 223 return *this; 224 } 225 226 uno::Reference< lang::XMultiServiceFactory > DrawModelWrapper::getShapeFactory() 227 { 228 uno::Reference< lang::XMultiServiceFactory > xShapeFactory( this->getUnoModel(), uno::UNO_QUERY ); 229 return xShapeFactory; 230 } 231 232 uno::Reference< drawing::XDrawPage > DrawModelWrapper::getMainDrawPage() 233 { 234 //create draw page: 235 if( !m_xMainDrawPage.is() ) 236 { 237 uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSuplier( this->getUnoModel(), uno::UNO_QUERY ); 238 if( xDrawPagesSuplier.is() ) 239 { 240 uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSuplier->getDrawPages () ); 241 if( xDrawPages->getCount()>1 ) 242 { 243 uno::Any aPage = xDrawPages->getByIndex( 0 ) ; 244 aPage >>= m_xMainDrawPage; 245 } 246 if(!m_xMainDrawPage.is()) 247 { 248 m_xMainDrawPage = xDrawPages->insertNewByIndex( 0 ); 249 } 250 } 251 } 252 //ensure that additional shapes are in front of the chart objects so create the chart root before 253 ShapeFactory(this->getShapeFactory()).getOrCreateChartRootShape( m_xMainDrawPage ); 254 return m_xMainDrawPage; 255 } 256 uno::Reference< drawing::XDrawPage > DrawModelWrapper::getHiddenDrawPage() 257 { 258 if( !m_xHiddenDrawPage.is() ) 259 { 260 uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSuplier( this->getUnoModel(), uno::UNO_QUERY ); 261 if( xDrawPagesSuplier.is() ) 262 { 263 uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSuplier->getDrawPages () ); 264 if( xDrawPages->getCount()>1 ) 265 { 266 uno::Any aPage = xDrawPages->getByIndex( 1 ) ; 267 aPage >>= m_xHiddenDrawPage; 268 } 269 270 if(!m_xHiddenDrawPage.is()) 271 { 272 if( xDrawPages->getCount()==0 ) 273 m_xMainDrawPage = xDrawPages->insertNewByIndex( 0 ); 274 m_xHiddenDrawPage = xDrawPages->insertNewByIndex( 1 ); 275 } 276 } 277 } 278 return m_xHiddenDrawPage; 279 } 280 void DrawModelWrapper::clearMainDrawPage() 281 { 282 //uno::Reference<drawing::XShapes> xChartRoot( m_xMainDrawPage, uno::UNO_QUERY ); 283 uno::Reference<drawing::XShapes> xChartRoot( ShapeFactory::getChartRootShape( m_xMainDrawPage ) ); 284 if( xChartRoot.is() ) 285 { 286 sal_Int32 nSubCount = xChartRoot->getCount(); 287 uno::Reference< drawing::XShape > xShape; 288 for( sal_Int32 nS = nSubCount; nS--; ) 289 { 290 if( xChartRoot->getByIndex( nS ) >>= xShape ) 291 xChartRoot->remove( xShape ); 292 } 293 } 294 } 295 296 uno::Reference< drawing::XShapes > DrawModelWrapper::getChartRootShape( 297 const uno::Reference< drawing::XDrawPage>& xDrawPage ) 298 { 299 return ShapeFactory::getChartRootShape( xDrawPage ); 300 } 301 302 void DrawModelWrapper::lockControllers() 303 { 304 uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() ); 305 if( xDrawModel.is()) 306 xDrawModel->lockControllers(); 307 } 308 void DrawModelWrapper::unlockControllers() 309 { 310 uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() ); 311 if( xDrawModel.is()) 312 xDrawModel->unlockControllers(); 313 } 314 315 void DrawModelWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel ) 316 { 317 OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel )); 318 if( pParentRefDev ) 319 { 320 SetRefDevice( pParentRefDev ); 321 } 322 } 323 324 OutputDevice* DrawModelWrapper::getReferenceDevice() const 325 { 326 return SdrModel::GetRefDevice(); 327 } 328 329 SfxItemPool& DrawModelWrapper::GetItemPool() 330 { 331 return this->SdrModel::GetItemPool(); 332 } 333 const SfxItemPool& DrawModelWrapper::GetItemPool() const 334 { 335 return this->SdrModel::GetItemPool(); 336 } 337 XColorList* DrawModelWrapper::GetColorTable() const 338 { 339 return this->SdrModel::GetColorTable(); 340 } 341 XDashList* DrawModelWrapper::GetDashList() const 342 { 343 return this->SdrModel::GetDashList(); 344 } 345 XLineEndList* DrawModelWrapper::GetLineEndList() const 346 { 347 return this->SdrModel::GetLineEndList(); 348 } 349 XGradientList* DrawModelWrapper::GetGradientList() const 350 { 351 return this->SdrModel::GetGradientList(); 352 } 353 XHatchList* DrawModelWrapper::GetHatchList() const 354 { 355 return this->SdrModel::GetHatchList(); 356 } 357 XBitmapList* DrawModelWrapper::GetBitmapList() const 358 { 359 return this->SdrModel::GetBitmapList(); 360 } 361 362 SdrObject* DrawModelWrapper::getNamedSdrObject( const rtl::OUString& rName ) 363 { 364 if(rName.getLength()==0) 365 return 0; 366 return getNamedSdrObject( rName, GetPage(0) ); 367 } 368 369 SdrObject* DrawModelWrapper::getNamedSdrObject( const String& rObjectCID, SdrObjList* pSearchList ) 370 { 371 if(!pSearchList || rObjectCID.Len()==0) 372 return 0; 373 sal_uLong nCount = pSearchList->GetObjCount(); 374 for( sal_uLong nN=0; nN<nCount; nN++ ) 375 { 376 SdrObject* pObj = pSearchList->GetObj(nN); 377 if(!pObj) 378 continue; 379 if( ObjectIdentifier::areIdenticalObjects( rObjectCID, pObj->GetName() ) ) 380 return pObj; 381 pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, pObj->GetSubList() ); 382 if(pObj) 383 return pObj; 384 } 385 return 0; 386 } 387 388 bool DrawModelWrapper::removeShape( const uno::Reference< drawing::XShape >& xShape ) 389 { 390 uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY ); 391 if( xChild.is() ) 392 { 393 uno::Reference<drawing::XShapes> xShapes( xChild->getParent(), uno::UNO_QUERY ); 394 if( xShapes.is() ) 395 { 396 xShapes->remove(xShape); 397 return true; 398 } 399 } 400 return false; 401 } 402 403 //............................................................................. 404 } //namespace chart 405 //............................................................................. 406