LibreOffice Module svx (master) 1
svdouno.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
22#include <com/sun/star/container/XChild.hpp>
23#include <com/sun/star/beans/XPropertySet.hpp>
24#include <com/sun/star/util/XCloneable.hpp>
25#include <com/sun/star/uno/XComponentContext.hpp>
27#include <svx/svdouno.hxx>
28#include <svx/svdpagv.hxx>
29#include <svx/svdmodel.hxx>
30#include <svx/dialmgr.hxx>
31#include <svx/strings.hrc>
32#include <svx/svdview.hxx>
33#include <svx/svdorect.hxx>
34#include <svx/svdviter.hxx>
35#include <rtl/ref.hxx>
36#include <svx/sdrpagewindow.hxx>
38#include <tools/debug.hxx>
40
41using namespace ::com::sun::star;
42using namespace sdr::contact;
43
44
45// Defines
46
47
48// Helper class SdrControlEventListenerImpl
49
50#include <com/sun/star/lang/XEventListener.hpp>
51
53
54
55class SdrControlEventListenerImpl : public ::cppu::WeakImplHelper< css::lang::XEventListener >
56{
57protected:
59
60public:
62 : pObj(_pObj)
63 {}
64
65 // XEventListener
66 virtual void SAL_CALL disposing( const css::lang::EventObject& Source ) override;
67
68 void StopListening(const uno::Reference< lang::XComponent >& xComp);
69 void StartListening(const uno::Reference< lang::XComponent >& xComp);
70};
71
72// XEventListener
73void SAL_CALL SdrControlEventListenerImpl::disposing( const css::lang::EventObject& /*Source*/)
74{
75 if (pObj)
76 {
77 pObj->xUnoControlModel = nullptr;
78 }
79}
80
81void SdrControlEventListenerImpl::StopListening(const uno::Reference< lang::XComponent >& xComp)
82{
83 if (xComp.is())
84 xComp->removeEventListener(this);
85}
86
87void SdrControlEventListenerImpl::StartListening(const uno::Reference< lang::XComponent >& xComp)
88{
89 if (xComp.is())
90 xComp->addEventListener(this);
91}
92
93
95{
96 mutable ::rtl::Reference< SdrControlEventListenerImpl >
98};
99
100
101namespace
102{
103 void lcl_ensureControlVisibility( SdrView const * _pView, const SdrUnoObj* _pObject, bool _bVisible )
104 {
105 OSL_PRECOND( _pObject, "lcl_ensureControlVisibility: no object -> no survival!" );
106
107 SdrPageView* pPageView = _pView ? _pView->GetSdrPageView() : nullptr;
108 DBG_ASSERT( pPageView, "lcl_ensureControlVisibility: no view found!" );
109 if ( !pPageView )
110 return;
111
112 ViewContact& rUnoControlContact( _pObject->GetViewContact() );
113
114 for ( sal_uInt32 i = 0; i < pPageView->PageWindowCount(); ++i )
115 {
116 SdrPageWindow* pPageWindow = pPageView->GetPageWindow( i );
117 DBG_ASSERT( pPageWindow, "lcl_ensureControlVisibility: invalid PageViewWindow!" );
118 if ( !pPageWindow )
119 continue;
120
121 if ( !pPageWindow->HasObjectContact() )
122 continue;
123
124 ObjectContact& rPageViewContact( pPageWindow->GetObjectContact() );
125 const ViewObjectContact& rViewObjectContact( rUnoControlContact.GetViewObjectContact( rPageViewContact ) );
126 const ViewObjectContactOfUnoControl* pUnoControlContact = dynamic_cast< const ViewObjectContactOfUnoControl* >( &rViewObjectContact );
127 DBG_ASSERT( pUnoControlContact, "lcl_ensureControlVisibility: wrong ViewObjectContact type!" );
128 if ( !pUnoControlContact )
129 continue;
130
131 pUnoControlContact->ensureControlVisibility( _bVisible );
132 }
133 }
134}
135
137 SdrModel& rSdrModel,
138 const OUString& rModelName)
139: SdrRectObj(rSdrModel),
141{
142 osl_atomic_increment(&m_refCount); // prevent deletion during creation
143 m_bIsUnoObj = true;
144
145 m_pImpl->pEventListener = new SdrControlEventListenerImpl(this);
146
147 // only an owner may create independently
148 if (!rModelName.isEmpty())
149 CreateUnoControlModel(rModelName);
150 osl_atomic_decrement(&m_refCount);
151}
152
153SdrUnoObj::SdrUnoObj( SdrModel& rSdrModel, SdrUnoObj const & rSource)
154: SdrRectObj(rSdrModel, rSource),
156{
157 m_bIsUnoObj = true;
158
159 m_pImpl->pEventListener = new SdrControlEventListenerImpl(this);
160
163
164 // copy the uno control model
165 const uno::Reference< awt::XControlModel > xSourceControlModel = rSource.GetUnoControlModel();
166 if ( xSourceControlModel.is() )
167 {
168 try
169 {
170 uno::Reference< util::XCloneable > xClone( xSourceControlModel, uno::UNO_QUERY_THROW );
171 xUnoControlModel.set( xClone->createClone(), uno::UNO_QUERY_THROW );
172 }
173 catch( const uno::Exception& )
174 {
176 }
177 }
178
179 // get service name of the control from the control model
180 uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY);
181 if (xSet.is())
182 {
183 uno::Any aValue( xSet->getPropertyValue("DefaultControl") );
184 OUString aStr;
185
186 if( aValue >>= aStr )
188 }
189
190 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
191 if (xComp.is())
192 m_pImpl->pEventListener->StartListening(xComp);
193}
194
196 SdrModel& rSdrModel,
197 const OUString& rModelName,
198 const uno::Reference< lang::XMultiServiceFactory >& rxSFac)
199: SdrRectObj(rSdrModel),
201{
202 m_bIsUnoObj = true;
203
204 m_pImpl->pEventListener = new SdrControlEventListenerImpl(this);
205
206 // only an owner may create independently
207 if (!rModelName.isEmpty())
208 CreateUnoControlModel(rModelName,rxSFac);
209}
210
212{
213 try
214 {
215 // clean up the control model
216 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
217 if (xComp.is())
218 {
219 // is the control model owned by its environment?
220 uno::Reference< container::XChild > xContent(xUnoControlModel, uno::UNO_QUERY);
221 if (xContent.is() && !xContent->getParent().is())
222 xComp->dispose();
223 else
224 m_pImpl->pEventListener->StopListening(xComp);
225 }
226 }
227 catch( const uno::Exception& )
228 {
229 TOOLS_WARN_EXCEPTION( "svx", "SdrUnoObj::~SdrUnoObj" );
230 }
231}
232
234{
235 rInfo.bRotateFreeAllowed = false;
236 rInfo.bRotate90Allowed = false;
237 rInfo.bMirrorFreeAllowed = false;
238 rInfo.bMirror45Allowed = false;
239 rInfo.bMirror90Allowed = false;
240 rInfo.bTransparenceAllowed = false;
241 rInfo.bShearAllowed = false;
242 rInfo.bEdgeRadiusAllowed = false;
243 rInfo.bNoOrthoDesired = false;
244 rInfo.bCanConvToPath = false;
245 rInfo.bCanConvToPoly = false;
246 rInfo.bCanConvToPathLineToArea = false;
247 rInfo.bCanConvToPolyLineToArea = false;
248 rInfo.bCanConvToContour = false;
249}
250
252{
253 return SdrObjKind::UNO;
254}
255
256void SdrUnoObj::SetContextWritingMode( const sal_Int16 _nContextWritingMode )
257{
258 try
259 {
260 uno::Reference< beans::XPropertySet > xModelProperties( GetUnoControlModel(), uno::UNO_QUERY_THROW );
261 xModelProperties->setPropertyValue( "ContextWritingMode", uno::Any( _nContextWritingMode ) );
262 }
263 catch( const uno::Exception& )
264 {
266 }
267}
268
270{
271 OUString sName(SvxResId(STR_ObjNameSingulUno));
272
273 OUString aName(GetName());
274 if (!aName.isEmpty())
275 sName += " '" + aName + "'";
276
277 return sName;
278}
279
281{
282 return SvxResId(STR_ObjNamePluralUno);
283}
284
286{
287 return new SdrUnoObj(rTargetModel, *this);
288}
289
290void SdrUnoObj::NbcResize(const Point& rRef, const Fraction& xFact, const Fraction& yFact)
291{
292 SdrRectObj::NbcResize(rRef,xFact,yFact);
293
294 if (maGeo.m_nShearAngle==0_deg100 && maGeo.m_nRotationAngle==0_deg100)
295 return;
296
297 // small correctors
298 if (maGeo.m_nRotationAngle>=9000_deg100 && maGeo.m_nRotationAngle<27000_deg100)
299 {
301 }
302
303 maGeo.m_nRotationAngle = 0_deg100;
304 maGeo.m_nShearAngle = 0_deg100;
309}
310
311
313{
314 // no special drag; we have no rounding rect and
315 // do want frame handles
316 return false;
317}
318
320{
321 if ( GetLayer() == _nLayer )
322 { // redundant call -> not interested in doing anything here
323 SdrRectObj::NbcSetLayer( _nLayer );
324 return;
325 }
326
327 // we need some special handling here in case we're moved from an invisible layer
328 // to a visible one, or vice versa
329 // (relative to a layer. Remember that the visibility of a layer is a view attribute
330 // - the same layer can be visible in one view, and invisible in another view, at the
331 // same time)
332
333 // collect all views in which our old layer is visible
334 o3tl::sorted_vector< SdrView* > aPreviouslyVisible;
335
336 {
338 [&aPreviouslyVisible] (SdrView* pView)
339 {
340 aPreviouslyVisible.insert( pView );
341 return false;
342 });
343 }
344
345 SdrRectObj::NbcSetLayer( _nLayer );
346
347 // collect all views in which our new layer is visible
349
351 [&aPreviouslyVisible, &aNewlyVisible] (SdrView* pView)
352 {
353 if ( aPreviouslyVisible.erase(pView) == 0 )
354 {
355 // in pView, we were visible _before_ the layer change, and are
356 // _not_ visible after the layer change
357 // => remember this view, as our visibility there changed
358 aNewlyVisible.insert( pView );
359 }
360 });
361
362 // now aPreviouslyVisible contains all views where we became invisible
363 for (const auto& rpView : aPreviouslyVisible)
364 {
365 lcl_ensureControlVisibility( rpView, this, false );
366 }
367
368 // and aNewlyVisible all views where we became visible
369 for (const auto& rpView : aNewlyVisible)
370 {
371 lcl_ensureControlVisibility( rpView, this, true );
372 }
373}
374
375void SdrUnoObj::CreateUnoControlModel(const OUString& rModelName)
376{
377 DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
378
379 aUnoControlModelTypeName = rModelName;
380
381 uno::Reference< awt::XControlModel > xModel;
382 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
383 if (!aUnoControlModelTypeName.isEmpty() )
384 {
385 xModel.set(xContext->getServiceManager()->createInstanceWithContext(
386 aUnoControlModelTypeName, xContext), uno::UNO_QUERY);
387
388 if (xModel.is())
389 SetChanged();
390 }
391
393}
394
395void SdrUnoObj::CreateUnoControlModel(const OUString& rModelName,
396 const uno::Reference< lang::XMultiServiceFactory >& rxSFac)
397{
398 DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
399
400 aUnoControlModelTypeName = rModelName;
401
402 uno::Reference< awt::XControlModel > xModel;
403 if (!aUnoControlModelTypeName.isEmpty() && rxSFac.is() )
404 {
405 xModel.set(rxSFac->createInstance(aUnoControlModelTypeName), uno::UNO_QUERY);
406
407 if (xModel.is())
408 SetChanged();
409 }
410
411 SetUnoControlModel(xModel);
412}
413
414void SdrUnoObj::SetUnoControlModel( const uno::Reference< awt::XControlModel >& xModel)
415{
416 if (xUnoControlModel.is())
417 {
418 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
419 if (xComp.is())
420 m_pImpl->pEventListener->StopListening(xComp);
421 }
422
424
425 // control model has to contain service name of the control
426 if (xUnoControlModel.is())
427 {
428 uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY);
429 if (xSet.is())
430 {
431 uno::Any aValue( xSet->getPropertyValue("DefaultControl") );
432 OUString aStr;
433 if( aValue >>= aStr )
435 }
436
437 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
438 if (xComp.is())
439 m_pImpl->pEventListener->StartListening(xComp);
440 }
441
442 // invalidate all ViewObject contacts
443 ViewContactOfUnoControl* pVC = nullptr;
444 if ( impl_getViewContact( pVC ) )
445 {
446 // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This
447 // is always allowed since they will be re-created on demand (and with the changed model)
449 }
450}
451
452
453uno::Reference< awt::XControl > SdrUnoObj::GetUnoControl(const SdrView& _rView, const OutputDevice& _rOut) const
454{
455 uno::Reference< awt::XControl > xControl;
456
457 SdrPageView* pPageView = _rView.GetSdrPageView();
458 OSL_ENSURE( pPageView && getSdrPageFromSdrObject() == pPageView->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" );
459 if ( !pPageView || getSdrPageFromSdrObject() != pPageView->GetPage() )
460 return nullptr;
461
462 SdrPageWindow* pPageWindow = pPageView->FindPageWindow( _rOut );
463 OSL_ENSURE( pPageWindow, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
464 if ( !pPageWindow )
465 return nullptr;
466
467 ViewObjectContact& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow->GetObjectContact() ) );
468 ViewObjectContactOfUnoControl* pUnoContact = dynamic_cast< ViewObjectContactOfUnoControl* >( &rViewObjectContact );
469 OSL_ENSURE( pUnoContact, "SdrUnoObj::GetUnoControl: wrong contact type!" );
470 if ( pUnoContact )
471 xControl = pUnoContact->getControl();
472
473 return xControl;
474}
475
476
477uno::Reference< awt::XControl > SdrUnoObj::GetTemporaryControlForWindow(
478 const vcl::Window& _rWindow, uno::Reference< awt::XControlContainer >& _inout_ControlContainer ) const
479{
480 uno::Reference< awt::XControl > xControl;
481
482 ViewContactOfUnoControl* pVC = nullptr;
483 if ( impl_getViewContact( pVC ) )
484 xControl = pVC->getTemporaryControlForWindow( _rWindow, _inout_ControlContainer );
485
486 return xControl;
487}
488
489
491{
492 ViewContact& rViewContact( GetViewContact() );
493 _out_rpContact = dynamic_cast< ViewContactOfUnoControl* >( &rViewContact );
494 DBG_ASSERT( _out_rpContact, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" );
495 return ( _out_rpContact != nullptr );
496}
497
498
499std::unique_ptr<sdr::contact::ViewContact> SdrUnoObj::CreateObjectSpecificViewContact()
500{
501 return std::make_unique<sdr::contact::ViewContactOfUnoControl>( *this );
502}
503
504
505/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
::std::unique_ptr< XmlIdRegistry_Impl > m_pImpl
double mfTanShearAngle
Definition: svdtrans.hxx:205
double mfCosRotationAngle
Definition: svdtrans.hxx:207
double mfSinRotationAngle
Definition: svdtrans.hxx:206
Degree100 m_nShearAngle
Definition: svdtrans.hxx:204
Degree100 m_nRotationAngle
Definition: svdtrans.hxx:203
void StartListening(const uno::Reference< lang::XComponent > &xComp)
Definition: svdouno.cxx:87
SdrControlEventListenerImpl(SdrUnoObj *_pObj)
Definition: svdouno.cxx:61
virtual void SAL_CALL disposing(const css::lang::EventObject &Source) override
Definition: svdouno.cxx:73
void StopListening(const uno::Reference< lang::XComponent > &xComp)
Definition: svdouno.cxx:81
Provides information about various ZObject properties.
Definition: svdobj.hxx:196
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:664
virtual const OUString & GetName() const
Definition: svdobj.cxx:771
bool m_bIsUnoObj
Definition: svdobj.hxx:918
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:261
virtual void SetChanged()
Definition: svdobj.cxx:1042
SdrPage * getSdrPageFromSdrObject() const
Definition: svdobj.cxx:279
virtual SdrLayerID GetLayer() const
Definition: svdobj.cxx:645
virtual void SetBoundAndSnapRectsDirty(bool bNotMyself=false, bool bRecursive=true)
Definition: svdobj.cxx:509
sal_uInt32 PageWindowCount() const
Definition: svdpagv.hxx:89
SdrPage * GetPage() const
Definition: svdpagv.hxx:166
SdrPageWindow * GetPageWindow(sal_uInt32 nIndex) const
Definition: svdpagv.cxx:83
SdrPageWindow * FindPageWindow(const SdrPaintWindow &rPaintWindow) const
Definition: svdpagv.cxx:43
bool HasObjectContact() const
determines whether there already exists an ObjectContact
const sdr::contact::ObjectContact & GetObjectContact() const
SdrPageView * GetSdrPageView() const
Definition: svdpntv.hxx:323
Rectangle objects (rectangle, circle, ...)
Definition: svdorect.hxx:39
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdorect.cxx:451
GeoStat maGeo
Definition: svdotext.hxx:196
tools::Rectangle const & getRectangle() const
Definition: svdotext.hxx:170
void moveRectangle(sal_Int32 nXDelta, sal_Int32 nYDelta)
Definition: svdotext.hxx:185
SVX_DLLPRIVATE void CreateUnoControlModel(const OUString &rModelName)
Definition: svdouno.cxx:375
virtual void NbcSetLayer(SdrLayerID nLayer) override
Definition: svdouno.cxx:319
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdouno.cxx:499
css::uno::Reference< css::awt::XControlModel > xUnoControlModel
Definition: svdouno.hxx:54
virtual OUString TakeObjNameSingul() const override
Definition: svdouno.cxx:269
css::uno::Reference< css::awt::XControl > GetTemporaryControlForWindow(const vcl::Window &_rWindow, css::uno::Reference< css::awt::XControlContainer > &_inout_ControlContainer) const
Retrieves a temporary XControl instance for a given output device.
Definition: svdouno.cxx:477
OUString aUnoControlTypeName
Definition: svdouno.hxx:51
OUString aUnoControlModelTypeName
Definition: svdouno.hxx:50
virtual void SetContextWritingMode(const sal_Int16 _nContextWritingMode) override
Definition: svdouno.cxx:256
virtual bool hasSpecialDrag() const override
The standard transformations (Move,Resize,Rotate,Mirror,Shear) are taken over by the View (TakeXorPol...
Definition: svdouno.cxx:312
virtual void TakeObjInfo(SdrObjTransformInfoRec &rInfo) const override
Definition: svdouno.cxx:233
std::unique_ptr< SdrUnoObjDataHolder > m_pImpl
Definition: svdouno.hxx:48
const css::uno::Reference< css::awt::XControlModel > & GetUnoControlModel() const
Definition: svdouno.hxx:88
css::uno::Reference< css::awt::XControl > GetUnoControl(const SdrView &_rView, const OutputDevice &_rOut) const
Definition: svdouno.cxx:453
friend class SdrControlEventListenerImpl
Definition: svdouno.hxx:46
virtual void NbcResize(const Point &rRef, const Fraction &xFact, const Fraction &yFact) override
Definition: svdouno.cxx:290
virtual OUString TakeObjNamePlural() const override
Definition: svdouno.cxx:280
virtual void SetUnoControlModel(const css::uno::Reference< css::awt::XControlModel > &xModel)
Definition: svdouno.cxx:414
SdrUnoObj(SdrModel &rSdrModel, const OUString &rModelName)
Definition: svdouno.cxx:136
virtual SdrObjKind GetObjIdentifier() const override
Definition: svdouno.cxx:251
virtual ~SdrUnoObj() override
Definition: svdouno.cxx:211
virtual rtl::Reference< SdrObject > CloneSdrObject(SdrModel &rTargetModel) const override
Definition: svdouno.cxx:285
SVX_DLLPRIVATE bool impl_getViewContact(sdr::contact::ViewContactOfUnoControl *&_out_rpContact) const
Retrieves the typed ViewContact for the object.
Definition: svdouno.cxx:490
oslInterlockedCount m_refCount
size_type erase(const Value &x)
std::pair< const_iterator, bool > insert(Value &&x)
css::uno::Reference< css::awt::XControl > getTemporaryControlForWindow(const vcl::Window &_rWindow, css::uno::Reference< css::awt::XControlContainer > &_inout_ControlContainer) const
retrieves a temporary XControl instance, whose parent is the given window @seealso SdrUnoObj::GetTemp...
void flushViewObjectContacts(bool bWithHierarchy=true)
ViewObjectContact & GetViewObjectContact(ObjectContact &rObjectContact)
Definition: viewcontact.cxx:65
css::uno::Reference< css::awt::XControl > getControl()
returns the ->XControl instance belonging to the instance, creates it if necessary
void ensureControlVisibility(bool _bVisible) const
ensures that the control belonging to this instances has a given visibility
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
#define DBG_UNHANDLED_EXCEPTION(...)
OUString SvxResId(TranslateId aId)
Definition: dialmgr.cxx:24
OUString sName
OUString aName
aStr
void ForAllViews(const SdrPage *pPage, std::function< void(SdrView *)> f)
Definition: svdviter.cxx:83
int i
mutable ::rtl::Reference< SdrControlEventListenerImpl > pEventListener
Definition: svdouno.cxx:97
Reference< XModel > xModel
SdrObjKind
Definition: svdobjkind.hxx:25
@ UNO
continuously activated OLE (PlugIn-Frame or similar)
Left
Right