LibreOffice Module svx (master) 1
fmtextcontrolshell.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
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/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
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 .
18 */
19
20
21#include <fmprop.hxx>
26#include <editeng/editeng.hxx>
28#include <svx/svxids.hrc>
29#include <editeng/udlnitem.hxx>
30
31#include <com/sun/star/beans/XPropertySet.hpp>
32#include <com/sun/star/frame/XDispatchProvider.hpp>
33#include <com/sun/star/container/XChild.hpp>
34#include <com/sun/star/awt/XFocusListener.hpp>
35#include <com/sun/star/awt/XMouseListener.hpp>
36#include <com/sun/star/awt/XWindow.hpp>
37#include <com/sun/star/util/URLTransformer.hpp>
38
42#include <sfx2/app.hxx>
43#include <sfx2/bindings.hxx>
44#include <sfx2/dispatch.hxx>
45#include <sfx2/msgpool.hxx>
46#include <sfx2/msg.hxx>
47#include <sfx2/objsh.hxx>
48#include <sfx2/request.hxx>
49#include <sfx2/sfxuno.hxx>
50#include <sfx2/viewfrm.hxx>
51#include <svl/eitem.hxx>
52#include <svl/itempool.hxx>
53#include <svl/ctloptions.hxx>
55#include <svl/whiter.hxx>
57#include <tools/debug.hxx>
59#include <sal/log.hxx>
60#include <vcl/svapp.hxx>
61#include <vcl/window.hxx>
62
63#include <memory>
64
65
66namespace svx
67{
68
69
70 using namespace ::com::sun::star;
71 using namespace ::com::sun::star::uno;
72 using namespace ::com::sun::star::form;
73 using namespace ::com::sun::star::form::runtime;
74 using namespace ::com::sun::star::lang;
75 using namespace ::com::sun::star::frame;
76 using namespace ::com::sun::star::util;
77 using namespace ::com::sun::star::beans;
78 using namespace ::com::sun::star::container;
79
80
81 typedef sal_uInt16 WhichId;
82
83
85 {
86 SID_CLIPBOARD_FORMAT_ITEMS,
87 SID_CUT,
88 SID_COPY,
89 SID_PASTE,
90 SID_SELECTALL,
91// SID_ATTR_TABSTOP, /* 2 */
92 SID_ATTR_CHAR_FONT,
93 SID_ATTR_CHAR_POSTURE,
94 SID_ATTR_CHAR_WEIGHT,
95 SID_ATTR_CHAR_SHADOWED,
96 SID_ATTR_CHAR_WORDLINEMODE,
97 SID_ATTR_CHAR_CONTOUR,
98 SID_ATTR_CHAR_STRIKEOUT,
99 SID_ATTR_CHAR_UNDERLINE,
100 SID_ATTR_CHAR_FONTHEIGHT,
101 SID_ATTR_CHAR_COLOR,
102 SID_ATTR_CHAR_KERNING,
103 SID_ATTR_CHAR_LANGUAGE, /* 20 */
104 SID_ATTR_CHAR_ESCAPEMENT,
105 SID_ATTR_PARA_ADJUST, /* 28 */
106 SID_ATTR_PARA_ADJUST_LEFT,
107 SID_ATTR_PARA_ADJUST_RIGHT,
108 SID_ATTR_PARA_ADJUST_CENTER,
109 SID_ATTR_PARA_ADJUST_BLOCK,
110 SID_ATTR_PARA_LINESPACE, /* 33 */
111 SID_ATTR_PARA_LINESPACE_10,
112 SID_ATTR_PARA_LINESPACE_15,
113 SID_ATTR_PARA_LINESPACE_20,
114 SID_ATTR_LRSPACE, /* 48 */
115 SID_ATTR_ULSPACE, /* 49 */
116 SID_ATTR_CHAR_AUTOKERN,
117 SID_SET_SUPER_SCRIPT,
118 SID_SET_SUB_SCRIPT,
119 SID_CHAR_DLG,
120 SID_PARA_DLG,
121// SID_TEXTDIRECTION_LEFT_TO_RIGHT, /* 907 */
122// SID_TEXTDIRECTION_TOP_TO_BOTTOM,
123 SID_ATTR_CHAR_SCALEWIDTH, /* 911 */
124 SID_ATTR_CHAR_RELIEF,
125 SID_ATTR_PARA_LEFT_TO_RIGHT, /* 950 */
126 SID_ATTR_PARA_RIGHT_TO_LEFT,
127 SID_ATTR_CHAR_OVERLINE,
128 0
129 };
130
131 // slots which we are not responsible for on the SfxShell level, but
132 // need to handle during the "paragraph attributes" and/or "character
133 // attributes" dialogs
135 {
136 SID_ATTR_TABSTOP,
137 SID_ATTR_PARA_HANGPUNCTUATION,
138 SID_ATTR_PARA_FORBIDDEN_RULES,
139 SID_ATTR_PARA_SCRIPTSPACE,
140 SID_ATTR_CHAR_LATIN_LANGUAGE,
141 SID_ATTR_CHAR_CJK_LANGUAGE,
142 SID_ATTR_CHAR_CTL_LANGUAGE,
143 SID_ATTR_CHAR_LATIN_FONT,
144 SID_ATTR_CHAR_CJK_FONT,
145 SID_ATTR_CHAR_CTL_FONT,
146 SID_ATTR_CHAR_LATIN_FONTHEIGHT,
147 SID_ATTR_CHAR_CJK_FONTHEIGHT,
148 SID_ATTR_CHAR_CTL_FONTHEIGHT,
149 SID_ATTR_CHAR_LATIN_WEIGHT,
150 SID_ATTR_CHAR_CJK_WEIGHT,
151 SID_ATTR_CHAR_CTL_WEIGHT,
152 SID_ATTR_CHAR_LATIN_POSTURE,
153 SID_ATTR_CHAR_CJK_POSTURE,
154 SID_ATTR_CHAR_CTL_POSTURE,
155 SID_ATTR_CHAR_EMPHASISMARK,
156 0
157 };
158
159 typedef ::cppu::WeakImplHelper < css::awt::XFocusListener
162 {
163 private:
165 Reference< css::awt::XWindow > m_xWindow;
166
167 public:
168 FmFocusListenerAdapter( const Reference< css::awt::XControl >& _rxControl, IFocusObserver* _pObserver );
169
170 // clean up the instance
171 void dispose();
172
173 protected:
174 virtual ~FmFocusListenerAdapter() override;
175
176 protected:
177 virtual void SAL_CALL focusGained( const css::awt::FocusEvent& e ) override;
178 virtual void SAL_CALL focusLost( const css::awt::FocusEvent& e ) override;
179 virtual void SAL_CALL disposing( const EventObject& Source ) override;
180 };
181
182
183 FmFocusListenerAdapter::FmFocusListenerAdapter( const Reference< css::awt::XControl >& _rxControl, IFocusObserver* _pObserver )
184 :m_pObserver( _pObserver )
185 ,m_xWindow( _rxControl, UNO_QUERY )
186 {
187
188 DBG_ASSERT( m_xWindow.is(), "FmFocusListenerAdapter::FmFocusListenerAdapter: invalid control!" );
189 osl_atomic_increment( &m_refCount );
190 {
191 try
192 {
193 if ( m_xWindow.is() )
194 m_xWindow->addFocusListener( this );
195 }
196 catch( const Exception& )
197 {
199 }
200 }
201 osl_atomic_decrement( &m_refCount );
202 }
203
204
206 {
207 acquire();
208 dispose();
209
210 }
211
212
214 {
215 if ( m_xWindow.is() )
216 {
217 m_xWindow->removeFocusListener( this );
218 m_xWindow.clear();
219 }
220 }
221
222
223 void SAL_CALL FmFocusListenerAdapter::focusGained( const css::awt::FocusEvent& e )
224 {
225 if ( m_pObserver )
227 }
228
229
230 void SAL_CALL FmFocusListenerAdapter::focusLost( const css::awt::FocusEvent& e )
231 {
232 if ( m_pObserver )
234 }
235
236
237 void SAL_CALL FmFocusListenerAdapter::disposing( const EventObject& Source )
238 {
239 DBG_ASSERT( Source.Source == m_xWindow, "FmFocusListenerAdapter::disposing: where did this come from?" );
240 m_xWindow.clear();
241 }
242
243 typedef ::cppu::WeakImplHelper < css::awt::XMouseListener
246 {
247 private:
249 Reference< css::awt::XWindow > m_xWindow;
250
251 public:
252 FmMouseListenerAdapter( const Reference< css::awt::XControl >& _rxControl, IContextRequestObserver* _pObserver );
253
254 // clean up the instance
255 void dispose();
256
257 protected:
258 virtual ~FmMouseListenerAdapter() override;
259
260 protected:
261 virtual void SAL_CALL mousePressed( const css::awt::MouseEvent& e ) override;
262 virtual void SAL_CALL mouseReleased( const css::awt::MouseEvent& e ) override;
263 virtual void SAL_CALL mouseEntered( const css::awt::MouseEvent& e ) override;
264 virtual void SAL_CALL mouseExited( const css::awt::MouseEvent& e ) override;
265 virtual void SAL_CALL disposing( const EventObject& Source ) override;
266 };
267
268 FmMouseListenerAdapter::FmMouseListenerAdapter( const Reference< css::awt::XControl >& _rxControl, IContextRequestObserver* _pObserver )
269 :m_pObserver( _pObserver )
270 ,m_xWindow( _rxControl, UNO_QUERY )
271 {
272
273 DBG_ASSERT( m_xWindow.is(), "FmMouseListenerAdapter::FmMouseListenerAdapter: invalid control!" );
274 osl_atomic_increment( &m_refCount );
275 {
276 try
277 {
278 if ( m_xWindow.is() )
279 m_xWindow->addMouseListener( this );
280 }
281 catch( const Exception& )
282 {
284 }
285 }
286 osl_atomic_decrement( &m_refCount );
287 }
288
289
291 {
292 acquire();
293 dispose();
294
295 }
296
297
299 {
300 if ( m_xWindow.is() )
301 {
302 m_xWindow->removeMouseListener( this );
303 m_xWindow.clear();
304 }
305 }
306
307
308 void SAL_CALL FmMouseListenerAdapter::mousePressed( const css::awt::MouseEvent& _rEvent )
309 {
310 SolarMutexGuard aGuard;
311 // is this a request for a context menu?
312 if ( _rEvent.PopupTrigger )
313 {
314 if ( m_pObserver )
316 }
317 }
318
319
320 void SAL_CALL FmMouseListenerAdapter::mouseReleased( const css::awt::MouseEvent& /*e*/ )
321 {
322 // not interested in
323 }
324
325
326 void SAL_CALL FmMouseListenerAdapter::mouseEntered( const css::awt::MouseEvent& /*e*/ )
327 {
328 // not interested in
329 }
330
331
332 void SAL_CALL FmMouseListenerAdapter::mouseExited( const css::awt::MouseEvent& /*e*/ )
333 {
334 // not interested in
335 }
336
337
338 void SAL_CALL FmMouseListenerAdapter::disposing( const EventObject& Source )
339 {
340 DBG_ASSERT( Source.Source == m_xWindow, "FmMouseListenerAdapter::disposing: where did this come from?" );
341 m_xWindow.clear();
342 }
343
344
345 //= FmTextControlShell
346
347
348 namespace
349 {
350
351 void lcl_translateUnoStateToItem( SfxSlotId _nSlot, const Any& _rUnoState, SfxItemSet& _rSet )
352 {
353 WhichId nWhich = _rSet.GetPool()->GetWhich( _nSlot );
354 if ( !_rUnoState.hasValue() )
355 {
356 if ( ( _nSlot != SID_CUT )
357 && ( _nSlot != SID_COPY )
358 && ( _nSlot != SID_PASTE )
359 )
360 {
361 _rSet.InvalidateItem( nWhich );
362 }
363 }
364 else
365 {
366 switch ( _rUnoState.getValueType().getTypeClass() )
367 {
368 case TypeClass_BOOLEAN:
369 {
370 bool bState = false;
371 _rUnoState >>= bState;
372 if ( _nSlot == SID_ATTR_PARA_SCRIPTSPACE )
373 _rSet.Put( SvxScriptSpaceItem( bState, nWhich ) );
374 else
375 _rSet.Put( SfxBoolItem( nWhich, bState ) );
376 }
377 break;
378
379 default:
380 {
381 Sequence< PropertyValue > aComplexState;
382 if ( _rUnoState >>= aComplexState )
383 {
384 if ( !aComplexState.hasElements() )
385 _rSet.InvalidateItem( nWhich );
386 else
387 {
388 SfxAllItemSet aAllItems( _rSet );
389 TransformParameters( _nSlot, aComplexState, aAllItems );
390 const SfxPoolItem* pTransformed = aAllItems.GetItem( nWhich );
391 OSL_ENSURE( pTransformed, "lcl_translateUnoStateToItem: non-empty parameter sequence leading to empty item?" );
392 if ( pTransformed )
393 _rSet.Put( *pTransformed );
394 else
395 _rSet.InvalidateItem( nWhich );
396 }
397 }
398 else
399 {
400 OSL_FAIL( "lcl_translateUnoStateToItem: invalid state!" );
401 }
402 }
403 }
404 }
405 }
406
407
408 OUString lcl_getUnoSlotName( SfxSlotId _nSlotId )
409 {
410 OUString sSlotUnoName;
411
413 const SfxSlot* pSlot = rSlotPool.GetSlot( _nSlotId );
414
415 const char* pAsciiUnoName = nullptr;
416 if ( pSlot )
417 {
418 pAsciiUnoName = pSlot->GetUnoName();
419 }
420 else
421 {
422 // some hard-coded slots, which do not have a UNO name at SFX level, but which
423 // we nevertheless need to transport via UNO mechanisms, so we need a name
424 switch ( _nSlotId )
425 {
426 case SID_ATTR_PARA_HANGPUNCTUATION: pAsciiUnoName = "AllowHangingPunctuation"; break;
427 case SID_ATTR_PARA_FORBIDDEN_RULES: pAsciiUnoName = "ApplyForbiddenCharacterRules"; break;
428 case SID_ATTR_PARA_SCRIPTSPACE: pAsciiUnoName = "UseScriptSpacing"; break;
429 }
430 }
431
432 if ( pAsciiUnoName )
433 {
434 sSlotUnoName = ".uno:" + OUString::createFromAscii( pAsciiUnoName );
435 }
436 else
437 {
438 SAL_WARN( "svx", "lcl_getUnoSlotName: invalid slot id, or invalid slot, or no UNO name! "
439 "(slot id: " << _nSlotId << ")");
440 }
441 return sSlotUnoName;
442 }
443
444
445 bool lcl_determineReadOnly( const Reference< css::awt::XControl >& _rxControl )
446 {
447 bool bIsReadOnlyModel = true;
448 try
449 {
450 Reference< XPropertySet > xModelProps;
451 if ( _rxControl.is() )
452 xModelProps.set(_rxControl->getModel(), css::uno::UNO_QUERY);
453 Reference< XPropertySetInfo > xModelPropInfo;
454 if ( xModelProps.is() )
455 xModelPropInfo = xModelProps->getPropertySetInfo();
456
457 if ( !xModelPropInfo.is() || !xModelPropInfo->hasPropertyByName( FM_PROP_READONLY ) )
458 bIsReadOnlyModel = true;
459 else
460 {
461 bool bReadOnly = true;
462 xModelProps->getPropertyValue( FM_PROP_READONLY ) >>= bReadOnly;
463 bIsReadOnlyModel = bReadOnly;
464 }
465 }
466 catch( const Exception& )
467 {
469 }
470 return bIsReadOnlyModel;
471 }
472
473
474 vcl::Window* lcl_getWindow( const Reference< css::awt::XControl >& _rxControl )
475 {
476 vcl::Window* pWindow = nullptr;
477 try
478 {
479 Reference< css::awt::XWindowPeer > xControlPeer;
480 if ( _rxControl.is() )
481 xControlPeer = _rxControl->getPeer();
482 if ( xControlPeer.is() )
483 pWindow = VCLUnoHelper::GetWindow( xControlPeer );
484 }
485 catch( const Exception& )
486 {
488 }
489
490 return pWindow;
491 }
492
493
494 bool lcl_isRichText( const Reference< css::awt::XControl >& _rxControl )
495 {
496 if ( !_rxControl.is() )
497 return false;
498
499 bool bIsRichText = false;
500 try
501 {
502 Reference< XPropertySet > xModelProps( _rxControl->getModel(), UNO_QUERY );
503 Reference< XPropertySetInfo > xPSI;
504 if ( xModelProps.is() )
505 xPSI = xModelProps->getPropertySetInfo();
506 OUString sRichTextPropertyName = "RichText";
507 if ( xPSI.is() && xPSI->hasPropertyByName( sRichTextPropertyName ) )
508 {
509 OSL_VERIFY( xModelProps->getPropertyValue( sRichTextPropertyName ) >>= bIsRichText );
510 }
511 }
512 catch( const Exception& )
513 {
515 }
516 return bIsRichText;
517 }
518 }
519
520
522 :m_bActiveControl( false )
523 ,m_bActiveControlIsReadOnly( true )
524 ,m_bActiveControlIsRichText( false )
525 ,m_pViewFrame( _pFrame )
526 ,m_rBindings( _pFrame->GetBindings() )
527 ,m_aClipboardInvalidation("svx FmTextControlShell m_aClipboardInvalidation")
528 ,m_bNeedClipboardInvalidation( true )
529 {
530 m_aClipboardInvalidation.SetInvokeHandler( LINK( this, FmTextControlShell, OnInvalidateClipboard ) );
532 }
533
534
536 {
537 dispose();
538 }
539
540
541 IMPL_LINK_NOARG( FmTextControlShell, OnInvalidateClipboard, Timer*, void )
542 {
543 if ( m_bNeedClipboardInvalidation )
544 {
545 SAL_INFO("svx.form", "invalidating clipboard slots" );
546 m_rBindings.Invalidate( SID_CUT );
547 m_rBindings.Invalidate( SID_COPY );
548 m_rBindings.Invalidate( SID_PASTE );
549 m_bNeedClipboardInvalidation = false;
550 }
551 }
552
553
554 void FmTextControlShell::transferFeatureStatesToItemSet( ControlFeatures& _rDispatchers, SfxAllItemSet& _rSet, bool _bTranslateLatin )
555 {
556 SfxItemPool& rPool = *_rSet.GetPool();
557
558 for (const auto& rFeature : _rDispatchers)
559 {
560 SfxSlotId nSlotId( rFeature.first );
561#if OSL_DEBUG_LEVEL > 0
562 OUString sUnoSlotName;
563 if ( SfxGetpApp() )
564 sUnoSlotName = lcl_getUnoSlotName( nSlotId );
565 else
566 sUnoSlotName = "<unknown>";
567 OString sUnoSlotNameAscii = "\"" +
568 OString( sUnoSlotName.getStr(), sUnoSlotName.getLength(), RTL_TEXTENCODING_ASCII_US ) +
569 "\"";
570#endif
571
572 if ( _bTranslateLatin )
573 {
574 // A rich text control offers a dispatcher for the "Font" slot/feature.
575 // Sadly, the semantics of the dispatches is that the feature "Font" depends
576 // on the current cursor position: If it's on latin text, it's the "latin font"
577 // which is set up at the control. If it's on CJK text, it's the "CJK font", and
578 // equivalent for "CTL font".
579 // The same holds for some other font related features/slots.
580 // Thus, we have separate dispatches for "Latin Font", "Latin Font Size", etc,
581 // which are only "virtual", in a sense that there exist no item with this id.
582 // So when we encounter such a dispatcher for, say, "Latin Font", we need to
583 // put an item into the set which has the "Font" id.
584
585 switch ( nSlotId )
586 {
587 case SID_ATTR_CHAR_LATIN_FONT: nSlotId = SID_ATTR_CHAR_FONT; break;
588 case SID_ATTR_CHAR_LATIN_FONTHEIGHT:nSlotId = SID_ATTR_CHAR_FONTHEIGHT; break;
589 case SID_ATTR_CHAR_LATIN_LANGUAGE: nSlotId = SID_ATTR_CHAR_LANGUAGE; break;
590 case SID_ATTR_CHAR_LATIN_POSTURE: nSlotId = SID_ATTR_CHAR_POSTURE; break;
591 case SID_ATTR_CHAR_LATIN_WEIGHT: nSlotId = SID_ATTR_CHAR_WEIGHT; break;
592 }
593 }
594
595 WhichId nWhich = rPool.GetWhich( nSlotId );
596 bool bIsInPool = rPool.IsInRange( nWhich );
597 if ( bIsInPool )
598 {
599#if OSL_DEBUG_LEVEL > 0
600 bool bFeatureIsEnabled = rFeature.second->isFeatureEnabled();
601 OString sMessage = "found a feature state for " + sUnoSlotNameAscii;
602 if ( !bFeatureIsEnabled )
603 sMessage += " (disabled)";
604 SAL_INFO("svx.form", sMessage );
605#endif
606
607 lcl_translateUnoStateToItem( nSlotId, rFeature.second->getFeatureState(), _rSet );
608 }
609#if OSL_DEBUG_LEVEL > 0
610 else
611 {
612 SAL_WARN("svx.form", "found a feature state for " << sUnoSlotNameAscii << ", but could not translate it into an item!" );
613 }
614#endif
615 }
616 }
617
618
620 {
621 const SvxFontListItem* pFontList = dynamic_cast<const SvxFontListItem*>( m_pViewFrame->GetObjectShell()->GetItem( SID_ATTR_CHAR_FONTLIST ) );
622 DBG_ASSERT( pFontList, "FmTextControlShell::executeAttributeDialog: no font list item!" );
623 if ( !pFontList )
624 return;
625
627 pPool->FreezeIdRanges();
628 std::optional< SfxItemSet > xPureItems(( SfxItemSet( *pPool ) ));
629
630 // put the current states of the items into the set
631 std::optional<SfxAllItemSet> xCurrentItems(( SfxAllItemSet( *xPureItems ) ));
632 transferFeatureStatesToItemSet( m_aControlFeatures, *xCurrentItems, false );
633
634 // additional items, which we are not responsible for at the SfxShell level,
635 // but which need to be forwarded to the dialog, anyway
636 ControlFeatures aAdditionalFestures;
638 transferFeatureStatesToItemSet( aAdditionalFestures, *xCurrentItems, true );
639
640 std::unique_ptr<SfxTabDialogController> xDialog;
641 if (_eSet == eCharAttribs)
642 xDialog = std::make_unique<TextControlCharAttribDialog>(rReq.GetFrameWeld(), *xCurrentItems, *pFontList);
643 else
644 xDialog = std::make_unique<TextControlParaAttribDialog>(rReq.GetFrameWeld(), *xCurrentItems);
645 if ( RET_OK == xDialog->run() )
646 {
647 const SfxItemSet& rModifiedItems = *xDialog->GetOutputItemSet();
648 for ( WhichId nWhich = pPool->GetFirstWhich(); nWhich <= pPool->GetLastWhich(); ++nWhich )
649 {
650 if ( rModifiedItems.GetItemState( nWhich ) == SfxItemState::SET )
651 {
652 SfxSlotId nSlotForItemSet = pPool->GetSlotId( nWhich );
653 const SfxPoolItem* pModifiedItem = rModifiedItems.GetItem( nWhich );
654
655
656 SfxSlotId nSlotForDispatcher = nSlotForItemSet;
657 switch ( nSlotForDispatcher )
658 {
659 case SID_ATTR_CHAR_FONT: nSlotForDispatcher = SID_ATTR_CHAR_LATIN_FONT; break;
660 case SID_ATTR_CHAR_FONTHEIGHT:nSlotForDispatcher = SID_ATTR_CHAR_LATIN_FONTHEIGHT; break;
661 case SID_ATTR_CHAR_LANGUAGE: nSlotForDispatcher = SID_ATTR_CHAR_LATIN_LANGUAGE; break;
662 case SID_ATTR_CHAR_POSTURE: nSlotForDispatcher = SID_ATTR_CHAR_LATIN_POSTURE; break;
663 case SID_ATTR_CHAR_WEIGHT: nSlotForDispatcher = SID_ATTR_CHAR_LATIN_WEIGHT; break;
664 }
665
666 // do we already have a dispatcher for this slot/feature?
667 ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlotForDispatcher );
668 bool bFound = aFeaturePos != m_aControlFeatures.end( );
669
670 if ( !bFound )
671 {
672 aFeaturePos = aAdditionalFestures.find( nSlotForDispatcher );
673 bFound = aFeaturePos != aAdditionalFestures.end( );
674 }
675
676 if ( bFound )
677 {
678 Sequence< PropertyValue > aArgs;
679 // temporarily put the modified item into a "clean" set,
680 // and let TransformItems calc the respective UNO parameters
681 xPureItems->Put( *pModifiedItem );
682 TransformItems( nSlotForItemSet, *xPureItems, aArgs );
683 xPureItems->ClearItem( nWhich );
684
685 if ( ( nSlotForItemSet == SID_ATTR_PARA_HANGPUNCTUATION )
686 || ( nSlotForItemSet == SID_ATTR_PARA_FORBIDDEN_RULES )
687 || ( nSlotForItemSet == SID_ATTR_PARA_SCRIPTSPACE )
688 )
689 {
690 // these are no UNO slots, they need special handling since TransformItems cannot
691 // handle them
692 DBG_ASSERT( !aArgs.hasElements(), "FmTextControlShell::executeAttributeDialog: these are no UNO slots - are they?" );
693
694 const SfxBoolItem* pBoolItem = dynamic_cast<const SfxBoolItem*>( pModifiedItem );
695 DBG_ASSERT( pBoolItem, "FmTextControlShell::executeAttributeDialog: no bool item?!" );
696 if ( pBoolItem )
697 {
698 aArgs = { comphelper::makePropertyValue("Enable",
699 pBoolItem->GetValue()) };
700 }
701 }
702
703 // dispatch this
704 aFeaturePos->second->dispatch( aArgs );
705 }
706 #if OSL_DEBUG_LEVEL > 0
707 else
708 {
709 OUString sUnoSlotName = lcl_getUnoSlotName( nSlotForItemSet );
710 if ( sUnoSlotName.isEmpty() )
711 sUnoSlotName = "unknown (no SfxSlot)";
712 SAL_WARN( "svx", "FmTextControShell::executeAttributeDialog: Could not handle the following item:"
713 "\n SlotID: " << nSlotForItemSet
714 << "\n WhichID: " << nWhich
715 << "\n UNO name: " << sUnoSlotName );
716 }
717 #endif
718 }
719 }
720 rReq.Done( rModifiedItems );
721 }
722
723 xDialog.reset();
724 xCurrentItems.reset();
725 xPureItems.reset();
726 pPool.clear();
727 }
728
729
731 {
732 try
733 {
734 if ( m_xActiveTextComponent.is() )
735 {
736 sal_Int32 nTextLen = m_xActiveTextComponent->getText().getLength();
737 m_xActiveTextComponent->setSelection( css::awt::Selection( 0, nTextLen ) );
738 }
739 }
740 catch( const Exception& )
741 {
743 }
744 }
745
746
748 {
749 try
750 {
751 if ( m_xActiveTextComponent.is() )
752 {
753 switch ( _nSlot )
754 {
755 case SID_COPY:
756 case SID_CUT:
757 {
758 OUString sSelectedText( m_xActiveTextComponent->getSelectedText() );
759 ::svt::OStringTransfer::CopyString( sSelectedText, lcl_getWindow( m_xActiveControl ) );
760 if ( SID_CUT == _nSlot )
761 {
762 css::awt::Selection aSelection( m_xActiveTextComponent->getSelection() );
763 m_xActiveTextComponent->insertText( aSelection, OUString() );
764 }
765 }
766 break;
767 case SID_PASTE:
768 {
769 OUString sClipboardContent;
770 OSL_VERIFY( ::svt::OStringTransfer::PasteString( sClipboardContent, lcl_getWindow( m_xActiveControl ) ) );
771 css::awt::Selection aSelection( m_xActiveTextComponent->getSelection() );
772 m_xActiveTextComponent->insertText( aSelection, sClipboardContent );
773 }
774 break;
775 default:
776 OSL_FAIL( "FmTextControlShell::executeClipboardSlot: invalid slot!" );
777 }
778 }
779 }
780 catch( const Exception& )
781 {
783 }
784 }
785
786
788 {
789 SfxSlotId nSlot = _rReq.GetSlot();
790
791 ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlot );
792 if ( aFeaturePos == m_aControlFeatures.end() )
793 {
794 // special slots
795 switch ( nSlot )
796 {
797 case SID_CHAR_DLG:
799 break;
800
801 case SID_PARA_DLG:
803 break;
804
805 case SID_SELECTALL:
807 break;
808
809 case SID_CUT:
810 case SID_COPY:
811 case SID_PASTE:
812 executeClipboardSlot( nSlot );
813 break;
814
815 default:
816 DBG_ASSERT( aFeaturePos != m_aControlFeatures.end(), "FmTextControShell::ExecuteTextAttribute: I have no such dispatcher, and cannot handle it at all!" );
817 return;
818 }
819 }
820 else
821 {
822 // slots which are dispatched to the control
823
824 switch ( nSlot )
825 {
826 case SID_ATTR_CHAR_STRIKEOUT:
827 case SID_ATTR_CHAR_UNDERLINE:
828 case SID_ATTR_CHAR_OVERLINE:
829 {
830 SfxItemSet aToggled( *_rReq.GetArgs() );
831
832 lcl_translateUnoStateToItem( nSlot, aFeaturePos->second->getFeatureState(), aToggled );
833 WhichId nWhich = aToggled.GetPool()->GetWhich( nSlot );
834 const SfxPoolItem* pItem = aToggled.GetItem( nWhich );
835 if ( ( SID_ATTR_CHAR_UNDERLINE == nSlot ) || ( SID_ATTR_CHAR_OVERLINE == nSlot ) )
836 {
837 const SvxTextLineItem* pTextLine = dynamic_cast<const SvxTextLineItem*>( pItem );
838 DBG_ASSERT( pTextLine, "FmTextControlShell::ExecuteTextAttribute: ooops - no underline/overline item!" );
839 if ( pTextLine )
840 {
841 FontLineStyle eTL = pTextLine->GetLineStyle();
842 if ( SID_ATTR_CHAR_UNDERLINE == nSlot ) {
843 aToggled.Put( SvxUnderlineItem( eTL == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, nWhich ) );
844 } else {
845 aToggled.Put( SvxOverlineItem( eTL == LINESTYLE_SINGLE ? LINESTYLE_NONE : LINESTYLE_SINGLE, nWhich ) );
846 }
847 }
848 }
849 else
850 {
851 const SvxCrossedOutItem* pCrossedOut = dynamic_cast<const SvxCrossedOutItem*>( pItem );
852 DBG_ASSERT( pCrossedOut, "FmTextControlShell::ExecuteTextAttribute: ooops - no CrossedOut item!" );
853 if ( pCrossedOut )
854 {
855 FontStrikeout eFS = pCrossedOut->GetStrikeout();
856 aToggled.Put( SvxCrossedOutItem( eFS == STRIKEOUT_SINGLE ? STRIKEOUT_NONE : STRIKEOUT_SINGLE, nWhich ) );
857 }
858 }
859
860 Sequence< PropertyValue > aArguments;
861 TransformItems( nSlot, aToggled, aArguments );
862 aFeaturePos->second->dispatch( aArguments );
863 }
864 break;
865
866 case SID_ATTR_CHAR_FONTHEIGHT:
867 case SID_ATTR_CHAR_FONT:
868 case SID_ATTR_CHAR_POSTURE:
869 case SID_ATTR_CHAR_WEIGHT:
870 case SID_ATTR_CHAR_SHADOWED:
871 case SID_ATTR_CHAR_CONTOUR:
872 case SID_SET_SUPER_SCRIPT:
873 case SID_SET_SUB_SCRIPT:
874 {
875 const SfxItemSet* pArgs = _rReq.GetArgs();
876 Sequence< PropertyValue > aArgs;
877 if ( pArgs )
878 TransformItems( nSlot, *pArgs, aArgs );
879 aFeaturePos->second->dispatch( aArgs );
880 }
881 break;
882
883 default:
884 if ( aFeaturePos->second->isFeatureEnabled() )
885 aFeaturePos->second->dispatch();
886 break;
887 }
888 }
889 _rReq.Done();
890 }
891
892
894 {
895 SfxWhichIter aIter( _rSet );
896 sal_uInt16 nSlot = aIter.FirstWhich();
897 while ( nSlot )
898 {
899 if ( ( nSlot == SID_ATTR_PARA_LEFT_TO_RIGHT )
900 || ( nSlot == SID_ATTR_PARA_RIGHT_TO_LEFT )
901 )
902 {
903 if ( !SvtCTLOptions().IsCTLFontEnabled() )
904 {
905 _rSet.DisableItem( nSlot );
906 nSlot = aIter.NextWhich();
907 continue;
908 }
909 }
910
911 ControlFeatures::const_iterator aFeaturePos = m_aControlFeatures.find( nSlot );
912 if ( aFeaturePos != m_aControlFeatures.end() )
913 {
914 if ( aFeaturePos->second->isFeatureEnabled() )
915 lcl_translateUnoStateToItem( nSlot, aFeaturePos->second->getFeatureState(), _rSet );
916 else
917 _rSet.DisableItem( nSlot );
918 }
919 else
920 {
921 bool bDisable = false;
922
923 bool bNeedWriteableControl = false;
924 bool bNeedTextComponent = false;
925 bool bNeedSelection = false;
926
927 switch ( nSlot )
928 {
929 case SID_CHAR_DLG:
930 case SID_PARA_DLG:
931 bDisable |= m_aControlFeatures.empty();
932 bNeedWriteableControl = true;
933 break;
934
935 case SID_CUT:
936 bNeedSelection = true;
937 bNeedTextComponent = true;
938 bNeedWriteableControl = true;
939 SAL_INFO("svx.form", "need to invalidate again" );
941 break;
942
943 case SID_PASTE:
944 {
945 vcl::Window* pActiveControlVCLWindow = lcl_getWindow( m_xActiveControl );
946 if ( pActiveControlVCLWindow )
947 {
948 TransferableDataHelper aDataHelper( TransferableDataHelper::CreateFromSystemClipboard( pActiveControlVCLWindow) );
949 bDisable |= !aDataHelper.HasFormat( SotClipboardFormatId::STRING );
950 }
951 else
952 bDisable = true;
953
954 bNeedTextComponent = true;
955 bNeedWriteableControl = true;
956 }
957 break;
958
959 case SID_COPY:
960 bNeedTextComponent = true;
961 bNeedSelection = true;
962 break;
963
964 case SID_SELECTALL:
965 bNeedTextComponent = true;
966 break;
967
968 default:
969 // slot is unknown at all
970 bDisable = true;
971 break;
972 }
973 SAL_WARN_IF( bNeedSelection && !bNeedTextComponent, "svx.form", "FmTextControlShell::GetTextAttributeState: bNeedSelection should imply bNeedTextComponent!" );
974
975 if ( !bDisable && bNeedWriteableControl )
977
978 if ( !bDisable && bNeedTextComponent )
979 bDisable |= !m_xActiveTextComponent.is();
980
981 if ( !bDisable && bNeedSelection )
982 {
983 css::awt::Selection aSelection = m_xActiveTextComponent->getSelection();
984 bDisable |= aSelection.Min == aSelection.Max;
985 }
986
987 if ( bDisable )
988 _rSet.DisableItem( nSlot );
989 }
990
991 nSlot = aIter.NextWhich();
992 }
993 }
994
995
996 bool FmTextControlShell::IsActiveControl( bool _bCountRichTextOnly ) const
997 {
998 if ( _bCountRichTextOnly && !m_bActiveControlIsRichText )
999 return false;
1000
1001 return m_bActiveControl;
1002 }
1003
1004
1006 {
1007 if ( IsActiveControl() )
1009 if ( isControllerListening() )
1011 }
1012
1013
1015 {
1017 }
1018
1019
1020 void FmTextControlShell::formActivated( const Reference< runtime::XFormController >& _rxController )
1021 {
1022#if OSL_DEBUG_LEVEL > 0
1023 SAL_INFO("svx.form", "0x" << OUString::number( reinterpret_cast<sal_IntPtr>(_rxController.get()), 16 ));
1024#endif
1025
1026 DBG_ASSERT( _rxController.is(), "FmTextControlShell::formActivated: invalid controller!" );
1027 if ( !_rxController.is() )
1028 return;
1029
1030 // sometimes, a form controller notifies activations, even if it's already activated
1031 if ( m_xActiveController == _rxController )
1032 return;
1033
1034 try
1035 {
1036 startControllerListening( _rxController );
1037 controlActivated( _rxController->getCurrentControl() );
1038 }
1039 catch( const Exception& )
1040 {
1042 }
1043 }
1044
1045
1046 void FmTextControlShell::formDeactivated( const Reference< runtime::XFormController >& _rxController )
1047 {
1048 SAL_INFO("svx.form", "0x" << OUString::number( reinterpret_cast<sal_IntPtr>(_rxController.get()), 16 ));
1049
1050 if ( IsActiveControl() )
1052 if ( isControllerListening() )
1054 }
1055
1056
1057 void FmTextControlShell::startControllerListening( const Reference< runtime::XFormController >& _rxController )
1058 {
1059 OSL_PRECOND( _rxController.is(), "FmTextControlShell::startControllerListening: invalid controller!" );
1060 if ( !_rxController.is() )
1061 return;
1062
1063 OSL_PRECOND( !isControllerListening(), "FmTextControlShell::startControllerListening: already listening!" );
1064 if ( isControllerListening() )
1066 DBG_ASSERT( !isControllerListening(), "FmTextControlShell::startControllerListening: inconsistence!" );
1067
1068 try
1069 {
1070 const Sequence< Reference< css::awt::XControl > > aControls( _rxController->getControls() );
1071 m_aControlObservers.resize( 0 );
1072 m_aControlObservers.reserve( aControls.getLength() );
1073
1074 std::transform(aControls.begin(), aControls.end(), std::back_inserter(m_aControlObservers),
1075 [this](const Reference< css::awt::XControl >& rControl) -> FocusListenerAdapter {
1076 return FocusListenerAdapter( new FmFocusListenerAdapter( rControl, this ) ); });
1077 }
1078 catch( const Exception& )
1079 {
1081 }
1082
1083 m_xActiveController = _rxController;
1084 }
1085
1086
1088 {
1089 OSL_PRECOND( isControllerListening(), "FmTextControlShell::stopControllerListening: inconsistence!" );
1090
1091 // dispose all listeners associated with the controls of the active controller
1092 for (auto& rpObserver : m_aControlObservers)
1093 {
1094 rpObserver->dispose();
1095 }
1096
1098
1099 m_xActiveController.clear();
1100 }
1101
1102
1104 {
1105 // no more features for this control
1106 for (auto& rFeature : m_aControlFeatures)
1107 {
1108 rFeature.second->dispose();
1109 }
1110
1112
1114 {
1115 m_aContextMenuObserver->dispose();
1117 }
1118
1119 if ( m_xActiveTextComponent.is() )
1120 {
1121 SAL_INFO("svx.form", "stopping timer for clipboard invalidation" );
1123 }
1124 // no more active control
1125 m_xActiveControl.clear();
1126 m_xActiveTextComponent.clear();
1129 m_bActiveControl = false;
1130 }
1131
1132
1134 {
1135 DBG_ASSERT( IsActiveControl(), "FmTextControlShell::controlDeactivated: no active control!" );
1136
1137 m_bActiveControl = false;
1138
1140 }
1141
1142
1143 void FmTextControlShell::controlActivated( const Reference< css::awt::XControl >& _rxControl )
1144 {
1145 // ensure that all knittings with the previously active control are lost
1146 if ( m_xActiveControl.is() )
1148 DBG_ASSERT( m_aControlFeatures.empty(), "FmTextControlShell::controlActivated: should have no dispatchers when I'm here!" );
1149
1150#if OSL_DEBUG_LEVEL > 0
1151 {
1152 Sequence< Reference< css::awt::XControl > > aActiveControls;
1153 if ( m_xActiveController.is() )
1154 aActiveControls = m_xActiveController->getControls();
1155
1156 bool bFoundThisControl = false;
1157
1158 const Reference< css::awt::XControl >* pControls = aActiveControls.getConstArray();
1159 const Reference< css::awt::XControl >* pControlsEnd = pControls + aActiveControls.getLength();
1160 for ( ; ( pControls != pControlsEnd ) && !bFoundThisControl; ++pControls )
1161 {
1162 if ( *pControls == _rxControl )
1163 bFoundThisControl = true;
1164 }
1165 DBG_ASSERT( bFoundThisControl, "FmTextControlShell::controlActivated: only controls which belong to the active controller can be activated!" );
1166 }
1167#endif
1168 // ask the control for dispatchers for our text-related slots
1170
1171 // remember this control
1172 m_xActiveControl = _rxControl;
1173 m_xActiveTextComponent.set(_rxControl, css::uno::UNO_QUERY);
1174 m_bActiveControlIsReadOnly = lcl_determineReadOnly( m_xActiveControl );
1175 m_bActiveControlIsRichText = lcl_isRichText( m_xActiveControl );
1176
1177 // if we found a rich text control, we need context menu support
1179 {
1180 DBG_ASSERT( !m_aContextMenuObserver, "FmTextControlShell::controlActivated: already have an observer!" );
1182 }
1183
1184 if ( m_xActiveTextComponent.is() )
1185 {
1186 SAL_INFO("svx.form", "starting timer for clipboard invalidation" );
1188 }
1189
1190 m_bActiveControl = true;
1191
1193
1194 if ( m_pViewFrame )
1196
1197 // don't call the activation handler if we don't have any slots we can serve
1198 // The activation handler is used to put the shell on the top of the dispatcher stack,
1199 // so it's preferred when slots are distributed.
1200 // Note that this is a slight hack, to prevent that we grab slots from the SfxDispatcher
1201 // which should be served by other shells (e.g. Cut/Copy/Paste).
1202 // A real solution would be a forwarding-mechanism for slots: We should be on the top
1203 // if we're active, but if we cannot handle the slot, then we need to tell the dispatcher
1204 // to skip our shell, and pass the slot to the next one. However, this mechanism is not
1205 // not in place in SFX.
1206 // Another possibility would be to have dedicated shells for the slots which we might
1207 // or might not be able to serve. However, this could probably increase the number of
1208 // shells too much (In theory, nearly every slot could have an own shell then).
1209
1210 // #i51621# / 2005-08-19 / frank.schoenheit@sun.com
1211 // bool bHaveAnyServeableSlots = m_xActiveTextComponent.is() || !m_aControlFeatures.empty();
1212 // LEM: not calling m_aControlActivatonHandler causes fdo#63695, so disable this hack for now.
1214
1216 }
1217
1218
1219 void FmTextControlShell::fillFeatureDispatchers(const Reference< css::awt::XControl >& _rxControl, SfxSlotId* _pZeroTerminatedSlots,
1220 ControlFeatures& _rDispatchers)
1221 {
1222 Reference< XDispatchProvider > xProvider( _rxControl, UNO_QUERY );
1223 SfxApplication* pApplication = SfxGetpApp();
1224 DBG_ASSERT( pApplication, "FmTextControlShell::fillFeatureDispatchers: no SfxApplication!" );
1225 if ( xProvider.is() && pApplication )
1226 {
1227 SfxSlotId* pSlots = _pZeroTerminatedSlots;
1228 while ( *pSlots )
1229 {
1230 rtl::Reference<FmTextControlFeature> pDispatcher = implGetFeatureDispatcher( xProvider, pApplication, *pSlots );
1231 if ( pDispatcher )
1232 _rDispatchers.emplace( *pSlots, pDispatcher );
1233
1234 ++pSlots;
1235 }
1236 }
1237 }
1238
1239
1240 rtl::Reference<FmTextControlFeature> FmTextControlShell::implGetFeatureDispatcher( const Reference< XDispatchProvider >& _rxProvider, SfxApplication const * _pApplication, SfxSlotId _nSlot )
1241 {
1242 OSL_PRECOND( _rxProvider.is() && _pApplication, "FmTextControlShell::implGetFeatureDispatcher: invalid arg(s)!" );
1243 URL aFeatureURL;
1244 aFeatureURL.Complete = lcl_getUnoSlotName( _nSlot );
1245 try
1246 {
1247 if ( !m_xURLTransformer.is() )
1248 {
1249 m_xURLTransformer = util::URLTransformer::create( ::comphelper::getProcessComponentContext() );
1250 }
1251 if ( m_xURLTransformer.is() )
1252 m_xURLTransformer->parseStrict( aFeatureURL );
1253 }
1254 catch( const Exception& )
1255 {
1257 }
1258 Reference< XDispatch > xDispatcher = _rxProvider->queryDispatch( aFeatureURL, OUString(), 0xFF );
1259 if ( xDispatcher.is() )
1260 return new FmTextControlFeature( xDispatcher, std::move(aFeatureURL), _nSlot, this );
1261 return nullptr;
1262 }
1263
1264
1266 {
1267 m_rBindings.Invalidate( _nSlot );
1268 // despite this method being called "Invalidate", we also update here - this gives more immediate
1269 // feedback in the UI
1270 m_rBindings.Update( _nSlot );
1271 }
1272
1273
1274 void FmTextControlShell::focusGained( const css::awt::FocusEvent& _rEvent )
1275 {
1276 Reference< css::awt::XControl > xControl( _rEvent.Source, UNO_QUERY );
1277
1278#if OSL_DEBUG_LEVEL > 0
1279 SAL_INFO("svx.form", "0x" << OUString::number( reinterpret_cast<sal_IntPtr>(xControl.get()), 16 ));
1280#endif
1281
1282 DBG_ASSERT( xControl.is(), "FmTextControlShell::focusGained: suspicious focus event!" );
1283 if ( xControl.is() )
1284 controlActivated( xControl );
1285 }
1286
1287
1288 void FmTextControlShell::focusLost( const css::awt::FocusEvent& _rEvent )
1289 {
1290 Reference< css::awt::XControl > xControl( _rEvent.Source, UNO_QUERY );
1291
1292#if OSL_DEBUG_LEVEL > 0
1293 SAL_INFO("svx.form", "0x" << OUString::number( reinterpret_cast<sal_IntPtr>(xControl.get()), 16 ));
1294#endif
1295
1296 m_bActiveControl = false;
1297 }
1298
1299
1301 {
1303 }
1304
1305
1307 {
1308 m_rBindings.GetDispatcher()->ExecutePopup( "formrichtext" );
1309 }
1310
1311
1312}
1313
1314
1315/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
SfxApplication * SfxGetpApp()
static rtl::Reference< SfxItemPool > CreatePool()
void Update(sal_uInt16 nId)
SfxDispatcher * GetDispatcher() const
void Invalidate(sal_uInt16 nId)
bool GetValue() const
void ExecutePopup(const OUString &rResName, vcl::Window *pWin=nullptr, const Point *pPos=nullptr)
sal_uInt16 GetWhich(sal_uInt16 nSlot, bool bDeep=true) const
bool IsInRange(sal_uInt16 nWhich) const
SfxItemPool * GetPool() const
SfxItemState GetItemState(sal_uInt16 nWhich, bool bSrchInParent=true, const SfxPoolItem **ppItem=nullptr) const
const SfxPoolItem * GetItem(sal_uInt16 nWhich, bool bSearchInParent=true) const
const SfxPoolItem * Put(const SfxPoolItem &rItem, sal_uInt16 nWhich)
void DisableItem(sal_uInt16 nWhich)
void InvalidateItem(sal_uInt16 nWhich)
sal_uInt16 GetSlot() const
const SfxItemSet * GetArgs() const
weld::Window * GetFrameWeld() const
void Done(bool bRemove=false)
const SfxPoolItem * GetItem(sal_uInt16 nSlotId) const
void UIFeatureChanged()
static SfxSlotPool & GetSlotPool(SfxViewFrame *pFrame=nullptr)
const SfxSlot * GetSlot(sal_uInt16 nId) const
const char * GetUnoName() const
virtual SfxObjectShell * GetObjectShell() override
sal_uInt16 FirstWhich()
sal_uInt16 NextWhich()
FontStrikeout GetStrikeout() const
FontLineStyle GetLineStyle() const
void Stop()
void SetTimeout(sal_uInt64 nTimeoutMs)
void SetInvokeHandler(const Link< Timer *, void > &rLink)
virtual void Start(bool bStartTimer=true) override
static TransferableDataHelper CreateFromSystemClipboard(vcl::Window *pWindow)
bool HasFormat(SotClipboardFormatId nFormat) const
static vcl::Window * GetWindow(const css::uno::Reference< css::awt::XWindow > &rxWindow)
static SVT_DLLPUBLIC bool PasteString(OUString &_rContent, vcl::Window *_pWindow)
static SVT_DLLPUBLIC void CopyString(const OUString &_rContent, vcl::Window *_pWindow)
FmFocusListenerAdapter(const Reference< css::awt::XControl > &_rxControl, IFocusObserver *_pObserver)
virtual void SAL_CALL focusGained(const css::awt::FocusEvent &e) override
virtual void SAL_CALL disposing(const EventObject &Source) override
virtual void SAL_CALL focusLost(const css::awt::FocusEvent &e) override
virtual ~FmFocusListenerAdapter() override
Reference< css::awt::XWindow > m_xWindow
virtual void SAL_CALL mouseExited(const css::awt::MouseEvent &e) override
virtual void SAL_CALL mousePressed(const css::awt::MouseEvent &e) override
IContextRequestObserver * m_pObserver
virtual ~FmMouseListenerAdapter() override
virtual void SAL_CALL mouseReleased(const css::awt::MouseEvent &e) override
Reference< css::awt::XWindow > m_xWindow
virtual void SAL_CALL mouseEntered(const css::awt::MouseEvent &e) override
FmMouseListenerAdapter(const Reference< css::awt::XControl > &_rxControl, IContextRequestObserver *_pObserver)
virtual void SAL_CALL disposing(const EventObject &Source) override
ControlFeatures m_aControlFeatures
void controlDeactivated()
to be called when the currently active control has been deactivated
css::uno::Reference< css::awt::XTextComponent > m_xActiveTextComponent
::std::map< SfxSlotId, ControlFeature > ControlFeatures
Link< LinkParamNone *, void > m_aControlActivationHandler
void stopControllerListening()
stops listening at the active controller @precond we have an active controller currently
void GetTextAttributeState(SfxItemSet &_rSet)
void ExecuteTextAttribute(SfxRequest &_rReq)
void Invalidate(SfxSlotId _nSlot)
static void transferFeatureStatesToItemSet(ControlFeatures &_rDispatchers, SfxAllItemSet &_rSet, bool _bTranslateLatin)
creates SfxPoolItes for all features in the given set, and puts them into the given SfxAllItemSet
css::uno::Reference< css::form::runtime::XFormController > m_xActiveController
::std::vector< FocusListenerAdapter > FocusListenerAdapters
void controlActivated(const css::uno::Reference< css::awt::XControl > &_rxControl)
to be called when a control has been activated
css::uno::Reference< css::util::XURLTransformer > m_xURLTransformer
void designModeChanged()
notifies the instance that the design mode has changed
bool IsActiveControl(bool _bCountRichTextOnly=false) const
void formActivated(const css::uno::Reference< css::form::runtime::XFormController > &_rxController)
to be called when a form in our document has been activated
MouseListenerAdapter m_aContextMenuObserver
void startControllerListening(const css::uno::Reference< css::form::runtime::XFormController > &_rxController)
starts listening at all controls of the given controller for focus events @precond we don't have an a...
FocusListenerAdapters m_aControlObservers
FmTextControlShell(SfxViewFrame *_pFrame)
virtual void focusGained(const css::awt::FocusEvent &_rEvent) override
css::uno::Reference< css::awt::XControl > m_xActiveControl
virtual void focusLost(const css::awt::FocusEvent &_rEvent) override
virtual void contextMenuRequested() override
void executeAttributeDialog(AttributeSet _eSet, SfxRequest &_rReq)
rtl::Reference< FmTextControlFeature > implGetFeatureDispatcher(const css::uno::Reference< css::frame::XDispatchProvider > &_rxProvider, SfxApplication const *_pApplication, SfxSlotId _nSlot)
void fillFeatureDispatchers(const css::uno::Reference< css::awt::XControl > &_rxControl, SfxSlotId *_pZeroTerminatedSlots, ControlFeatures &_rDispatchers)
void executeClipboardSlot(SfxSlotId _nSlot)
void formDeactivated(const css::uno::Reference< css::form::runtime::XFormController > &_rxController)
to be called when a form in our document has been deactivated
rtl::Reference< FmMouseListenerAdapter > MouseListenerAdapter
virtual void contextMenuRequested()=0
virtual void focusGained(const css::awt::FocusEvent &_rEvent)=0
virtual void focusLost(const css::awt::FocusEvent &_rEvent)=0
#define DBG_ASSERT(sCon, aError)
#define DBG_UNHANDLED_EXCEPTION(...)
virtual SfxBindings & GetBindings() override
ULONG m_refCount
constexpr OUStringLiteral FM_PROP_READONLY
Definition: fmprop.hxx:48
FontLineStyle
LINESTYLE_SINGLE
LINESTYLE_NONE
FontStrikeout
STRIKEOUT_SINGLE
STRIKEOUT_NONE
bool bReadOnly
Sequence< PropertyValue > aArguments
#define SAL_WARN_IF(condition, area, stream)
#define SAL_WARN(area, stream)
#define SAL_INFO(area, stream)
@ Exception
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
sal_uInt16 SfxSlotId
static SfxSlotId pDialogSlots[]
static SfxSlotId pTextControlSlots[]
::cppu::WeakImplHelper< css::awt::XMouseListener > FmMouseListenerAdapter_Base
::cppu::WeakImplHelper< css::awt::XFocusListener > FmFocusListenerAdapter_Base
sal_uInt16 SfxSlotId
IMPL_LINK_NOARG(SuggestionDisplay, SelectSuggestionValueSetHdl, ValueSet *, void)
sal_uInt16 WhichId
SFX2_DLLPUBLIC void TransformParameters(sal_uInt16 nSlotId, const css::uno::Sequence< css::beans::PropertyValue > &seqArgs, SfxAllItemSet &aSet, const SfxSlot *pSlot=nullptr)
SFX2_DLLPUBLIC void TransformItems(sal_uInt16 nSlotId, const SfxItemSet &aSet, css::uno::Sequence< css::beans::PropertyValue > &seqArgs, const SfxSlot *pSlot=nullptr)
OUString sMessage
RET_OK