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: richtextcontrol.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_forms.hxx"
33 #include "richtextcontrol.hxx"
34 #include "frm_module.hxx"
35 #ifndef _FRM_PROPERTY_HRC_
36 #include "property.hrc"
38 #include "services.hxx"
40 #include "richtextmodel.hxx"
41 #include "richtextvclcontrol.hxx"
42 #include "clipboarddispatcher.hxx"
43 #include "parametrizedattributedispatcher.hxx"
44 #include "specialdispatchers.hxx"
46 /** === begin UNO includes === **/
47 #include <com/sun/star/awt/PosSize.hpp>
48 /** === end UNO includes === **/
49 #include <tools/diagnose_ex.h>
50 #include <vcl/svapp.hxx>
52 #include <svx/svxids.hrc>
53 #include <svx/editview.hxx>
54 #include <svtools/itemset.hxx>
55 #include <svtools/itempool.hxx>
56 #include <sfx2/msgpool.hxx>
58 //--------------------------------------------------------------------------
59 extern "C" void SAL_CALL
createRegistryInfo_ORichTextControl()
61 static ::frm::OMultiInstanceAutoRegistration
< ::frm::ORichTextControl
> aAutoRegistration
;
64 //.........................................................................
67 //.........................................................................
69 using namespace ::com::sun::star::uno
;
70 using namespace ::com::sun::star::beans
;
71 using namespace ::com::sun::star::awt
;
72 using namespace ::com::sun::star::lang
;
73 using namespace ::com::sun::star::frame
;
75 #define FORWARD_TO_PEER_1( unoInterface, method, param1 ) \
76 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
77 if ( xTypedPeer.is() ) \
79 xTypedPeer->method( param1 ); \
82 #define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 ) \
84 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
85 if ( xTypedPeer.is() ) \
87 aReturn = xTypedPeer->method( param1 ); \
91 #define FORWARD_TO_PEER_3( unoInterface, method, param1, param2, param3 ) \
92 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
93 if ( xTypedPeer.is() ) \
95 xTypedPeer->method( param1, param2, param3 ); \
98 #define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 ) \
100 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
101 if ( xTypedPeer.is() ) \
103 aReturn = xTypedPeer->method( param1, param2, param3 ); \
107 //==================================================================
109 //==================================================================
110 DBG_NAME( ORichTextControl
)
111 //------------------------------------------------------------------
112 ORichTextControl::ORichTextControl( const Reference
< XMultiServiceFactory
>& _rxORB
)
115 DBG_CTOR( ORichTextControl
, NULL
);
118 //------------------------------------------------------------------
119 ORichTextControl::~ORichTextControl()
121 DBG_DTOR( ORichTextControl
, NULL
);
124 //------------------------------------------------------------------
125 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextControl
, UnoEditControl
, ORichTextControl_Base
)
127 //------------------------------------------------------------------
128 Any SAL_CALL
ORichTextControl::queryAggregation( const Type
& _rType
) throw ( RuntimeException
)
130 Any aReturn
= UnoEditControl::queryAggregation( _rType
);
132 if ( !aReturn
.hasValue() )
133 aReturn
= ORichTextControl_Base::queryInterface( _rType
);
138 //------------------------------------------------------------------
141 //..............................................................
142 static void implAdjustTriStateFlag( const Reference
< XPropertySet
>& _rxProps
, const ::rtl::OUString
& _rPropertyName
,
143 WinBits
& _rAllBits
, WinBits _nPositiveFlag
, WinBits nNegativeFlag
)
145 sal_Bool bFlagValue
= sal_False
;
146 if ( _rxProps
->getPropertyValue( _rPropertyName
) >>= bFlagValue
)
147 _rAllBits
|= ( bFlagValue
? _nPositiveFlag
: nNegativeFlag
);
150 //..............................................................
151 static void implAdjustTwoStateFlag( const Any
& _rValue
, WinBits
& _rAllBits
, WinBits _nFlag
, bool _bInvert
= false )
153 sal_Bool bFlagValue
= sal_False
;
154 if ( _rValue
>>= bFlagValue
)
157 bFlagValue
= !bFlagValue
;
161 _rAllBits
&= ~_nFlag
;
165 //..............................................................
166 static void implAdjustTwoStateFlag( const Reference
< XPropertySet
>& _rxProps
, const ::rtl::OUString
& _rPropertyName
,
167 WinBits
& _rAllBits
, WinBits _nFlag
, bool _bInvert
= false )
169 implAdjustTwoStateFlag( _rxProps
->getPropertyValue( _rPropertyName
), _rAllBits
, _nFlag
, _bInvert
);
172 //..............................................................
173 static void adjustTwoStateWinBit( Window
* _pWindow
, const Any
& _rValue
, WinBits _nFlag
, bool _bInvert
= false )
175 WinBits nBits
= _pWindow
->GetStyle();
176 implAdjustTwoStateFlag( _rValue
, nBits
, _nFlag
, _bInvert
);
177 _pWindow
->SetStyle( nBits
);
180 //..............................................................
181 static WinBits
getWinBits( const Reference
< XControlModel
>& _rxModel
, WinBits nBaseBits
= 0 )
183 WinBits nBits
= nBaseBits
;
186 Reference
< XPropertySet
> xProps( _rxModel
, UNO_QUERY
);
189 sal_Int16 nBorder
= 0;
190 xProps
->getPropertyValue( PROPERTY_BORDER
) >>= nBorder
;
194 implAdjustTriStateFlag( xProps
, PROPERTY_TABSTOP
, nBits
, WB_TABSTOP
, WB_NOTABSTOP
);
195 implAdjustTwoStateFlag( xProps
, PROPERTY_HSCROLL
, nBits
, WB_HSCROLL
);
196 implAdjustTwoStateFlag( xProps
, PROPERTY_VSCROLL
, nBits
, WB_VSCROLL
);
197 implAdjustTwoStateFlag( xProps
, PROPERTY_HARDLINEBREAKS
, nBits
, WB_WORDBREAK
, true );
200 catch( const Exception
& )
202 DBG_UNHANDLED_EXCEPTION();
208 //------------------------------------------------------------------
209 void SAL_CALL
ORichTextControl::createPeer( const Reference
< XToolkit
>& _rToolkit
, const Reference
< XWindowPeer
>& _rParentPeer
) throw( RuntimeException
)
211 sal_Bool bReallyActAsRichText
= sal_False
;
214 Reference
< XPropertySet
> xModelProps( getModel(), UNO_QUERY_THROW
);
215 xModelProps
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bReallyActAsRichText
;
217 catch( const Exception
& )
219 DBG_UNHANDLED_EXCEPTION();
222 if ( !bReallyActAsRichText
)
224 UnoEditControl::createPeer( _rToolkit
, _rParentPeer
);
225 OControl::initFormControlPeer( getPeer() );
229 ::vos::OGuard
aGuard( Application::GetSolarMutex() );
233 mbCreatingPeer
= sal_True
;
235 // determine the VLC window for the parent
236 Window
* pParentWin
= NULL
;
237 if ( _rParentPeer
.is() )
239 VCLXWindow
* pParentXWin
= VCLXWindow::GetImplementation( _rParentPeer
);
241 pParentWin
= pParentXWin
->GetWindow();
242 DBG_ASSERT( pParentWin
, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" );
246 Reference
< XControlModel
> xModel( getModel() );
247 ORichTextPeer
* pPeer
= ORichTextPeer::Create( xModel
, pParentWin
, getWinBits( xModel
) );
248 DBG_ASSERT( pPeer
, "ORichTextControl::createPeer: invalid peer returned!" );
251 // by definition, the returned component is aquired once
254 // announce the peer to the base class
257 // initialize ourself (and thus the peer) with the model properties
260 Reference
< XView
> xPeerView( getPeer(), UNO_QUERY
);
261 if ( xPeerView
.is() )
263 xPeerView
->setZoom( maComponentInfos
.nZoomX
, maComponentInfos
.nZoomY
);
264 xPeerView
->setGraphics( mxGraphics
);
267 // a lot of initial settings from our component infos
268 setPosSize( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
, PosSize::POSSIZE
);
270 pPeer
->setVisible ( maComponentInfos
.bVisible
&& !mbDesignMode
);
271 pPeer
->setEnable ( maComponentInfos
.bEnable
);
272 pPeer
->setDesignMode( mbDesignMode
);
277 mbCreatingPeer
= sal_False
;
279 OControl::initFormControlPeer( getPeer() );
283 //------------------------------------------------------------------
284 ::rtl::OUString SAL_CALL
ORichTextControl::getImplementationName() throw( RuntimeException
)
286 return getImplementationName_Static();
289 //------------------------------------------------------------------
290 Sequence
< ::rtl::OUString
> SAL_CALL
ORichTextControl::getSupportedServiceNames() throw( RuntimeException
)
292 return getSupportedServiceNames_Static();
295 //------------------------------------------------------------------
296 ::rtl::OUString SAL_CALL
ORichTextControl::getImplementationName_Static()
298 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.form.ORichTextControl" ) );
301 //------------------------------------------------------------------
302 Sequence
< ::rtl::OUString
> SAL_CALL
ORichTextControl::getSupportedServiceNames_Static()
304 Sequence
< ::rtl::OUString
> aServices( 3 );
305 aServices
[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControl" ) );
306 aServices
[ 1 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.awt.UnoControlEdit" ) );
307 aServices
[ 2 ] = FRM_SUN_CONTROL_RICHTEXTCONTROL
;
311 //------------------------------------------------------------------
312 Reference
< XInterface
> SAL_CALL
ORichTextControl::Create( const Reference
< XMultiServiceFactory
>& _rxFactory
)
314 return *( new ORichTextControl( _rxFactory
) );
317 //--------------------------------------------------------------------
318 Reference
< XDispatch
> SAL_CALL
ORichTextControl::queryDispatch( const ::com::sun::star::util::URL
& _rURL
, const ::rtl::OUString
& _rTargetFrameName
, sal_Int32 _nSearchFlags
) throw (RuntimeException
)
320 FORWARD_TO_PEER_3_RET( Reference
< XDispatch
>, XDispatchProvider
, queryDispatch
, _rURL
, _rTargetFrameName
, _nSearchFlags
);
323 //--------------------------------------------------------------------
324 Sequence
< Reference
< XDispatch
> > SAL_CALL
ORichTextControl::queryDispatches( const Sequence
< DispatchDescriptor
>& _rRequests
) throw (RuntimeException
)
326 FORWARD_TO_PEER_1_RET( Sequence
< Reference
< XDispatch
> >, XDispatchProvider
, queryDispatches
, _rRequests
);
329 //--------------------------------------------------------------------
330 sal_Bool
ORichTextControl::requiresNewPeer( const ::rtl::OUString
& _rPropertyName
) const
332 return UnoControl::requiresNewPeer( _rPropertyName
) || _rPropertyName
.equals( PROPERTY_RICH_TEXT
);
335 //==================================================================
337 //==================================================================
338 DBG_NAME( ORichTextPeer
)
339 //------------------------------------------------------------------
340 ORichTextPeer
* ORichTextPeer::Create( const Reference
< XControlModel
>& _rxModel
, Window
* _pParentWindow
, WinBits _nStyle
)
342 DBG_TESTSOLARMUTEX();
344 // the EditEngine of the model
345 RichTextEngine
* pEngine
= ORichTextModel::getEditEngine( _rxModel
);
346 OSL_ENSURE( pEngine
, "ORichTextPeer::Create: could not obtaine the edit engine from the model!" );
351 ORichTextPeer
* pPeer
= new ORichTextPeer
;
352 pPeer
->acquire(); // by definition, the returned object is aquired once
354 // the VCL control for the peer
355 RichTextControl
* pRichTextControl
= new RichTextControl( pEngine
, _pParentWindow
, _nStyle
, NULL
, pPeer
);
358 pRichTextControl
->SetComponentInterface( pPeer
);
364 //------------------------------------------------------------------
365 ORichTextPeer::ORichTextPeer()
367 DBG_CTOR( ORichTextPeer
, NULL
);
370 //------------------------------------------------------------------
371 ORichTextPeer::~ORichTextPeer()
373 DBG_DTOR( ORichTextPeer
, NULL
);
376 //------------------------------------------------------------------
377 void ORichTextPeer::dispose( ) throw(RuntimeException
)
380 ::vos::OGuard
aGuard( GetMutex() );
381 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
383 if ( pRichTextControl
)
385 for ( AttributeDispatchers::iterator aDisposeLoop
= m_aDispatchers
.begin();
386 aDisposeLoop
!= m_aDispatchers
.end();
390 pRichTextControl
->disableAttributeNotification( aDisposeLoop
->first
);
391 aDisposeLoop
->second
->dispose();
395 AttributeDispatchers aEmpty
;
396 m_aDispatchers
.swap( aEmpty
);
399 VCLXWindow::dispose();
402 //--------------------------------------------------------------------
403 void SAL_CALL
ORichTextPeer::setProperty( const ::rtl::OUString
& _rPropertyName
, const Any
& _rValue
) throw (RuntimeException
)
407 VCLXWindow::setProperty( _rPropertyName
, _rValue
);
411 if ( _rPropertyName
.equals( PROPERTY_BACKGROUNDCOLOR
) )
413 RichTextControl
* pControl
= static_cast< RichTextControl
* >( GetWindow() );
414 if ( !_rValue
.hasValue() )
416 pControl
->SetBackgroundColor( );
420 sal_Int32 nColor
= COL_TRANSPARENT
;
422 pControl
->SetBackgroundColor( Color( nColor
) );
425 else if ( _rPropertyName
.equals( PROPERTY_HSCROLL
) )
427 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_HSCROLL
);
429 else if ( _rPropertyName
.equals( PROPERTY_VSCROLL
) )
431 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_VSCROLL
);
433 else if ( _rPropertyName
.equals( PROPERTY_HARDLINEBREAKS
) )
435 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_WORDBREAK
, true );
437 else if ( _rPropertyName
.equals( PROPERTY_READONLY
) )
439 RichTextControl
* pControl
= static_cast< RichTextControl
* >( GetWindow() );
440 sal_Bool
bReadOnly( pControl
->IsReadOnly() );
441 OSL_VERIFY( _rValue
>>= bReadOnly
);
442 pControl
->SetReadOnly( bReadOnly
);
444 // update the dispatchers
445 for ( AttributeDispatchers::iterator aDispatcherLoop
= m_aDispatchers
.begin();
446 aDispatcherLoop
!= m_aDispatchers
.end();
450 aDispatcherLoop
->second
->invalidate();
453 else if ( _rPropertyName
.equals( PROPERTY_HIDEINACTIVESELECTION
) )
455 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
456 sal_Bool bHide
= pRichTextControl
->GetHideInactiveSelection();
457 OSL_VERIFY( _rValue
>>= bHide
);
458 pRichTextControl
->SetHideInactiveSelection( bHide
);
461 VCLXWindow::setProperty( _rPropertyName
, _rValue
);
464 //------------------------------------------------------------------
465 IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer
, VCLXWindow
, ORichTextPeer_Base
)
467 //------------------------------------------------------------------
468 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer
, VCLXWindow
, ORichTextPeer_Base
)
470 //--------------------------------------------------------------------
473 static SfxSlotId
lcl_translateConflictingSlot( SfxSlotId _nIDFromPool
)
476 // unfortunately, some of our applications have some conflicting slots,
477 // i.e. slots which have the same UNO name as an existing other (common)
479 // For instance, both the slots SID_SET_SUPER_SCRIPT (from SVX) and FN_SET_SUPER_SCRIPT
480 // (from SW) have the UNO name "SuperScript".
481 // Now, if the controls lives in a text document, and asks the SfxSlotPool for
482 // the id belonging to "SuperScript", it gets the FN_SET_SUPER_SCRIPT - which
483 // is completely unknown to the EditEngine.
484 // So, we need to translate such conflicting ids.
486 // Note that the real solution would be to fix the applications to
487 // *not* define conflicting slots. Alternatively, if SFX would provide a slot pool
488 // which is *static* (i.e. independent on the active application), then we
489 // would also never encounter such a conflict.
490 SfxSlotId
nReturn( _nIDFromPool
);
491 switch ( _nIDFromPool
)
493 case 20411: /* FM_SET_SUPER_SCRIPT, originating in SW */
494 nReturn
= SID_SET_SUPER_SCRIPT
;
496 case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */
497 nReturn
= SID_SET_SUB_SCRIPT
;
504 //--------------------------------------------------------------------
505 ORichTextPeer::SingleAttributeDispatcher
ORichTextPeer::implCreateDispatcher( SfxSlotId _nSlotId
, const ::com::sun::star::util::URL
& _rURL
)
507 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
508 OSL_PRECOND( pRichTextControl
, "ORichTextPeer::implCreateDispatcher: invalid window!" );
509 if ( !pRichTextControl
)
510 return SingleAttributeDispatcher( NULL
);
512 ORichTextFeatureDispatcher
* pDispatcher
= NULL
;
513 OAttributeDispatcher
* pAttributeDispatcher
= NULL
;
517 pDispatcher
= new OClipboardDispatcher( pRichTextControl
->getView(), OClipboardDispatcher::eCut
);
521 pDispatcher
= new OClipboardDispatcher( pRichTextControl
->getView(), OClipboardDispatcher::eCopy
);
525 pDispatcher
= new OPasteClipboardDispatcher( pRichTextControl
->getView() );
529 pDispatcher
= new OSelectAllDispatcher( pRichTextControl
->getView(), _rURL
);
532 case SID_ATTR_PARA_LEFT_TO_RIGHT
:
533 case SID_ATTR_PARA_RIGHT_TO_LEFT
:
534 pAttributeDispatcher
= new OParagraphDirectionDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
537 case SID_TEXTDIRECTION_TOP_TO_BOTTOM
:
538 case SID_TEXTDIRECTION_LEFT_TO_RIGHT
:
539 pDispatcher
= new OTextDirectionDispatcher( pRichTextControl
->getView(), _rURL
);
542 case SID_ATTR_PARA_HANGPUNCTUATION
:
543 case SID_ATTR_PARA_FORBIDDEN_RULES
:
544 case SID_ATTR_PARA_SCRIPTSPACE
:
545 pAttributeDispatcher
= new OAsianFontLayoutDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
550 // is it a supported slot?
551 bool bSupportedSlot
= false;
552 if ( !bSupportedSlot
)
554 const SfxItemPool
& rPool
= *pRichTextControl
->getView().GetEmptyItemSet().GetPool();
555 bSupportedSlot
= rPool
.IsInRange( rPool
.GetWhich( _nSlotId
) );
557 if ( !bSupportedSlot
)
558 bSupportedSlot
= RichTextControl::isMappableSlot( _nSlotId
);
560 if ( bSupportedSlot
)
561 { // it's really a slot which is supported by the EditEngine
563 bool bNeedParametrizedDispatcher
= true;
564 if ( ( _nSlotId
== SID_ATTR_CHAR_POSTURE
)
565 || ( _nSlotId
== SID_ATTR_CHAR_CJK_POSTURE
)
566 || ( _nSlotId
== SID_ATTR_CHAR_CTL_POSTURE
)
567 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_POSTURE
)
568 || ( _nSlotId
== SID_ATTR_CHAR_WEIGHT
)
569 || ( _nSlotId
== SID_ATTR_CHAR_CJK_WEIGHT
)
570 || ( _nSlotId
== SID_ATTR_CHAR_CTL_WEIGHT
)
571 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_WEIGHT
)
572 || ( _nSlotId
== SID_ATTR_CHAR_LANGUAGE
)
573 || ( _nSlotId
== SID_ATTR_CHAR_CJK_LANGUAGE
)
574 || ( _nSlotId
== SID_ATTR_CHAR_CTL_LANGUAGE
)
575 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_LANGUAGE
)
576 || ( _nSlotId
== SID_ATTR_CHAR_CONTOUR
)
577 || ( _nSlotId
== SID_ATTR_CHAR_SHADOWED
)
578 || ( _nSlotId
== SID_ATTR_CHAR_WORDLINEMODE
)
579 || ( _nSlotId
== SID_ATTR_CHAR_COLOR
)
580 || ( _nSlotId
== SID_ATTR_CHAR_RELIEF
)
581 || ( _nSlotId
== SID_ATTR_CHAR_KERNING
)
582 || ( _nSlotId
== SID_ATTR_CHAR_AUTOKERN
)
583 || ( _nSlotId
== SID_ATTR_CHAR_SCALEWIDTH
)
586 bNeedParametrizedDispatcher
= true;
588 else if ( ( _nSlotId
== SID_ATTR_PARA_HANGPUNCTUATION
)
589 || ( _nSlotId
== SID_ATTR_PARA_FORBIDDEN_RULES
)
590 || ( _nSlotId
== SID_ATTR_PARA_SCRIPTSPACE
)
593 bNeedParametrizedDispatcher
= false;
597 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( NULL
);
598 const SfxSlot
* pSlot
= rSlotPool
.GetSlot( _nSlotId
);
599 const SfxType
* pType
= pSlot
? pSlot
->GetType() : NULL
;
602 bNeedParametrizedDispatcher
= ( pType
->nAttribs
> 0 );
606 if ( bNeedParametrizedDispatcher
)
608 #if OSL_DEBUG_LEVEL > 0
609 ::rtl::OString
sTrace( "ORichTextPeer::implCreateDispatcher: creating *parametrized* dispatcher for " );
610 sTrace
+= ::rtl::OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
611 DBG_TRACE( sTrace
.getStr() );
613 pAttributeDispatcher
= new OParametrizedAttributeDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
617 #if OSL_DEBUG_LEVEL > 0
618 ::rtl::OString
sTrace( "ORichTextPeer::implCreateDispatcher: creating *normal* dispatcher for " );
619 sTrace
+= ::rtl::OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
620 DBG_TRACE( sTrace
.getStr() );
622 pAttributeDispatcher
= new OAttributeDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
625 #if OSL_DEBUG_LEVEL > 0
628 ::rtl::OString
sTrace( "ORichTextPeer::implCreateDispatcher: not creating dispatcher (unsupported slot) for " );
629 sTrace
+= ::rtl::OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
630 DBG_TRACE( sTrace
.getStr() );
637 SingleAttributeDispatcher
xDispatcher( pDispatcher
);
638 if ( pAttributeDispatcher
)
640 xDispatcher
= SingleAttributeDispatcher( pAttributeDispatcher
);
641 pRichTextControl
->enableAttributeNotification( _nSlotId
, pAttributeDispatcher
);
647 //--------------------------------------------------------------------
650 SfxSlotId
lcl_getSlotFromUnoName( SfxSlotPool
& _rSlotPool
, const ::rtl::OUString
& _rUnoSlotName
)
652 const SfxSlot
* pSlot
= _rSlotPool
.GetUnoSlot( _rUnoSlotName
);
655 // okay, there's a slot with the given UNO name
656 return lcl_translateConflictingSlot( pSlot
->GetSlotId() );
659 // some hard-coded slots, which do not have a UNO name at SFX level, but which
660 // we nevertheless need to transport via UNO mechanisms, so we need a name
661 if ( _rUnoSlotName
.equalsAscii( "AllowHangingPunctuation" ) )
662 return SID_ATTR_PARA_HANGPUNCTUATION
;
663 if ( _rUnoSlotName
.equalsAscii( "ApplyForbiddenCharacterRules" ) )
664 return SID_ATTR_PARA_FORBIDDEN_RULES
;
665 if ( _rUnoSlotName
.equalsAscii( "UseScriptSpacing" ) )
666 return SID_ATTR_PARA_SCRIPTSPACE
;
668 OSL_ENSURE( pSlot
, "lcl_getSlotFromUnoName: unknown UNO slot name!" );
673 //--------------------------------------------------------------------
674 Reference
< XDispatch
> SAL_CALL
ORichTextPeer::queryDispatch( const ::com::sun::star::util::URL
& _rURL
, const ::rtl::OUString
& /*_rTargetFrameName*/, sal_Int32
/*_nSearchFlags*/ ) throw (RuntimeException
)
676 Reference
< XDispatch
> xReturn
;
679 OSL_ENSURE( sal_False
, "ORichTextPeer::queryDispatch: already disposed?" );
683 // is it an UNO slot?
684 ::rtl::OUString
sUnoProtocolPrefix( RTL_CONSTASCII_USTRINGPARAM( ".uno:" ) );
685 if ( 0 == _rURL
.Complete
.compareTo( sUnoProtocolPrefix
, sUnoProtocolPrefix
.getLength() ) )
687 ::rtl::OUString sUnoSlotName
= _rURL
.Complete
.copy( sUnoProtocolPrefix
.getLength() );
688 SfxSlotId nSlotId
= lcl_getSlotFromUnoName( SfxSlotPool::GetSlotPool( NULL
), sUnoSlotName
);
691 // do we already have a dispatcher for this?
692 AttributeDispatchers::const_iterator aDispatcherPos
= m_aDispatchers
.find( nSlotId
);
693 if ( aDispatcherPos
== m_aDispatchers
.end() )
695 SingleAttributeDispatcher pDispatcher
= implCreateDispatcher( nSlotId
, _rURL
);
696 if ( pDispatcher
.is() )
698 aDispatcherPos
= m_aDispatchers
.insert( AttributeDispatchers::value_type( nSlotId
, pDispatcher
) ).first
;
702 if ( aDispatcherPos
!= m_aDispatchers
.end() )
703 xReturn
= aDispatcherPos
->second
.getRef();
710 //--------------------------------------------------------------------
711 Sequence
< Reference
< XDispatch
> > SAL_CALL
ORichTextPeer::queryDispatches( const Sequence
< DispatchDescriptor
>& _rRequests
) throw (RuntimeException
)
713 Sequence
< Reference
< XDispatch
> > aReturn( _rRequests
.getLength() );
714 Reference
< XDispatch
>* pReturn
= aReturn
.getArray();
716 const DispatchDescriptor
* pRequest
= _rRequests
.getConstArray();
717 const DispatchDescriptor
* pRequestEnd
= pRequest
+ _rRequests
.getLength();
718 for ( ; pRequest
!= pRequestEnd
; ++pRequest
, ++pReturn
)
720 *pReturn
= queryDispatch( pRequest
->FeatureURL
, pRequest
->FrameName
, pRequest
->SearchFlags
);
725 //--------------------------------------------------------------------
726 void ORichTextPeer::onSelectionChanged( const ESelection
& /*_rSelection*/ )
728 AttributeDispatchers::iterator aDispatcherPos
= m_aDispatchers
.find( SID_COPY
);
729 if ( aDispatcherPos
!= m_aDispatchers
.end() )
730 aDispatcherPos
->second
.get()->invalidate();
732 aDispatcherPos
= m_aDispatchers
.find( SID_CUT
);
733 if ( aDispatcherPos
!= m_aDispatchers
.end() )
734 aDispatcherPos
->second
.get()->invalidate();
737 //........................................................................
739 //........................................................................