bump product version to 4.1.6.2
[LibreOffice.git] / svx / source / svdraw / svdouno.cxx
blob06697135ebab04ea8669589804a622c4e5982c62
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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>
47 #include <set>
48 #include <memory>
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 //************************************************************
58 // Defines
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 >
71 protected:
72 SdrUnoObj* pObj;
74 public:
75 SdrControlEventListenerImpl(SdrUnoObj* _pObj)
76 : pObj(_pObj)
79 // XEventListener
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);
86 // XEventListener
87 void SAL_CALL SdrControlEventListenerImpl::disposing( const ::com::sun::star::lang::EventObject& /*Source*/)
88 throw(::com::sun::star::uno::RuntimeException)
90 if (pObj)
92 pObj->xUnoControlModel = NULL;
96 void SdrControlEventListenerImpl::StopListening(const uno::Reference< lang::XComponent >& xComp)
98 if (xComp.is())
99 xComp->removeEventListener(this);
102 void SdrControlEventListenerImpl::StartListening(const uno::Reference< lang::XComponent >& xComp)
104 if (xComp.is())
105 xComp->addEventListener(this);
108 // =============================================================================
109 struct SAL_DLLPRIVATE SdrUnoObjDataHolder
111 mutable ::rtl::Reference< SdrControlEventListenerImpl >
112 pEventListener;
115 // =============================================================================
116 namespace
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!" );
124 if ( !pPageView )
125 return;
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!" );
133 if ( !pPageWindow )
134 continue;
136 if ( !pPageWindow->HasObjectContact() )
137 continue;
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 )
144 continue;
146 pUnoControlContact->ensureControlVisibility( _bVisible );
151 //************************************************************
152 // SdrUnoObj
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);
191 if (xComp.is())
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())
196 xComp->dispose();
197 else
198 m_pImpl->pEventListener->StopListening(xComp);
201 catch( const uno::Exception& )
203 OSL_FAIL( "SdrUnoObj::~SdrUnoObj: caught an exception!" );
205 delete m_pImpl;
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() );
263 if(aName.Len())
265 rName += sal_Unicode(' ');
266 rName += sal_Unicode('\'');
267 rName += aName;
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)
284 if( this == &rObj )
285 return *this;
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);
311 if (xSet.is())
313 uno::Any aValue( xSet->getPropertyValue( OUString("DefaultControl")) );
314 OUString aStr;
316 if( aValue >>= aStr )
317 aUnoControlTypeName = String(aStr);
320 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
321 if (xComp.is())
322 m_pImpl->pEventListener->StartListening(xComp);
323 return *this;
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)
332 // small correctures
333 if (aGeo.nDrehWink>=9000 && aGeo.nDrehWink<27000)
335 aRect.Move(aRect.Left()-aRect.Right(),aRect.Top()-aRect.Bottom());
338 aGeo.nDrehWink = 0;
339 aGeo.nShearWink = 0;
340 aGeo.nSin = 0.0;
341 aGeo.nCos = 1.0;
342 aGeo.nTan = 0.0;
343 SetRectsDirty();
347 // -----------------------------------------------------------------------------
349 bool SdrUnoObj::hasSpecialDrag() const
351 // no special drag; we have no rounding rect and
352 // do want frame handles
353 return false;
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
360 // enabled
361 static bool bDoSupportFullDrag(true);
363 return bDoSupportFullDrag;
366 SdrObject* SdrUnoObj::getFullDragClone() const
368 SdrObject* pRetval = 0;
369 static bool bHandleSpecial(false);
371 if(bHandleSpecial)
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());
378 else
380 // call parent (simply clone)
381 pRetval = SdrRectObj::getFullDragClone();
384 return pRetval;
387 // -----------------------------------------------------------------------------
388 void SdrUnoObj::NbcSetLayer( SdrLayerID _nLayer )
390 if ( GetLayer() == _nLayer )
391 { // redundant call -> not interested in doing anything here
392 SdrRectObj::NbcSetLayer( _nLayer );
393 return;
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
400 // same time)
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 );
427 else
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();
441 ++aLoopViews
444 lcl_ensureControlVisibility( *aLoopViews, this, false );
447 // and aNewlyVisible all views where we became visible
448 for ( aLoopViews = aNewlyVisible.begin();
449 aLoopViews != aNewlyVisible.end();
450 ++aLoopViews
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);
470 if (xModel.is())
471 SetChanged();
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);
490 if (xModel.is())
491 SetChanged();
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);
502 if (xComp.is())
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);
512 if (xSet.is())
514 uno::Any aValue( xSet->getPropertyValue(String("DefaultControl", osl_getThreadTextEncoding())) );
515 OUString aStr;
516 if( aValue >>= aStr )
517 aUnoControlTypeName = String(aStr);
520 uno::Reference< lang::XComponent > xComp(xUnoControlModel, uno::UNO_QUERY);
521 if (xComp.is())
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() )
543 return NULL;
545 SdrPageWindow* pPageWindow = pPageView ? pPageView->FindPageWindow( _rOut ) : NULL;
546 OSL_ENSURE( pPageWindow, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
547 if ( !pPageWindow )
548 return NULL;
550 ViewObjectContact& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow->GetObjectContact() ) );
551 ViewObjectContactOfUnoControl* pUnoContact = dynamic_cast< ViewObjectContactOfUnoControl* >( &rViewObjectContact );
552 OSL_ENSURE( pUnoContact, "SdrUnoObj::GetUnoControl: wrong contact type!" );
553 if ( pUnoContact )
554 xControl = pUnoContact->getControl();
556 return xControl;
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 );
569 return xControl;
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: */