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