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 .
22 #include "svx/fmresids.hrc"
23 #include "fmtextcontroldialogs.hxx"
24 #include "fmtextcontrolfeature.hxx"
25 #include "fmtextcontrolshell.hxx"
26 #include "editeng/crossedoutitem.hxx"
27 #include "svx/dialmgr.hxx"
28 #include "editeng/editeng.hxx"
29 #include "editeng/eeitem.hxx"
30 #include "svx/fmglob.hxx"
31 #include "editeng/scriptspaceitem.hxx"
32 #include "svx/svxids.hrc"
33 #include "editeng/udlnitem.hxx"
35 #include <com/sun/star/beans/XPropertySet.hpp>
36 #include <com/sun/star/awt/FontDescriptor.hpp>
37 #include <com/sun/star/frame/XDispatchProvider.hpp>
38 #include <com/sun/star/form/XForm.hpp>
39 #include <com/sun/star/container/XChild.hpp>
40 #include <com/sun/star/awt/XFocusListener.hpp>
41 #include <com/sun/star/awt/XMouseListener.hpp>
42 #include <com/sun/star/util/URLTransformer.hpp>
44 #include <comphelper/componentcontext.hxx>
45 #include <comphelper/processfactory.hxx>
46 #include <cppuhelper/implbase1.hxx>
47 #include <sfx2/app.hxx>
48 #include <sfx2/bindings.hxx>
49 #include <sfx2/dispatch.hxx>
50 #include <sfx2/msgpool.hxx>
51 #include <sfx2/objsh.hxx>
52 #include <sfx2/request.hxx>
53 #include <sfx2/sfxuno.hxx>
54 #include <sfx2/viewfrm.hxx>
55 #include <svl/eitem.hxx>
56 #include <svl/intitem.hxx>
57 #include <svl/itempool.hxx>
58 #include <svl/languageoptions.hxx>
59 #include <svtools/stringtransfer.hxx>
60 #include <svl/whiter.hxx>
61 #include <toolkit/helper/vclunohelper.hxx>
62 #include <tools/diagnose_ex.h>
63 #include <vcl/msgbox.hxx>
64 #include <vcl/outdev.hxx>
65 #include <osl/mutex.hxx>
69 //........................................................................
72 //........................................................................
74 using namespace ::com::sun::star
;
75 using namespace ::com::sun::star::uno
;
76 using namespace ::com::sun::star::awt
;
77 using namespace ::com::sun::star::form
;
78 using namespace ::com::sun::star::form::runtime
;
79 using namespace ::com::sun::star::lang
;
80 using namespace ::com::sun::star::frame
;
81 using namespace ::com::sun::star::util
;
82 using namespace ::com::sun::star::beans
;
83 using namespace ::com::sun::star::container
;
85 //====================================================================
86 typedef sal_uInt16 WhichId
;
88 //====================================================================
89 static SfxSlotId pTextControlSlots
[] =
91 SID_CLIPBOARD_FORMAT_ITEMS
,
96 // SID_ATTR_TABSTOP, /* 2 */
98 SID_ATTR_CHAR_POSTURE
,
100 SID_ATTR_CHAR_SHADOWED
,
101 SID_ATTR_CHAR_WORDLINEMODE
,
102 SID_ATTR_CHAR_CONTOUR
,
103 SID_ATTR_CHAR_STRIKEOUT
,
104 SID_ATTR_CHAR_UNDERLINE
,
105 SID_ATTR_CHAR_FONTHEIGHT
,
107 SID_ATTR_CHAR_KERNING
,
108 SID_ATTR_CHAR_LANGUAGE
, /* 20 */
109 SID_ATTR_CHAR_ESCAPEMENT
,
110 SID_ATTR_PARA_ADJUST
, /* 28 */
111 SID_ATTR_PARA_ADJUST_LEFT
,
112 SID_ATTR_PARA_ADJUST_RIGHT
,
113 SID_ATTR_PARA_ADJUST_CENTER
,
114 SID_ATTR_PARA_ADJUST_BLOCK
,
115 SID_ATTR_PARA_LINESPACE
, /* 33 */
116 SID_ATTR_PARA_LINESPACE_10
,
117 SID_ATTR_PARA_LINESPACE_15
,
118 SID_ATTR_PARA_LINESPACE_20
,
119 SID_ATTR_LRSPACE
, /* 48 */
120 SID_ATTR_ULSPACE
, /* 49 */
121 SID_ATTR_CHAR_AUTOKERN
,
122 SID_SET_SUPER_SCRIPT
,
126 // SID_TEXTDIRECTION_LEFT_TO_RIGHT, /* 907 */
127 // SID_TEXTDIRECTION_TOP_TO_BOTTOM,
128 SID_ATTR_CHAR_SCALEWIDTH
, /* 911 */
129 SID_ATTR_CHAR_RELIEF
,
130 SID_ATTR_PARA_LEFT_TO_RIGHT
, /* 950 */
131 SID_ATTR_PARA_RIGHT_TO_LEFT
,
132 SID_ATTR_CHAR_OVERLINE
,
136 // slots which we are not responsible for on the SfxShell level, but
137 // need to handle during the "paragraph attributes" and/or "character
138 // attributes" dialogs
139 static SfxSlotId pDialogSlots
[] =
142 SID_ATTR_PARA_HANGPUNCTUATION
,
143 SID_ATTR_PARA_FORBIDDEN_RULES
,
144 SID_ATTR_PARA_SCRIPTSPACE
,
145 SID_ATTR_CHAR_LATIN_LANGUAGE
,
146 SID_ATTR_CHAR_CJK_LANGUAGE
,
147 SID_ATTR_CHAR_CTL_LANGUAGE
,
148 SID_ATTR_CHAR_LATIN_FONT
,
149 SID_ATTR_CHAR_CJK_FONT
,
150 SID_ATTR_CHAR_CTL_FONT
,
151 SID_ATTR_CHAR_LATIN_FONTHEIGHT
,
152 SID_ATTR_CHAR_CJK_FONTHEIGHT
,
153 SID_ATTR_CHAR_CTL_FONTHEIGHT
,
154 SID_ATTR_CHAR_LATIN_WEIGHT
,
155 SID_ATTR_CHAR_CJK_WEIGHT
,
156 SID_ATTR_CHAR_CTL_WEIGHT
,
157 SID_ATTR_CHAR_LATIN_POSTURE
,
158 SID_ATTR_CHAR_CJK_POSTURE
,
159 SID_ATTR_CHAR_CTL_POSTURE
,
160 SID_ATTR_CHAR_EMPHASISMARK
,
164 //====================================================================
165 //= FmFocusListenerAdapter
166 //====================================================================
167 typedef ::cppu::WeakImplHelper1
< XFocusListener
168 > FmFocusListenerAdapter_Base
;
169 class FmFocusListenerAdapter
: public FmFocusListenerAdapter_Base
172 IFocusObserver
* m_pObserver
;
173 Reference
< XWindow
> m_xWindow
;
176 FmFocusListenerAdapter( const Reference
< XControl
>& _rxControl
, IFocusObserver
* _pObserver
);
178 // clean up the instance
182 ~FmFocusListenerAdapter();
185 virtual void SAL_CALL
focusGained( const FocusEvent
& e
) throw (RuntimeException
);
186 virtual void SAL_CALL
focusLost( const FocusEvent
& e
) throw (RuntimeException
);
187 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
190 //--------------------------------------------------------------------
191 DBG_NAME( FmFocusListenerAdapter
)
192 //--------------------------------------------------------------------
193 FmFocusListenerAdapter::FmFocusListenerAdapter( const Reference
< XControl
>& _rxControl
, IFocusObserver
* _pObserver
)
194 :m_pObserver( _pObserver
)
195 ,m_xWindow( _rxControl
, UNO_QUERY
)
197 DBG_CTOR( FmFocusListenerAdapter
, NULL
);
199 DBG_ASSERT( m_xWindow
.is(), "FmFocusListenerAdapter::FmFocusListenerAdapter: invalid control!" );
200 osl_atomic_increment( &m_refCount
);
204 if ( m_xWindow
.is() )
205 m_xWindow
->addFocusListener( this );
207 catch( const Exception
& )
209 DBG_UNHANDLED_EXCEPTION();
212 osl_atomic_decrement( &m_refCount
);
215 //--------------------------------------------------------------------
216 FmFocusListenerAdapter::~FmFocusListenerAdapter()
221 DBG_DTOR( FmFocusListenerAdapter
, NULL
);
224 //--------------------------------------------------------------------
225 void FmFocusListenerAdapter::dispose()
227 if ( m_xWindow
.is() )
229 m_xWindow
->removeFocusListener( this );
234 //--------------------------------------------------------------------
235 void SAL_CALL
FmFocusListenerAdapter::focusGained( const FocusEvent
& e
) throw (RuntimeException
)
238 m_pObserver
->focusGained( e
);
241 //--------------------------------------------------------------------
242 void SAL_CALL
FmFocusListenerAdapter::focusLost( const FocusEvent
& e
) throw (RuntimeException
)
245 m_pObserver
->focusLost( e
);
248 //--------------------------------------------------------------------
249 void SAL_CALL
FmFocusListenerAdapter::disposing( const EventObject
& Source
) throw (RuntimeException
)
252 DBG_ASSERT( Source
.Source
== m_xWindow
, "FmFocusListenerAdapter::disposing: where did this come from?" );
256 //====================================================================
257 //= FmMouseListenerAdapter
258 //====================================================================
259 typedef ::cppu::WeakImplHelper1
< XMouseListener
260 > FmMouseListenerAdapter_Base
;
261 class FmMouseListenerAdapter
: public FmMouseListenerAdapter_Base
264 IContextRequestObserver
* m_pObserver
;
265 Reference
< XWindow
> m_xWindow
;
268 FmMouseListenerAdapter( const Reference
< XControl
>& _rxControl
, IContextRequestObserver
* _pObserver
);
270 // clean up the instance
274 ~FmMouseListenerAdapter();
277 virtual void SAL_CALL
mousePressed( const awt::MouseEvent
& e
) throw (RuntimeException
);
278 virtual void SAL_CALL
mouseReleased( const awt::MouseEvent
& e
) throw (RuntimeException
);
279 virtual void SAL_CALL
mouseEntered( const awt::MouseEvent
& e
) throw (RuntimeException
);
280 virtual void SAL_CALL
mouseExited( const awt::MouseEvent
& e
) throw (RuntimeException
);
281 virtual void SAL_CALL
disposing( const EventObject
& Source
) throw (RuntimeException
);
284 //====================================================================
285 //= FmMouseListenerAdapter
286 //====================================================================
287 //--------------------------------------------------------------------
288 DBG_NAME( FmMouseListenerAdapter
)
289 //--------------------------------------------------------------------
290 FmMouseListenerAdapter::FmMouseListenerAdapter( const Reference
< XControl
>& _rxControl
, IContextRequestObserver
* _pObserver
)
291 :m_pObserver( _pObserver
)
292 ,m_xWindow( _rxControl
, UNO_QUERY
)
294 DBG_CTOR( FmMouseListenerAdapter
, NULL
);
296 DBG_ASSERT( m_xWindow
.is(), "FmMouseListenerAdapter::FmMouseListenerAdapter: invalid control!" );
297 osl_atomic_increment( &m_refCount
);
301 if ( m_xWindow
.is() )
302 m_xWindow
->addMouseListener( this );
304 catch( const Exception
& )
306 DBG_UNHANDLED_EXCEPTION();
309 osl_atomic_decrement( &m_refCount
);
312 //--------------------------------------------------------------------
313 FmMouseListenerAdapter::~FmMouseListenerAdapter()
318 DBG_DTOR( FmMouseListenerAdapter
, NULL
);
321 //--------------------------------------------------------------------
322 void FmMouseListenerAdapter::dispose()
324 if ( m_xWindow
.is() )
326 m_xWindow
->removeMouseListener( this );
331 //--------------------------------------------------------------------
332 void SAL_CALL
FmMouseListenerAdapter::mousePressed( const awt::MouseEvent
& _rEvent
) throw (::com::sun::star::uno::RuntimeException
)
334 SolarMutexGuard aGuard
;
335 // is this a request for a context menu?
336 if ( _rEvent
.PopupTrigger
)
339 m_pObserver
->contextMenuRequested( _rEvent
);
343 //--------------------------------------------------------------------
344 void SAL_CALL
FmMouseListenerAdapter::mouseReleased( const awt::MouseEvent
& /*e*/ ) throw (::com::sun::star::uno::RuntimeException
)
349 //--------------------------------------------------------------------
350 void SAL_CALL
FmMouseListenerAdapter::mouseEntered( const awt::MouseEvent
& /*e*/ ) throw (::com::sun::star::uno::RuntimeException
)
355 //--------------------------------------------------------------------
356 void SAL_CALL
FmMouseListenerAdapter::mouseExited( const awt::MouseEvent
& /*e*/ ) throw (::com::sun::star::uno::RuntimeException
)
361 //--------------------------------------------------------------------
362 void SAL_CALL
FmMouseListenerAdapter::disposing( const EventObject
& Source
) throw (RuntimeException
)
365 DBG_ASSERT( Source
.Source
== m_xWindow
, "FmMouseListenerAdapter::disposing: where did this come from?" );
369 //====================================================================
370 //= FmTextControlShell
371 //====================================================================
372 //------------------------------------------------------------------------
375 //....................................................................
376 void lcl_translateUnoStateToItem( SfxSlotId _nSlot
, const Any
& _rUnoState
, SfxItemSet
& _rSet
)
378 WhichId nWhich
= _rSet
.GetPool()->GetWhich( _nSlot
);
379 if ( !_rUnoState
.hasValue() )
381 if ( ( _nSlot
!= SID_CUT
)
382 && ( _nSlot
!= SID_COPY
)
383 && ( _nSlot
!= SID_PASTE
)
386 _rSet
.InvalidateItem( nWhich
);
391 switch ( _rUnoState
.getValueType().getTypeClass() )
393 case TypeClass_BOOLEAN
:
395 sal_Bool bState
= sal_False
;
396 _rUnoState
>>= bState
;
397 if ( _nSlot
== SID_ATTR_PARA_SCRIPTSPACE
)
398 _rSet
.Put( SvxScriptSpaceItem( bState
, nWhich
) );
400 _rSet
.Put( SfxBoolItem( nWhich
, bState
) );
406 Sequence
< PropertyValue
> aComplexState
;
407 if ( _rUnoState
>>= aComplexState
)
409 if ( !aComplexState
.getLength() )
410 _rSet
.InvalidateItem( nWhich
);
413 SfxAllItemSet
aAllItems( _rSet
);
414 TransformParameters( _nSlot
, aComplexState
, aAllItems
);
415 const SfxPoolItem
* pTransformed
= aAllItems
.GetItem( nWhich
);
416 OSL_ENSURE( pTransformed
, "lcl_translateUnoStateToItem: non-empty parameter sequence leading to empty item?" );
418 _rSet
.Put( *pTransformed
);
420 _rSet
.InvalidateItem( nWhich
);
425 OSL_FAIL( "lcl_translateUnoStateToItem: invalid state!" );
432 //....................................................................
433 OUString
lcl_getUnoSlotName( SfxApplication
&, SfxSlotId _nSlotId
)
435 OUString sSlotUnoName
;
437 SfxSlotPool
& rSlotPool
= SfxSlotPool::GetSlotPool( NULL
);
438 const SfxSlot
* pSlot
= rSlotPool
.GetSlot( _nSlotId
);
440 const sal_Char
* pAsciiUnoName
= NULL
;
443 pAsciiUnoName
= pSlot
->GetUnoName();
447 // some hard-coded slots, which do not have a UNO name at SFX level, but which
448 // we nevertheless need to transport via UNO mechanisms, so we need a name
451 case SID_ATTR_PARA_HANGPUNCTUATION
: pAsciiUnoName
= "AllowHangingPunctuation"; break;
452 case SID_ATTR_PARA_FORBIDDEN_RULES
: pAsciiUnoName
= "ApplyForbiddenCharacterRules"; break;
453 case SID_ATTR_PARA_SCRIPTSPACE
: pAsciiUnoName
= "UseScriptSpacing"; break;
459 sSlotUnoName
= OUString( ".uno:" );
460 sSlotUnoName
+= OUString::createFromAscii( pAsciiUnoName
);
462 #if OSL_DEBUG_LEVEL > 0
465 OString
sMessage( "lcl_getUnoSlotName: invalid slot id, or invalid slot, or no UNO name!\n" );
466 sMessage
+= "(slot id: ";
467 sMessage
+= OString::valueOf( (sal_Int32
)_nSlotId
);
469 OSL_FAIL( sMessage
.getStr() );
475 //....................................................................
476 bool lcl_determineReadOnly( const Reference
< XControl
>& _rxControl
)
478 bool bIsReadOnlyModel
= true;
481 Reference
< XPropertySet
> xModelProps
;
482 if ( _rxControl
.is() )
483 xModelProps
= xModelProps
.query( _rxControl
->getModel() );
484 Reference
< XPropertySetInfo
> xModelPropInfo
;
485 if ( xModelProps
.is() )
486 xModelPropInfo
= xModelProps
->getPropertySetInfo();
488 if ( !xModelPropInfo
.is() || !xModelPropInfo
->hasPropertyByName( FM_PROP_READONLY
) )
489 bIsReadOnlyModel
= true;
492 sal_Bool bReadOnly
= sal_True
;
493 xModelProps
->getPropertyValue( FM_PROP_READONLY
) >>= bReadOnly
;
494 bIsReadOnlyModel
= bReadOnly
;
497 catch( const Exception
& )
499 DBG_UNHANDLED_EXCEPTION();
501 return bIsReadOnlyModel
;
504 //....................................................................
505 static Window
* lcl_getWindow( const Reference
< XControl
>& _rxControl
)
507 Window
* pWindow
= NULL
;
510 Reference
< XWindowPeer
> xControlPeer
;
511 if ( _rxControl
.is() )
512 xControlPeer
= _rxControl
->getPeer();
513 if ( xControlPeer
.is() )
514 pWindow
= VCLUnoHelper::GetWindow( xControlPeer
);
516 catch( const Exception
& )
518 DBG_UNHANDLED_EXCEPTION();
524 //....................................................................
525 bool lcl_isRichText( const Reference
< XControl
>& _rxControl
)
527 if ( !_rxControl
.is() )
530 bool bIsRichText
= false;
533 Reference
< XPropertySet
> xModelProps( _rxControl
->getModel(), UNO_QUERY
);
534 Reference
< XPropertySetInfo
> xPSI
;
535 if ( xModelProps
.is() )
536 xPSI
= xModelProps
->getPropertySetInfo();
537 OUString sRichTextPropertyName
= OUString( "RichText" );
538 if ( xPSI
.is() && xPSI
->hasPropertyByName( sRichTextPropertyName
) )
540 OSL_VERIFY( xModelProps
->getPropertyValue( sRichTextPropertyName
) >>= bIsRichText
);
543 catch( const Exception
& )
545 DBG_UNHANDLED_EXCEPTION();
551 //------------------------------------------------------------------------
552 FmTextControlShell::FmTextControlShell( SfxViewFrame
* _pFrame
)
553 :m_bActiveControl( false )
554 ,m_bActiveControlIsReadOnly( true )
555 ,m_bActiveControlIsRichText( false )
556 ,m_pViewFrame( _pFrame
)
557 ,m_rBindings( _pFrame
->GetBindings() )
558 ,m_bNeedClipboardInvalidation( true )
560 m_aClipboardInvalidation
.SetTimeoutHdl( LINK( this, FmTextControlShell
, OnInvalidateClipboard
) );
561 m_aClipboardInvalidation
.SetTimeout( 200 );
564 //------------------------------------------------------------------------
565 FmTextControlShell::~FmTextControlShell()
570 //------------------------------------------------------------------------
571 IMPL_LINK( FmTextControlShell
, OnInvalidateClipboard
, void*, /*_pNotInterestedIn*/ )
573 if ( m_bNeedClipboardInvalidation
)
575 OSL_TRACE( "FmTextControlShell::ClipBoard: invalidating clipboard slots" );
576 m_rBindings
.Invalidate( SID_CUT
);
577 m_rBindings
.Invalidate( SID_COPY
);
578 m_rBindings
.Invalidate( SID_PASTE
);
579 m_bNeedClipboardInvalidation
= false;
584 //------------------------------------------------------------------------
585 void FmTextControlShell::transferFeatureStatesToItemSet( ControlFeatures
& _rDispatchers
, SfxAllItemSet
& _rSet
, bool _bTranslateLatin
)
587 SfxItemPool
& rPool
= *_rSet
.GetPool();
589 for ( ControlFeatures::const_iterator aFeature
= _rDispatchers
.begin();
590 aFeature
!= _rDispatchers
.end();
594 SfxSlotId
nSlotId( aFeature
->first
);
595 #if OSL_DEBUG_LEVEL > 0
596 OUString sUnoSlotName
;
598 sUnoSlotName
= lcl_getUnoSlotName( *SFX_APP(), nSlotId
);
600 sUnoSlotName
= OUString( "<unknown>" );
601 OString
sUnoSlotNameAscii( "\"" );
602 sUnoSlotNameAscii
+= OString( sUnoSlotName
.getStr(), sUnoSlotName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
603 sUnoSlotNameAscii
+= "\"";
606 if ( _bTranslateLatin
)
608 // A rich text control offers a dispatcher for the "Font" slot/feature.
609 // Sadly, the semantics of the dispatches is that the feature "Font" depends
610 // on the current cursor position: If it's on latin text, it's the "latin font"
611 // which is set up at the control. If it's on CJK text, it's the "CJK font", and
612 // aequivalent for "CTL font".
613 // The same holds for some other font related features/slots.
614 // Thus, we have separate dispatches for "Latin Font", "Latin Font Size", etc,
615 // which are only "virtual", in a sense that there exist no item with this id.
616 // So when we encounter such a dispatcher for, say, "Latin Font", we need to
617 // put an item into the set which has the "Font" id.
621 case SID_ATTR_CHAR_LATIN_FONT
: nSlotId
= SID_ATTR_CHAR_FONT
; break;
622 case SID_ATTR_CHAR_LATIN_FONTHEIGHT
:nSlotId
= SID_ATTR_CHAR_FONTHEIGHT
; break;
623 case SID_ATTR_CHAR_LATIN_LANGUAGE
: nSlotId
= SID_ATTR_CHAR_LANGUAGE
; break;
624 case SID_ATTR_CHAR_LATIN_POSTURE
: nSlotId
= SID_ATTR_CHAR_POSTURE
; break;
625 case SID_ATTR_CHAR_LATIN_WEIGHT
: nSlotId
= SID_ATTR_CHAR_WEIGHT
; break;
629 WhichId nWhich
= rPool
.GetWhich( nSlotId
);
630 bool bIsInPool
= rPool
.IsInRange( nWhich
);
633 #if OSL_DEBUG_LEVEL > 0
634 bool bFeatureIsEnabled
= aFeature
->second
->isFeatureEnabled();
635 OString
sMessage( "FmTextControlShell::transferFeatureStatesToItemSet: found a feature state for " );
636 sMessage
+= sUnoSlotNameAscii
;
637 if ( !bFeatureIsEnabled
)
638 sMessage
+= " (disabled)";
639 OSL_TRACE( "%s", sMessage
.getStr() );
642 lcl_translateUnoStateToItem( nSlotId
, aFeature
->second
->getFeatureState(), _rSet
);
644 #if OSL_DEBUG_LEVEL > 0
647 OString
sMessage( "FmTextControlShell::transferFeatureStatesToItemSet: found a feature state for " );
648 sMessage
+= sUnoSlotNameAscii
;
649 sMessage
+= ", but could not translate it into an item!";
650 OSL_TRACE( "%s", sMessage
.getStr() );
656 //------------------------------------------------------------------------
657 void FmTextControlShell::executeAttributeDialog( AttributeSet _eSet
, SfxRequest
& _rReq
)
659 const SvxFontListItem
* pFontList
= PTR_CAST( SvxFontListItem
, m_pViewFrame
->GetObjectShell()->GetItem( SID_ATTR_CHAR_FONTLIST
) );
660 DBG_ASSERT( pFontList
, "FmTextControlShell::executeAttributeDialog: no font list item!" );
664 SfxItemPool
* pPool
= EditEngine::CreatePool();
665 pPool
->FreezeIdRanges();
666 ::std::auto_ptr
< SfxItemSet
> pPureItems( new SfxItemSet( *pPool
) );
668 // put the current states of the items into the set
669 ::std::auto_ptr
< SfxAllItemSet
> pCurrentItems( new SfxAllItemSet( *pPureItems
) );
670 transferFeatureStatesToItemSet( m_aControlFeatures
, *pCurrentItems
);
672 // additional items, which we are not responsible for at the SfxShell level,
673 // but which need to be forwarded to the dialog, anyway
674 ControlFeatures aAdditionalFestures
;
675 fillFeatureDispatchers( m_xActiveControl
, pDialogSlots
, aAdditionalFestures
);
676 transferFeatureStatesToItemSet( aAdditionalFestures
, *pCurrentItems
, true );
678 ::std::auto_ptr
< SfxTabDialog
> pDialog ( _eSet
== eCharAttribs
679 ? static_cast< SfxTabDialog
* >( new TextControlCharAttribDialog( NULL
, *pCurrentItems
, *pFontList
) )
680 : static_cast< SfxTabDialog
* >( new TextControlParaAttribDialog( NULL
, *pCurrentItems
) ) );
681 if ( RET_OK
== pDialog
->Execute() )
683 const SfxItemSet
& rModifiedItems
= *pDialog
->GetOutputItemSet();
684 for ( WhichId nWhich
= pPool
->GetFirstWhich(); nWhich
<= pPool
->GetLastWhich(); ++nWhich
)
686 if ( rModifiedItems
.GetItemState( nWhich
) == SFX_ITEM_SET
)
688 SfxSlotId nSlotForItemSet
= pPool
->GetSlotId( nWhich
);
689 const SfxPoolItem
* pModifiedItem
= rModifiedItems
.GetItem( nWhich
);
692 SfxSlotId nSlotForDispatcher
= nSlotForItemSet
;
693 switch ( nSlotForDispatcher
)
695 case SID_ATTR_CHAR_FONT
: nSlotForDispatcher
= SID_ATTR_CHAR_LATIN_FONT
; break;
696 case SID_ATTR_CHAR_FONTHEIGHT
:nSlotForDispatcher
= SID_ATTR_CHAR_LATIN_FONTHEIGHT
; break;
697 case SID_ATTR_CHAR_LANGUAGE
: nSlotForDispatcher
= SID_ATTR_CHAR_LATIN_LANGUAGE
; break;
698 case SID_ATTR_CHAR_POSTURE
: nSlotForDispatcher
= SID_ATTR_CHAR_LATIN_POSTURE
; break;
699 case SID_ATTR_CHAR_WEIGHT
: nSlotForDispatcher
= SID_ATTR_CHAR_LATIN_WEIGHT
; break;
702 // do we already have a dispatcher for this slot/feature?
703 ControlFeatures::const_iterator aFeaturePos
= m_aControlFeatures
.find( nSlotForDispatcher
);
704 bool bFound
= aFeaturePos
!= m_aControlFeatures
.end( );
708 aFeaturePos
= aAdditionalFestures
.find( nSlotForDispatcher
);
709 bFound
= aFeaturePos
!= aAdditionalFestures
.end( );
714 Sequence
< PropertyValue
> aArgs
;
715 // temporarily put the modified item into a "clean" set,
716 // and let TransformItems calc the respective UNO parameters
717 pPureItems
->Put( *pModifiedItem
);
718 TransformItems( nSlotForItemSet
, *pPureItems
, aArgs
);
719 pPureItems
->ClearItem( nWhich
);
721 if ( ( nSlotForItemSet
== SID_ATTR_PARA_HANGPUNCTUATION
)
722 || ( nSlotForItemSet
== SID_ATTR_PARA_FORBIDDEN_RULES
)
723 || ( nSlotForItemSet
== SID_ATTR_PARA_SCRIPTSPACE
)
726 // these are no UNO slots, they need special handling since TransformItems cannot
728 DBG_ASSERT( aArgs
.getLength() == 0, "FmTextControlShell::executeAttributeDialog: these are no UNO slots - are they?" );
730 const SfxBoolItem
* pBoolItem
= PTR_CAST( SfxBoolItem
, pModifiedItem
);
731 DBG_ASSERT( pBoolItem
, "FmTextControlShell::executeAttributeDialog: no bool item?!" );
735 aArgs
[ 0 ].Name
= OUString( "Enable" );
736 aArgs
[ 0 ].Value
<<= (sal_Bool
)pBoolItem
->GetValue();
741 aFeaturePos
->second
->dispatch( aArgs
);
743 #if OSL_DEBUG_LEVEL > 0
746 OString
sError( "FmTextControShell::executeAttributeDialog: Could not handle the following item:" );
747 sError
+= "\n SlotID: "; sError
+= OString::valueOf( (sal_Int32
)nSlotForItemSet
);
748 sError
+= "\n WhichID: "; sError
+= OString::valueOf( (sal_Int32
)nWhich
);
749 sError
+= "\n UNO name: ";
751 OUString sUnoSlotName
= lcl_getUnoSlotName( *SFX_APP(), nSlotForItemSet
);
752 if ( !sUnoSlotName
.isEmpty() )
753 sError
+= OString( sUnoSlotName
.getStr(), sUnoSlotName
.getLength(), RTL_TEXTENCODING_ASCII_US
);
755 sError
+= "unknown (no SfxSlot)";
756 OSL_FAIL( sError
.getStr() );
761 _rReq
.Done( rModifiedItems
);
765 pCurrentItems
.reset();
767 SfxItemPool::Free(pPool
);
770 //------------------------------------------------------------------------
771 bool FmTextControlShell::executeSelectAll( )
775 if ( m_xActiveTextComponent
.is() )
777 sal_Int32 nTextLen
= m_xActiveTextComponent
->getText().getLength();
778 m_xActiveTextComponent
->setSelection( awt::Selection( 0, nTextLen
) );
782 catch( const Exception
& )
784 DBG_UNHANDLED_EXCEPTION();
786 return false; // not handled
789 //------------------------------------------------------------------------
790 bool FmTextControlShell::executeClipboardSlot( SfxSlotId _nSlot
)
794 if ( m_xActiveTextComponent
.is() )
801 OUString
sSelectedText( m_xActiveTextComponent
->getSelectedText() );
802 ::svt::OStringTransfer::CopyString( sSelectedText
, lcl_getWindow( m_xActiveControl
) );
803 if ( SID_CUT
== _nSlot
)
805 awt::Selection
aSelection( m_xActiveTextComponent
->getSelection() );
806 m_xActiveTextComponent
->insertText( aSelection
, OUString() );
812 OUString sClipboardContent
;
813 OSL_VERIFY( ::svt::OStringTransfer::PasteString( sClipboardContent
, lcl_getWindow( m_xActiveControl
) ) );
814 awt::Selection
aSelection( m_xActiveTextComponent
->getSelection() );
815 m_xActiveTextComponent
->insertText( aSelection
, sClipboardContent
);
819 OSL_FAIL( "FmTextControlShell::executeClipboardSlot: invalid slot!" );
824 catch( const Exception
& )
826 DBG_UNHANDLED_EXCEPTION();
828 return false; // not handled
831 //------------------------------------------------------------------------
832 void FmTextControlShell::ExecuteTextAttribute( SfxRequest
& _rReq
)
834 SfxSlotId nSlot
= _rReq
.GetSlot();
836 ControlFeatures::const_iterator aFeaturePos
= m_aControlFeatures
.find( nSlot
);
837 if ( aFeaturePos
== m_aControlFeatures
.end() )
843 executeAttributeDialog( eCharAttribs
, _rReq
);
847 executeAttributeDialog( eParaAttribs
, _rReq
);
857 executeClipboardSlot( nSlot
);
861 DBG_ASSERT( aFeaturePos
!= m_aControlFeatures
.end(), "FmTextControShell::ExecuteTextAttribute: I have no such dispatcher, and cannot handle it at all!" );
867 // slots which are dispatched to the control
871 case SID_ATTR_CHAR_STRIKEOUT
:
872 case SID_ATTR_CHAR_UNDERLINE
:
873 case SID_ATTR_CHAR_OVERLINE
:
875 SfxItemSet
aToggled( *_rReq
.GetArgs() );
877 lcl_translateUnoStateToItem( nSlot
, aFeaturePos
->second
->getFeatureState(), aToggled
);
878 WhichId nWhich
= aToggled
.GetPool()->GetWhich( nSlot
);
879 const SfxPoolItem
* pItem
= aToggled
.GetItem( nWhich
);
880 if ( ( SID_ATTR_CHAR_UNDERLINE
== nSlot
) || ( SID_ATTR_CHAR_OVERLINE
== nSlot
) )
882 const SvxOverlineItem
* pTextLine
= PTR_CAST( SvxOverlineItem
, pItem
);
883 DBG_ASSERT( pTextLine
, "FmTextControlShell::ExecuteTextAttribute: ooops - no underline/overline item!" );
886 FontUnderline eTL
= pTextLine
->GetLineStyle();
887 if ( SID_ATTR_CHAR_UNDERLINE
== nSlot
) {
888 aToggled
.Put( SvxUnderlineItem( eTL
== UNDERLINE_SINGLE
? UNDERLINE_NONE
: UNDERLINE_SINGLE
, nWhich
) );
890 aToggled
.Put( SvxOverlineItem( eTL
== UNDERLINE_SINGLE
? UNDERLINE_NONE
: UNDERLINE_SINGLE
, nWhich
) );
896 const SvxCrossedOutItem
* pCrossedOut
= PTR_CAST( SvxCrossedOutItem
, pItem
);
897 DBG_ASSERT( pCrossedOut
, "FmTextControlShell::ExecuteTextAttribute: ooops - no CrossedOut item!" );
900 FontStrikeout eFS
= pCrossedOut
->GetStrikeout();
901 aToggled
.Put( SvxCrossedOutItem( eFS
== STRIKEOUT_SINGLE
? STRIKEOUT_NONE
: STRIKEOUT_SINGLE
, nWhich
) );
905 Sequence
< PropertyValue
> aArguments
;
906 TransformItems( nSlot
, aToggled
, aArguments
);
907 aFeaturePos
->second
->dispatch( aArguments
);
911 case SID_ATTR_CHAR_FONTHEIGHT
:
912 case SID_ATTR_CHAR_FONT
:
913 case SID_ATTR_CHAR_POSTURE
:
914 case SID_ATTR_CHAR_WEIGHT
:
915 case SID_ATTR_CHAR_SHADOWED
:
916 case SID_ATTR_CHAR_CONTOUR
:
917 case SID_SET_SUPER_SCRIPT
:
918 case SID_SET_SUB_SCRIPT
:
920 const SfxItemSet
* pArgs
= _rReq
.GetArgs();
921 Sequence
< PropertyValue
> aArgs
;
923 TransformItems( nSlot
, *pArgs
, aArgs
);
924 aFeaturePos
->second
->dispatch( aArgs
);
929 if ( aFeaturePos
->second
->isFeatureEnabled() )
930 aFeaturePos
->second
->dispatch();
937 //------------------------------------------------------------------------
938 void FmTextControlShell::GetTextAttributeState( SfxItemSet
& _rSet
)
940 SfxWhichIter
aIter( _rSet
);
941 sal_uInt16 nSlot
= aIter
.FirstWhich();
944 if ( ( nSlot
== SID_ATTR_PARA_LEFT_TO_RIGHT
)
945 || ( nSlot
== SID_ATTR_PARA_RIGHT_TO_LEFT
)
948 if ( !SvtLanguageOptions().IsCTLFontEnabled() )
950 _rSet
.DisableItem( nSlot
);
951 nSlot
= aIter
.NextWhich();
956 ControlFeatures::const_iterator aFeaturePos
= m_aControlFeatures
.find( nSlot
);
957 if ( aFeaturePos
!= m_aControlFeatures
.end() )
959 if ( aFeaturePos
->second
->isFeatureEnabled() )
960 lcl_translateUnoStateToItem( nSlot
, aFeaturePos
->second
->getFeatureState(), _rSet
);
962 _rSet
.DisableItem( nSlot
);
966 bool bDisable
= false;
968 bool bNeedWriteableControl
= false;
969 bool bNeedTextComponent
= false;
970 bool bNeedSelection
= false;
976 bDisable
|= m_aControlFeatures
.empty();
977 bNeedWriteableControl
= true;
981 bNeedSelection
= true;
982 bNeedTextComponent
= true;
983 bNeedWriteableControl
= true;
984 OSL_TRACE( "FmTextControlShell::ClipBoard: need to invalidate again" );
985 m_bNeedClipboardInvalidation
= true;
990 Window
* pActiveControlVCLWindow
= lcl_getWindow( m_xActiveControl
);
991 if ( pActiveControlVCLWindow
)
993 TransferableDataHelper
aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pActiveControlVCLWindow
) );
994 bDisable
|= !aDataHelper
.HasFormat( SOT_FORMAT_STRING
);
999 bNeedTextComponent
= true;
1000 bNeedWriteableControl
= true;
1005 bNeedTextComponent
= true;
1006 bNeedSelection
= true;
1010 bNeedTextComponent
= true;
1014 // slot is unknown at all
1018 OSL_POSTCOND( !bNeedSelection
|| bNeedTextComponent
, "FmTextControlShell::GetTextAttributeState: bNeedSelection should imply bNeedTextComponent!" );
1020 if ( !bDisable
&& bNeedWriteableControl
)
1021 bDisable
|= !IsActiveControl( ) || m_bActiveControlIsReadOnly
;
1023 if ( !bDisable
&& bNeedTextComponent
)
1024 bDisable
|= !m_xActiveTextComponent
.is();
1026 if ( !bDisable
&& bNeedSelection
)
1028 awt::Selection aSelection
= m_xActiveTextComponent
->getSelection();
1029 bDisable
|= aSelection
.Min
== aSelection
.Max
;
1033 _rSet
.DisableItem( nSlot
);
1036 nSlot
= aIter
.NextWhich();
1040 //------------------------------------------------------------------------
1041 bool FmTextControlShell::IsActiveControl( bool _bCountRichTextOnly
) const
1043 if ( _bCountRichTextOnly
&& !m_bActiveControlIsRichText
)
1046 return m_bActiveControl
;
1049 //------------------------------------------------------------------------
1050 void FmTextControlShell::dispose()
1052 if ( IsActiveControl() )
1053 controlDeactivated();
1054 if ( isControllerListening() )
1055 stopControllerListening();
1058 //------------------------------------------------------------------------
1059 void FmTextControlShell::designModeChanged( bool /*_bNewDesignMode*/ )
1061 m_rBindings
.Invalidate( pTextControlSlots
);
1064 //------------------------------------------------------------------------
1065 void FmTextControlShell::formActivated( const Reference
< XFormController
>& _rxController
)
1067 #if OSL_DEBUG_LEVEL > 0
1068 OString
sTrace( "FmTextControlShell::formActivated: 0x" );
1069 sTrace
+= OString::valueOf( (sal_IntPtr
)_rxController
.get(), 16 );
1070 OSL_TRACE( "%s", sTrace
.getStr() );
1073 DBG_ASSERT( _rxController
.is(), "FmTextControlShell::formActivated: invalid controller!" );
1074 if ( !_rxController
.is() )
1077 // sometimes, a form controller notifies activations, even if it's already activated
1078 if ( m_xActiveController
== _rxController
)
1083 startControllerListening( _rxController
);
1084 controlActivated( _rxController
->getCurrentControl() );
1086 catch( const Exception
& )
1088 DBG_UNHANDLED_EXCEPTION();
1092 //------------------------------------------------------------------------
1093 void FmTextControlShell::formDeactivated( const Reference
< XFormController
>& _rxController
)
1095 #if OSL_DEBUG_LEVEL > 0
1096 OString
sTrace( "FmTextControlShell::formDeactivated: 0x" );
1097 sTrace
+= OString::valueOf( (sal_IntPtr
)_rxController
.get(), 16 );
1098 OSL_TRACE( "%s", sTrace
.getStr() );
1100 (void)_rxController
;
1102 if ( IsActiveControl() )
1103 controlDeactivated();
1104 if ( isControllerListening() )
1105 stopControllerListening();
1108 //------------------------------------------------------------------------
1109 void FmTextControlShell::startControllerListening( const Reference
< XFormController
>& _rxController
)
1111 OSL_PRECOND( _rxController
.is(), "FmTextControlShell::startControllerListening: invalid controller!" );
1112 if ( !_rxController
.is() )
1115 OSL_PRECOND( !isControllerListening(), "FmTextControlShell::startControllerListening: already listening!" );
1116 if ( isControllerListening() )
1117 stopControllerListening( );
1118 DBG_ASSERT( !isControllerListening(), "FmTextControlShell::startControllerListening: inconsistence!" );
1122 Sequence
< Reference
< XControl
> > aControls( _rxController
->getControls() );
1123 m_aControlObservers
.resize( 0 );
1124 m_aControlObservers
.reserve( aControls
.getLength() );
1126 const Reference
< XControl
>* pControls
= aControls
.getConstArray();
1127 const Reference
< XControl
>* pControlsEnd
= pControls
+ aControls
.getLength();
1128 for ( ; pControls
!= pControlsEnd
; ++pControls
)
1130 m_aControlObservers
.push_back( FocusListenerAdapter( new FmFocusListenerAdapter( *pControls
, this ) ) );
1133 catch( const Exception
& )
1135 DBG_UNHANDLED_EXCEPTION();
1138 m_xActiveController
= _rxController
;
1141 //------------------------------------------------------------------------
1142 void FmTextControlShell::stopControllerListening( )
1144 OSL_PRECOND( isControllerListening(), "FmTextControlShell::stopControllerListening: inconsistence!" );
1146 // dispose all listeners associated with the controls of the active controller
1147 for ( FocusListenerAdapters::iterator aLoop
= m_aControlObservers
.begin();
1148 aLoop
!= m_aControlObservers
.end();
1152 (*aLoop
)->dispose();
1155 FocusListenerAdapters aEmpty
;
1156 m_aControlObservers
.swap( aEmpty
);
1158 m_xActiveController
.clear();
1161 //------------------------------------------------------------------------
1162 void FmTextControlShell::implClearActiveControlRef()
1164 // no more features for this control
1165 for ( ControlFeatures::iterator aLoop
= m_aControlFeatures
.begin();
1166 aLoop
!= m_aControlFeatures
.end();
1170 aLoop
->second
->dispose();
1173 ControlFeatures aEmpty
;
1174 m_aControlFeatures
.swap( aEmpty
);
1176 if ( m_aContextMenuObserver
.get() )
1178 m_aContextMenuObserver
->dispose();
1179 m_aContextMenuObserver
= MouseListenerAdapter();
1182 if ( m_xActiveTextComponent
.is() )
1184 OSL_TRACE( "FmTextControlShell::ClipBoard: stopping timer for clipboard invalidation" );
1185 m_aClipboardInvalidation
.Stop();
1187 // no more active control
1188 m_xActiveControl
.clear();
1189 m_xActiveTextComponent
.clear();
1190 m_bActiveControlIsReadOnly
= true;
1191 m_bActiveControlIsRichText
= false;
1192 m_bActiveControl
= false;
1195 //------------------------------------------------------------------------
1196 void FmTextControlShell::controlDeactivated( )
1198 DBG_ASSERT( IsActiveControl(), "FmTextControlShell::controlDeactivated: no active control!" );
1200 m_bActiveControl
= false;
1202 m_rBindings
.Invalidate( pTextControlSlots
);
1205 //------------------------------------------------------------------------
1206 void FmTextControlShell::controlActivated( const Reference
< XControl
>& _rxControl
)
1208 // ensure that all knittings with the previously active control are lost
1209 if ( m_xActiveControl
.is() )
1210 implClearActiveControlRef();
1211 DBG_ASSERT( m_aControlFeatures
.empty(), "FmTextControlShell::controlActivated: should have no dispatchers when I'm here!" );
1213 #if OSL_DEBUG_LEVEL > 0
1215 Sequence
< Reference
< XControl
> > aActiveControls
;
1216 if ( m_xActiveController
.is() )
1217 aActiveControls
= m_xActiveController
->getControls();
1219 bool bFoundThisControl
= false;
1221 const Reference
< XControl
>* pControls
= aActiveControls
.getConstArray();
1222 const Reference
< XControl
>* pControlsEnd
= pControls
+ aActiveControls
.getLength();
1223 for ( ; ( pControls
!= pControlsEnd
) && !bFoundThisControl
; ++pControls
)
1225 if ( *pControls
== _rxControl
)
1226 bFoundThisControl
= true;
1228 DBG_ASSERT( bFoundThisControl
, "FmTextControlShell::controlActivated: only controls which belong to the active controller can be activated!" );
1231 // ask the control for dispatchers for our text-related slots
1232 fillFeatureDispatchers( _rxControl
, pTextControlSlots
, m_aControlFeatures
);
1234 // remember this control
1235 m_xActiveControl
= _rxControl
;
1236 m_xActiveTextComponent
= m_xActiveTextComponent
.query( _rxControl
);
1237 m_bActiveControlIsReadOnly
= lcl_determineReadOnly( m_xActiveControl
);
1238 m_bActiveControlIsRichText
= lcl_isRichText( m_xActiveControl
);
1240 // if we found a rich text control, we need context menu support
1241 if ( m_bActiveControlIsRichText
)
1243 DBG_ASSERT( NULL
== m_aContextMenuObserver
.get(), "FmTextControlShell::controlActivated: already have an observer!" );
1244 m_aContextMenuObserver
= MouseListenerAdapter( new FmMouseListenerAdapter( _rxControl
, this ) );
1247 if ( m_xActiveTextComponent
.is() )
1249 OSL_TRACE( "FmTextControlShell::ClipBoard: starting timer for clipboard invalidation" );
1250 m_aClipboardInvalidation
.Start();
1253 m_bActiveControl
= true;
1255 m_rBindings
.Invalidate( pTextControlSlots
);
1258 m_pViewFrame
->UIFeatureChanged();
1260 // don't call the activation handler if we don't have any slots we can serve
1261 // The activation handler is used to put the shell on the top of the dispatcher stack,
1262 // so it's preferred when slots are distributed.
1263 // Note that this is a slight hack, to prevent that we grab slots from the SfxDispatcher
1264 // which should be served by other shells (e.g. Cut/Copy/Paste).
1265 // A real solution would be a forwarding-mechanism for slots: We should be on the top
1266 // if we're active, but if we cannot handle the slot, then we need to tell the dispatcher
1267 // to skip our shell, and pass the slot to the next one. However, this mechanism is not
1268 // not in place in SFX.
1269 // Another possibility would be to have dedicated shells for the slots which we might
1270 // or might not be able to serve. However, this could probably increase the number of
1271 // shells too much (In theory, nearly every slot could have an own shell then).
1273 // #i51621# / 2005-08-19 / frank.schoenheit@sun.com
1274 // bool bHaveAnyServeableSlots = m_xActiveTextComponent.is() || !m_aControlFeatures.empty();
1275 // LEM: not calling m_aControlActivatonHandler causes fdo#63695, so disable this hack for now.
1276 if ( m_aControlActivationHandler
.IsSet() /* && bHaveAnyServeableSlots */ )
1277 m_aControlActivationHandler
.Call( NULL
);
1279 m_bNeedClipboardInvalidation
= true;
1282 //------------------------------------------------------------------------
1283 void FmTextControlShell::fillFeatureDispatchers( const Reference
< XControl
> _rxControl
, SfxSlotId
* _pZeroTerminatedSlots
,
1284 ControlFeatures
& _rDispatchers
)
1286 Reference
< XDispatchProvider
> xProvider( _rxControl
, UNO_QUERY
);
1287 SfxApplication
* pApplication
= SFX_APP();
1288 DBG_ASSERT( pApplication
, "FmTextControlShell::fillFeatureDispatchers: no SfxApplication!" );
1289 if ( xProvider
.is() && pApplication
)
1291 SfxSlotId
* pSlots
= _pZeroTerminatedSlots
;
1294 FmTextControlFeature
* pDispatcher
= implGetFeatureDispatcher( xProvider
, pApplication
, *pSlots
);
1296 _rDispatchers
.insert( ControlFeatures::value_type( *pSlots
, ControlFeature( pDispatcher
) ) );
1303 //------------------------------------------------------------------------
1304 void FmTextControlShell::impl_parseURL_nothrow( URL
& _rURL
)
1308 if ( !m_xURLTransformer
.is() )
1310 m_xURLTransformer
= util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
1312 if ( m_xURLTransformer
.is() )
1313 m_xURLTransformer
->parseStrict( _rURL
);
1315 catch( const Exception
& )
1317 DBG_UNHANDLED_EXCEPTION();
1321 //------------------------------------------------------------------------
1322 FmTextControlFeature
* FmTextControlShell::implGetFeatureDispatcher( const Reference
< XDispatchProvider
>& _rxProvider
, SfxApplication
* _pApplication
, SfxSlotId _nSlot
)
1324 OSL_PRECOND( _rxProvider
.is() && _pApplication
, "FmTextControlShell::implGetFeatureDispatcher: invalid arg(s)!" );
1326 aFeatureURL
.Complete
= lcl_getUnoSlotName( *_pApplication
, _nSlot
);
1327 impl_parseURL_nothrow( aFeatureURL
);
1328 Reference
< XDispatch
> xDispatcher
= _rxProvider
->queryDispatch( aFeatureURL
, OUString(), 0xFF );
1329 if ( xDispatcher
.is() )
1330 return new FmTextControlFeature( xDispatcher
, aFeatureURL
, _nSlot
, this );
1334 //------------------------------------------------------------------------
1335 void FmTextControlShell::Invalidate( SfxSlotId _nSlot
)
1337 m_rBindings
.Invalidate( _nSlot
);
1338 // despite this method being called "Invalidate", we also update here - this gives more immediate
1339 // feedback in the UI
1340 m_rBindings
.Update( _nSlot
);
1343 //------------------------------------------------------------------------
1344 void FmTextControlShell::focusGained( const ::com::sun::star::awt::FocusEvent
& _rEvent
)
1346 Reference
< XControl
> xControl( _rEvent
.Source
, UNO_QUERY
);
1348 #if OSL_DEBUG_LEVEL > 0
1349 OString
sTrace( "FmTextControlShell::focusGained: 0x" );
1350 sTrace
+= OString::valueOf( (sal_IntPtr
)xControl
.get(), 16 );
1351 OSL_TRACE( "%s", sTrace
.getStr() );
1354 DBG_ASSERT( xControl
.is(), "FmTextControlShell::focusGained: suspicious focus event!" );
1355 if ( xControl
.is() )
1356 controlActivated( xControl
);
1359 //------------------------------------------------------------------------
1360 void FmTextControlShell::focusLost( const ::com::sun::star::awt::FocusEvent
& _rEvent
)
1362 Reference
< XControl
> xControl( _rEvent
.Source
, UNO_QUERY
);
1364 #if OSL_DEBUG_LEVEL > 0
1365 OString
sTrace( "FmTextControlShell::focusLost: 0x" );
1366 sTrace
+= OString::valueOf( (sal_IntPtr
)xControl
.get(), 16 );
1367 OSL_TRACE( "%s", sTrace
.getStr() );
1370 m_bActiveControl
= false;
1373 //------------------------------------------------------------------------
1374 void FmTextControlShell::ForgetActiveControl()
1376 implClearActiveControlRef();
1379 //------------------------------------------------------------------------
1380 void FmTextControlShell::contextMenuRequested( const awt::MouseEvent
& /*_rEvent*/ )
1382 m_rBindings
.GetDispatcher()->ExecutePopup( SVX_RES( RID_FM_TEXTATTRIBUTE_MENU
) );
1385 //........................................................................
1387 //........................................................................
1389 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */