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 321 : DrawModelWrapper::DrawModelWrapper( const uno::Reference<uno::XComponentContext>& /*xContext*/ )
94 642 : : SdrModel( SvtPathOptions().GetPalettePath(), NULL, NULL, false, false )
95 : , m_pChartItemPool(0)
96 : , m_xMainDrawPage(0)
97 642 : , m_xHiddenDrawPage(0)
98 : {
99 321 : m_pChartItemPool = ChartItemPool::CreateChartItemPool();
100 :
101 321 : SetScaleUnit(MAP_100TH_MM);
102 321 : SetScaleFraction(Fraction(1, 1));
103 321 : SetDefaultFontHeight(423); // 12pt
104 :
105 321 : SfxItemPool* pMasterPool = &GetItemPool();
106 321 : pMasterPool->SetDefaultMetric(SFX_MAPUNIT_100TH_MM);
107 321 : pMasterPool->SetPoolDefaultItem(SfxBoolItem(EE_PARA_HYPHENATE, true) );
108 321 : pMasterPool->SetPoolDefaultItem(makeSvx3DPercentDiagonalItem (5));
109 :
110 321 : SfxItemPool* pPool = pMasterPool;
111 : // append chart pool to end of pool chain
112 : for (;;)
113 : {
114 642 : SfxItemPool* pSecondary = pPool->GetSecondaryPool();
115 642 : if (!pSecondary)
116 321 : break;
117 :
118 321 : pPool = pSecondary;
119 321 : }
120 321 : pPool->SetSecondaryPool(m_pChartItemPool);
121 321 : 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 321 : if(!b3dFactoryInitialized)
127 : {
128 18 : E3dObjFactory aObjFactory;
129 18 : b3dFactoryInitialized = true;
130 : }
131 :
132 : //Hyphenyation and spellchecking
133 321 : SdrOutliner& rOutliner = GetDrawOutliner();
134 : try
135 : {
136 321 : uno::Reference< linguistic2::XHyphenator > xHyphenator( LinguMgr::GetHyphenator() );
137 321 : if( xHyphenator.is() )
138 321 : rOutliner.SetHyphenator( xHyphenator );
139 :
140 642 : uno::Reference< linguistic2::XSpellChecker1 > xSpellChecker( LinguMgr::GetSpellChecker() );
141 321 : if ( xSpellChecker.is() )
142 642 : 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 321 : OutputDevice* pDefaultDevice = rOutliner.GetRefDevice();
151 321 : if( !pDefaultDevice )
152 0 : pDefaultDevice = Application::GetDefaultDevice();
153 321 : m_pRefDevice.disposeAndClear();
154 321 : m_pRefDevice = VclPtr<VirtualDevice>::Create(*pDefaultDevice);
155 321 : MapMode aMapMode = m_pRefDevice->GetMapMode();
156 321 : aMapMode.SetMapUnit(MAP_100TH_MM);
157 321 : m_pRefDevice->SetMapMode(aMapMode);
158 321 : SetRefDevice(m_pRefDevice.get());
159 321 : rOutliner.SetRefDevice(m_pRefDevice.get());
160 321 : }
161 :
162 915 : DrawModelWrapper::~DrawModelWrapper()
163 : {
164 : //remove m_pChartItemPool from pool chain
165 305 : if(m_pChartItemPool)
166 : {
167 305 : SfxItemPool* pPool = &GetItemPool();
168 : for (;;)
169 : {
170 610 : SfxItemPool* pSecondary = pPool->GetSecondaryPool();
171 610 : if(pSecondary == m_pChartItemPool)
172 : {
173 305 : pPool->SetSecondaryPool (NULL);
174 305 : break;
175 : }
176 305 : pPool = pSecondary;
177 305 : }
178 305 : SfxItemPool::Free(m_pChartItemPool);
179 : }
180 305 : m_pRefDevice.disposeAndClear();
181 610 : }
182 :
183 321 : uno::Reference< uno::XInterface > DrawModelWrapper::createUnoModel()
184 : {
185 321 : 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
186 321 : return uno::Reference< uno::XInterface >::query( xComponent );
187 : }
188 :
189 3916 : uno::Reference< frame::XModel > DrawModelWrapper::getUnoModel()
190 : {
191 3916 : uno::Reference< uno::XInterface > xI = this->SdrModel::getUnoModel();
192 3916 : return uno::Reference<frame::XModel>::query( xI );
193 : }
194 :
195 6270 : SdrModel& DrawModelWrapper::getSdrModel()
196 : {
197 6270 : return *this;
198 : }
199 :
200 1381 : uno::Reference< lang::XMultiServiceFactory > DrawModelWrapper::getShapeFactory()
201 : {
202 1381 : uno::Reference< lang::XMultiServiceFactory > xShapeFactory( this->getUnoModel(), uno::UNO_QUERY );
203 1381 : return xShapeFactory;
204 : }
205 :
206 1118 : uno::Reference< drawing::XDrawPage > DrawModelWrapper::getMainDrawPage()
207 : {
208 1118 : if (m_xMainDrawPage.is())
209 797 : return m_xMainDrawPage;
210 :
211 : // Create draw page.
212 321 : uno::Reference<drawing::XDrawPagesSupplier> xDrawPagesSuplier(getUnoModel(), uno::UNO_QUERY);
213 321 : if (!xDrawPagesSuplier.is())
214 0 : return m_xMainDrawPage;
215 :
216 642 : uno::Reference<drawing::XDrawPages> xDrawPages = xDrawPagesSuplier->getDrawPages();
217 321 : if (xDrawPages->getCount() > 1)
218 : {
219 : // Take the first page in case of multiple pages.
220 0 : uno::Any aPage = xDrawPages->getByIndex(0);
221 0 : aPage >>= m_xMainDrawPage;
222 : }
223 :
224 321 : if (!m_xMainDrawPage.is())
225 : {
226 321 : m_xMainDrawPage = xDrawPages->insertNewByIndex(0);
227 : }
228 :
229 : //ensure that additional shapes are in front of the chart objects so create the chart root before
230 : // let us disable this call for now
231 : // TODO:moggi
232 : // AbstractShapeFactory::getOrCreateShapeFactory(this->getShapeFactory())->getOrCreateChartRootShape( m_xMainDrawPage );
233 642 : return m_xMainDrawPage;
234 : }
235 0 : uno::Reference< drawing::XDrawPage > DrawModelWrapper::getHiddenDrawPage()
236 : {
237 0 : if( !m_xHiddenDrawPage.is() )
238 : {
239 0 : uno::Reference< drawing::XDrawPagesSupplier > xDrawPagesSuplier( this->getUnoModel(), uno::UNO_QUERY );
240 0 : if( xDrawPagesSuplier.is() )
241 : {
242 0 : uno::Reference< drawing::XDrawPages > xDrawPages( xDrawPagesSuplier->getDrawPages () );
243 0 : if( xDrawPages->getCount()>1 )
244 : {
245 0 : uno::Any aPage = xDrawPages->getByIndex( 1 ) ;
246 0 : aPage >>= m_xHiddenDrawPage;
247 : }
248 :
249 0 : if(!m_xHiddenDrawPage.is())
250 : {
251 0 : if( xDrawPages->getCount()==0 )
252 0 : m_xMainDrawPage = xDrawPages->insertNewByIndex( 0 );
253 0 : m_xHiddenDrawPage = xDrawPages->insertNewByIndex( 1 );
254 0 : }
255 0 : }
256 : }
257 0 : return m_xHiddenDrawPage;
258 : }
259 1176 : void DrawModelWrapper::clearMainDrawPage()
260 : {
261 : //uno::Reference<drawing::XShapes> xChartRoot( m_xMainDrawPage, uno::UNO_QUERY );
262 1176 : uno::Reference<drawing::XShapes> xChartRoot( AbstractShapeFactory::getChartRootShape( m_xMainDrawPage ) );
263 1176 : if( xChartRoot.is() )
264 : {
265 904 : sal_Int32 nSubCount = xChartRoot->getCount();
266 904 : uno::Reference< drawing::XShape > xShape;
267 5148 : for( sal_Int32 nS = nSubCount; nS--; )
268 : {
269 3340 : if( xChartRoot->getByIndex( nS ) >>= xShape )
270 3340 : xChartRoot->remove( xShape );
271 904 : }
272 1176 : }
273 1176 : }
274 :
275 542 : uno::Reference< drawing::XShapes > DrawModelWrapper::getChartRootShape(
276 : const uno::Reference< drawing::XDrawPage>& xDrawPage )
277 : {
278 542 : return AbstractShapeFactory::getChartRootShape( xDrawPage );
279 : }
280 :
281 1107 : void DrawModelWrapper::lockControllers()
282 : {
283 1107 : uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() );
284 1107 : if( xDrawModel.is())
285 1107 : xDrawModel->lockControllers();
286 1107 : }
287 1107 : void DrawModelWrapper::unlockControllers()
288 : {
289 1107 : uno::Reference< frame::XModel > xDrawModel( this->getUnoModel() );
290 1107 : if( xDrawModel.is())
291 1107 : xDrawModel->unlockControllers();
292 1107 : }
293 :
294 0 : void DrawModelWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel )
295 : {
296 0 : OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel ));
297 0 : if( pParentRefDev )
298 : {
299 0 : SetRefDevice( pParentRefDev );
300 : }
301 0 : }
302 :
303 0 : OutputDevice* DrawModelWrapper::getReferenceDevice() const
304 : {
305 0 : return SdrModel::GetRefDevice();
306 : }
307 :
308 2025 : SfxItemPool& DrawModelWrapper::GetItemPool()
309 : {
310 2025 : return this->SdrModel::GetItemPool();
311 : }
312 0 : const SfxItemPool& DrawModelWrapper::GetItemPool() const
313 : {
314 0 : return this->SdrModel::GetItemPool();
315 : }
316 0 : XColorListRef DrawModelWrapper::GetColorList() const
317 : {
318 0 : return this->SdrModel::GetColorList();
319 : }
320 0 : XDashListRef DrawModelWrapper::GetDashList() const
321 : {
322 0 : return this->SdrModel::GetDashList();
323 : }
324 0 : XLineEndListRef DrawModelWrapper::GetLineEndList() const
325 : {
326 0 : return this->SdrModel::GetLineEndList();
327 : }
328 0 : XGradientListRef DrawModelWrapper::GetGradientList() const
329 : {
330 0 : return this->SdrModel::GetGradientList();
331 : }
332 0 : XHatchListRef DrawModelWrapper::GetHatchList() const
333 : {
334 0 : return this->SdrModel::GetHatchList();
335 : }
336 0 : XBitmapListRef DrawModelWrapper::GetBitmapList() const
337 : {
338 0 : return this->SdrModel::GetBitmapList();
339 : }
340 :
341 0 : SdrObject* DrawModelWrapper::getNamedSdrObject( const OUString& rName )
342 : {
343 0 : if( rName.isEmpty() )
344 0 : return 0;
345 0 : return getNamedSdrObject( rName, GetPage(0) );
346 : }
347 :
348 26771 : SdrObject* DrawModelWrapper::getNamedSdrObject( const OUString& rObjectCID, SdrObjList* pSearchList )
349 : {
350 26771 : if(!pSearchList || rObjectCID.isEmpty())
351 11062 : return 0;
352 15709 : const size_t nCount = pSearchList->GetObjCount();
353 39854 : for( size_t nN=0; nN<nCount; ++nN )
354 : {
355 26745 : SdrObject* pObj = pSearchList->GetObj(nN);
356 26745 : if(!pObj)
357 0 : continue;
358 26745 : if( ObjectIdentifier::areIdenticalObjects( rObjectCID, pObj->GetName() ) )
359 996 : return pObj;
360 25749 : pObj = DrawModelWrapper::getNamedSdrObject( rObjectCID, pObj->GetSubList() );
361 25749 : if(pObj)
362 1604 : return pObj;
363 : }
364 13109 : return 0;
365 : }
366 :
367 0 : bool DrawModelWrapper::removeShape( const uno::Reference< drawing::XShape >& xShape )
368 : {
369 0 : uno::Reference< container::XChild > xChild( xShape, uno::UNO_QUERY );
370 0 : if( xChild.is() )
371 : {
372 0 : uno::Reference<drawing::XShapes> xShapes( xChild->getParent(), uno::UNO_QUERY );
373 0 : if( xShapes.is() )
374 : {
375 0 : xShapes->remove(xShape);
376 0 : return true;
377 0 : }
378 : }
379 0 : return false;
380 : }
381 :
382 57 : } //namespace chart
383 :
384 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|