1 /**************************************************************
2 *
3 * Licensed to the Apache Software Foundation (ASF) under one
4 * or more contributor license agreements. See the NOTICE file
5 * distributed with this work for additional information
6 * regarding copyright ownership. The ASF licenses this file
7 * to you under the Apache License, Version 2.0 (the
8 * "License"); you may not use this file except in compliance
9 * with the License. You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing,
14 * software distributed under the License is distributed on an
15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16 * KIND, either express or implied. See the License for the
17 * specific language governing permissions and limitations
18 * under the License.
19 *
20 *************************************************************/
21
22
23
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_chart2.hxx"
26 #include "DrawViewWrapper.hxx"
27 #include "chartview/DrawModelWrapper.hxx"
28 #include "ConfigurationAccess.hxx"
29 #include "macros.hxx"
30
31 #include <unotools/lingucfg.hxx>
32 #include <editeng/langitem.hxx>
33 // header for class SdrPage
34 #include <svx/svdpage.hxx>
35 //header for class SdrPageView
36 #include <svx/svdpagv.hxx>
37 // header for class SdrModel
38 #include <svx/svdmodel.hxx>
39 // header for class E3dScene
40 #include <svx/scene3d.hxx>
41 #include <svx/svdetc.hxx>
42 #include <svx/svdoutl.hxx>
43
44 // header for class SvxForbiddenCharactersTable
45 #include <editeng/forbiddencharacterstable.hxx>
46
47 #ifndef _SVX_SVXIDS_HRC
48 #include <svx/svxids.hrc>
49 #endif
50
51 // header for class SvxShape
52 #include <svx/unoshape.hxx>
53 #include <editeng/fhgtitem.hxx>
54
55 #include <com/sun/star/container/XChild.hpp>
56 #include <com/sun/star/lang/XUnoTunnel.hpp>
57
58 #include <sfx2/objsh.hxx>
59 #include <svx/helperhittest3d.hxx>
60
61 using namespace ::com::sun::star;
62
63 //.............................................................................
64 namespace chart
65 {
66 //.............................................................................
67
68 namespace
69 {
lcl_getHitTolerance(OutputDevice * pOutDev)70 short lcl_getHitTolerance( OutputDevice* pOutDev )
71 {
72 const short HITPIX=2; //hit-tolerance in pixel
73 short nHitTolerance = 50;
74 if(pOutDev)
75 nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width());
76 return nHitTolerance;
77 }
78
79 // this code is copied from sfx2/source/doc/objembed.cxx
lcl_GetParentObjectShell(const uno::Reference<frame::XModel> & xModel)80 SfxObjectShell * lcl_GetParentObjectShell( const uno::Reference< frame::XModel > & xModel )
81 {
82 SfxObjectShell* pResult = NULL;
83
84 try
85 {
86 uno::Reference< container::XChild > xChildModel( xModel, uno::UNO_QUERY );
87 if ( xChildModel.is() )
88 {
89 uno::Reference< lang::XUnoTunnel > xParentTunnel( xChildModel->getParent(), uno::UNO_QUERY );
90 if ( xParentTunnel.is() )
91 {
92 SvGlobalName aSfxIdent( SFX_GLOBAL_CLASSID );
93 pResult = reinterpret_cast< SfxObjectShell * >(
94 xParentTunnel->getSomething( uno::Sequence< sal_Int8 >( aSfxIdent.GetByteSequence() ) ) );
95 }
96 }
97 }
98 catch( uno::Exception& )
99 {
100 // TODO: error handling
101 }
102
103 return pResult;
104 }
105
106 // this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to
107 // get the reference device (e.g. printer) fromthe parent document
lcl_GetParentRefDevice(const uno::Reference<frame::XModel> & xModel)108 OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel )
109 {
110 SfxObjectShell * pParent = lcl_GetParentObjectShell( xModel );
111 if ( pParent )
112 return pParent->GetDocumentRefDev();
113 return NULL;
114 }
115
116 }
117
118 /*
119 void lcl_initOutliner( SdrOutliner* pTargetOutliner, SdrOutliner* pSourceOutliner )
120 {
121 //just an unsuccessful try to initialize the text edit outliner correctly
122 //if( bInit )
123 {
124 pTargetOutliner->EraseVirtualDevice();
125 pTargetOutliner->SetUpdateMode(sal_False);
126 pTargetOutliner->SetEditTextObjectPool( pSourceOutliner->GetEditTextObjectPool() );
127 pTargetOutliner->SetDefTab( pSourceOutliner->GetDefTab() );
128 }
129
130 pTargetOutliner->SetRefDevice( pSourceOutliner->GetRefDevice() );
131 pTargetOutliner->SetForbiddenCharsTable( pSourceOutliner->GetForbiddenCharsTable() );
132 pTargetOutliner->SetAsianCompressionMode( pSourceOutliner->GetAsianCompressionMode() );
133 pTargetOutliner->SetKernAsianPunctuation( pSourceOutliner->IsKernAsianPunctuation() );
134 pTargetOutliner->SetStyleSheetPool( pSourceOutliner->GetStyleSheetPool() );
135 pTargetOutliner->SetRefMapMode( pSourceOutliner->GetRefMapMode() );
136 pTargetOutliner->SetDefaultLanguage( pSourceOutliner->GetDefaultLanguage() );
137 pTargetOutliner->SetHyphenator( pSourceOutliner->GetHyphenator() );
138
139 sal_uInt16 nX, nY;
140 pSourceOutliner->GetGlobalCharStretching( nX, nY );
141 pTargetOutliner->SetGlobalCharStretching( nX, nY );
142
143 *//*
144 if ( !GetRefDevice() )
145 {
146 MapMode aMapMode(eObjUnit, Point(0,0), aObjUnit, aObjUnit);
147 pTargetOutliner->SetRefMapMode(aMapMode);
148 }
149 *//*
150 }
151 */
152
DrawViewWrapper(SdrModel * pSdrModel,OutputDevice * pOut,bool bPaintPageForEditMode)153 DrawViewWrapper::DrawViewWrapper( SdrModel* pSdrModel, OutputDevice* pOut, bool bPaintPageForEditMode)
154 : E3dView(pSdrModel, pOut)
155 , m_pMarkHandleProvider(NULL)
156 , m_apOutliner( SdrMakeOutliner( OUTLINERMODE_TEXTOBJECT, pSdrModel ) )
157 , m_bRestoreMapMode( false )
158 {
159 // #114898#
160 SetBufferedOutputAllowed(true);
161 SetBufferedOverlayAllowed(true);
162
163 SetPagePaintingAllowed(bPaintPageForEditMode);
164
165 // #i12587# support for shapes in chart
166 SdrOutliner* pOutliner = getOutliner();
167 SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : NULL );
168 if ( pOutlinerPool )
169 {
170 SvtLinguConfig aLinguConfig;
171 SvtLinguOptions aLinguOptions;
172 if ( aLinguConfig.GetOptions( aLinguOptions ) )
173 {
174 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) );
175 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CJK, EE_CHAR_LANGUAGE_CJK ) );
176 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage_CTL, EE_CHAR_LANGUAGE_CTL ) );
177 }
178
179 // set font height without changing SdrEngineDefaults
180 pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt
181 }
182
183 // #121463# Use big handles by default
184 SetMarkHdlSizePixel(9);
185
186 ReInit();
187 }
188
ReInit()189 void DrawViewWrapper::ReInit()
190 {
191 OutputDevice* pOutDev = this->GetFirstOutputDevice();
192 Size aOutputSize(100,100);
193 if(pOutDev)
194 aOutputSize = pOutDev->GetOutputSize();
195
196 bPageVisible = false;
197 bPageBorderVisible = false;
198 bBordVisible = false;
199 bGridVisible = false;
200 bHlplVisible = false;
201
202 this->SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object)
203 //this->SetResizeAtCenter(true);//for interactive resize-dragging: keep the object center fix
204
205 //a correct work area is at least necessary for correct values in the position and size dialog
206 Rectangle aRect(Point(0,0), aOutputSize);
207 this->SetWorkArea(aRect);
208
209 this->ShowSdrPage(this->GetModel()->GetPage(0));
210 }
211
~DrawViewWrapper()212 DrawViewWrapper::~DrawViewWrapper()
213 {
214 aComeBackTimer.Stop();//@todo this should be done in destructor of base class
215 UnmarkAllObj();//necessary to aavoid a paint call during the destructor hierarchy
216 }
217
GetPageView() const218 SdrPageView* DrawViewWrapper::GetPageView() const
219 {
220 SdrPageView* pSdrPageView = this->GetSdrPageView();
221 return pSdrPageView;
222 };
223
224 //virtual
SetMarkHandles()225 void DrawViewWrapper::SetMarkHandles()
226 {
227 if( m_pMarkHandleProvider && m_pMarkHandleProvider->getMarkHandles( aHdl ) )
228 return;
229 else
230 SdrView::SetMarkHandles();
231 }
232
getHitObject(const Point & rPnt) const233 SdrObject* DrawViewWrapper::getHitObject( const Point& rPnt ) const
234 {
235 SdrObject* pRet = NULL;
236 //sal_uLong nOptions =SDRSEARCH_DEEP|SDRSEARCH_PASS2BOUND|SDRSEARCH_PASS3NEAREST;
237 sal_uLong nOptions = SDRSEARCH_DEEP | SDRSEARCH_TESTMARKABLE;
238
239 SdrPageView* pSdrPageView = this->GetPageView();
240 this->SdrView::PickObj(rPnt, lcl_getHitTolerance( this->GetFirstOutputDevice() ), pRet, pSdrPageView, nOptions);
241
242 if( pRet )
243 {
244 //ignore some special shapes
245 rtl::OUString aShapeName = pRet->GetName();
246 if( aShapeName.match(C2U("PlotAreaIncludingAxes")) || aShapeName.match(C2U("PlotAreaExcludingAxes")) )
247 {
248 pRet->SetMarkProtect( true );
249 return getHitObject( rPnt );
250 }
251
252 //3d objects need a special treatment
253 //because the simple PickObj method is not accurate in this case for performance reasons
254 E3dObject* pE3d = dynamic_cast< E3dObject* >(pRet);
255 if( pE3d )
256 {
257 E3dScene* pScene = pE3d->GetScene();
258 if( pScene )
259 {
260 // prepare result vector and call helper
261 ::std::vector< const E3dCompoundObject* > aHitList;
262 const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y());
263 getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList);
264
265 if(aHitList.size())
266 {
267 // choose the frontmost hit 3D object of the scene
268 pRet = const_cast< E3dCompoundObject* >(aHitList[0]);
269 }
270 }
271 }
272 }
273 return pRet;
274 }
275
MarkObject(SdrObject * pObj)276 void DrawViewWrapper::MarkObject( SdrObject* pObj )
277 {
278 bool bFrameDragSingles = true;//true == green == surrounding handles
279 if(pObj)
280 pObj->SetMarkProtect(false);
281 if( m_pMarkHandleProvider )
282 bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles();
283
284 this->SetFrameDragSingles(bFrameDragSingles);//decide whether each single object should get handles
285 this->SdrView::MarkObj( pObj, this->GetPageView() );
286 this->showMarkHandles();
287 }
288
289
setMarkHandleProvider(MarkHandleProvider * pMarkHandleProvider)290 void DrawViewWrapper::setMarkHandleProvider( MarkHandleProvider* pMarkHandleProvider )
291 {
292 m_pMarkHandleProvider = pMarkHandleProvider;
293 }
294
CompleteRedraw(OutputDevice * pOut,const Region & rReg,sdr::contact::ViewObjectContactRedirector *)295 void DrawViewWrapper::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* /* pRedirector */)
296 {
297 svtools::ColorConfig aColorConfig;
298 Color aFillColor = Color( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
299 this->SetApplicationBackgroundColor(aFillColor);
300 this->E3dView::CompleteRedraw( pOut, rReg );
301 }
302
getSelectedObject() const303 SdrObject* DrawViewWrapper::getSelectedObject() const
304 {
305 SdrObject* pObj(NULL);
306 const SdrMarkList& rMarkList = this->GetMarkedObjectList();
307 if(rMarkList.GetMarkCount() == 1)
308 {
309 SdrMark* pMark = rMarkList.GetMark(0);
310 pObj = pMark->GetMarkedSdrObj();
311 }
312 return pObj;
313 }
314
getTextEditObject() const315 SdrObject* DrawViewWrapper::getTextEditObject() const
316 {
317 SdrObject* pObj = this->getSelectedObject();
318 SdrObject* pTextObj = NULL;
319 if( pObj && pObj->HasTextEdit())
320 pTextObj = (SdrTextObj*)pObj;
321 return pTextObj;
322 }
323
attachParentReferenceDevice(const uno::Reference<frame::XModel> & xChartModel)324 void DrawViewWrapper::attachParentReferenceDevice( const uno::Reference< frame::XModel > & xChartModel )
325 {
326 OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel ));
327 SdrOutliner * pOutliner( getOutliner());
328 if( pParentRefDev && pOutliner )
329 {
330 pOutliner->SetRefDevice( pParentRefDev );
331 }
332 }
333
getOutliner() const334 SdrOutliner* DrawViewWrapper::getOutliner() const
335 {
336 // lcl_initOutliner( m_apOutliner.get(), &GetModel()->GetDrawOutliner() );
337 return m_apOutliner.get();
338 }
339
getPositionAndSizeItemSetFromMarkedObject() const340 SfxItemSet DrawViewWrapper::getPositionAndSizeItemSetFromMarkedObject() const
341 {
342 SfxItemSet aFullSet( GetModel()->GetItemPool(),
343 SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_ANGLE,
344 SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_AUTOHEIGHT,
345 SDRATTR_ECKENRADIUS, SDRATTR_ECKENRADIUS,
346 SID_ATTR_METRIC, SID_ATTR_METRIC,
347 0);
348 SfxItemSet aGeoSet( E3dView::GetGeoAttrFromMarked() );
349 aFullSet.Put( aGeoSet );
350 aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC,static_cast< sal_uInt16 >( ConfigurationAccess::getFieldUnit())));
351 return aFullSet;
352 }
353
getNamedSdrObject(const rtl::OUString & rName) const354 SdrObject* DrawViewWrapper::getNamedSdrObject( const rtl::OUString& rName ) const
355 {
356 if( rName.isEmpty() )
357 return 0;
358 SdrPageView* pSdrPageView = this->GetPageView();
359 if( pSdrPageView )
360 {
361 return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() );
362 }
363 return 0;
364 }
365
IsObjectHit(SdrObject * pObj,const Point & rPnt) const366 bool DrawViewWrapper::IsObjectHit( SdrObject* pObj, const Point& rPnt ) const
367 {
368 if(pObj)
369 {
370 Rectangle aRect(pObj->GetCurrentBoundRect());
371 return aRect.IsInside(rPnt);
372 }
373 return false;
374 }
375
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)376 void DrawViewWrapper::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
377 {
378 //prevent wrong reselection of objects
379 SdrModel* pSdrModel( this->GetModel() );
380 if( pSdrModel && pSdrModel->isLocked() )
381 return;
382
383 const SdrHint* pSdrHint = dynamic_cast< const SdrHint* >( &rHint );
384
385 //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created )
386 SdrPageView* pSdrPageView = this->GetPageView();
387 if( pSdrHint && pSdrPageView )
388 {
389 if( pSdrPageView->GetPage() != pSdrHint->GetPage() )
390 return;
391 }
392
393 E3dView::Notify(rBC, rHint);
394
395 if( pSdrHint != 0 )
396 {
397 SdrHintKind eKind = pSdrHint->GetKind();
398 if( eKind == HINT_BEGEDIT )
399 {
400 // #i79965# remember map mode
401 OSL_ASSERT( ! m_bRestoreMapMode );
402 OutputDevice* pOutDev = this->GetFirstOutputDevice();
403 if( pOutDev )
404 {
405 m_aMapModeToRestore = pOutDev->GetMapMode();
406 m_bRestoreMapMode = true;
407 }
408 }
409 else if( eKind == HINT_ENDEDIT )
410 {
411 // #i79965# scroll back view when ending text edit
412 OSL_ASSERT( m_bRestoreMapMode );
413 if( m_bRestoreMapMode )
414 {
415 OutputDevice* pOutDev = this->GetFirstOutputDevice();
416 if( pOutDev )
417 {
418 pOutDev->SetMapMode( m_aMapModeToRestore );
419 m_bRestoreMapMode = false;
420 }
421 }
422 }
423 }
424 }
425
getSdrObject(const uno::Reference<drawing::XShape> & xShape)426 SdrObject* DrawViewWrapper::getSdrObject( const uno::Reference<
427 drawing::XShape >& xShape )
428 {
429 SdrObject* pRet = 0;
430 uno::Reference< lang::XUnoTunnel > xUnoTunnel( xShape, uno::UNO_QUERY );
431 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
432 if(xUnoTunnel.is()&&xTypeProvider.is())
433 {
434 SvxShape* pSvxShape = reinterpret_cast<SvxShape*>(xUnoTunnel->getSomething( SvxShape::getUnoTunnelId() ));
435 if(pSvxShape)
436 pRet = pSvxShape->GetSdrObject();
437 }
438 return pRet;
439 }
440
441 //.............................................................................
442 } //namespace chart
443 //.............................................................................
444