Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include "chartview/DrawModelWrapper.hxx"
21 : #include "macros.hxx"
22 : #include "AbstractShapeFactory.hxx"
23 : #include "ChartItemPool.hxx"
24 : #include "ObjectIdentifier.hxx"
25 : #include <svx/unomodel.hxx>
26 : #include <svl/itempool.hxx>
27 : #include <svl/eitem.hxx>
28 : #include <editeng/eeitem.hxx>
29 : #include <svx/svx3ditems.hxx>
30 : #include <unotools/pathoptions.hxx>
31 : #include <svx/objfac3d.hxx>
32 : #include <svx/svdpage.hxx>
33 : #include <svx/XPropertyTable.hxx>
34 : #include <svx/xtable.hxx>
35 : #include <svx/svdoutl.hxx>
36 : #include <editeng/unolingu.hxx>
37 : #include <vcl/svapp.hxx>
38 : #include <vcl/virdev.hxx>
39 :
40 : #include <com/sun/star/container/XChild.hpp>
41 : #include <com/sun/star/lang/XUnoTunnel.hpp>
42 :
43 : #include <sfx2/objsh.hxx>
44 : #include <com/sun/star/linguistic2/XHyphenator.hpp>
45 : #include <com/sun/star/linguistic2/XSpellChecker1.hpp>
46 :
47 : using namespace ::com::sun::star;
48 :
49 : namespace
50 : {
51 : // this code is copied from sfx2/source/doc/objembed.cxx
52 0 : SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel )
53 : {
54 0 : SfxObjectShell* pResult = NULL;
55 :
56 : try
57 : {
58 0 : uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY );
59 0 : if ( xChildModel.is() )
60 : {
61 0 : uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY );
62 0 : if ( xParentTunnel.is() )
63 : {
64 0 : SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID );
65 : pResult = reinterpret_cast< SfxObjectShell * >(
66 0 : xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) );
67 0 : }
68 0 : }
69 : }
70 0 : catch( const uno::Exception& )
71 : {
72 : // TODO: error handling
73 : }
74 :
75 0 : return pResult;
76 : }
77 :
78 : // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to
79 : // get the reference device (e.g. printer) fromthe parent document
80 0 : OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel )
81 : {
82 0 : SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel );
83 0 : if ( pParent )
84 0 : return pParent->GetDocumentRefDev();
85 0 : return NULL;
86 : }
87 :
88 : } // anonymous namespace
89 :
90 : namespace chart
91 : {
92 :
93 606 : DrawModelWrapper::DrawModelWrapper( const uno::Reference<uno::XComponentContext>& /*xContext*/ )
94 1212 : : SdrModel( SvtPathOptions().GetPalettePath(), NULL, NULL, false, false )
95 : , m_pChartItemPool(0)
96 : , m_xMainDrawPage(0)
97 1212 : , m_xHiddenDrawPage(0)
98 : {
99 606 : m_pChartItemPool = ChartItemPool::CreateChartItemPool();
100 :
101 606 : SetScaleUnit(MAP_100TH_MM);
102 606 : SetScaleFraction(Fraction(1, 1));
103 606 : SetDefaultFontHeight(423); // 12pt
104 :
105 606 : SfxItemPool* pMasterPool = &GetItemPool();
106 606 : pMasterPool->SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
107 606 : pMasterPool->SetPoolDefaultItem(SfxBoolItem(EE_PARA_HYPHENATE, true) );
108 606 : pMasterPool->SetPoolDefaultItem(makeSvx3DPercentDiagonalItem (5));
109 :
110 606 : SfxItemPool* pPool = pMasterPool;
111 : // append chart pool to end of pool chain
112 : for (;;)
113 : {
114 1212 : SfxItemPool* pSecondary = pPool->GetSecondaryPool();
115 1212 : if (!pSecondary)
116 606 : break;
117 :
118 606 : pPool = pSecondary;
119 606 : }
120 606 : pPool->SetSecondaryPool(m_pChartItemPool);
121 606 : pMasterPool->FreezeIdRanges();
122 :
123 : //this factory needs to be created before first use of 3D scenes once upon an office runtime
124 : //@todo in future this should be done by drawing engine itself on demand
125 : static bool b3dFactoryInitialized = false;
126 606 : if(!b3dFactoryInitialized)
127 : {
128 32 : E3dObjFactory aObjFactory;
129 32 : b3dFactoryInitialized = true;
130 : }
131 :
132 : //Hyphenyation and spellchecking
133 606 : SdrOutliner& rOutliner = GetDrawOutliner();
134 : try
135 : {
136 606 : uno::Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
137 606 : if( xHyphenator.is() )
138 606 : rOutliner.SetHyphenator( xHyphenator );
139 :
140 1212 : uno::Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
141 606 : if ( xSpellChecker.is() )
142 1212 : rOutliner.SetSpeller( xSpellChecker );
143 : }
144 0 : catch(...)
145 : {
146 : OSL_FAIL("Can't get Hyphenator or SpellChecker for chart");
147 : }
148 :
149 : //ref device for font rendering
150 606 : OutputDevice* pDefaultDevice = rOutliner.GetRefDevice();
151 606 : if( !pDefaultDevice )
152 0 : pDefaultDevice = Application::GetDefaultDevice();
153 606 : m_pRefDevice.reset(new VirtualDevice(*pDefaultDevice));
154 606 : MapMode aMapMode = m_pRefDevice->GetMapMode();
155 606 : aMapMode.SetMapUnit(MAP_100TH_MM);
156 606 : m_pRefDevice->SetMapMode(aMapMode);
157 606 : SetRefDevice(m_pRefDevice.get());
158 606 : rOutliner.SetRefDevice(m_pRefDevice.get());
159 606 : }
160 :
161 1722 : DrawModelWrapper::~DrawModelWrapper()
162 : {
163 : //remove m_pChartItemPool from pool chain
164 574 : if(m_pChartItemPool)
165 : {
166 574 : SfxItemPool* pPool = &GetItemPool();
167 : for (;;)
168 : {
169 1148 : SfxItemPool* pSecondary = pPool->GetSecondaryPool();
170 1148 : if(pSecondary == m_pChartItemPool)
171 : {
172 574 : pPool->SetSecondaryPool (NULL);
173 574 : break;
174 : }
175 574 : pPool = pSecondary;
176 574 : }
177 574 : SfxItemPool::Free(m_pChartItemPool);
178 : }
179 1148 : }
180 :
181 606 : uno::Reference< uno::XInterface > DrawModelWrapper
182 : ::createUnoModel()
183 : {
184 606 : 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
185 606 : return uno::Reference< uno::XInterface >::query( xComponent );
186 : }
187 :
188 5116 : uno::Reference< frame::XModel > DrawModelWrapper::getUnoModel()
189 : {
190 5116 : uno::Reference< uno::XInterface > xI = this->SdrModel::getUnoModel();
191 5116 : return uno::Reference<frame::XModel>::query( xI );
192 : }
193 :
194 9380 : SdrModel& DrawModelWrapper::getSdrModel()
195 : {
196 9380 : return *this;
197 : }
198 :
199 2960 : uno::Reference< lang::XMultiServiceFactory > DrawModelWrapper::getShapeFactory()
200 : {
201 2960 : uno::Reference< lang::XMultiServiceFactory > xShapeFactory( this->getUnoModel(), uno::UNO_QUERY );
202 2960 : return xShapeFactory;
203 : }
204 :
205 2445 : uno::Reference< drawing::XDrawPage > DrawModelWrapper::getMainDrawPage()
206 : {
207 2445 : if (m_xMainDrawPage.is())
208 1839 : return m_xMainDrawPage;
209 :
210 : // Create draw page.
211 606 : uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSuplier(getUnoModel(), uno::UNO_QUERY);
212 606 : if (!xDrawPagesSuplier.is())
213 0 : return m_xMainDrawPage;
214 :
215 1212 : uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSuplier->getDrawPages();
216 606 : if (xDrawPages->getCount() > 1)
217 : {
218 : // Take the first page in case of multiple pages.
219 0 : uno::Any aPage = xDrawPages->getByIndex(0);
220 0 : aPage >>= m_xMainDrawPage;
221 : }
222 :
223 606 : if (!m_xMainDrawPage.is())
224 : {
225 606 : m_xMainDrawPage = xDrawPages->insertNewByIndex(0);
226 : }
227 :
228 : //ensure that additional shapes are in front of the chart objects so create the chart root before
229 : // let us disable this call for now
230 : // TODO:moggi
231 : // AbstractShapeFactory::getOrCreateShapeFactory(this->getShapeFactory())->getOrCreateChartRootShape( m_xMainDrawPage );
232 1212 : return m_xMainDrawPage;
233 : }
234 0 : uno::Reference< drawing::XDrawPage > DrawModelWrapper::getHiddenDrawPage()
235 : {
236 0 : if( !m_xHiddenDrawPage.is() )
237 : {
238 0 : uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSuplier( this->getUnoModel(), uno::UNO_QUERY );
239 0 : if( xDrawPagesSuplier.is() )
240 : {
241 0 : uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSuplier->getDrawPages () );
242 0 : if( xDrawPages->getCount()>1 )
243 : {
244 0 : uno::Any aPage = xDrawPages->getByIndex( 1 ) ;
245 0 : aPage >>= m_xHiddenDrawPage;
246 : }
247 :
248 0 : if(!m_xHiddenDrawPage.is())
249 : {
250 0 : if( xDrawPages->getCount()==0 )
251 0 : m_xMainDrawPage = xDrawPages->insertNewByIndex( 0 );
252 0 : m_xHiddenDrawPage = xDrawPages->insertNewByIndex( 1 );
253 0 : }
254 0 : }
255 : }
256 0 : return m_xHiddenDrawPage;
257 : }
258 886 : void DrawModelWrapper::clearMainDrawPage()
259 : {
260 : //uno::Reference<drawing::XShapes> xChartRoot( m_xMainDrawPage, uno::UNO_QUERY );
261 886 : uno::Reference<drawing::XShapes> xChartRoot( AbstractShapeFactory::getChartRootShape( m_xMainDrawPage ) );
262 886 : if( xChartRoot.is() )
263 : {
264 450 : sal_Int32 nSubCount = xChartRoot->getCount();
265 450 : uno::Reference< drawing::XShape > xShape;
266 2330 : for( sal_Int32 nS = nSubCount; nS--; )
267 : {
268 1430 : if( xChartRoot->getByIndex( nS ) >>= xShape )
269 1430 : xChartRoot->remove( xShape );
270 450 : }
271 886 : }
272 886 : }
273 :
274 1434 : uno::Reference< drawing::XShapes > DrawModelWrapper::getChartRootShape(
275 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
276 : {
277 1434 : return AbstractShapeFactory::getChartRootShape( xDrawPage );
278 : }
279 :
280 775 : void DrawModelWrapper::lockControllers()
281 : {
282 775 : uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() );
283 775 : if( xDrawModel.is())
284 775 : xDrawModel->lockControllers();
285 775 : }
286 775 : void DrawModelWrapper::unlockControllers()
287 : {
288 775 : uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() );
289 775 : if( xDrawModel.is())
290 775 : xDrawModel->unlockControllers();
291 775 : }
292 :
293 0 : void DrawModelWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel )
294 : {
295 0 : OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel ));
296 0 : if( pParentRefDev )
297 : {
298 0 : SetRefDevice( pParentRefDev );
299 : }
300 0 : }
301 :
302 0 : OutputDevice* DrawModelWrapper::getReferenceDevice() const
303 : {
304 0 : return SdrModel::GetRefDevice();
305 : }
306 :
307 2212 : SfxItemPool& DrawModelWrapper::GetItemPool()
308 : {
309 2212 : return this->SdrModel::GetItemPool();
310 : }
311 0 : const SfxItemPool& DrawModelWrapper::GetItemPool() const
312 : {
313 0 : return this->SdrModel::GetItemPool();
314 : }
315 0 : XColorListRef DrawModelWrapper::GetColorList() const
316 : {
317 0 : return this->SdrModel::GetColorList();
318 : }
319 0 : XDashListRef DrawModelWrapper::GetDashList() const
320 : {
321 0 : return this->SdrModel::GetDashList();
322 : }
323 0 : XLineEndListRef DrawModelWrapper::GetLineEndList() const
324 : {
325 0 : return this->SdrModel::GetLineEndList();
326 : }
327 0 : XGradientListRef DrawModelWrapper::GetGradientList() const
328 : {
329 0 : return this->SdrModel::GetGradientList();
330 : }
331 0 : XHatchListRef DrawModelWrapper::GetHatchList() const
332 : {
333 0 : return this->SdrModel::GetHatchList();
334 : }
335 0 : XBitmapListRef DrawModelWrapper::GetBitmapList() const
336 : {
337 0 : return this->SdrModel::GetBitmapList();
338 : }
339 :
340 0 : SdrObject* DrawModelWrapper::getNamedSdrObject( const OUString& rName )
341 : {
342 0 : if( rName.isEmpty() )
343 0 : return 0;
344 0 : return getNamedSdrObject( rName, GetPage(0) );
345 : }
346 :
347 11876 : SdrObject* DrawModelWrapper::getNamedSdrObject( const OUString& rObjectCID, SdrObjList* pSearchList )
348 : {
349 11876 : if(!pSearchList || rObjectCID.isEmpty())
350 5206 : return 0;
351 6670 : const size_t nCount = pSearchList->GetObjCount();
352 14322 : for( size_t nN=0; nN<nCount; ++nN )
353 : {
354 11250 : SdrObject* pObj = pSearchList->GetObj(nN);
355 11250 : if(!pObj)
356 0 : continue;
357 11250 : if( ObjectIdentifier::areIdenticalObjects( rObjectCID, pObj->GetName() ) )
358 1230 : return pObj;
359 10020 : pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, pObj->GetSubList() );
360 10020 : if(pObj)
361 2368 : return pObj;
362 : }
363 3072 : return 0;
364 : }
365 :
366 0 : bool DrawModelWrapper::removeShape( const uno::Reference< drawing::XShape >& xShape )
367 : {
368 0 : uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
369 0 : if( xChild.is() )
370 : {
371 0 : uno::Reference<drawing::XShapes> xShapes( xChild->getParent(), uno::UNO_QUERY );
372 0 : if( xShapes.is() )
373 : {
374 0 : xShapes->remove(xShape);
375 0 : return true;
376 0 : }
377 : }
378 0 : return false;
379 : }
380 :
381 108 : } //namespace chart
382 :
383 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|