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 "richtextcontrol.hxx"
21 #include "frm_module.hxx"
22 #include "property.hrc"
23 #include "services.hxx"
25 #include "richtextmodel.hxx"
26 #include "richtextvclcontrol.hxx"
27 #include "clipboarddispatcher.hxx"
28 #include "parametrizedattributedispatcher.hxx"
29 #include "specialdispatchers.hxx"
31 #include <com/sun/star/awt/PosSize.hpp>
33 #include <toolkit/helper/vclunohelper.hxx>
34 #include <tools/diagnose_ex.h>
35 #include <vcl/svapp.hxx>
37 #include <svx/svxids.hrc>
38 #include <editeng/editview.hxx>
39 #include <svl/itemset.hxx>
40 #include <svl/itempool.hxx>
41 #include <sfx2/msgpool.hxx>
43 //--------------------------------------------------------------------------
44 extern "C" void SAL_CALL
createRegistryInfo_ORichTextControl()
46 static ::frm::OMultiInstanceAutoRegistration
< ::frm::ORichTextControl
> aAutoRegistration
;
49 //.........................................................................
52 //.........................................................................
54 using namespace ::com::sun::star::uno
;
55 using namespace ::com::sun::star::beans
;
56 using namespace ::com::sun::star::awt
;
57 using namespace ::com::sun::star::lang
;
58 using namespace ::com::sun::star::frame
;
60 #define FORWARD_TO_PEER_1_RET( returnType, unoInterface, method, param1 ) \
62 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
63 if ( xTypedPeer.is() ) \
65 aReturn = xTypedPeer->method( param1 ); \
69 #define FORWARD_TO_PEER_3_RET( returnType, unoInterface, method, param1, param2, param3 ) \
71 Reference< unoInterface > xTypedPeer( getPeer(), UNO_QUERY ); \
72 if ( xTypedPeer.is() ) \
74 aReturn = xTypedPeer->method( param1, param2, param3 ); \
78 //==================================================================
80 //==================================================================
81 DBG_NAME( ORichTextControl
)
82 //------------------------------------------------------------------
83 ORichTextControl::ORichTextControl()
86 DBG_CTOR( ORichTextControl
, NULL
);
89 //------------------------------------------------------------------
90 ORichTextControl::~ORichTextControl()
92 DBG_DTOR( ORichTextControl
, NULL
);
95 //------------------------------------------------------------------
96 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextControl
, UnoEditControl
, ORichTextControl_Base
)
98 //------------------------------------------------------------------
99 Any SAL_CALL
ORichTextControl::queryAggregation( const Type
& _rType
) throw ( RuntimeException
)
101 Any aReturn
= UnoEditControl::queryAggregation( _rType
);
103 if ( !aReturn
.hasValue() )
104 aReturn
= ORichTextControl_Base::queryInterface( _rType
);
109 //------------------------------------------------------------------
112 //..............................................................
113 static void implAdjustTriStateFlag( const Reference
< XPropertySet
>& _rxProps
, const OUString
& _rPropertyName
,
114 WinBits
& _rAllBits
, WinBits _nPositiveFlag
, WinBits nNegativeFlag
)
116 sal_Bool bFlagValue
= sal_False
;
117 if ( _rxProps
->getPropertyValue( _rPropertyName
) >>= bFlagValue
)
118 _rAllBits
|= ( bFlagValue
? _nPositiveFlag
: nNegativeFlag
);
121 //..............................................................
122 static void implAdjustTwoStateFlag( const Any
& _rValue
, WinBits
& _rAllBits
, WinBits _nFlag
, bool _bInvert
= false )
124 sal_Bool bFlagValue
= sal_False
;
125 if ( _rValue
>>= bFlagValue
)
128 bFlagValue
= !bFlagValue
;
132 _rAllBits
&= ~_nFlag
;
136 //..............................................................
137 static void implAdjustTwoStateFlag( const Reference
< XPropertySet
>& _rxProps
, const OUString
& _rPropertyName
,
138 WinBits
& _rAllBits
, WinBits _nFlag
, bool _bInvert
= false )
140 implAdjustTwoStateFlag( _rxProps
->getPropertyValue( _rPropertyName
), _rAllBits
, _nFlag
, _bInvert
);
143 //..............................................................
144 static void adjustTwoStateWinBit( Window
* _pWindow
, const Any
& _rValue
, WinBits _nFlag
, bool _bInvert
= false )
146 WinBits nBits
= _pWindow
->GetStyle();
147 implAdjustTwoStateFlag( _rValue
, nBits
, _nFlag
, _bInvert
);
148 _pWindow
->SetStyle( nBits
);
151 //..............................................................
152 static WinBits
getWinBits( const Reference
< XControlModel
>& _rxModel
, WinBits nBaseBits
= 0 )
154 WinBits nBits
= nBaseBits
;
157 Reference
< XPropertySet
> xProps( _rxModel
, UNO_QUERY
);
160 sal_Int16 nBorder
= 0;
161 xProps
->getPropertyValue( PROPERTY_BORDER
) >>= nBorder
;
165 implAdjustTriStateFlag( xProps
, PROPERTY_TABSTOP
, nBits
, WB_TABSTOP
, WB_NOTABSTOP
);
166 implAdjustTwoStateFlag( xProps
, PROPERTY_HSCROLL
, nBits
, WB_HSCROLL
);
167 implAdjustTwoStateFlag( xProps
, PROPERTY_VSCROLL
, nBits
, WB_VSCROLL
);
168 implAdjustTwoStateFlag( xProps
, PROPERTY_HARDLINEBREAKS
, nBits
, WB_WORDBREAK
, true );
171 catch( const Exception
& )
173 DBG_UNHANDLED_EXCEPTION();
179 //------------------------------------------------------------------
180 void SAL_CALL
ORichTextControl::createPeer( const Reference
< XToolkit
>& _rToolkit
, const Reference
< XWindowPeer
>& _rParentPeer
) throw( RuntimeException
)
182 sal_Bool bReallyActAsRichText
= sal_False
;
185 Reference
< XPropertySet
> xModelProps( getModel(), UNO_QUERY_THROW
);
186 xModelProps
->getPropertyValue( PROPERTY_RICH_TEXT
) >>= bReallyActAsRichText
;
188 catch( const Exception
& )
190 DBG_UNHANDLED_EXCEPTION();
193 if ( !bReallyActAsRichText
)
195 UnoEditControl::createPeer( _rToolkit
, _rParentPeer
);
196 OControl::initFormControlPeer( getPeer() );
200 SolarMutexGuard aGuard
;
204 mbCreatingPeer
= sal_True
;
206 // determine the VLC window for the parent
207 Window
* pParentWin
= NULL
;
208 if ( _rParentPeer
.is() )
210 VCLXWindow
* pParentXWin
= VCLXWindow::GetImplementation( _rParentPeer
);
212 pParentWin
= pParentXWin
->GetWindow();
213 DBG_ASSERT( pParentWin
, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" );
217 Reference
< XControlModel
> xModel( getModel() );
218 ORichTextPeer
* pPeer
= ORichTextPeer::Create( xModel
, pParentWin
, getWinBits( xModel
) );
219 DBG_ASSERT( pPeer
, "ORichTextControl::createPeer: invalid peer returned!" );
222 // by definition, the returned component is aquired once
225 // announce the peer to the base class
228 // initialize ourself (and thus the peer) with the model properties
231 Reference
< XView
> xPeerView( getPeer(), UNO_QUERY
);
232 if ( xPeerView
.is() )
234 xPeerView
->setZoom( maComponentInfos
.nZoomX
, maComponentInfos
.nZoomY
);
235 xPeerView
->setGraphics( mxGraphics
);
238 // a lot of initial settings from our component infos
239 setPosSize( maComponentInfos
.nX
, maComponentInfos
.nY
, maComponentInfos
.nWidth
, maComponentInfos
.nHeight
, PosSize::POSSIZE
);
241 pPeer
->setVisible ( maComponentInfos
.bVisible
&& !mbDesignMode
);
242 pPeer
->setEnable ( maComponentInfos
.bEnable
);
243 pPeer
->setDesignMode( mbDesignMode
);
248 mbCreatingPeer
= sal_False
;
250 OControl::initFormControlPeer( getPeer() );
254 //------------------------------------------------------------------
255 OUString SAL_CALL
ORichTextControl::getImplementationName() throw( RuntimeException
)
257 return getImplementationName_Static();
260 //------------------------------------------------------------------
261 Sequence
< OUString
> SAL_CALL
ORichTextControl::getSupportedServiceNames() throw( RuntimeException
)
263 return getSupportedServiceNames_Static();
266 //------------------------------------------------------------------
267 OUString SAL_CALL
ORichTextControl::getImplementationName_Static()
269 return OUString( "com.sun.star.comp.form.ORichTextControl" );
272 //------------------------------------------------------------------
273 Sequence
< OUString
> SAL_CALL
ORichTextControl::getSupportedServiceNames_Static()
275 Sequence
< OUString
> aServices( 3 );
276 aServices
[ 0 ] = OUString( "com.sun.star.awt.UnoControl" );
277 aServices
[ 1 ] = OUString( "com.sun.star.awt.UnoControlEdit" );
278 aServices
[ 2 ] = FRM_SUN_CONTROL_RICHTEXTCONTROL
;
282 //------------------------------------------------------------------
283 Reference
< XInterface
> SAL_CALL
ORichTextControl::Create( const Reference
< XMultiServiceFactory
>& )
285 return *( new ORichTextControl() );
288 //--------------------------------------------------------------------
289 Reference
< XDispatch
> SAL_CALL
ORichTextControl::queryDispatch( const ::com::sun::star::util::URL
& _rURL
, const OUString
& _rTargetFrameName
, sal_Int32 _nSearchFlags
) throw (RuntimeException
)
291 FORWARD_TO_PEER_3_RET( Reference
< XDispatch
>, XDispatchProvider
, queryDispatch
, _rURL
, _rTargetFrameName
, _nSearchFlags
);
294 //--------------------------------------------------------------------
295 Sequence
< Reference
< XDispatch
> > SAL_CALL
ORichTextControl::queryDispatches( const Sequence
< DispatchDescriptor
>& _rRequests
) throw (RuntimeException
)
297 FORWARD_TO_PEER_1_RET( Sequence
< Reference
< XDispatch
> >, XDispatchProvider
, queryDispatches
, _rRequests
);
300 //--------------------------------------------------------------------
301 sal_Bool
ORichTextControl::requiresNewPeer( const OUString
& _rPropertyName
) const
303 return UnoControl::requiresNewPeer( _rPropertyName
) || _rPropertyName
.equals( PROPERTY_RICH_TEXT
);
306 //==================================================================
308 //==================================================================
309 DBG_NAME( ORichTextPeer
)
310 //------------------------------------------------------------------
311 ORichTextPeer
* ORichTextPeer::Create( const Reference
< XControlModel
>& _rxModel
, Window
* _pParentWindow
, WinBits _nStyle
)
313 DBG_TESTSOLARMUTEX();
315 // the EditEngine of the model
316 RichTextEngine
* pEngine
= ORichTextModel::getEditEngine( _rxModel
);
317 OSL_ENSURE( pEngine
, "ORichTextPeer::Create: could not obtaine the edit engine from the model!" );
322 ORichTextPeer
* pPeer
= new ORichTextPeer
;
323 pPeer
->acquire(); // by definition, the returned object is aquired once
325 // the VCL control for the peer
326 RichTextControl
* pRichTextControl
= new RichTextControl( pEngine
, _pParentWindow
, _nStyle
, NULL
, pPeer
);
329 pRichTextControl
->SetComponentInterface( pPeer
);
335 //------------------------------------------------------------------
336 ORichTextPeer::ORichTextPeer()
338 DBG_CTOR( ORichTextPeer
, NULL
);
341 //------------------------------------------------------------------
342 ORichTextPeer::~ORichTextPeer()
344 DBG_DTOR( ORichTextPeer
, NULL
);
347 //------------------------------------------------------------------
348 void ORichTextPeer::dispose( ) throw(RuntimeException
)
351 SolarMutexGuard aGuard
;
352 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
354 if ( pRichTextControl
)
356 for ( AttributeDispatchers::iterator aDisposeLoop
= m_aDispatchers
.begin();
357 aDisposeLoop
!= m_aDispatchers
.end();
361 pRichTextControl
->disableAttributeNotification( aDisposeLoop
->first
);
362 aDisposeLoop
->second
->dispose();
366 AttributeDispatchers aEmpty
;
367 m_aDispatchers
.swap( aEmpty
);
370 VCLXWindow::dispose();
373 //--------------------------------------------------------------------
374 void SAL_CALL
ORichTextPeer::draw( sal_Int32 _nX
, sal_Int32 _nY
) throw(::com::sun::star::uno::RuntimeException
)
376 SolarMutexGuard aGuard
;
378 RichTextControl
* pControl
= static_cast< RichTextControl
* >( GetWindow() );
382 OutputDevice
* pTargetDevice
= VCLUnoHelper::GetOutputDevice( getGraphics() );
383 OSL_ENSURE( pTargetDevice
!= NULL
, "ORichTextPeer::draw: no graphics -> no drawing!" );
384 if ( !pTargetDevice
)
387 ::Size aSize
= pControl
->GetSizePixel();
388 const MapUnit eTargetUnit
= pTargetDevice
->GetMapMode().GetMapUnit();
389 if ( eTargetUnit
!= MAP_PIXEL
)
390 aSize
= pTargetDevice
->PixelToLogic( aSize
);
392 ::Point
aPos( _nX
, _nY
);
393 // the XView::draw API talks about pixels, always ...
394 if ( eTargetUnit
!= MAP_PIXEL
)
395 aPos
= pTargetDevice
->PixelToLogic( aPos
);
397 pControl
->Draw( pTargetDevice
, aPos
, aSize
, WINDOW_DRAW_NOCONTROLS
);
400 //--------------------------------------------------------------------
401 void SAL_CALL
ORichTextPeer::setProperty( const OUString
& _rPropertyName
, const Any
& _rValue
) throw (RuntimeException
)
405 VCLXWindow::setProperty( _rPropertyName
, _rValue
);
409 if ( _rPropertyName
.equals( PROPERTY_BACKGROUNDCOLOR
) )
411 RichTextControl
* pControl
= static_cast< RichTextControl
* >( GetWindow() );
412 if ( !_rValue
.hasValue() )
414 pControl
->SetBackgroundColor( );
418 sal_Int32 nColor
= COL_TRANSPARENT
;
420 pControl
->SetBackgroundColor( Color( nColor
) );
423 else if ( _rPropertyName
.equals( PROPERTY_HSCROLL
) )
425 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_HSCROLL
);
427 else if ( _rPropertyName
.equals( PROPERTY_VSCROLL
) )
429 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_VSCROLL
);
431 else if ( _rPropertyName
.equals( PROPERTY_HARDLINEBREAKS
) )
433 adjustTwoStateWinBit( GetWindow(), _rValue
, WB_WORDBREAK
, true );
435 else if ( _rPropertyName
.equals( PROPERTY_READONLY
) )
437 RichTextControl
* pControl
= static_cast< RichTextControl
* >( GetWindow() );
438 sal_Bool
bReadOnly( pControl
->IsReadOnly() );
439 OSL_VERIFY( _rValue
>>= bReadOnly
);
440 pControl
->SetReadOnly( bReadOnly
);
442 // update the dispatchers
443 for ( AttributeDispatchers::iterator aDispatcherLoop
= m_aDispatchers
.begin();
444 aDispatcherLoop
!= m_aDispatchers
.end();
448 aDispatcherLoop
->second
->invalidate();
451 else if ( _rPropertyName
.equals( PROPERTY_HIDEINACTIVESELECTION
) )
453 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
454 sal_Bool bHide
= pRichTextControl
->GetHideInactiveSelection();
455 OSL_VERIFY( _rValue
>>= bHide
);
456 pRichTextControl
->SetHideInactiveSelection( bHide
);
459 VCLXWindow::setProperty( _rPropertyName
, _rValue
);
462 //------------------------------------------------------------------
463 IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer
, VCLXWindow
, ORichTextPeer_Base
)
465 //------------------------------------------------------------------
466 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer
, VCLXWindow
, ORichTextPeer_Base
)
468 //--------------------------------------------------------------------
471 static SfxSlotId
lcl_translateConflictingSlot( SfxSlotId _nIDFromPool
)
474 // unfortunately, some of our applications have some conflicting slots,
475 // i.e. slots which have the same UNO name as an existing other (common)
477 // For instance, both the slots SID_SET_SUPER_SCRIPT (from SVX) and FN_SET_SUPER_SCRIPT
478 // (from SW) have the UNO name "SuperScript".
479 // Now, if the controls lives in a text document, and asks the SfxSlotPool for
480 // the id belonging to "SuperScript", it gets the FN_SET_SUPER_SCRIPT - which
481 // is completely unknown to the EditEngine.
482 // So, we need to translate such conflicting ids.
484 // Note that the real solution would be to fix the applications to
485 // *not* define conflicting slots. Alternatively, if SFX would provide a slot pool
486 // which is *static* (i.e. independent on the active application), then we
487 // would also never encounter such a conflict.
488 SfxSlotId
nReturn( _nIDFromPool
);
489 switch ( _nIDFromPool
)
491 case 20411: /* FM_SET_SUPER_SCRIPT, originating in SW */
492 nReturn
= SID_SET_SUPER_SCRIPT
;
494 case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */
495 nReturn
= SID_SET_SUB_SCRIPT
;
502 //--------------------------------------------------------------------
503 ORichTextPeer::SingleAttributeDispatcher
ORichTextPeer::implCreateDispatcher( SfxSlotId _nSlotId
, const ::com::sun::star::util::URL
& _rURL
)
505 RichTextControl
* pRichTextControl
= static_cast< RichTextControl
* >( GetWindow() );
506 OSL_PRECOND( pRichTextControl
, "ORichTextPeer::implCreateDispatcher: invalid window!" );
507 if ( !pRichTextControl
)
508 return SingleAttributeDispatcher( NULL
);
510 ORichTextFeatureDispatcher
* pDispatcher
= NULL
;
511 OAttributeDispatcher
* pAttributeDispatcher
= NULL
;
515 pDispatcher
= new OClipboardDispatcher( pRichTextControl
->getView(), OClipboardDispatcher::eCut
);
519 pDispatcher
= new OClipboardDispatcher( pRichTextControl
->getView(), OClipboardDispatcher::eCopy
);
523 pDispatcher
= new OPasteClipboardDispatcher( pRichTextControl
->getView() );
527 pDispatcher
= new OSelectAllDispatcher( pRichTextControl
->getView(), _rURL
);
530 case SID_ATTR_PARA_LEFT_TO_RIGHT
:
531 case SID_ATTR_PARA_RIGHT_TO_LEFT
:
532 pAttributeDispatcher
= new OParagraphDirectionDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
535 case SID_TEXTDIRECTION_TOP_TO_BOTTOM
:
536 case SID_TEXTDIRECTION_LEFT_TO_RIGHT
:
537 pDispatcher
= new OTextDirectionDispatcher( pRichTextControl
->getView(), _rURL
);
540 case SID_ATTR_PARA_HANGPUNCTUATION
:
541 case SID_ATTR_PARA_FORBIDDEN_RULES
:
542 case SID_ATTR_PARA_SCRIPTSPACE
:
543 pAttributeDispatcher
= new OAsianFontLayoutDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
548 // is it a supported slot?
549 bool bSupportedSlot
= false;
550 if ( !bSupportedSlot
)
552 const SfxItemPool
& rPool
= *pRichTextControl
->getView().GetEmptyItemSet().GetPool();
553 bSupportedSlot
= rPool
.IsInRange( rPool
.GetWhich( _nSlotId
) );
555 if ( !bSupportedSlot
)
556 bSupportedSlot
= RichTextControl::isMappableSlot( _nSlotId
);
558 if ( bSupportedSlot
)
559 { // it's really a slot which is supported by the EditEngine
561 bool bNeedParametrizedDispatcher
= true;
562 if ( ( _nSlotId
== SID_ATTR_CHAR_POSTURE
)
563 || ( _nSlotId
== SID_ATTR_CHAR_CJK_POSTURE
)
564 || ( _nSlotId
== SID_ATTR_CHAR_CTL_POSTURE
)
565 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_POSTURE
)
566 || ( _nSlotId
== SID_ATTR_CHAR_WEIGHT
)
567 || ( _nSlotId
== SID_ATTR_CHAR_CJK_WEIGHT
)
568 || ( _nSlotId
== SID_ATTR_CHAR_CTL_WEIGHT
)
569 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_WEIGHT
)
570 || ( _nSlotId
== SID_ATTR_CHAR_LANGUAGE
)
571 || ( _nSlotId
== SID_ATTR_CHAR_CJK_LANGUAGE
)
572 || ( _nSlotId
== SID_ATTR_CHAR_CTL_LANGUAGE
)
573 || ( _nSlotId
== SID_ATTR_CHAR_LATIN_LANGUAGE
)
574 || ( _nSlotId
== SID_ATTR_CHAR_CONTOUR
)
575 || ( _nSlotId
== SID_ATTR_CHAR_SHADOWED
)
576 || ( _nSlotId
== SID_ATTR_CHAR_WORDLINEMODE
)
577 || ( _nSlotId
== SID_ATTR_CHAR_COLOR
)
578 || ( _nSlotId
== SID_ATTR_CHAR_RELIEF
)
579 || ( _nSlotId
== SID_ATTR_CHAR_KERNING
)
580 || ( _nSlotId
== SID_ATTR_CHAR_AUTOKERN
)
581 || ( _nSlotId
== SID_ATTR_CHAR_SCALEWIDTH
)
584 bNeedParametrizedDispatcher
= true;
586 else if ( ( _nSlotId
== SID_ATTR_PARA_HANGPUNCTUATION
)
587 || ( _nSlotId
== SID_ATTR_PARA_FORBIDDEN_RULES
)
588 || ( _nSlotId
== SID_ATTR_PARA_SCRIPTSPACE
)
591 bNeedParametrizedDispatcher
= false;
595 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( NULL
);
596 const SfxSlot
* pSlot
= rSlotPool
.GetSlot( _nSlotId
);
597 const SfxType
* pType
= pSlot
? pSlot
->GetType() : NULL
;
600 bNeedParametrizedDispatcher
= ( pType
->nAttribs
> 0 );
604 if ( bNeedParametrizedDispatcher
)
606 #if OSL_DEBUG_LEVEL > 0
607 OString
sTrace( "ORichTextPeer::implCreateDispatcher: creating *parametrized* dispatcher for " );
608 sTrace
+= OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
609 OSL_TRACE( "%s", sTrace
.getStr() );
611 pAttributeDispatcher
= new OParametrizedAttributeDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
615 #if OSL_DEBUG_LEVEL > 0
616 OString
sTrace( "ORichTextPeer::implCreateDispatcher: creating *normal* dispatcher for " );
617 sTrace
+= OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
618 OSL_TRACE( "%s", sTrace
.getStr() );
620 pAttributeDispatcher
= new OAttributeDispatcher( pRichTextControl
->getView(), _nSlotId
, _rURL
, pRichTextControl
);
623 #if OSL_DEBUG_LEVEL > 0
626 OString
sTrace( "ORichTextPeer::implCreateDispatcher: not creating dispatcher (unsupported slot) for " );
627 sTrace
+= OString( _rURL
.Complete
.getStr(), _rURL
.Complete
.getLength(), RTL_TEXTENCODING_ASCII_US
);
628 OSL_TRACE( "%s", sTrace
.getStr() );
635 SingleAttributeDispatcher
xDispatcher( pDispatcher
);
636 if ( pAttributeDispatcher
)
638 xDispatcher
= SingleAttributeDispatcher( pAttributeDispatcher
);
639 pRichTextControl
->enableAttributeNotification( _nSlotId
, pAttributeDispatcher
);
645 //--------------------------------------------------------------------
648 SfxSlotId
lcl_getSlotFromUnoName( SfxSlotPool
& _rSlotPool
, const OUString
& _rUnoSlotName
)
650 const SfxSlot
* pSlot
= _rSlotPool
.GetUnoSlot( _rUnoSlotName
);
653 // okay, there's a slot with the given UNO name
654 return lcl_translateConflictingSlot( pSlot
->GetSlotId() );
657 // some hard-coded slots, which do not have a UNO name at SFX level, but which
658 // we nevertheless need to transport via UNO mechanisms, so we need a name
659 if ( _rUnoSlotName
== "AllowHangingPunctuation" )
660 return SID_ATTR_PARA_HANGPUNCTUATION
;
661 if ( _rUnoSlotName
== "ApplyForbiddenCharacterRules" )
662 return SID_ATTR_PARA_FORBIDDEN_RULES
;
663 if ( _rUnoSlotName
== "UseScriptSpacing" )
664 return SID_ATTR_PARA_SCRIPTSPACE
;
666 OSL_ENSURE( pSlot
, "lcl_getSlotFromUnoName: unknown UNO slot name!" );
671 //--------------------------------------------------------------------
672 Reference
< XDispatch
> SAL_CALL
ORichTextPeer::queryDispatch( const ::com::sun::star::util::URL
& _rURL
, const OUString
& /*_rTargetFrameName*/, sal_Int32
/*_nSearchFlags*/ ) throw (RuntimeException
)
674 Reference
< XDispatch
> xReturn
;
677 OSL_FAIL( "ORichTextPeer::queryDispatch: already disposed?" );
681 // is it an UNO slot?
682 OUString
sUnoProtocolPrefix( ".uno:" );
683 if ( _rURL
.Complete
.startsWith( sUnoProtocolPrefix
) )
685 OUString sUnoSlotName
= _rURL
.Complete
.copy( sUnoProtocolPrefix
.getLength() );
686 SfxSlotId nSlotId
= lcl_getSlotFromUnoName( SfxSlotPool::GetSlotPool( NULL
), sUnoSlotName
);
689 // do we already have a dispatcher for this?
690 AttributeDispatchers::const_iterator aDispatcherPos
= m_aDispatchers
.find( nSlotId
);
691 if ( aDispatcherPos
== m_aDispatchers
.end() )
693 SingleAttributeDispatcher pDispatcher
= implCreateDispatcher( nSlotId
, _rURL
);
694 if ( pDispatcher
.is() )
696 aDispatcherPos
= m_aDispatchers
.insert( AttributeDispatchers::value_type( nSlotId
, pDispatcher
) ).first
;
700 if ( aDispatcherPos
!= m_aDispatchers
.end() )
701 xReturn
= aDispatcherPos
->second
.getRef();
708 //--------------------------------------------------------------------
709 Sequence
< Reference
< XDispatch
> > SAL_CALL
ORichTextPeer::queryDispatches( const Sequence
< DispatchDescriptor
>& _rRequests
) throw (RuntimeException
)
711 Sequence
< Reference
< XDispatch
> > aReturn( _rRequests
.getLength() );
712 Reference
< XDispatch
>* pReturn
= aReturn
.getArray();
714 const DispatchDescriptor
* pRequest
= _rRequests
.getConstArray();
715 const DispatchDescriptor
* pRequestEnd
= pRequest
+ _rRequests
.getLength();
716 for ( ; pRequest
!= pRequestEnd
; ++pRequest
, ++pReturn
)
718 *pReturn
= queryDispatch( pRequest
->FeatureURL
, pRequest
->FrameName
, pRequest
->SearchFlags
);
723 //--------------------------------------------------------------------
724 void ORichTextPeer::onSelectionChanged( const ESelection
& /*_rSelection*/ )
726 AttributeDispatchers::iterator aDispatcherPos
= m_aDispatchers
.find( SID_COPY
);
727 if ( aDispatcherPos
!= m_aDispatchers
.end() )
728 aDispatcherPos
->second
.get()->invalidate();
730 aDispatcherPos
= m_aDispatchers
.find( SID_CUT
);
731 if ( aDispatcherPos
!= m_aDispatchers
.end() )
732 aDispatcherPos
->second
.get()->invalidate();
735 //........................................................................
737 //........................................................................
739 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */