LCOV - code coverage report
Current view: top level - libreoffice/svx/source/form - fmtextcontrolshell.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 21 484 4.3 %
Date: 2012-12-27 Functions: 8 52 15.4 %
Legend: Lines: hit not hit

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

Generated by: LCOV version 1.10