LibreOffice Module chart2 (master) 1
DrawViewWrapper.cxx
Go to the documentation of this file.
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>
22
23#include <unotools/lingucfg.hxx>
26#include <editeng/eeitem.hxx>
27#include <editeng/langitem.hxx>
28#include <svl/intitem.hxx>
29#include <svl/itempool.hxx>
30#include <svx/obj3d.hxx>
31#include <svx/svdpagv.hxx>
32#include <svx/svdmodel.hxx>
33#include <svx/svdetc.hxx>
34#include <svx/svdoutl.hxx>
35#include <svx/svxids.hrc>
36#include <editeng/fhgtitem.hxx>
37#include <osl/diagnose.h>
38
39#include <com/sun/star/frame/XModel.hpp>
40#include <com/sun/star/drawing/XShape.hpp>
41
42#include <sfx2/objsh.hxx>
44#include <officecfg/Office/Calc.hxx>
45
46using namespace ::com::sun::star;
47
48namespace chart
49{
50
51namespace
52{
53 short lcl_getHitTolerance( OutputDevice const * pOutDev )
54 {
55 const short HITPIX=2; //hit-tolerance in pixel
56 short nHitTolerance = 50;
57 if(pOutDev)
58 nHitTolerance = static_cast<short>(pOutDev->PixelToLogic(Size(HITPIX,0)).Width());
59 return nHitTolerance;
60 }
61
62// this code is copied from sfx2/source/doc/objembed.cxx. It is a workaround to
63// get the reference device (e.g. printer) from the parent document
64OutputDevice * lcl_GetParentRefDevice( const uno::Reference< frame::XModel > & xModel )
65{
67 if ( pParent )
68 return pParent->GetDocumentRefDev();
69 return nullptr;
70}
71
72}
73
75 SdrModel& rSdrModel,
76 OutputDevice* pOut)
77: E3dView(rSdrModel, pOut)
78 ,m_pMarkHandleProvider(nullptr)
79 ,m_apOutliner(SdrMakeOutliner(OutlinerMode::TextObject, rSdrModel))
80 ,m_bRestoreMapMode( false )
81{
84
85 // #i12587# support for shapes in chart
86 SdrOutliner* pOutliner = getOutliner();
87 SfxItemPool* pOutlinerPool = ( pOutliner ? pOutliner->GetEditTextObjectPool() : nullptr );
88 if ( pOutlinerPool )
89 {
90 SvtLinguConfig aLinguConfig;
91 SvtLinguOptions aLinguOptions;
92 aLinguConfig.GetOptions( aLinguOptions );
93 pOutlinerPool->SetPoolDefaultItem( SvxLanguageItem( aLinguOptions.nDefaultLanguage, EE_CHAR_LANGUAGE ) );
96
97 // set font height without changing SdrEngineDefaults
98 pOutlinerPool->SetPoolDefaultItem( SvxFontHeightItem( 423, 100, EE_CHAR_FONTHEIGHT ) ); // 12pt
99 }
100
101 // #i121463# Use big handles by default
103
104 ReInit();
105}
106
108{
110 Size aOutputSize(100,100);
111 if(pOutDev)
112 aOutputSize = pOutDev->GetOutputSize();
113
114 mbPageVisible = false;
115 mbPageBorderVisible = false;
116 mbBordVisible = false;
117 mbGridVisible = false;
118 mbHlplVisible = false;
119
120 SetNoDragXorPolys(true);//for interactive 3D resize-dragging: paint only a single rectangle (not a simulated 3D object)
121
122 //a correct work area is at least necessary for correct values in the position and size dialog
123 tools::Rectangle aRect(Point(0,0), aOutputSize);
124 SetWorkArea(aRect);
125
126 ShowSdrPage(GetModel().GetPage(0));
127}
128
130{
131 maComeBackIdle.Stop();//@todo this should be done in destructor of base class
132 UnmarkAllObj();//necessary to avoid a paint call during the destructor hierarchy
133}
134
136{
137 SdrPageView* pSdrPageView = GetSdrPageView();
138 return pSdrPageView;
139};
140
142{
144 return;
145 else
146 SdrView::SetMarkHandles(pOtherShell);
147}
148
150{
151 SdrPageView* pSdrPageView = GetPageView();
152 SdrObject* pRet = SdrView::PickObj(rPnt, lcl_getHitTolerance( GetFirstOutputDevice() ), pSdrPageView,
153 SdrSearchOptions::DEEP | SdrSearchOptions::TESTMARKABLE);
154
155 if( pRet )
156 {
157 // ignore some special shapes
158 OUString aShapeName = pRet->GetName();
159
160 // return right away if it is a field button
161 if (aShapeName.startsWith("FieldButton"))
162 return pRet;
163
164 if( aShapeName.match("PlotAreaIncludingAxes") || aShapeName.match("PlotAreaExcludingAxes") )
165 {
166 pRet->SetMarkProtect( true );
167 return getHitObject( rPnt );
168 }
169
170 //3d objects need a special treatment
171 //because the simple PickObj method is not accurate in this case for performance reasons
172 E3dObject* pE3d = DynCastE3dObject(pRet);
173 if( pE3d )
174 {
175 E3dScene* pScene(pE3d->getRootE3dSceneFromE3dObject());
176
177 if(nullptr != pScene)
178 {
179 // prepare result vector and call helper
180 std::vector< const E3dCompoundObject* > aHitList;
181 const basegfx::B2DPoint aHitPoint(rPnt.X(), rPnt.Y());
182 getAllHit3DObjectsSortedFrontToBack(aHitPoint, *pScene, aHitList);
183
184 if(!aHitList.empty())
185 {
186 // choose the frontmost hit 3D object of the scene
187 pRet = const_cast< E3dCompoundObject* >(aHitList[0]);
188 }
189 }
190 }
191 }
192 return pRet;
193}
194
196{
197 bool bFrameDragSingles = true;//true == green == surrounding handles
198 if(pObj)
199 pObj->SetMarkProtect(false);
201 bFrameDragSingles = m_pMarkHandleProvider->getFrameDragSingles();
202
203 SetFrameDragSingles(bFrameDragSingles);//decide whether each single object should get handles
204 SdrView::MarkObj( pObj, GetPageView() );
206}
207
209{
210 m_pMarkHandleProvider = pMarkHandleProvider;
211}
212
214{
215 svtools::ColorConfig aColorConfig;
216 Color aFillColor( aColorConfig.GetColorValue( svtools::DOCCOLOR ).nColor );
219}
220
222{
223 SdrObject* pObj(nullptr);
224 const SdrMarkList& rMarkList = GetMarkedObjectList();
225 if(rMarkList.GetMarkCount() == 1)
226 {
227 SdrMark* pMark = rMarkList.GetMark(0);
228 pObj = pMark->GetMarkedSdrObj();
229 }
230 return pObj;
231}
232
234{
236 SdrObject* pTextObj = nullptr;
237 if( pObj && pObj->HasTextEdit())
238 pTextObj = pObj;
239 return pTextObj;
240}
241
243{
244 OutputDevice * pParentRefDev( lcl_GetParentRefDevice( xChartModel ));
245 SdrOutliner * pOutliner( getOutliner());
246 if( pParentRefDev && pOutliner )
247 {
248 pOutliner->SetRefDevice( pParentRefDev );
249 }
250}
251
253{
254 return m_apOutliner.get();
255}
256
258{
259 SvtSysLocale aSysLocale;
261 sal_uInt16 nAttrMetric;
262 if( eSys == MeasurementSystem::Metric )
263 nAttrMetric = officecfg::Office::Calc::Layout::Other::MeasureUnit::Metric::get();
264 else
265 nAttrMetric = officecfg::Office::Calc::Layout::Other::MeasureUnit::NonMetric::get();
266
267 SfxItemSet aFullSet(
268 GetModel().GetItemPool(),
271 SID_ATTR_TRANSFORM_POS_X, SID_ATTR_TRANSFORM_ANGLE,
272 SID_ATTR_TRANSFORM_PROTECT_POS, SID_ATTR_TRANSFORM_AUTOHEIGHT,
273 SID_ATTR_METRIC, SID_ATTR_METRIC>);
275 aFullSet.Put( aGeoSet );
276 aFullSet.Put( SfxUInt16Item(SID_ATTR_METRIC, nAttrMetric) );
277 return aFullSet;
278}
279
280SdrObject* DrawViewWrapper::getNamedSdrObject( const OUString& rName ) const
281{
282 if(rName.isEmpty())
283 return nullptr;
284 SdrPageView* pSdrPageView = GetPageView();
285 if( pSdrPageView )
286 {
287 return DrawModelWrapper::getNamedSdrObject( rName, pSdrPageView->GetObjList() );
288 }
289 return nullptr;
290}
291
292bool DrawViewWrapper::IsObjectHit( SdrObject const * pObj, const Point& rPnt )
293{
294 if(pObj)
295 {
297 return aRect.Contains(rPnt);
298 }
299 return false;
300}
301
303{
304 //prevent wrong reselection of objects
305 SdrModel& rSdrModel = GetModel();
306 if (rSdrModel.isLocked())
307 return;
308
309 const SdrHint* pSdrHint = ( rHint.GetId() == SfxHintId::ThisIsAnSdrHint ? static_cast<const SdrHint*>(&rHint) : nullptr );
310
311 //#i76053# do nothing when only changes on the hidden draw page were made ( e.g. when the symbols for the dialogs are created )
312 SdrPageView* pSdrPageView = GetPageView();
313 if( pSdrHint && pSdrPageView )
314 {
315 if( pSdrPageView->GetPage() != pSdrHint->GetPage() )
316 return;
317 }
318
319 E3dView::Notify(rBC, rHint);
320
321 if( pSdrHint == nullptr )
322 return;
323
324 SdrHintKind eKind = pSdrHint->GetKind();
325 if( eKind == SdrHintKind::BeginEdit )
326 {
327 // #i79965# remember map mode
328 OSL_ASSERT( ! m_bRestoreMapMode );
330 if( pOutDev )
331 {
332 m_aMapModeToRestore = pOutDev->GetMapMode();
333 m_bRestoreMapMode = true;
334 }
335 }
336 else if( eKind == SdrHintKind::EndEdit )
337 {
338 // #i79965# scroll back view when ending text edit
339 OSL_ASSERT( m_bRestoreMapMode );
341 {
343 if( pOutDev )
344 {
346 m_bRestoreMapMode = false;
347 }
348 }
349 }
350}
351
353 drawing::XShape >& xShape )
354{
355 SdrObject* pRet = nullptr;
356 uno::Reference< lang::XTypeProvider > xTypeProvider( xShape, uno::UNO_QUERY );
357 if(xTypeProvider.is())
358 {
360 }
361 return pRet;
362}
363
364} //namespace chart
365
366/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
virtual E3dScene * getRootE3dSceneFromE3dObject() const
MeasurementSystem getMeasurementSystemEnum() const
Size GetOutputSize() const
SAL_WARN_UNUSED_RESULT Point PixelToLogic(const Point &rDevicePt) const
void SetMapMode()
const MapMode & GetMapMode() const
constexpr tools::Long Y() const
constexpr tools::Long X() const
void SetWorkArea(const tools::Rectangle &rRect)
void SetNoDragXorPolys(bool bOn)
virtual void SetMarkHandles(SfxViewShell *pOtherShell) override
SfxItemSet GetGeoAttrFromMarked() const
const SdrPage * GetPage() const
SdrHintKind GetKind() const
size_t GetMarkCount() const
SdrMark * GetMark(size_t nNum) const
void SetFrameDragSingles(bool bOn=true)
const SdrMarkList & GetMarkedObjectList() const
SdrObject * PickObj(const Point &rPnt, short nTol, SdrPageView *&rpPV, SdrSearchOptions nOptions, SdrObject **ppRootObj, bool *pbHitPassDirect=nullptr) const
SdrHdlList maHdlList
void UnmarkAllObj(SdrPageView const *pPV=nullptr)
void SetMarkHdlSizePixel(sal_uInt16 nSiz)
void showMarkHandles()
bool MarkObj(const Point &rPnt, short nTol=-2, bool bToggle=false, bool bDeep=false)
SdrObject * GetMarkedSdrObj() const
bool isLocked() const
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
SdrPageView * ShowSdrPage(SdrPage *pPage) override
static SdrObject * getSdrObjectFromXShape(const css::uno::Reference< css::uno::XInterface > &xInt)
void SetMarkProtect(bool bProt)
virtual const tools::Rectangle & GetCurrentBoundRect() const
virtual const OUString & GetName() const
virtual bool HasTextEdit() const
SdrObjList * GetObjList() const
SdrPage * GetPage() const
bool mbBordVisible
bool mbPageBorderVisible
bool mbGridVisible
virtual void CompleteRedraw(OutputDevice *pOut, const vcl::Region &rReg, sdr::contact::ViewObjectContactRedirector *pRedirector=nullptr)
OutputDevice * GetFirstOutputDevice() const
void SetApplicationBackgroundColor(Color aBackgroundColor)
void SetBufferedOverlayAllowed(bool bNew)
bool mbPageVisible
Idle maComeBackIdle
SdrPageView * GetSdrPageView() const
bool mbHlplVisible
SdrModel & GetModel() const
void SetBufferedOutputAllowed(bool bNew)
SfxHintId GetId() const
void SetPoolDefaultItem(const SfxPoolItem &)
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
virtual OutputDevice * GetDocumentRefDev()
static SfxObjectShell * GetParentShell(const css::uno::Reference< css::uno::XInterface > &xChild)
void GetOptions(SvtLinguOptions &rOptions) const
const LocaleDataWrapper & GetLocaleData() const
void Stop()
SdrObject * getNamedSdrObject(const OUString &rName)
virtual void Notify(SfxBroadcaster &rBC, const SfxHint &rHint) override
SdrPageView * GetPageView() const
void attachParentReferenceDevice(const css::uno::Reference< css::frame::XModel > &xChartModel)
tries to get an OutputDevice from the XParent of the model to use as reference device
void setMarkHandleProvider(MarkHandleProvider *pMarkHandleProvider)
void MarkObject(SdrObject *pObj)
SdrObject * getTextEditObject() const
SdrObject * getHitObject(const Point &rPnt) const
void CompleteRedraw(OutputDevice *pOut, const vcl::Region &rReg, sdr::contact::ViewObjectContactRedirector *pRedirector=nullptr) override
virtual ~DrawViewWrapper() override
static SdrObject * getSdrObject(const css::uno::Reference< css::drawing::XShape > &xShape)
SdrOutliner * getOutliner() const
MarkHandleProvider * m_pMarkHandleProvider
SdrObject * getNamedSdrObject(const OUString &rName) const
static bool IsObjectHit(SdrObject const *pObj, const Point &rPnt)
virtual void SetMarkHandles(SfxViewShell *pOtherShell) override
SdrObject * getSelectedObject() const
SfxItemSet getPositionAndSizeItemSetFromMarkedObject() const
std::unique_ptr< SdrOutliner > m_apOutliner
DrawViewWrapper(SdrModel &rSdrModel, OutputDevice *pOut)
The DrawViewWrapper should help us to reduce effort if the underlying DrawingLayer changes.
virtual bool getFrameDragSingles()=0
virtual bool getMarkHandles(SdrHdlList &rHdlList)=0
ColorConfigValue GetColorValue(ColorConfigEntry eEntry, bool bSmart=true) const
bool Contains(const Point &rPOINT) const
constexpr TypedWhichId< SvxFontHeightItem > EE_CHAR_FONTHEIGHT(EE_CHAR_START+2)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE_CTL(EE_CHAR_START+16)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE_CJK(EE_CHAR_START+15)
constexpr TypedWhichId< SvxLanguageItem > EE_CHAR_LANGUAGE(EE_CHAR_START+14)
SVXCORE_DLLPUBLIC void getAllHit3DObjectsSortedFrontToBack(const basegfx::B2DPoint &rPoint, const E3dScene &rScene, ::std::vector< const E3dCompoundObject * > &o_rResult)
MeasurementSystem
static constexpr auto Items
OutlinerMode
LanguageType nDefaultLanguage
LanguageType nDefaultLanguage_CTL
LanguageType nDefaultLanguage_CJK
constexpr TypedWhichId< SdrMetricItem > SDRATTR_CORNER_RADIUS(SDRATTR_MISC_FIRST+0)
SVXCORE_DLLPUBLIC std::unique_ptr< SdrOutliner > SdrMakeOutliner(OutlinerMode nOutlinerMode, SdrModel &rMod)
SdrHintKind
SVXCORE_DLLPUBLIC E3dObject * DynCastE3dObject(SdrObject *)
oslFileHandle & pOut