1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: svdouno.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
33 #include <svx/sdr/contact/viewcontactofunocontrol.hxx>
34 #include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx>
35 #include <com/sun/star/container/XChild.hpp>
36 #include <com/sun/star/awt/XWindow.hpp>
37 #include <com/sun/star/awt/PosSize.hpp>
38 #include <com/sun/star/beans/XPropertySet.hpp>
39 #include <com/sun/star/io/XPersistObject.hpp>
40 #include <com/sun/star/io/XOutputStream.hpp>
41 #include <com/sun/star/io/XInputStream.hpp>
42 #include <com/sun/star/io/XActiveDataSink.hpp>
43 #include <com/sun/star/io/XActiveDataSource.hpp>
44 #include <com/sun/star/io/XObjectOutputStream.hpp>
45 #include <com/sun/star/io/XObjectInputStream.hpp>
46 #include <com/sun/star/util/XCloneable.hpp>
47 #include <comphelper/processfactory.hxx>
48 #include <comphelper/types.hxx>
49 #include <vcl/pdfextoutdevdata.hxx>
50 #include <svx/svdouno.hxx>
51 #include <svx/svdpagv.hxx>
52 #include <svx/svdmodel.hxx>
53 #include "svdglob.hxx" // Stringcache
54 #include "svdstr.hrc" // Objektname
55 #include <svx/svdetc.hxx>
56 #include <svx/svdview.hxx>
57 #include <svx/svdorect.hxx>
58 #include "svdviter.hxx"
59 #include <rtl/ref.hxx>
62 #include <svx/sdrpagewindow.hxx>
63 #include <sdrpaintwindow.hxx>
64 #include <tools/diagnose_ex.h>
65 #include <svx/svdograf.hxx>
67 using namespace ::com::sun::star
;
68 using namespace ::sdr::contact
;
70 //************************************************************
72 //************************************************************
74 //************************************************************
75 // Hilfsklasse SdrControlEventListenerImpl
76 //************************************************************
77 #include <com/sun/star/lang/XEventListener.hpp>
79 #include <cppuhelper/implbase1.hxx>
81 // =============================================================================
82 class SdrControlEventListenerImpl
: public ::cppu::WeakImplHelper1
< ::com::sun::star::lang::XEventListener
>
88 SdrControlEventListenerImpl(SdrUnoObj
* _pObj
)
93 virtual void SAL_CALL
disposing( const ::com::sun::star::lang::EventObject
& Source
) throw(::com::sun::star::uno::RuntimeException
);
95 void StopListening(const uno::Reference
< lang::XComponent
>& xComp
);
96 void StartListening(const uno::Reference
< lang::XComponent
>& xComp
);
100 void SAL_CALL
SdrControlEventListenerImpl::disposing( const ::com::sun::star::lang::EventObject
& /*Source*/)
101 throw(::com::sun::star::uno::RuntimeException
)
105 pObj
->xUnoControlModel
= NULL
;
109 void SdrControlEventListenerImpl::StopListening(const uno::Reference
< lang::XComponent
>& xComp
)
112 xComp
->removeEventListener(this);
115 void SdrControlEventListenerImpl::StartListening(const uno::Reference
< lang::XComponent
>& xComp
)
118 xComp
->addEventListener(this);
121 // =============================================================================
122 struct SAL_DLLPRIVATE SdrUnoObjDataHolder
124 mutable ::rtl::Reference
< SdrControlEventListenerImpl
>
128 // =============================================================================
131 void lcl_ensureControlVisibility( SdrView
* _pView
, const SdrUnoObj
* _pObject
, bool _bVisible
)
133 OSL_PRECOND( _pObject
, "lcl_ensureControlVisibility: no object -> no survival!" );
135 SdrPageView
* pPageView
= _pView
? _pView
->GetSdrPageView() : NULL
;
136 DBG_ASSERT( pPageView
, "lcl_ensureControlVisibility: no view found!" );
140 ViewContact
& rUnoControlContact( _pObject
->GetViewContact() );
142 for ( sal_uInt32 i
= 0; i
< pPageView
->PageWindowCount(); ++i
)
144 const SdrPageWindow
* pPageWindow
= pPageView
->GetPageWindow( i
);
145 DBG_ASSERT( pPageWindow
, "lcl_ensureControlVisibility: invalid PageViewWindow!" );
149 if ( !pPageWindow
->HasObjectContact() )
152 ObjectContact
& rPageViewContact( pPageWindow
->GetObjectContact() );
153 const ViewObjectContact
& rViewObjectContact( rUnoControlContact
.GetViewObjectContact( rPageViewContact
) );
154 const ViewObjectContactOfUnoControl
* pUnoControlContact
= dynamic_cast< const ViewObjectContactOfUnoControl
* >( &rViewObjectContact
);
155 DBG_ASSERT( pUnoControlContact
, "lcl_ensureControlVisibility: wrong ViewObjectContact type!" );
156 if ( !pUnoControlContact
)
159 pUnoControlContact
->ensureControlVisibility( _bVisible
);
164 //************************************************************
166 //************************************************************
168 TYPEINIT1(SdrUnoObj
, SdrRectObj
);
170 SdrUnoObj::SdrUnoObj(const String
& rModelName
, BOOL _bOwnUnoControlModel
)
171 : m_pImpl( new SdrUnoObjDataHolder
),
172 bOwnUnoControlModel( _bOwnUnoControlModel
)
176 m_pImpl
->pEventListener
= new SdrControlEventListenerImpl(this);
178 // nur ein owner darf eigenstaendig erzeugen
179 if (rModelName
.Len())
180 CreateUnoControlModel(rModelName
);
183 SdrUnoObj::SdrUnoObj(const String
& rModelName
,
184 const uno::Reference
< lang::XMultiServiceFactory
>& rxSFac
,
185 BOOL _bOwnUnoControlModel
)
186 : m_pImpl( new SdrUnoObjDataHolder
),
187 bOwnUnoControlModel( _bOwnUnoControlModel
)
191 m_pImpl
->pEventListener
= new SdrControlEventListenerImpl(this);
193 // nur ein owner darf eigenstaendig erzeugen
194 if (rModelName
.Len())
195 CreateUnoControlModel(rModelName
,rxSFac
);
198 SdrUnoObj::~SdrUnoObj()
202 // clean up the control model
203 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
206 // is the control model owned by it's environment?
207 uno::Reference
< container::XChild
> xContent(xUnoControlModel
, uno::UNO_QUERY
);
208 if (xContent
.is() && !xContent
->getParent().is())
211 m_pImpl
->pEventListener
->StopListening(xComp
);
214 catch( const uno::Exception
& )
216 OSL_ENSURE( sal_False
, "SdrUnoObj::~SdrUnoObj: caught an exception!" );
221 void SdrUnoObj::SetModel(SdrModel
* pNewModel
)
223 SdrRectObj::SetModel(pNewModel
);
226 void SdrUnoObj::SetPage(SdrPage
* pNewPage
)
228 SdrRectObj::SetPage(pNewPage
);
231 void SdrUnoObj::TakeObjInfo(SdrObjTransformInfoRec
& rInfo
) const
233 rInfo
.bRotateFreeAllowed
= FALSE
;
234 rInfo
.bRotate90Allowed
= FALSE
;
235 rInfo
.bMirrorFreeAllowed
= FALSE
;
236 rInfo
.bMirror45Allowed
= FALSE
;
237 rInfo
.bMirror90Allowed
= FALSE
;
238 rInfo
.bTransparenceAllowed
= FALSE
;
239 rInfo
.bGradientAllowed
= FALSE
;
240 rInfo
.bShearAllowed
= FALSE
;
241 rInfo
.bEdgeRadiusAllowed
= FALSE
;
242 rInfo
.bNoOrthoDesired
= FALSE
;
243 rInfo
.bCanConvToPath
= FALSE
;
244 rInfo
.bCanConvToPoly
= FALSE
;
245 rInfo
.bCanConvToPathLineToArea
= FALSE
;
246 rInfo
.bCanConvToPolyLineToArea
= FALSE
;
247 rInfo
.bCanConvToContour
= FALSE
;
250 UINT16
SdrUnoObj::GetObjIdentifier() const
252 return UINT16(OBJ_UNO
);
255 void SdrUnoObj::SetContextWritingMode( const sal_Int16 _nContextWritingMode
)
259 uno::Reference
< beans::XPropertySet
> xModelProperties( GetUnoControlModel(), uno::UNO_QUERY_THROW
);
260 xModelProperties
->setPropertyValue(
261 ::rtl::OUString::intern( RTL_CONSTASCII_USTRINGPARAM( "ContextWritingMode" ) ),
262 uno::makeAny( _nContextWritingMode
)
265 catch( const uno::Exception
& )
267 DBG_UNHANDLED_EXCEPTION();
271 // ----------------------------------------------------------------------------
274 /** helper class to restore graphics at <awt::XView> object after <SdrUnoObj::Paint>
276 OD 08.05.2003 #109432#
277 Restoration of graphics necessary to assure that paint on a window
281 class RestoreXViewGraphics
284 uno::Reference
< awt::XView
> m_rXView
;
285 uno::Reference
< awt::XGraphics
> m_rXGraphics
;
288 RestoreXViewGraphics( const uno::Reference
< awt::XView
>& _rXView
)
291 m_rXGraphics
= m_rXView
->getGraphics();
293 ~RestoreXViewGraphics()
295 m_rXView
->setGraphics( m_rXGraphics
);
300 void SdrUnoObj::TakeObjNameSingul(XubString
& rName
) const
302 rName
= ImpGetResStr(STR_ObjNameSingulUno
);
304 String
aName( GetName() );
307 rName
+= sal_Unicode(' ');
308 rName
+= sal_Unicode('\'');
310 rName
+= sal_Unicode('\'');
314 void SdrUnoObj::TakeObjNamePlural(XubString
& rName
) const
316 rName
= ImpGetResStr(STR_ObjNamePluralUno
);
319 void SdrUnoObj::operator = (const SdrObject
& rObj
)
321 SdrRectObj::operator = (rObj
);
323 // release the reference to the current control model
324 SetUnoControlModel(uno::Reference
< awt::XControlModel
>());
326 aUnoControlModelTypeName
= ((SdrUnoObj
&) rObj
).aUnoControlModelTypeName
;
327 aUnoControlTypeName
= ((SdrUnoObj
&) rObj
).aUnoControlTypeName
;
329 // copy the uno control model
330 uno::Reference
< awt::XControlModel
> xCtrl( ((SdrUnoObj
&) rObj
).GetUnoControlModel(), uno::UNO_QUERY
);
331 uno::Reference
< util::XCloneable
> xClone( xCtrl
, uno::UNO_QUERY
);
335 // copy the model by cloning
336 uno::Reference
< awt::XControlModel
> xNewModel( xClone
->createClone(), uno::UNO_QUERY
);
337 DBG_ASSERT( xNewModel
.is(), "SdrUnoObj::operator =, no control model!");
338 xUnoControlModel
= xNewModel
;
342 // copy the model by streaming
343 uno::Reference
< io::XPersistObject
> xObj( xCtrl
, uno::UNO_QUERY
);
344 uno::Reference
< lang::XMultiServiceFactory
> xFactory( ::comphelper::getProcessServiceFactory() );
346 if ( xObj
.is() && xFactory
.is() )
349 uno::Reference
< io::XOutputStream
> xOutPipe(xFactory
->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.Pipe")), uno::UNO_QUERY
);
350 uno::Reference
< io::XInputStream
> xInPipe(xOutPipe
, uno::UNO_QUERY
);
352 // creating the mark streams
353 uno::Reference
< io::XInputStream
> xMarkIn(xFactory
->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.MarkableInputStream")), uno::UNO_QUERY
);
354 uno::Reference
< io::XActiveDataSink
> xMarkSink(xMarkIn
, uno::UNO_QUERY
);
356 uno::Reference
< io::XOutputStream
> xMarkOut(xFactory
->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.MarkableOutputStream")), uno::UNO_QUERY
);
357 uno::Reference
< io::XActiveDataSource
> xMarkSource(xMarkOut
, uno::UNO_QUERY
);
359 // connect mark and sink
360 uno::Reference
< io::XActiveDataSink
> xSink(xFactory
->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.ObjectInputStream")), uno::UNO_QUERY
);
362 // connect mark and source
363 uno::Reference
< io::XActiveDataSource
> xSource(xFactory
->createInstance( rtl::OUString::createFromAscii("com.sun.star.io.ObjectOutputStream")), uno::UNO_QUERY
);
365 uno::Reference
< io::XObjectOutputStream
> xOutStrm(xSource
, uno::UNO_QUERY
);
366 uno::Reference
< io::XObjectInputStream
> xInStrm(xSink
, uno::UNO_QUERY
);
368 if (xMarkSink
.is() && xMarkSource
.is() && xSink
.is() && xSource
.is())
370 xMarkSink
->setInputStream(xInPipe
);
371 xMarkSource
->setOutputStream(xOutPipe
);
372 xSink
->setInputStream(xMarkIn
);
373 xSource
->setOutputStream(xMarkOut
);
375 // write the object to source
376 xOutStrm
->writeObject(xObj
);
377 xOutStrm
->closeOutput();
379 uno::Reference
< awt::XControlModel
> xModel(xInStrm
->readObject(), uno::UNO_QUERY
);
380 xInStrm
->closeInput();
382 DBG_ASSERT(xModel
.is(), "SdrUnoObj::operator =, keine Model erzeugt");
384 xUnoControlModel
= xModel
;
389 // get service name of the control from the control model
390 uno::Reference
< beans::XPropertySet
> xSet(xUnoControlModel
, uno::UNO_QUERY
);
393 uno::Any
aValue( xSet
->getPropertyValue( rtl::OUString::createFromAscii("DefaultControl")) );
394 ::rtl::OUString aStr
;
396 if( aValue
>>= aStr
)
397 aUnoControlTypeName
= String(aStr
);
400 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
402 m_pImpl
->pEventListener
->StartListening(xComp
);
405 void SdrUnoObj::NbcResize(const Point
& rRef
, const Fraction
& xFact
, const Fraction
& yFact
)
407 SdrRectObj::NbcResize(rRef
,xFact
,yFact
);
409 if (aGeo
.nShearWink
!=0 || aGeo
.nDrehWink
!=0)
411 // kleine Korrekturen
412 if (aGeo
.nDrehWink
>=9000 && aGeo
.nDrehWink
<27000)
414 aRect
.Move(aRect
.Left()-aRect
.Right(),aRect
.Top()-aRect
.Bottom());
426 // -----------------------------------------------------------------------------
428 bool SdrUnoObj::hasSpecialDrag() const
430 // no special drag; we have no rounding rect and
431 // do want frame handles
435 bool SdrUnoObj::supportsFullDrag() const
437 // overloaded to have the possibility to enable/disable in debug and
438 // to ckeck some things out. Current solution is working, so default is
440 static bool bDoSupportFullDrag(true);
442 return bDoSupportFullDrag
;
445 SdrObject
* SdrUnoObj::getFullDragClone() const
447 SdrObject
* pRetval
= 0;
448 static bool bHandleSpecial(false);
452 // special handling for SdrUnoObj (FormControl). Create a SdrGrafObj
453 // for drag containing the graphical representation. This does not work too
454 // well, so the default is to simply clone
455 pRetval
= new SdrGrafObj(SdrDragView::GetObjGraphic(GetModel(), this), GetLogicRect());
459 // call parent (simply clone)
460 pRetval
= SdrRectObj::getFullDragClone();
466 // -----------------------------------------------------------------------------
467 void SdrUnoObj::NbcSetLayer( SdrLayerID _nLayer
)
469 if ( GetLayer() == _nLayer
)
470 { // redundant call -> not interested in doing anything here
471 SdrRectObj::NbcSetLayer( _nLayer
);
475 // we need some special handling here in case we're moved from an invisible layer
476 // to a visible one, or vice versa
477 // (relative to a layer. Remember that the visibility of a layer is a view attribute
478 // - the same layer can be visible in one view, and invisible in another view, at the
480 // 2003-06-03 - #110592# - fs@openoffice.org
482 // collect all views in which our old layer is visible
483 ::std::set
< SdrView
* > aPreviouslyVisible
;
486 SdrViewIter
aIter( this );
487 for ( SdrView
* pView
= aIter
.FirstView(); pView
; pView
= aIter
.NextView() )
488 aPreviouslyVisible
.insert( pView
);
491 SdrRectObj::NbcSetLayer( _nLayer
);
493 // collect all views in which our new layer is visible
494 ::std::set
< SdrView
* > aNewlyVisible
;
497 SdrViewIter
aIter( this );
498 for ( SdrView
* pView
= aIter
.FirstView(); pView
; pView
= aIter
.NextView() )
500 ::std::set
< SdrView
* >::const_iterator aPrevPos
= aPreviouslyVisible
.find( pView
);
501 if ( aPreviouslyVisible
.end() != aPrevPos
)
502 { // in pView, we were visible _before_ the layer change, and are
503 // visible _after_ the layer change, too
504 // -> we're not interested in this view at all
505 aPreviouslyVisible
.erase( aPrevPos
);
509 // in pView, we were visible _before_ the layer change, and are
510 // _not_ visible after the layer change
511 // => remember this view, as our visibility there changed
512 aNewlyVisible
.insert( pView
);
517 // now aPreviouslyVisible contains all views where we became invisible
518 ::std::set
< SdrView
* >::const_iterator aLoopViews
;
519 for ( aLoopViews
= aPreviouslyVisible
.begin();
520 aLoopViews
!= aPreviouslyVisible
.end();
524 lcl_ensureControlVisibility( *aLoopViews
, this, false );
527 // and aNewlyVisible all views where we became visible
528 for ( aLoopViews
= aNewlyVisible
.begin();
529 aLoopViews
!= aNewlyVisible
.end();
533 lcl_ensureControlVisibility( *aLoopViews
, this, true );
537 void SdrUnoObj::CreateUnoControlModel(const String
& rModelName
)
539 DBG_ASSERT(!xUnoControlModel
.is(), "model already exists");
541 aUnoControlModelTypeName
= rModelName
;
543 uno::Reference
< awt::XControlModel
> xModel
;
544 uno::Reference
< lang::XMultiServiceFactory
> xFactory( ::comphelper::getProcessServiceFactory() );
545 if (aUnoControlModelTypeName
.Len() && xFactory
.is() )
547 xModel
= uno::Reference
< awt::XControlModel
>(xFactory
->createInstance(
548 aUnoControlModelTypeName
), uno::UNO_QUERY
);
554 SetUnoControlModel(xModel
);
557 void SdrUnoObj::CreateUnoControlModel(const String
& rModelName
,
558 const uno::Reference
< lang::XMultiServiceFactory
>& rxSFac
)
560 DBG_ASSERT(!xUnoControlModel
.is(), "model already exists");
562 aUnoControlModelTypeName
= rModelName
;
564 uno::Reference
< awt::XControlModel
> xModel
;
565 if (aUnoControlModelTypeName
.Len() && rxSFac
.is() )
567 xModel
= uno::Reference
< awt::XControlModel
>(rxSFac
->createInstance(
568 aUnoControlModelTypeName
), uno::UNO_QUERY
);
574 SetUnoControlModel(xModel
);
577 void SdrUnoObj::SetUnoControlModel( const uno::Reference
< awt::XControlModel
>& xModel
)
579 if (xUnoControlModel
.is())
581 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
583 m_pImpl
->pEventListener
->StopListening(xComp
);
586 xUnoControlModel
= xModel
;
588 // control model muss servicename des controls enthalten
589 if (xUnoControlModel
.is())
591 uno::Reference
< beans::XPropertySet
> xSet(xUnoControlModel
, uno::UNO_QUERY
);
594 uno::Any
aValue( xSet
->getPropertyValue(String("DefaultControl", gsl_getSystemTextEncoding())) );
595 ::rtl::OUString aStr
;
596 if( aValue
>>= aStr
)
597 aUnoControlTypeName
= String(aStr
);
600 uno::Reference
< lang::XComponent
> xComp(xUnoControlModel
, uno::UNO_QUERY
);
602 m_pImpl
->pEventListener
->StartListening(xComp
);
605 // invalidate all ViewObject contacts
606 ViewContactOfUnoControl
* pVC
= NULL
;
607 if ( impl_getViewContact( pVC
) )
609 // flushViewObjectContacts() removes all existing VOCs for the local DrawHierarchy. This
610 // is always allowed since they will be re-created on demand (and with the changed model)
611 GetViewContact().flushViewObjectContacts(true);
615 //------------------------------------------------------------------------
616 uno::Reference
< awt::XControl
> SdrUnoObj::GetUnoControl(const SdrView
& _rView
, const OutputDevice
& _rOut
) const
618 uno::Reference
< awt::XControl
> xControl
;
620 SdrPageView
* pPageView
= _rView
.GetSdrPageView();
621 OSL_ENSURE( GetPage() == pPageView
->GetPage(), "SdrUnoObj::GetUnoControl: This object is not displayed in that particular view!" );
622 if ( GetPage() != pPageView
->GetPage() )
625 SdrPageWindow
* pPageWindow
= pPageView
? pPageView
->FindPageWindow( _rOut
) : NULL
;
626 OSL_ENSURE( pPageWindow
, "SdrUnoObj::GetUnoControl: did not find my SdrPageWindow!" );
630 ViewObjectContact
& rViewObjectContact( GetViewContact().GetViewObjectContact( pPageWindow
->GetObjectContact() ) );
631 ViewObjectContactOfUnoControl
* pUnoContact
= dynamic_cast< ViewObjectContactOfUnoControl
* >( &rViewObjectContact
);
632 OSL_ENSURE( pUnoContact
, "SdrUnoObj::GetUnoControl: wrong contact type!" );
634 xControl
= pUnoContact
->getControl();
639 //------------------------------------------------------------------------
640 uno::Reference
< awt::XControl
> SdrUnoObj::GetTemporaryControlForWindow(
641 const Window
& _rWindow
, uno::Reference
< awt::XControlContainer
>& _inout_ControlContainer
) const
643 uno::Reference
< awt::XControl
> xControl
;
645 ViewContactOfUnoControl
* pVC
= NULL
;
646 if ( impl_getViewContact( pVC
) )
647 xControl
= pVC
->getTemporaryControlForWindow( _rWindow
, _inout_ControlContainer
);
652 //------------------------------------------------------------------------
653 bool SdrUnoObj::impl_getViewContact( ViewContactOfUnoControl
*& _out_rpContact
) const
655 ViewContact
& rViewContact( GetViewContact() );
656 _out_rpContact
= dynamic_cast< ViewContactOfUnoControl
* >( &rViewContact
);
657 DBG_ASSERT( _out_rpContact
, "SdrUnoObj::impl_getViewContact: could not find my ViewContact!" );
658 return ( _out_rpContact
!= NULL
);
661 //------------------------------------------------------------------------
662 ::sdr::contact::ViewContact
* SdrUnoObj::CreateObjectSpecificViewContact()
664 return new ::sdr::contact::ViewContactOfUnoControl( *this );
667 // -----------------------------------------------------------------------------