Version 5.2.6.1, tag libreoffice-5.2.6.1
[LibreOffice.git] / forms / source / richtext / richtextcontrol.cxx
blob471df8e83ec0a5c09a1ad7b5a1c028842ae2b6e6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "richtextcontrol.hxx"
21 #include "property.hrc"
22 #include "services.hxx"
24 #include "richtextmodel.hxx"
25 #include "richtextvclcontrol.hxx"
26 #include "clipboarddispatcher.hxx"
27 #include "parametrizedattributedispatcher.hxx"
28 #include "specialdispatchers.hxx"
30 #include <com/sun/star/awt/PosSize.hpp>
32 #include <toolkit/helper/vclunohelper.hxx>
33 #include <tools/diagnose_ex.h>
34 #include <vcl/svapp.hxx>
36 #include <svx/svxids.hrc>
37 #include <editeng/editview.hxx>
38 #include <svl/itemset.hxx>
39 #include <svl/itempool.hxx>
40 #include <sfx2/msgpool.hxx>
42 namespace frm
46 using namespace ::com::sun::star::uno;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::awt;
49 using namespace ::com::sun::star::lang;
50 using namespace ::com::sun::star::frame;
52 ORichTextControl::ORichTextControl()
53 :UnoEditControl()
58 ORichTextControl::~ORichTextControl()
63 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextControl, UnoEditControl, ORichTextControl_Base )
66 Any SAL_CALL ORichTextControl::queryAggregation( const Type& _rType ) throw ( RuntimeException, std::exception )
68 Any aReturn = UnoEditControl::queryAggregation( _rType );
70 if ( !aReturn.hasValue() )
71 aReturn = ORichTextControl_Base::queryInterface( _rType );
73 return aReturn;
77 namespace
80 void implAdjustTriStateFlag( const Reference< XPropertySet >& _rxProps, const OUString& _rPropertyName,
81 WinBits& _rAllBits, WinBits _nPositiveFlag, WinBits nNegativeFlag )
83 bool bFlagValue = false;
84 if ( _rxProps->getPropertyValue( _rPropertyName ) >>= bFlagValue )
85 _rAllBits |= ( bFlagValue ? _nPositiveFlag : nNegativeFlag );
89 void implAdjustTwoStateFlag( const Any& _rValue, WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false )
91 bool bFlagValue = false;
92 if ( _rValue >>= bFlagValue )
94 if ( _bInvert )
95 bFlagValue = !bFlagValue;
96 if ( bFlagValue )
97 _rAllBits |= _nFlag;
98 else
99 _rAllBits &= ~_nFlag;
104 void implAdjustTwoStateFlag( const Reference< XPropertySet >& _rxProps, const OUString& _rPropertyName,
105 WinBits& _rAllBits, WinBits _nFlag, bool _bInvert = false )
107 implAdjustTwoStateFlag( _rxProps->getPropertyValue( _rPropertyName ), _rAllBits, _nFlag, _bInvert );
111 void adjustTwoStateWinBit( vcl::Window* _pWindow, const Any& _rValue, WinBits _nFlag, bool _bInvert = false )
113 WinBits nBits = _pWindow->GetStyle();
114 implAdjustTwoStateFlag( _rValue, nBits, _nFlag, _bInvert );
115 _pWindow->SetStyle( nBits );
119 WinBits getWinBits( const Reference< XControlModel >& _rxModel )
121 WinBits nBits = 0;
124 Reference< XPropertySet > xProps( _rxModel, UNO_QUERY );
125 if ( xProps.is() )
127 sal_Int16 nBorder = 0;
128 xProps->getPropertyValue( PROPERTY_BORDER ) >>= nBorder;
129 if ( nBorder )
130 nBits |= WB_BORDER;
132 implAdjustTriStateFlag( xProps, PROPERTY_TABSTOP, nBits, WB_TABSTOP, WB_NOTABSTOP );
133 implAdjustTwoStateFlag( xProps, PROPERTY_HSCROLL, nBits, WB_HSCROLL );
134 implAdjustTwoStateFlag( xProps, PROPERTY_VSCROLL, nBits, WB_VSCROLL );
135 implAdjustTwoStateFlag( xProps, PROPERTY_HARDLINEBREAKS, nBits, WB_WORDBREAK, true );
138 catch( const Exception& )
140 DBG_UNHANDLED_EXCEPTION();
142 return nBits;
147 void SAL_CALL ORichTextControl::createPeer( const Reference< XToolkit >& _rToolkit, const Reference< XWindowPeer >& _rParentPeer ) throw( RuntimeException, std::exception )
149 bool bReallyActAsRichText = false;
152 Reference< XPropertySet > xModelProps( getModel(), UNO_QUERY_THROW );
153 xModelProps->getPropertyValue( PROPERTY_RICH_TEXT ) >>= bReallyActAsRichText;
155 catch( const Exception& )
157 DBG_UNHANDLED_EXCEPTION();
160 if ( !bReallyActAsRichText )
162 UnoEditControl::createPeer( _rToolkit, _rParentPeer );
163 return;
166 SolarMutexGuard aGuard;
168 if (!getPeer().is())
170 mbCreatingPeer = true;
172 // determine the VLC window for the parent
173 vcl::Window* pParentWin = nullptr;
174 if ( _rParentPeer.is() )
176 VCLXWindow* pParentXWin = VCLXWindow::GetImplementation( _rParentPeer );
177 if ( pParentXWin )
178 pParentWin = pParentXWin->GetWindow();
179 DBG_ASSERT( pParentWin, "ORichTextControl::createPeer: could not obtain the VCL-level parent window!" );
182 // create the peer
183 Reference< XControlModel > xModel( getModel() );
184 ORichTextPeer* pPeer = ORichTextPeer::Create( xModel, pParentWin, getWinBits( xModel ) );
185 DBG_ASSERT( pPeer, "ORichTextControl::createPeer: invalid peer returned!" );
186 if ( pPeer )
188 // by definition, the returned component is acquired once
189 pPeer->release();
191 // announce the peer to the base class
192 setPeer( pPeer );
194 // initialize ourself (and thus the peer) with the model properties
195 updateFromModel();
197 Reference< XView > xPeerView( getPeer(), UNO_QUERY );
198 if ( xPeerView.is() )
200 xPeerView->setZoom( maComponentInfos.nZoomX, maComponentInfos.nZoomY );
201 xPeerView->setGraphics( mxGraphics );
204 // a lot of initial settings from our component infos
205 setPosSize( maComponentInfos.nX, maComponentInfos.nY, maComponentInfos.nWidth, maComponentInfos.nHeight, PosSize::POSSIZE );
207 pPeer->setVisible ( maComponentInfos.bVisible && !mbDesignMode );
208 pPeer->setEnable ( maComponentInfos.bEnable );
209 pPeer->setDesignMode( mbDesignMode );
211 peerCreated();
214 mbCreatingPeer = false;
219 OUString SAL_CALL ORichTextControl::getImplementationName() throw( RuntimeException, std::exception )
221 return getImplementationName_Static();
225 Sequence< OUString > SAL_CALL ORichTextControl::getSupportedServiceNames() throw( RuntimeException, std::exception )
227 return getSupportedServiceNames_Static();
230 OUString SAL_CALL ORichTextControl::getImplementationName_Static()
232 return OUString( "com.sun.star.comp.form.ORichTextControl" );
235 Sequence< OUString > SAL_CALL ORichTextControl::getSupportedServiceNames_Static()
237 Sequence< OUString > aServices( 3 );
238 aServices[ 0 ] = "com.sun.star.awt.UnoControl";
239 aServices[ 1 ] = "com.sun.star.awt.UnoControlEdit";
240 aServices[ 2 ] = FRM_SUN_CONTROL_RICHTEXTCONTROL;
241 return aServices;
244 Reference< XDispatch > SAL_CALL ORichTextControl::queryDispatch( const css::util::URL& _rURL, const OUString& _rTargetFrameName, sal_Int32 _nSearchFlags ) throw (RuntimeException, std::exception)
246 Reference< XDispatch > aReturn;
247 Reference< XDispatchProvider > xTypedPeer( getPeer(), UNO_QUERY );
248 if ( xTypedPeer.is() )
250 aReturn = xTypedPeer->queryDispatch( _rURL, _rTargetFrameName, _nSearchFlags );
252 return aReturn;
255 Sequence< Reference< XDispatch > > SAL_CALL ORichTextControl::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException, std::exception)
257 Sequence< Reference< XDispatch > > aReturn;
258 Reference< XDispatchProvider > xTypedPeer( getPeer(), UNO_QUERY );
259 if ( xTypedPeer.is() )
261 aReturn = xTypedPeer->queryDispatches( _rRequests );
263 return aReturn;
266 bool ORichTextControl::requiresNewPeer( const OUString& _rPropertyName ) const
268 return UnoControl::requiresNewPeer( _rPropertyName ) || _rPropertyName == PROPERTY_RICH_TEXT;
271 // ORichTextPeer
272 ORichTextPeer* ORichTextPeer::Create( const Reference< XControlModel >& _rxModel, vcl::Window* _pParentWindow, WinBits _nStyle )
274 DBG_TESTSOLARMUTEX();
276 // the EditEngine of the model
277 RichTextEngine* pEngine = ORichTextModel::getEditEngine( _rxModel );
278 OSL_ENSURE( pEngine, "ORichTextPeer::Create: could not obtaine the edit engine from the model!" );
279 if ( !pEngine )
280 return nullptr;
282 // the peer itself
283 ORichTextPeer* pPeer = new ORichTextPeer;
284 pPeer->acquire(); // by definition, the returned object is acquired once
286 // the VCL control for the peer
287 VclPtrInstance<RichTextControl> pRichTextControl( pEngine, _pParentWindow, _nStyle, nullptr, pPeer );
289 // some knittings
290 pRichTextControl->SetComponentInterface( pPeer );
292 // outta here
293 return pPeer;
297 ORichTextPeer::ORichTextPeer()
302 ORichTextPeer::~ORichTextPeer()
307 void ORichTextPeer::dispose( ) throw(RuntimeException, std::exception)
310 SolarMutexGuard aGuard;
311 VclPtr< RichTextControl > pRichTextControl = GetAs< RichTextControl >();
313 if ( pRichTextControl )
315 for ( AttributeDispatchers::iterator aDisposeLoop = m_aDispatchers.begin();
316 aDisposeLoop != m_aDispatchers.end();
317 ++aDisposeLoop
320 pRichTextControl->disableAttributeNotification( aDisposeLoop->first );
321 aDisposeLoop->second->dispose();
325 AttributeDispatchers aEmpty;
326 m_aDispatchers.swap( aEmpty );
329 VCLXWindow::dispose();
333 void SAL_CALL ORichTextPeer::draw( sal_Int32 _nX, sal_Int32 _nY ) throw(css::uno::RuntimeException, std::exception)
335 SolarMutexGuard aGuard;
337 VclPtr< RichTextControl > pControl = GetAs< RichTextControl >();
338 if ( !pControl )
339 return;
341 OutputDevice* pTargetDevice = VCLUnoHelper::GetOutputDevice( getGraphics() );
342 OSL_ENSURE( pTargetDevice != nullptr, "ORichTextPeer::draw: no graphics -> no drawing!" );
343 if ( !pTargetDevice )
344 return;
346 ::Size aSize = pControl->GetSizePixel();
347 const MapUnit eTargetUnit = pTargetDevice->GetMapMode().GetMapUnit();
348 if ( eTargetUnit != MAP_PIXEL )
349 aSize = pTargetDevice->PixelToLogic( aSize );
351 ::Point aPos( _nX, _nY );
352 // the XView::draw API talks about pixels, always ...
353 if ( eTargetUnit != MAP_PIXEL )
354 aPos = pTargetDevice->PixelToLogic( aPos );
356 pControl->Draw( pTargetDevice, aPos, aSize, DrawFlags::NoControls );
360 void SAL_CALL ORichTextPeer::setProperty( const OUString& _rPropertyName, const Any& _rValue )
361 throw (RuntimeException,
362 std::exception)
364 SolarMutexGuard g;
366 if ( !GetWindow() )
368 VCLXWindow::setProperty( _rPropertyName, _rValue );
369 return;
372 if ( _rPropertyName == PROPERTY_BACKGROUNDCOLOR )
374 VclPtr< RichTextControl > pControl = GetAs< RichTextControl >();
375 if ( !_rValue.hasValue() )
377 pControl->SetBackgroundColor( );
379 else
381 sal_Int32 nColor = COL_TRANSPARENT;
382 _rValue >>= nColor;
383 pControl->SetBackgroundColor( Color( nColor ) );
386 else if ( _rPropertyName == PROPERTY_HSCROLL )
388 adjustTwoStateWinBit( GetWindow(), _rValue, WB_HSCROLL );
390 else if ( _rPropertyName == PROPERTY_VSCROLL )
392 adjustTwoStateWinBit( GetWindow(), _rValue, WB_VSCROLL );
394 else if ( _rPropertyName == PROPERTY_HARDLINEBREAKS )
396 adjustTwoStateWinBit( GetWindow(), _rValue, WB_WORDBREAK, true );
398 else if ( _rPropertyName == PROPERTY_READONLY )
400 VclPtr< RichTextControl > pControl = GetAs< RichTextControl >();
401 bool bReadOnly( pControl->IsReadOnly() );
402 OSL_VERIFY( _rValue >>= bReadOnly );
403 pControl->SetReadOnly( bReadOnly );
405 // update the dispatchers
406 for ( AttributeDispatchers::iterator aDispatcherLoop = m_aDispatchers.begin();
407 aDispatcherLoop != m_aDispatchers.end();
408 ++aDispatcherLoop
411 aDispatcherLoop->second->invalidate();
414 else if ( _rPropertyName == PROPERTY_HIDEINACTIVESELECTION )
416 VclPtr< RichTextControl > pRichTextControl = GetAs< RichTextControl >();
417 bool bHide = pRichTextControl->GetHideInactiveSelection();
418 OSL_VERIFY( _rValue >>= bHide );
419 pRichTextControl->SetHideInactiveSelection( bHide );
421 else
422 VCLXWindow::setProperty( _rPropertyName, _rValue );
426 IMPLEMENT_FORWARD_XINTERFACE2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
429 IMPLEMENT_FORWARD_XTYPEPROVIDER2( ORichTextPeer, VCLXWindow, ORichTextPeer_Base )
432 namespace
434 SfxSlotId lcl_translateConflictingSlot( SfxSlotId _nIDFromPool )
436 // HACK HACK HACK
437 // unfortunately, some of our applications have some conflicting slots,
438 // i.e. slots which have the same UNO name as an existing other (common)
439 // slot.
440 // For instance, both the slots SID_SET_SUPER_SCRIPT (from SVX) and FN_SET_SUPER_SCRIPT
441 // (from SW) have the UNO name "SuperScript".
442 // Now, if the controls lives in a text document, and asks the SfxSlotPool for
443 // the id belonging to "SuperScript", it gets the FN_SET_SUPER_SCRIPT - which
444 // is completely unknown to the EditEngine.
445 // So, we need to translate such conflicting ids.
447 // Note that the real solution would be to fix the applications to
448 // *not* define conflicting slots. Alternatively, if SFX would provide a slot pool
449 // which is *static* (i.e. independent on the active application), then we
450 // would also never encounter such a conflict.
451 SfxSlotId nReturn( _nIDFromPool );
452 switch ( _nIDFromPool )
454 case 20411: /* FM_SET_SUPER_SCRIPT, originating in SW */
455 nReturn = SID_SET_SUPER_SCRIPT;
456 break;
457 case 20412: /* FN_SET_SUB_SCRIPT, originating in SW */
458 nReturn = SID_SET_SUB_SCRIPT;
459 break;
461 return nReturn;
466 ORichTextPeer::SingleAttributeDispatcher ORichTextPeer::implCreateDispatcher( SfxSlotId _nSlotId, const css::util::URL& _rURL )
468 VclPtr< RichTextControl > pRichTextControl = GetAs< RichTextControl >();
469 OSL_PRECOND( pRichTextControl, "ORichTextPeer::implCreateDispatcher: invalid window!" );
470 if ( !pRichTextControl )
471 return SingleAttributeDispatcher( nullptr );
473 ORichTextFeatureDispatcher* pDispatcher = nullptr;
474 OAttributeDispatcher* pAttributeDispatcher = nullptr;
475 switch ( _nSlotId )
477 case SID_CUT:
478 pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCut );
479 break;
481 case SID_COPY:
482 pDispatcher = new OClipboardDispatcher( pRichTextControl->getView(), OClipboardDispatcher::eCopy );
483 break;
485 case SID_PASTE:
486 pDispatcher = new OPasteClipboardDispatcher( pRichTextControl->getView() );
487 break;
489 case SID_SELECTALL:
490 pDispatcher = new OSelectAllDispatcher( pRichTextControl->getView(), _rURL );
491 break;
493 case SID_ATTR_PARA_LEFT_TO_RIGHT:
494 case SID_ATTR_PARA_RIGHT_TO_LEFT:
495 pAttributeDispatcher = new OParagraphDirectionDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
496 break;
498 case SID_TEXTDIRECTION_TOP_TO_BOTTOM:
499 case SID_TEXTDIRECTION_LEFT_TO_RIGHT:
500 pDispatcher = new OTextDirectionDispatcher( pRichTextControl->getView(), _rURL );
501 break;
503 case SID_ATTR_PARA_HANGPUNCTUATION:
504 case SID_ATTR_PARA_FORBIDDEN_RULES:
505 case SID_ATTR_PARA_SCRIPTSPACE:
506 pAttributeDispatcher = new OAsianFontLayoutDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
507 break;
509 default:
511 const SfxItemPool& rPool = *pRichTextControl->getView().GetEmptyItemSet().GetPool();
512 bool bSupportedSlot = rPool.IsInRange( rPool.GetWhich( _nSlotId ) );
514 if ( !bSupportedSlot )
515 bSupportedSlot = RichTextControl::isMappableSlot( _nSlotId );
517 if ( bSupportedSlot )
518 { // it's really a slot which is supported by the EditEngine
520 bool bNeedParametrizedDispatcher = true;
521 if ( ( _nSlotId == SID_ATTR_CHAR_POSTURE )
522 || ( _nSlotId == SID_ATTR_CHAR_CJK_POSTURE )
523 || ( _nSlotId == SID_ATTR_CHAR_CTL_POSTURE )
524 || ( _nSlotId == SID_ATTR_CHAR_LATIN_POSTURE )
525 || ( _nSlotId == SID_ATTR_CHAR_WEIGHT )
526 || ( _nSlotId == SID_ATTR_CHAR_CJK_WEIGHT )
527 || ( _nSlotId == SID_ATTR_CHAR_CTL_WEIGHT )
528 || ( _nSlotId == SID_ATTR_CHAR_LATIN_WEIGHT )
529 || ( _nSlotId == SID_ATTR_CHAR_LANGUAGE )
530 || ( _nSlotId == SID_ATTR_CHAR_CJK_LANGUAGE )
531 || ( _nSlotId == SID_ATTR_CHAR_CTL_LANGUAGE )
532 || ( _nSlotId == SID_ATTR_CHAR_LATIN_LANGUAGE )
533 || ( _nSlotId == SID_ATTR_CHAR_CONTOUR )
534 || ( _nSlotId == SID_ATTR_CHAR_SHADOWED )
535 || ( _nSlotId == SID_ATTR_CHAR_WORDLINEMODE )
536 || ( _nSlotId == SID_ATTR_CHAR_COLOR )
537 || ( _nSlotId == SID_ATTR_CHAR_RELIEF )
538 || ( _nSlotId == SID_ATTR_CHAR_KERNING )
539 || ( _nSlotId == SID_ATTR_CHAR_AUTOKERN )
540 || ( _nSlotId == SID_ATTR_CHAR_SCALEWIDTH )
543 bNeedParametrizedDispatcher = true;
545 else
547 SfxSlotPool& rSlotPool = SfxSlotPool::GetSlotPool();
548 const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId );
549 const SfxType* pType = pSlot ? pSlot->GetType() : nullptr;
550 if ( pType )
552 bNeedParametrizedDispatcher = ( pType->nAttribs > 0 );
556 if ( bNeedParametrizedDispatcher )
558 #if OSL_DEBUG_LEVEL > 0
559 OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *parametrized* dispatcher for " );
560 sTrace += OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
561 OSL_TRACE( "%s", sTrace.getStr() );
562 #endif
563 pAttributeDispatcher = new OParametrizedAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
565 else
567 #if OSL_DEBUG_LEVEL > 0
568 OString sTrace( "ORichTextPeer::implCreateDispatcher: creating *normal* dispatcher for " );
569 sTrace += OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
570 OSL_TRACE( "%s", sTrace.getStr() );
571 #endif
572 pAttributeDispatcher = new OAttributeDispatcher( pRichTextControl->getView(), _nSlotId, _rURL, pRichTextControl );
575 #if OSL_DEBUG_LEVEL > 0
576 else
578 OString sTrace( "ORichTextPeer::implCreateDispatcher: not creating dispatcher (unsupported slot) for " );
579 sTrace += OString( _rURL.Complete.getStr(), _rURL.Complete.getLength(), RTL_TEXTENCODING_ASCII_US );
580 OSL_TRACE( "%s", sTrace.getStr() );
582 #endif
584 break;
587 SingleAttributeDispatcher xDispatcher( pDispatcher );
588 if ( pAttributeDispatcher )
590 xDispatcher = SingleAttributeDispatcher( pAttributeDispatcher );
591 pRichTextControl->enableAttributeNotification( _nSlotId, pAttributeDispatcher );
594 return xDispatcher;
598 namespace
600 SfxSlotId lcl_getSlotFromUnoName( SfxSlotPool& _rSlotPool, const OUString& _rUnoSlotName )
602 const SfxSlot* pSlot = _rSlotPool.GetUnoSlot( _rUnoSlotName );
603 if ( pSlot )
605 // okay, there's a slot with the given UNO name
606 return lcl_translateConflictingSlot( pSlot->GetSlotId() );
609 // some hard-coded slots, which do not have a UNO name at SFX level, but which
610 // we nevertheless need to transport via UNO mechanisms, so we need a name
611 if ( _rUnoSlotName == "AllowHangingPunctuation" )
612 return SID_ATTR_PARA_HANGPUNCTUATION;
613 if ( _rUnoSlotName == "ApplyForbiddenCharacterRules" )
614 return SID_ATTR_PARA_FORBIDDEN_RULES;
615 if ( _rUnoSlotName == "UseScriptSpacing" )
616 return SID_ATTR_PARA_SCRIPTSPACE;
618 OSL_ENSURE( pSlot, "lcl_getSlotFromUnoName: unknown UNO slot name!" );
619 return 0;
624 Reference< XDispatch > SAL_CALL ORichTextPeer::queryDispatch( const css::util::URL& _rURL, const OUString& /*_rTargetFrameName*/, sal_Int32 /*_nSearchFlags*/ ) throw (RuntimeException, std::exception)
626 Reference< XDispatch > xReturn;
627 if ( !GetWindow() )
629 OSL_FAIL( "ORichTextPeer::queryDispatch: already disposed?" );
630 return xReturn;
633 // is it an UNO slot?
634 OUString sUnoProtocolPrefix( ".uno:" );
635 if ( _rURL.Complete.startsWith( sUnoProtocolPrefix ) )
637 OUString sUnoSlotName = _rURL.Complete.copy( sUnoProtocolPrefix.getLength() );
638 SfxSlotId nSlotId = lcl_getSlotFromUnoName( SfxSlotPool::GetSlotPool(), sUnoSlotName );
639 if ( nSlotId > 0 )
641 // do we already have a dispatcher for this?
642 AttributeDispatchers::const_iterator aDispatcherPos = m_aDispatchers.find( nSlotId );
643 if ( aDispatcherPos == m_aDispatchers.end() )
645 SingleAttributeDispatcher pDispatcher = implCreateDispatcher( nSlotId, _rURL );
646 if ( pDispatcher.is() )
648 aDispatcherPos = m_aDispatchers.insert( AttributeDispatchers::value_type( nSlotId, pDispatcher ) ).first;
652 if ( aDispatcherPos != m_aDispatchers.end() )
653 xReturn = aDispatcherPos->second.get();
657 return xReturn;
661 Sequence< Reference< XDispatch > > SAL_CALL ORichTextPeer::queryDispatches( const Sequence< DispatchDescriptor >& _rRequests ) throw (RuntimeException, std::exception)
663 Sequence< Reference< XDispatch > > aReturn( _rRequests.getLength() );
664 Reference< XDispatch >* pReturn = aReturn.getArray();
666 const DispatchDescriptor* pRequest = _rRequests.getConstArray();
667 const DispatchDescriptor* pRequestEnd = pRequest + _rRequests.getLength();
668 for ( ; pRequest != pRequestEnd; ++pRequest, ++pReturn )
670 *pReturn = queryDispatch( pRequest->FeatureURL, pRequest->FrameName, pRequest->SearchFlags );
672 return aReturn;
676 void ORichTextPeer::onSelectionChanged( const ESelection& /*_rSelection*/ )
678 AttributeDispatchers::iterator aDispatcherPos = m_aDispatchers.find( SID_COPY );
679 if ( aDispatcherPos != m_aDispatchers.end() )
680 aDispatcherPos->second.get()->invalidate();
682 aDispatcherPos = m_aDispatchers.find( SID_CUT );
683 if ( aDispatcherPos != m_aDispatchers.end() )
684 aDispatcherPos->second.get()->invalidate();
688 } // namespace frm
690 extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface* SAL_CALL
691 com_sun_star_comp_form_ORichTextControl_get_implementation(css::uno::XComponentContext*,
692 css::uno::Sequence<css::uno::Any> const &)
694 return cppu::acquire(new frm::ORichTextControl());
697 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */