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