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.nShearAngle==0_deg100 && maGeo.nRotationAngle==0_deg100)
295 return;
296
297 // small correctors
298 if (maGeo.nRotationAngle>=9000_deg100 && maGeo.nRotationAngle<27000_deg100)
299 {
301 }
302
303 maGeo.nRotationAngle = 0_deg100;
304 maGeo.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 {
337 SdrViewIter aIter( this );
338 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
339 aPreviouslyVisible.insert( pView );
340 }
341
342 SdrRectObj::NbcSetLayer( _nLayer );
343
344 // collect all views in which our new layer is visible
346
347 {
348 SdrViewIter aIter( this );
349 for ( SdrView* pView = aIter.FirstView(); pView; pView = aIter.NextView() )
350 {
351 if ( aPreviouslyVisible.erase(pView) == 0 )
352 {
353 // in pView, we were visible _before_ the layer change, and are
354 // _not_ visible after the layer change
355 // => remember this view, as our visibility there changed
356 aNewlyVisible.insert( pView );
357 }
358 }
359 }
360
361 // now aPreviouslyVisible contains all views where we became invisible
362 for (const auto& rpView : aPreviouslyVisible)
363 {
364 lcl_ensureControlVisibility( rpView, this, false );
365 }
366
367 // and aNewlyVisible all views where we became visible
368 for (const auto& rpView : aNewlyVisible)
369 {
370 lcl_ensureControlVisibility( rpView, this, true );
371 }
372}
373
374void SdrUnoObj::CreateUnoControlModel(const OUString& rModelName)
375{
376 DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
377
378 aUnoControlModelTypeName = rModelName;
379
380 uno::Reference< awt::XControlModel > xModel;
381 uno::Reference< uno::XComponentContext > xContext( ::comphelper::getProcessComponentContext() );
382 if (!aUnoControlModelTypeName.isEmpty() )
383 {
384 xModel.set(xContext->getServiceManager()->createInstanceWithContext(
385 aUnoControlModelTypeName, xContext), uno::UNO_QUERY);
386
387 if (xModel.is())
388 SetChanged();
389 }
390
392}
393
394void SdrUnoObj::CreateUnoControlModel(const OUString& rModelName,
395 const uno::Reference< lang::XMultiServiceFactory >& rxSFac)
396{
397 DBG_ASSERT(!xUnoControlModel.is(), "model already exists");
398
399 aUnoControlModelTypeName = rModelName;
400
401 uno::Reference< awt::XControlModel > xModel;
402 if (!aUnoControlModelTypeName.isEmpty() && rxSFac.is() )
403 {
404 xModel.set(rxSFac->createInstance(aUnoControlModelTypeName), uno::UNO_QUERY);
405
406 if (xModel.is())
407 SetChanged();
408 }
409
410 SetUnoControlModel(xModel);
411}
412
413void SdrUnoObj::SetUnoControlModel( const uno::Reference< awt::XControlModel >& xModel)
414{
415 if (xUnoControlModel.is())
416 {
417 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
418 if (xComp.is())
419 m_pImpl->pEventListener->StopListening(xComp);
420 }
421
423
424 // control model has to contain service name of the control
425 if (xUnoControlModel.is())
426 {
427 uno::Reference< beans::XPropertySet > xSet(xUnoControlModel, uno::UNO_QUERY);
428 if (xSet.is())
429 {
430 uno::Any aValue( xSet->getPropertyValue("DefaultControl") );
431 OUString aStr;
432 if( aValue >>= aStr )
434 }
435
436 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
437 if (xComp.is())
438 m_pImpl->pEventListener->StartListening(xComp);
439 }
440
441 // invalidate all ViewObject contacts
442 ViewContactOfUnoControl* pVC = nullptr;
443 if ( impl_getViewContact( pVC ) )
444 {
445 // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This
446 // is always allowed since they will be re-created on demand (and with the changed model)
448 }
449}
450
451
452uno::Reference< awt::XControl > SdrUnoObj::GetUnoControl(const SdrView& _rView, const OutputDevice& _rOut) const
453{
454 uno::Reference< awt::XControl > xControl;
455
456 SdrPageView* pPageView = _rView.GetSdrPageView();
457 OSL_ENSURE( pPageView && getSdrPageFromSdrObject() == pPageView->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" );
458 if ( !pPageView || getSdrPageFromSdrObject() != pPageView->GetPage() )
459 return nullptr;
460
461 SdrPageWindow* pPageWindow = pPageView->FindPageWindow( _rOut );
462 OSL_ENSURE( pPageWindow, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
463 if ( !pPageWindow )
464 return nullptr;
465
466 ViewObjectContact& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow->GetObjectContact() ) );
467 ViewObjectContactOfUnoControl* pUnoContact = dynamic_cast< ViewObjectContactOfUnoControl* >( &rViewObjectContact );
468 OSL_ENSURE( pUnoContact, "SdrUnoObj::GetUnoControl: wrong contact type!" );
469 if ( pUnoContact )
470 xControl = pUnoContact->getControl();
471
472 return xControl;
473}
474
475
476uno::Reference< awt::XControl > SdrUnoObj::GetTemporaryControlForWindow(
477 const vcl::Window& _rWindow, uno::Reference< awt::XControlContainer >& _inout_ControlContainer ) const
478{
479 uno::Reference< awt::XControl > xControl;
480
481 ViewContactOfUnoControl* pVC = nullptr;
482 if ( impl_getViewContact( pVC ) )
483 xControl = pVC->getTemporaryControlForWindow( _rWindow, _inout_ControlContainer );
484
485 return xControl;
486}
487
488
490{
491 ViewContact& rViewContact( GetViewContact() );
492 _out_rpContact = dynamic_cast< ViewContactOfUnoControl* >( &rViewContact );
493 DBG_ASSERT( _out_rpContact, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" );
494 return ( _out_rpContact != nullptr );
495}
496
497
498std::unique_ptr<sdr::contact::ViewContact> SdrUnoObj::CreateObjectSpecificViewContact()
499{
500 return std::make_unique<sdr::contact::ViewContactOfUnoControl>( *this );
501}
502
503
504/* 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
Degree100 nShearAngle
Definition: svdtrans.hxx:204
double mfSinRotationAngle
Definition: svdtrans.hxx:206
Degree100 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:197
virtual void NbcSetLayer(SdrLayerID nLayer)
Definition: svdobj.cxx:662
const OUString & GetName() const
Definition: svdobj.cxx:769
bool m_bIsUnoObj
Definition: svdobj.hxx:924
sdr::contact::ViewContact & GetViewContact() const
Definition: svdobj.cxx:261
virtual void SetChanged()
Definition: svdobj.cxx:1002
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:300
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:171
tools::Rectangle maRect
Definition: svdotext.hxx:168
SVX_DLLPRIVATE void CreateUnoControlModel(const OUString &rModelName)
Definition: svdouno.cxx:374
virtual void NbcSetLayer(SdrLayerID nLayer) override
Definition: svdouno.cxx:319
virtual std::unique_ptr< sdr::contact::ViewContact > CreateObjectSpecificViewContact() override
Definition: svdouno.cxx:498
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:476
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:452
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:413
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:489
SdrView * NextView()
Definition: svdviter.cxx:159
SdrView * FirstView()
Definition: svdviter.cxx:153
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
constexpr tools::Long Top() const
void Move(tools::Long nHorzMoveDelta, tools::Long nVertMoveDelta)
constexpr tools::Long Right() const
constexpr tools::Long Left() const
constexpr tools::Long Bottom() const
#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
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)