1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <svx/sdr/contact/viewcontactofunocontrol.hxx>
21 #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
22 #include <com/sun/star/container/XChild.hpp>
23 #include <com/sun/star/awt/XWindow.hpp>
24 #include <com/sun/star/awt/PosSize.hpp>
25 #include <com/sun/star/beans/XPropertySet.hpp>
26 #include <com/sun/star/io/XPersistObject.hpp>
27 #include <com/sun/star/io/XOutputStream.hpp>
28 #include <com/sun/star/io/XInputStream.hpp>
29 #include <com/sun/star/io/XActiveDataSink.hpp>
30 #include <com/sun/star/io/XActiveDataSource.hpp>
31 #include <com/sun/star/io/XObjectOutputStream.hpp>
32 #include <com/sun/star/io/XObjectInputStream.hpp>
33 #include <com/sun/star/util/XCloneable.hpp>
34 #include <comphelper/processfactory.hxx>
35 #include <comphelper/types.hxx>
36 #include <vcl/pdfextoutdevdata.hxx>
37 #include <svx/svdouno.hxx>
38 #include <svx/svdpagv.hxx>
39 #include <svx/svdmodel.hxx>
40 #include "svx/svdglob.hxx" // string cache
41 #include "svx/svdstr.hrc" // the object's name
42 #include <svx/svdetc.hxx>
43 #include <svx/svdview.hxx>
44 #include <svx/svdorect.hxx>
45 #include "svx/svdviter.hxx"
46 #include <rtl/ref.hxx>
49 #include <svx/sdrpagewindow.hxx>
50 #include <svx/sdrpaintwindow.hxx>
51 #include <tools/diagnose_ex.h>
52 #include <svx/svdograf.hxx>
54 using namespace ::com::sun::star
;
55 using namespace ::sdr::contact
;
57 //************************************************************
59 //************************************************************
61 //************************************************************
62 // Helper class SdrControlEventListenerImpl
63 //************************************************************
64 #include <com/sun/star/lang/XEventListener.hpp>
66 #include <cppuhelper/implbase1.hxx>
68 // =============================================================================
69 class SdrControlEventListenerImpl
: public ::cppu::WeakImplHelper1
< ::com::sun::star::lang::XEventListener
>
75 SdrControlEventListenerImpl(SdrUnoObj
* _pObj
)
80 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw(::com::sun::star::uno::RuntimeException
);
82 void StopListening(const uno::Reference
< lang::XComponent
>& xComp
);
83 void StartListening(const uno::Reference
< lang::XComponent
>& xComp
);
87 void SAL_CALL
SdrControlEventListenerImpl::disposing( const ::com::sun::star::lang::EventObject
& /*Source*/)
88 throw(::com::sun::star::uno::RuntimeException
)
92 pObj
->xUnoControlModel
= NULL
;
96 void SdrControlEventListenerImpl::StopListening(const uno::Reference
< lang::XComponent
>& xComp
)
99 xComp
->removeEventListener(this);
102 void SdrControlEventListenerImpl::StartListening(const uno::Reference
< lang::XComponent
>& xComp
)
105 xComp
->addEventListener(this);
108 // =============================================================================
109 struct SAL_DLLPRIVATE SdrUnoObjDataHolder
111 mutable ::rtl::Reference
< SdrControlEventListenerImpl
>
115 // =============================================================================
118 void lcl_ensureControlVisibility( SdrView
* _pView
, const SdrUnoObj
* _pObject
, bool _bVisible
)
120 OSL_PRECOND( _pObject
, "lcl_ensureControlVisibility: no object -> no survival!" );
122 SdrPageView
* pPageView
= _pView
? _pView
->GetSdrPageView() : NULL
;
123 DBG_ASSERT( pPageView
, "lcl_ensureControlVisibility: no view found!" );
127 ViewContact
& rUnoControlContact( _pObject
->GetViewContact() );
129 for ( sal_uInt32 i
= 0; i
< pPageView
->PageWindowCount(); ++i
)
131 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( i
);
132 DBG_ASSERT( pPageWindow
, "lcl_ensureControlVisibility: invalid PageViewWindow!" );
136 if ( !pPageWindow
->HasObjectContact() )
139 ObjectContact
& rPageViewContact( pPageWindow
->GetObjectContact() );
140 const ViewObjectContact
& rViewObjectContact( rUnoControlContact
.GetViewObjectContact( rPageViewContact
) );
141 const ViewObjectContactOfUnoControl
* pUnoControlContact
= dynamic_cast< const ViewObjectContactOfUnoControl
* >( &rViewObjectContact
);
142 DBG_ASSERT( pUnoControlContact
, "lcl_ensureControlVisibility: wrong ViewObjectContact type!" );
143 if ( !pUnoControlContact
)
146 pUnoControlContact
->ensureControlVisibility( _bVisible
);
151 //************************************************************
153 //************************************************************
155 TYPEINIT1(SdrUnoObj
, SdrRectObj
);
157 SdrUnoObj::SdrUnoObj(const String
& rModelName
, sal_Bool _bOwnUnoControlModel
)
158 : m_pImpl( new SdrUnoObjDataHolder
),
159 bOwnUnoControlModel( _bOwnUnoControlModel
)
161 bIsUnoObj
= sal_True
;
163 m_pImpl
->pEventListener
= new SdrControlEventListenerImpl(this);
165 // only an owner may create independently
166 if (rModelName
.Len())
167 CreateUnoControlModel(rModelName
);
170 SdrUnoObj::SdrUnoObj(const String
& rModelName
,
171 const uno::Reference
< lang::XMultiServiceFactory
>& rxSFac
,
172 sal_Bool _bOwnUnoControlModel
)
173 : m_pImpl( new SdrUnoObjDataHolder
),
174 bOwnUnoControlModel( _bOwnUnoControlModel
)
176 bIsUnoObj
= sal_True
;
178 m_pImpl
->pEventListener
= new SdrControlEventListenerImpl(this);
180 // only an owner may create independently
181 if (rModelName
.Len())
182 CreateUnoControlModel(rModelName
,rxSFac
);
185 SdrUnoObj::~SdrUnoObj()
189 // clean up the control model
190 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
193 // is the control model owned by its environment?
194 uno::Reference
< container::XChild
> xContent(xUnoControlModel
, uno::UNO_QUERY
);
195 if (xContent
.is() && !xContent
->getParent().is())
198 m_pImpl
->pEventListener
->StopListening(xComp
);
201 catch( const uno::Exception
& )
203 OSL_FAIL( "SdrUnoObj::~SdrUnoObj: caught an exception!" );
208 void SdrUnoObj::SetModel(SdrModel
* pNewModel
)
210 SdrRectObj::SetModel(pNewModel
);
213 void SdrUnoObj::SetPage(SdrPage
* pNewPage
)
215 SdrRectObj::SetPage(pNewPage
);
218 void SdrUnoObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
220 rInfo
.bRotateFreeAllowed
= sal_False
;
221 rInfo
.bRotate90Allowed
= sal_False
;
222 rInfo
.bMirrorFreeAllowed
= sal_False
;
223 rInfo
.bMirror45Allowed
= sal_False
;
224 rInfo
.bMirror90Allowed
= sal_False
;
225 rInfo
.bTransparenceAllowed
= sal_False
;
226 rInfo
.bGradientAllowed
= sal_False
;
227 rInfo
.bShearAllowed
= sal_False
;
228 rInfo
.bEdgeRadiusAllowed
= sal_False
;
229 rInfo
.bNoOrthoDesired
= sal_False
;
230 rInfo
.bCanConvToPath
= sal_False
;
231 rInfo
.bCanConvToPoly
= sal_False
;
232 rInfo
.bCanConvToPathLineToArea
= sal_False
;
233 rInfo
.bCanConvToPolyLineToArea
= sal_False
;
234 rInfo
.bCanConvToContour
= sal_False
;
237 sal_uInt16
SdrUnoObj::GetObjIdentifier() const
239 return sal_uInt16(OBJ_UNO
);
242 void SdrUnoObj::SetContextWritingMode( const sal_Int16 _nContextWritingMode
)
246 uno::Reference
< beans::XPropertySet
> xModelProperties( GetUnoControlModel(), uno::UNO_QUERY_THROW
);
247 xModelProperties
->setPropertyValue(
248 OUString( "ContextWritingMode" ),
249 uno::makeAny( _nContextWritingMode
)
252 catch( const uno::Exception
& )
254 DBG_UNHANDLED_EXCEPTION();
258 void SdrUnoObj::TakeObjNameSingul(XubString
& rName
) const
260 rName
= ImpGetResStr(STR_ObjNameSingulUno
);
262 String
aName( GetName() );
265 rName
+= sal_Unicode(' ');
266 rName
+= sal_Unicode('\'');
268 rName
+= sal_Unicode('\'');
272 void SdrUnoObj::TakeObjNamePlural(XubString
& rName
) const
274 rName
= ImpGetResStr(STR_ObjNamePluralUno
);
277 SdrUnoObj
* SdrUnoObj::Clone() const
279 return CloneHelper
< SdrUnoObj
>();
282 SdrUnoObj
& SdrUnoObj::operator= (const SdrUnoObj
& rObj
)
286 SdrRectObj::operator= (rObj
);
288 // release the reference to the current control model
289 SetUnoControlModel( NULL
);
291 aUnoControlModelTypeName
= rObj
.aUnoControlModelTypeName
;
292 aUnoControlTypeName
= rObj
.aUnoControlTypeName
;
294 // copy the uno control model
295 const uno::Reference
< awt::XControlModel
> xSourceControlModel( rObj
.GetUnoControlModel(), uno::UNO_QUERY
);
296 if ( xSourceControlModel
.is() )
300 uno::Reference
< util::XCloneable
> xClone( xSourceControlModel
, uno::UNO_QUERY_THROW
);
301 xUnoControlModel
.set( xClone
->createClone(), uno::UNO_QUERY_THROW
);
303 catch( const uno::Exception
& )
305 DBG_UNHANDLED_EXCEPTION();
309 // get service name of the control from the control model
310 uno::Reference
< beans::XPropertySet
> xSet(xUnoControlModel
, uno::UNO_QUERY
);
313 uno::Any
aValue( xSet
->getPropertyValue( OUString("DefaultControl")) );
316 if( aValue
>>= aStr
)
317 aUnoControlTypeName
= String(aStr
);
320 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
322 m_pImpl
->pEventListener
->StartListening(xComp
);
326 void SdrUnoObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
328 SdrRectObj::NbcResize(rRef
,xFact
,yFact
);
330 if (aGeo
.nShearWink
!=0 || aGeo
.nDrehWink
!=0)
333 if (aGeo
.nDrehWink
>=9000 && aGeo
.nDrehWink
<27000)
335 aRect
.Move(aRect
.Left()-aRect
.Right(),aRect
.Top()-aRect
.Bottom());
347 // -----------------------------------------------------------------------------
349 bool SdrUnoObj::hasSpecialDrag() const
351 // no special drag; we have no rounding rect and
352 // do want frame handles
356 bool SdrUnoObj::supportsFullDrag() const
358 // overloaded to have the possibility to enable/disable in debug and
359 // to ckeck some things out. Current solution is working, so default is
361 static bool bDoSupportFullDrag(true);
363 return bDoSupportFullDrag
;
366 SdrObject
* SdrUnoObj::getFullDragClone() const
368 SdrObject
* pRetval
= 0;
369 static bool bHandleSpecial(false);
373 // special handling for SdrUnoObj (FormControl). Create a SdrGrafObj
374 // for drag containing the graphical representation. This does not work too
375 // well, so the default is to simply clone
376 pRetval
= new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect());
380 // call parent (simply clone)
381 pRetval
= SdrRectObj::getFullDragClone();
387 // -----------------------------------------------------------------------------
388 void SdrUnoObj::NbcSetLayer( SdrLayerID _nLayer
)
390 if ( GetLayer() == _nLayer
)
391 { // redundant call -> not interested in doing anything here
392 SdrRectObj::NbcSetLayer( _nLayer
);
396 // we need some special handling here in case we're moved from an invisible layer
397 // to a visible one, or vice versa
398 // (relative to a layer. Remember that the visibility of a layer is a view attribute
399 // - the same layer can be visible in one view, and invisible in another view, at the
402 // collect all views in which our old layer is visible
403 ::std::set
< SdrView
* > aPreviouslyVisible
;
406 SdrViewIter
aIter( this );
407 for ( SdrView
* pView
= aIter
.FirstView(); pView
; pView
= aIter
.NextView() )
408 aPreviouslyVisible
.insert( pView
);
411 SdrRectObj::NbcSetLayer( _nLayer
);
413 // collect all views in which our new layer is visible
414 ::std::set
< SdrView
* > aNewlyVisible
;
417 SdrViewIter
aIter( this );
418 for ( SdrView
* pView
= aIter
.FirstView(); pView
; pView
= aIter
.NextView() )
420 ::std::set
< SdrView
* >::const_iterator aPrevPos
= aPreviouslyVisible
.find( pView
);
421 if ( aPreviouslyVisible
.end() != aPrevPos
)
422 { // in pView, we were visible _before_ the layer change, and are
423 // visible _after_ the layer change, too
424 // -> we're not interested in this view at all
425 aPreviouslyVisible
.erase( aPrevPos
);
429 // in pView, we were visible _before_ the layer change, and are
430 // _not_ visible after the layer change
431 // => remember this view, as our visibility there changed
432 aNewlyVisible
.insert( pView
);
437 // now aPreviouslyVisible contains all views where we became invisible
438 ::std::set
< SdrView
* >::const_iterator aLoopViews
;
439 for ( aLoopViews
= aPreviouslyVisible
.begin();
440 aLoopViews
!= aPreviouslyVisible
.end();
444 lcl_ensureControlVisibility( *aLoopViews
, this, false );
447 // and aNewlyVisible all views where we became visible
448 for ( aLoopViews
= aNewlyVisible
.begin();
449 aLoopViews
!= aNewlyVisible
.end();
453 lcl_ensureControlVisibility( *aLoopViews
, this, true );
457 void SdrUnoObj::CreateUnoControlModel(const String
& rModelName
)
459 DBG_ASSERT(!xUnoControlModel
.is(), "model already exists");
461 aUnoControlModelTypeName
= rModelName
;
463 uno::Reference
< awt::XControlModel
> xModel
;
464 uno::Reference
< uno::XComponentContext
> xContext( ::comphelper::getProcessComponentContext() );
465 if (aUnoControlModelTypeName
.Len() )
467 xModel
= uno::Reference
< awt::XControlModel
>(xContext
->getServiceManager()->createInstanceWithContext(
468 aUnoControlModelTypeName
, xContext
), uno::UNO_QUERY
);
474 SetUnoControlModel(xModel
);
477 void SdrUnoObj::CreateUnoControlModel(const String
& rModelName
,
478 const uno::Reference
< lang::XMultiServiceFactory
>& rxSFac
)
480 DBG_ASSERT(!xUnoControlModel
.is(), "model already exists");
482 aUnoControlModelTypeName
= rModelName
;
484 uno::Reference
< awt::XControlModel
> xModel
;
485 if (aUnoControlModelTypeName
.Len() && rxSFac
.is() )
487 xModel
= uno::Reference
< awt::XControlModel
>(rxSFac
->createInstance(
488 aUnoControlModelTypeName
), uno::UNO_QUERY
);
494 SetUnoControlModel(xModel
);
497 void SdrUnoObj::SetUnoControlModel( const uno::Reference
< awt::XControlModel
>& xModel
)
499 if (xUnoControlModel
.is())
501 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
503 m_pImpl
->pEventListener
->StopListening(xComp
);
506 xUnoControlModel
= xModel
;
508 // control model has to contain service name of the control
509 if (xUnoControlModel
.is())
511 uno::Reference
< beans::XPropertySet
> xSet(xUnoControlModel
, uno::UNO_QUERY
);
514 uno::Any
aValue( xSet
->getPropertyValue(String("DefaultControl", osl_getThreadTextEncoding())) );
516 if( aValue
>>= aStr
)
517 aUnoControlTypeName
= String(aStr
);
520 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
522 m_pImpl
->pEventListener
->StartListening(xComp
);
525 // invalidate all ViewObject contacts
526 ViewContactOfUnoControl
* pVC
= NULL
;
527 if ( impl_getViewContact( pVC
) )
529 // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This
530 // is always allowed since they will be re-created on demand (and with the changed model)
531 GetViewContact().flushViewObjectContacts(true);
535 //------------------------------------------------------------------------
536 uno::Reference
< awt::XControl
> SdrUnoObj::GetUnoControl(const SdrView
& _rView
, const OutputDevice
& _rOut
) const
538 uno::Reference
< awt::XControl
> xControl
;
540 SdrPageView
* pPageView
= _rView
.GetSdrPageView();
541 OSL_ENSURE( GetPage() == pPageView
->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" );
542 if ( GetPage() != pPageView
->GetPage() )
545 SdrPageWindow
* pPageWindow
= pPageView
? pPageView
->FindPageWindow( _rOut
) : NULL
;
546 OSL_ENSURE( pPageWindow
, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
550 ViewObjectContact
& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow
->GetObjectContact() ) );
551 ViewObjectContactOfUnoControl
* pUnoContact
= dynamic_cast< ViewObjectContactOfUnoControl
* >( &rViewObjectContact
);
552 OSL_ENSURE( pUnoContact
, "SdrUnoObj::GetUnoControl: wrong contact type!" );
554 xControl
= pUnoContact
->getControl();
559 //------------------------------------------------------------------------
560 uno::Reference
< awt::XControl
> SdrUnoObj::GetTemporaryControlForWindow(
561 const Window
& _rWindow
, uno::Reference
< awt::XControlContainer
>& _inout_ControlContainer
) const
563 uno::Reference
< awt::XControl
> xControl
;
565 ViewContactOfUnoControl
* pVC
= NULL
;
566 if ( impl_getViewContact( pVC
) )
567 xControl
= pVC
->getTemporaryControlForWindow( _rWindow
, _inout_ControlContainer
);
572 //------------------------------------------------------------------------
573 bool SdrUnoObj::impl_getViewContact( ViewContactOfUnoControl
*& _out_rpContact
) const
575 ViewContact
& rViewContact( GetViewContact() );
576 _out_rpContact
= dynamic_cast< ViewContactOfUnoControl
* >( &rViewContact
);
577 DBG_ASSERT( _out_rpContact
, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" );
578 return ( _out_rpContact
!= NULL
);
581 //------------------------------------------------------------------------
582 ::sdr::contact::ViewContact
* SdrUnoObj::CreateObjectSpecificViewContact()
584 return new ::sdr::contact::ViewContactOfUnoControl( *this );
588 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */