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