update dev300-m58
[ooovba.git] / forms / source / richtext / richtextcontrol.cxx
blobfb3a2562b805481ac8dfc93c7318656980c3d191
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: richtextcontrol.cxx,v $
10 * $Revision: 1.9 $
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"
37 #endif
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 //.........................................................................
65 namespace frm
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() ) \
78 { \
79 xTypedPeer->method( param1 ); \
82 #define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 ) \
83 returnType aReturn; \
84 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
85 if ( xTypedPeer.is() ) \
86 { \
87 aReturn = xTypedPeer->method( param1 ); \
88 } \
89 return aReturn;
91 #define FORWARD_TO_PEER_3( unoInterface, method, param1, param2, param3 ) \
92 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
93 if ( xTypedPeer.is() ) \
94 { \
95 xTypedPeer->method( param1, param2, param3 ); \
98 #define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 ) \
99 returnType aReturn; \
100 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
101 if ( xTypedPeer.is() ) \
103 aReturn = xTypedPeer->method( param1, param2, param3 ); \
105 return aReturn;
107 //==================================================================
108 // ORichTextControl
109 //==================================================================
110 DBG_NAME( ORichTextControl )
111 //------------------------------------------------------------------
112 ORichTextControl::ORichTextControl( const Reference< XMultiServiceFactory >& _rxORB )
113 :m_xORB( _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 );
135 return aReturn;
138 //------------------------------------------------------------------
139 namespace
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 )
156 if ( _bInvert )
157 bFlagValue = !bFlagValue;
158 if ( bFlagValue )
159 _rAllBits |= _nFlag;
160 else
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 );
187 if ( xProps.is() )
189 sal_Int16 nBorder = 0;
190 xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder;
191 if ( nBorder )
192 nBits |= WB_BORDER;
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();
204 return nBits;
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() );
226 return;
229 ::vos::OGuard aGuard( Application::GetSolarMutex() );
231 if (!getPeer().is())
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 );
240 if ( pParentXWin )
241 pParentWin = pParentXWin->GetWindow();
242 DBG_ASSERT( pParentWin, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" );
245 // create the peer
246 Reference< XControlModel > xModel( getModel() );
247 ORichTextPeer* pPeer = ORichTextPeer::Create( xModel, pParentWin, getWinBits( xModel ) );
248 DBG_ASSERT( pPeer, "ORichTextControl::createPeer: invalid peer returned!" );
249 if ( pPeer )
251 // by definition, the returned component is aquired once
252 pPeer->release();
254 // announce the peer to the base class
255 setPeer( pPeer );
257 // initialize ourself (and thus the peer) with the model properties
258 updateFromModel();
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 );
274 peerCreated();
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;
308 return aServices;
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 //==================================================================
336 // ORichTextPeer
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!" );
347 if ( !pEngine )
348 return NULL;
350 // the peer itself
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 );
357 // some knittings
358 pRichTextControl->SetComponentInterface( pPeer );
360 // outta here
361 return 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();
387 ++aDisposeLoop
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)
405 if ( !GetWindow() )
407 VCLXWindow::setProperty( _rPropertyName, _rValue );
408 return;
411 if ( _rPropertyName.equals( PROPERTY_BACKGROUNDCOLOR ) )
413 RichTextControl* pControl = static_cast< RichTextControl* >( GetWindow() );
414 if ( !_rValue.hasValue() )
416 pControl->SetBackgroundColor( );
418 else
420 sal_Int32 nColor = COL_TRANSPARENT;
421 _rValue >>= nColor;
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();
447 ++aDispatcherLoop
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 );
460 else
461 VCLXWindow::setProperty( _rPropertyName, _rValue );
464 //------------------------------------------------------------------
465 IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
467 //------------------------------------------------------------------
468 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
470 //--------------------------------------------------------------------
471 namespace
473 static SfxSlotId lcl_translateConflictingSlot( SfxSlotId _nIDFromPool )
475 // HACK HACK HACK
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)
478 // slot.
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;
495 break;
496 case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */
497 nReturn = SID_SET_SUB_SCRIPT;
498 break;
500 return nReturn;
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;
514 switch ( _nSlotId )
516 case SID_CUT:
517 pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCut );
518 break;
520 case SID_COPY:
521 pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCopy );
522 break;
524 case SID_PASTE:
525 pDispatcher = new OPasteClipboardDispatcher( pRichTextControl->getView() );
526 break;
528 case SID_SELECTALL:
529 pDispatcher = new OSelectAllDispatcher( pRichTextControl->getView(), _rURL );
530 break;
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 );
535 break;
537 case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
538 case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
539 pDispatcher = new OTextDirectionDispatcher( pRichTextControl->getView(), _rURL );
540 break;
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 );
546 break;
548 default:
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;
595 else
597 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool( NULL );
598 const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId );
599 const SfxType* pType = pSlot ? pSlot->GetType() : NULL;
600 if ( pType )
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() );
612 #endif
613 pAttributeDispatcher = new OParametrizedAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
615 else
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() );
621 #endif
622 pAttributeDispatcher = new OAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
625 #if OSL_DEBUG_LEVEL > 0
626 else
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() );
632 #endif
634 break;
637 SingleAttributeDispatcher xDispatcher( pDispatcher );
638 if ( pAttributeDispatcher )
640 xDispatcher = SingleAttributeDispatcher( pAttributeDispatcher );
641 pRichTextControl->enableAttributeNotification( _nSlotId, pAttributeDispatcher );
644 return xDispatcher;
647 //--------------------------------------------------------------------
648 namespace
650 SfxSlotId lcl_getSlotFromUnoName( SfxSlotPool& _rSlotPool, const ::rtl::OUString& _rUnoSlotName )
652 const SfxSlot* pSlot = _rSlotPool.GetUnoSlot( _rUnoSlotName );
653 if ( pSlot )
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!" );
669 return 0;
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;
677 if ( !GetWindow() )
679 OSL_ENSURE( sal_False, "ORichTextPeer::queryDispatch: already disposed?" );
680 return xReturn;
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 );
689 if ( nSlotId > 0 )
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();
707 return xReturn;
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 );
722 return aReturn;
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 //........................................................................
738 } // namespace frm
739 //........................................................................