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