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 "DrawViewWrapper.hxx"
21 : #include "chartview/DrawModelWrapper.hxx"
22 : #include "ConfigurationAccess.hxx"
23 : #include "macros.hxx"
24 :
25 : #include <unotools/lingucfg.hxx>
26 : #include <editeng/langitem.hxx>
27 : #include <svx/svdpage.hxx>
28 : #include <svx/svdpagv.hxx>
29 : #include <svx/svdmodel.hxx>
30 : #include <svx/scene3d.hxx>
31 : #include <svx/svdetc.hxx>
32 : #include <svx/svdoutl.hxx>
33 : #include <svx/svxids.hrc>
34 : #include <svx/unoshape.hxx>
35 : #include <editeng/fhgtitem.hxx>
36 :
37 : #include <com/sun/star/container/XChild.hpp>
38 : #include <com/sun/star/lang/XUnoTunnel.hpp>
39 :
40 : #include <sfx2/objsh.hxx>
41 : #include <svx/helperhittest3d.hxx>
42 :
43 : using namespace ::com::sun::star;
44 :
45 : namespace chart
46 : {
47 :
48 : namespace
49 : {
50 0 : short lcl_getHitTolerance( OutputDevice* pOutDev )
51 : {
52 0 : const short HITPIX=2; //hit-tolerance in pixel
53 0 : short nHitTolerance = 50;
54 0 : if(pOutDev)
55 0 : nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width());
56 0 : return nHitTolerance;
57 : }
58 :
59 : // this code is copied from sfx2/source/doc/objembed.cxx
60 17 : SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel )
61 : {
62 17 : SfxObjectShell* pResult = NULL;
63 :
64 : try
65 : {
66 17 : uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY );
67 17 : if ( xChildModel.is() )
68 : {
69 17 : uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY );
70 17 : if ( xParentTunnel.is() )
71 : {
72 1 : SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID );
73 : pResult = reinterpret_cast< SfxObjectShell * >(
74 1 : xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) );
75 17 : }
76 17 : }
77 : }
78 0 : catch( const uno::Exception& )
79 : {
80 : // TODO: error handling
81 : }
82 :
83 17 : return pResult;
84 : }
85 :
86 : // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to
87 : // get the reference device (e.g. printer) fromthe parent document
88 17 : OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel )
89 : {
90 17 : SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel );
91 17 : if ( pParent )
92 1 : return pParent->GetDocumentRefDev();
93 16 : return NULL;
94 : }
95 :
96 : }
97 :
98 17 : DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut, bool bPaintPageForEditMode)
99 : : E3dView(pSdrModel, pOut)
100 : , m_pMarkHandleProvider(NULL)
101 : , m_apOutliner(SdrMakeOutliner(OUTLINERMODE_TEXTOBJECT, *pSdrModel))
102 17 : , m_bRestoreMapMode( false )
103 : {
104 17 : SetBufferedOutputAllowed(true);
105 17 : SetBufferedOverlayAllowed(true);
106 :
107 17 : SetPagePaintingAllowed(bPaintPageForEditMode);
108 :
109 : // #i12587# support for shapes in chart
110 17 : SdrOutliner* pOutliner = getOutliner();
111 17 : SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : NULL );
112 17 : if ( pOutlinerPool )
113 : {
114 17 : SvtLinguConfig aLinguConfig;
115 34 : SvtLinguOptions aLinguOptions;
116 17 : if ( aLinguConfig.GetOptions( aLinguOptions ) )
117 : {
118 17 : pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) );
119 17 : pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) );
120 17 : pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) );
121 : }
122 :
123 : // set font height without changing SdrEngineDefaults
124 34 : pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt
125 : }
126 :
127 : // #i121463# Use big handles by default
128 17 : SetMarkHdlSizePixel(9);
129 :
130 17 : ReInit();
131 17 : }
132 :
133 780 : void DrawViewWrapper::ReInit()
134 : {
135 780 : OutputDevice* pOutDev = this->GetFirstOutputDevice();
136 780 : Size aOutputSize(100,100);
137 780 : if(pOutDev)
138 780 : aOutputSize = pOutDev->GetOutputSize();
139 :
140 780 : bPageVisible = false;
141 780 : bPageBorderVisible = false;
142 780 : bBordVisible = false;
143 780 : bGridVisible = false;
144 780 : bHlplVisible = false;
145 :
146 780 : this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object)
147 :
148 : //a correct work area is at least necessary for correct values in the position and size dialog
149 780 : Rectangle aRect(Point(0,0), aOutputSize);
150 780 : this->SetWorkArea(aRect);
151 :
152 780 : this->ShowSdrPage(this->GetModel()->GetPage(0));
153 780 : }
154 :
155 3 : DrawViewWrapper::~DrawViewWrapper()
156 : {
157 1 : aComeBackIdle.Stop();//@todo this should be done in destructor of base class
158 1 : UnmarkAllObj();//necessary to avoid a paint call during the destructor hierarchy
159 2 : }
160 :
161 0 : SdrPageView* DrawViewWrapper::GetPageView() const
162 : {
163 0 : SdrPageView* pSdrPageView = this->GetSdrPageView();
164 0 : return pSdrPageView;
165 : };
166 :
167 0 : void DrawViewWrapper::SetMarkHandles()
168 : {
169 0 : if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( maHdlList ) )
170 0 : return;
171 : else
172 0 : SdrView::SetMarkHandles();
173 : }
174 :
175 0 : SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
176 : {
177 0 : SdrObject* pRet = NULL;
178 0 : SdrSearchOptions nOptions = SdrSearchOptions::DEEP | SdrSearchOptions::TESTMARKABLE;
179 :
180 0 : SdrPageView* pSdrPageView = this->GetPageView();
181 0 : this->SdrView::PickObj(rPnt, lcl_getHitTolerance( this->GetFirstOutputDevice() ), pRet, pSdrPageView, nOptions);
182 :
183 0 : if( pRet )
184 : {
185 : //ignore some special shapes
186 0 : OUString aShapeName = pRet->GetName();
187 0 : if( aShapeName.match("PlotAreaIncludingAxes") || aShapeName.match("PlotAreaExcludingAxes") )
188 : {
189 0 : pRet->SetMarkProtect( true );
190 0 : return getHitObject( rPnt );
191 : }
192 :
193 : //3d objects need a special treatment
194 : //because the simple PickObj method is not accurate in this case for performance reasons
195 0 : E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet);
196 0 : if( pE3d )
197 : {
198 0 : E3dScene* pScene = pE3d->GetScene();
199 0 : if( pScene )
200 : {
201 : // prepare result vector and call helper
202 0 : ::std::vector< const E3dCompoundObject* > aHitList;
203 0 : const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y());
204 0 : getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList);
205 :
206 0 : if(!aHitList.empty())
207 : {
208 : // choose the frontmost hit 3D object of the scene
209 0 : pRet = const_cast< E3dCompoundObject* >(aHitList[0]);
210 0 : }
211 : }
212 0 : }
213 : }
214 0 : return pRet;
215 : }
216 :
217 0 : void DrawViewWrapper::MarkObject( SdrObject* pObj )
218 : {
219 0 : bool bFrameDragSingles = true;//true == green == surrounding handles
220 0 : if(pObj)
221 0 : pObj->SetMarkProtect(false);
222 0 : if( m_pMarkHandleProvider )
223 0 : bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles();
224 :
225 0 : this->SetFrameDragSingles(bFrameDragSingles);//decide whether each single object should get handles
226 0 : this->SdrView::MarkObj( pObj, this->GetPageView() );
227 0 : this->showMarkHandles();
228 0 : }
229 :
230 0 : void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider )
231 : {
232 0 : m_pMarkHandleProvider = pMarkHandleProvider;
233 0 : }
234 :
235 849 : void DrawViewWrapper::CompleteRedraw(OutputDevice* pOut, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* /* pRedirector */)
236 : {
237 849 : svtools::ColorConfig aColorConfig;
238 849 : Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
239 849 : this->SetApplicationBackgroundColor(aFillColor);
240 849 : this->E3dView::CompleteRedraw( pOut, rReg );
241 849 : }
242 :
243 0 : SdrObject* DrawViewWrapper::getSelectedObject() const
244 : {
245 0 : SdrObject* pObj(NULL);
246 0 : const SdrMarkList& rMarkList = this->GetMarkedObjectList();
247 0 : if(rMarkList.GetMarkCount() == 1)
248 : {
249 0 : SdrMark* pMark = rMarkList.GetMark(0);
250 0 : pObj = pMark->GetMarkedSdrObj();
251 : }
252 0 : return pObj;
253 : }
254 :
255 0 : SdrObject* DrawViewWrapper::getTextEditObject() const
256 : {
257 0 : SdrObject* pObj = this->getSelectedObject();
258 0 : SdrObject* pTextObj = NULL;
259 0 : if( pObj && pObj->HasTextEdit())
260 0 : pTextObj = static_cast<SdrTextObj*>(pObj);
261 0 : return pTextObj;
262 : }
263 :
264 17 : void DrawViewWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel )
265 : {
266 17 : OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel ));
267 17 : SdrOutliner * pOutliner( getOutliner());
268 17 : if( pParentRefDev && pOutliner )
269 : {
270 1 : pOutliner->SetRefDevice( pParentRefDev );
271 : }
272 17 : }
273 :
274 34 : SdrOutliner* DrawViewWrapper::getOutliner() const
275 : {
276 34 : return m_apOutliner.get();
277 : }
278 :
279 0 : SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const
280 : {
281 0 : SfxItemSet aFullSet( GetModel()->GetItemPool(),
282 : SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_ANGLE,
283 : SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_AUTOHEIGHT,
284 : SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS,
285 : SID_ATTR_METRIC, SID_ATTR_METRIC,
286 0 : 0);
287 0 : SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() );
288 0 : aFullSet.Put( aGeoSet );
289 0 : aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,static_cast< sal_uInt16 >( ConfigurationAccess::getFieldUnit())));
290 0 : return aFullSet;
291 : }
292 :
293 0 : SdrObject* DrawViewWrapper::getNamedSdrObject( const OUString& rName ) const
294 : {
295 0 : if(rName.isEmpty())
296 0 : return 0;
297 0 : SdrPageView* pSdrPageView = this->GetPageView();
298 0 : if( pSdrPageView )
299 : {
300 0 : return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() );
301 : }
302 0 : return 0;
303 : }
304 :
305 0 : bool DrawViewWrapper::IsObjectHit( SdrObject* pObj, const Point& rPnt )
306 : {
307 0 : if(pObj)
308 : {
309 0 : Rectangle aRect(pObj->GetCurrentBoundRect());
310 0 : return aRect.IsInside(rPnt);
311 : }
312 0 : return false;
313 : }
314 :
315 64140 : void DrawViewWrapper::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
316 : {
317 : //prevent wrong reselection of objects
318 64140 : SdrModel* pSdrModel( this->GetModel() );
319 64140 : if( pSdrModel && pSdrModel->isLocked() )
320 64140 : return;
321 :
322 0 : const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
323 :
324 : //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created )
325 0 : SdrPageView* pSdrPageView = this->GetPageView();
326 0 : if( pSdrHint && pSdrPageView )
327 : {
328 0 : if( pSdrPageView->GetPage() != pSdrHint->GetPage() )
329 0 : return;
330 : }
331 :
332 0 : E3dView::Notify(rBC, rHint);
333 :
334 0 : if( pSdrHint != 0 )
335 : {
336 0 : SdrHintKind eKind = pSdrHint->GetKind();
337 0 : if( eKind == HINT_BEGEDIT )
338 : {
339 : // #i79965# remember map mode
340 : OSL_ASSERT( ! m_bRestoreMapMode );
341 0 : OutputDevice* pOutDev = this->GetFirstOutputDevice();
342 0 : if( pOutDev )
343 : {
344 0 : m_aMapModeToRestore = pOutDev->GetMapMode();
345 0 : m_bRestoreMapMode = true;
346 : }
347 : }
348 0 : else if( eKind == HINT_ENDEDIT )
349 : {
350 : // #i79965# scroll back view when ending text edit
351 : OSL_ASSERT( m_bRestoreMapMode );
352 0 : if( m_bRestoreMapMode )
353 : {
354 0 : OutputDevice* pOutDev = this->GetFirstOutputDevice();
355 0 : if( pOutDev )
356 : {
357 0 : pOutDev->SetMapMode( m_aMapModeToRestore );
358 0 : m_bRestoreMapMode = false;
359 : }
360 : }
361 : }
362 : }
363 : }
364 :
365 0 : SdrObject* DrawViewWrapper::getSdrObject( const uno::Reference<
366 : drawing::XShape >& xShape )
367 : {
368 0 : SdrObject* pRet = 0;
369 0 : uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
370 0 : uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
371 0 : if(xUnoTunnel.is()&&xTypeProvider.is())
372 : {
373 0 : SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
374 0 : if(pSvxShape)
375 0 : pRet = pSvxShape->GetSdrObject();
376 : }
377 0 : return pRet;
378 : }
379 :
380 57 : } //namespace chart
381 :
382 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|