LCOV - code coverage report
Current view: top level - svx/source/accessibility - AccessibleEmptyEditSource.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 45 129 34.9 %
Date: 2014-11-03 Functions: 25 75 33.3 %
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             : 
      22             : 
      23             : // Global header
      24             : 
      25             : 
      26             : #include <svl/itemset.hxx>
      27             : #include <editeng/editdata.hxx>
      28             : #include <editeng/outliner.hxx>
      29             : #include <svx/svdmodel.hxx>
      30             : #include <svx/svdobj.hxx>
      31             : #include <svx/svdpool.hxx>
      32             : 
      33             : 
      34             : 
      35             : // Project-local header
      36             : 
      37             : 
      38             : 
      39             : #include "AccessibleEmptyEditSource.hxx"
      40             : #include <svx/unoshtxt.hxx>
      41             : 
      42             : namespace accessibility
      43             : {
      44             : 
      45             :     /** This class simply wraps a SvxTextEditSource, forwarding all
      46             :         methods except the GetBroadcaster() call
      47             :      */
      48             :     class AccessibleProxyEditSource_Impl : public SvxEditSource
      49             :     {
      50             :     public:
      51             :         /** Construct AccessibleEmptyEditSource_Impl
      52             : 
      53             :             @param rBrdCast
      54             : 
      55             :             Proxy broadcaster to allow seamless flipping of edit source implementations. ProxyEditSource and EmptyEditSource
      56             :          */
      57             :         AccessibleProxyEditSource_Impl( SdrObject&      rObj,
      58             :                                         SdrView&        rView,
      59             :                                         const vcl::Window&   rViewWindow );
      60             :         virtual ~AccessibleProxyEditSource_Impl();
      61             : 
      62             :         // from the SvxEditSource interface
      63             :         SvxTextForwarder*       GetTextForwarder() SAL_OVERRIDE;
      64             :         SvxViewForwarder*       GetViewForwarder() SAL_OVERRIDE;
      65             :         SvxEditViewForwarder*   GetEditViewForwarder( bool bCreate = false ) SAL_OVERRIDE;
      66             : 
      67             :         SvxEditSource*          Clone() const SAL_OVERRIDE;
      68             : 
      69             :         void                    UpdateData() SAL_OVERRIDE;
      70             : 
      71             :         SfxBroadcaster&         GetBroadcaster() const SAL_OVERRIDE;
      72             : 
      73             :     private:
      74             :         SvxTextEditSource       maEditSource;
      75             : 
      76             :     };
      77             : 
      78             :     /** Dummy class, faking exactly one empty paragraph for EditEngine accessibility
      79             :      */
      80             :     class AccessibleEmptyEditSource_Impl : public SvxEditSource, public SvxViewForwarder, public SvxTextForwarder, public SfxBroadcaster
      81             :     {
      82             :     public:
      83             : 
      84           8 :         AccessibleEmptyEditSource_Impl() {}
      85          16 :         virtual ~AccessibleEmptyEditSource_Impl() {}
      86             : 
      87             :         // SvxEditSource
      88          78 :         SvxTextForwarder*       GetTextForwarder() SAL_OVERRIDE { return this; }
      89          26 :         SvxViewForwarder*       GetViewForwarder() SAL_OVERRIDE { return this; }
      90           0 :         SvxEditSource*          Clone() const SAL_OVERRIDE { return NULL; }
      91           0 :         void                    UpdateData() SAL_OVERRIDE {}
      92           0 :         SfxBroadcaster&         GetBroadcaster() const SAL_OVERRIDE { return *(const_cast<AccessibleEmptyEditSource_Impl*>(this)); }
      93             : 
      94             :         // SvxTextForwarder
      95          36 :         sal_Int32          GetParagraphCount() const SAL_OVERRIDE { return 1; }
      96          12 :         sal_Int32          GetTextLen( sal_Int32 /*nParagraph*/ ) const SAL_OVERRIDE { return 0; }
      97          12 :         OUString           GetText( const ESelection& /*rSel*/ ) const SAL_OVERRIDE { return OUString(); }
      98           0 :         SfxItemSet         GetAttribs( const ESelection& /*rSel*/, EditEngineAttribs /*nOnlyHardAttrib*/ = EditEngineAttribs_All ) const SAL_OVERRIDE
      99             :         {
     100             :             // AW: Very dangerous: The former implementation used a SfxItemPool created on the
     101             :             // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
     102             :             // a deleted Pool by design.
     103           0 :             return SfxItemSet(SdrObject::GetGlobalDrawObjectItemPool());
     104             :         }
     105           0 :         SfxItemSet      GetParaAttribs( sal_Int32 /*nPara*/ ) const SAL_OVERRIDE { return GetAttribs(ESelection()); }
     106           0 :         void            SetParaAttribs( sal_Int32 /*nPara*/, const SfxItemSet& /*rSet*/ ) SAL_OVERRIDE {}
     107           0 :         void            RemoveAttribs( const ESelection& /*rSelection*/, bool /*bRemoveParaAttribs*/, sal_uInt16 /*nWhich*/ ) SAL_OVERRIDE {}
     108           0 :         void            GetPortions( sal_Int32 /*nPara*/, std::vector<sal_Int32>& /*rList*/ ) const SAL_OVERRIDE {}
     109             : 
     110           0 :         SfxItemState    GetItemState( const ESelection& /*rSel*/, sal_uInt16 /*nWhich*/ ) const SAL_OVERRIDE { return SfxItemState::UNKNOWN; }
     111           0 :         SfxItemState    GetItemState( sal_Int32 /*nPara*/, sal_uInt16 /*nWhich*/ ) const SAL_OVERRIDE { return SfxItemState::UNKNOWN; }
     112             : 
     113           0 :         SfxItemPool*    GetPool() const SAL_OVERRIDE { return NULL; }
     114             : 
     115           0 :         void            QuickInsertText( const OUString& /*rText*/, const ESelection& /*rSel*/ ) SAL_OVERRIDE {}
     116           0 :         void            QuickInsertField( const SvxFieldItem& /*rFld*/, const ESelection& /*rSel*/ ) SAL_OVERRIDE {}
     117           0 :         void            QuickSetAttribs( const SfxItemSet& /*rSet*/, const ESelection& /*rSel*/ ) SAL_OVERRIDE {}
     118           0 :         void            QuickInsertLineBreak( const ESelection& /*rSel*/ ) SAL_OVERRIDE {}
     119             : 
     120           0 :         const SfxItemSet * GetEmptyItemSetPtr() SAL_OVERRIDE { return 0; }
     121             : 
     122           0 :         void        AppendParagraph() SAL_OVERRIDE {}
     123           0 :         sal_Int32  AppendTextPortion( sal_Int32 /*nPara*/, const OUString & /*rText*/, const SfxItemSet & /*rSet*/ ) SAL_OVERRIDE { return 0; }
     124             : 
     125             :         //XTextCopy
     126           0 :         void        CopyText(const SvxTextForwarder& ) SAL_OVERRIDE {}
     127             : 
     128           0 :         OUString    CalcFieldValue( const SvxFieldItem& /*rField*/, sal_Int32 /*nPara*/, sal_Int32 /*nPos*/, Color*& /*rpTxtColor*/, Color*& /*rpFldColor*/ ) SAL_OVERRIDE
     129             :         {
     130           0 :             return  OUString();
     131             :         }
     132           0 :         void            FieldClicked( const SvxFieldItem&, sal_Int32, sal_Int32 ) SAL_OVERRIDE {;}
     133             : 
     134         104 :         bool            IsValid() const SAL_OVERRIDE { return true; }
     135             : 
     136           0 :         LanguageType    GetLanguage( sal_Int32, sal_Int32 ) const SAL_OVERRIDE { return LANGUAGE_DONTKNOW; }
     137          36 :         sal_Int32       GetFieldCount( sal_Int32 ) const SAL_OVERRIDE { return 0; }
     138           0 :         EFieldInfo      GetFieldInfo( sal_Int32, sal_uInt16 ) const SAL_OVERRIDE { return EFieldInfo(); }
     139          90 :         EBulletInfo     GetBulletInfo( sal_Int32 ) const SAL_OVERRIDE { return EBulletInfo(); }
     140           0 :         Rectangle       GetCharBounds( sal_Int32, sal_Int32 ) const SAL_OVERRIDE { return Rectangle(); }
     141          26 :         Rectangle       GetParaBounds( sal_Int32 ) const SAL_OVERRIDE { return Rectangle(); }
     142          26 :         MapMode         GetMapMode() const SAL_OVERRIDE { return MapMode(); }
     143           0 :         OutputDevice*   GetRefDevice() const SAL_OVERRIDE { return NULL; }
     144           0 :         bool            GetIndexAtPoint( const Point&, sal_Int32&, sal_Int32& ) const SAL_OVERRIDE { return false; }
     145           0 :         bool            GetWordIndices( sal_Int32, sal_Int32, sal_Int32&, sal_Int32& ) const SAL_OVERRIDE { return false; }
     146           0 :         bool            GetAttributeRun( sal_Int32&, sal_Int32&, sal_Int32, sal_Int32, bool ) const SAL_OVERRIDE { return false; }
     147           0 :         sal_Int32       GetLineCount( sal_Int32 nPara ) const SAL_OVERRIDE { return nPara == 0 ? 1 : 0; }
     148           0 :         sal_Int32       GetLineLen( sal_Int32, sal_Int32 ) const SAL_OVERRIDE { return 0; }
     149           0 :         void            GetLineBoundaries( /*out*/sal_Int32 & rStart, /*out*/sal_Int32 & rEnd, sal_Int32 /*nParagraph*/, sal_Int32 /*nLine*/ ) const SAL_OVERRIDE  { rStart = rEnd = 0; }
     150           0 :         sal_Int32       GetLineNumberAtIndex( sal_Int32 /*nPara*/, sal_Int32 /*nIndex*/ ) const SAL_OVERRIDE   { return 0; }
     151             : 
     152             :         // the following two methods would, strictly speaking, require
     153             :         // a switch to a real EditSource, too. Fortunately, the
     154             :         // AccessibleEditableTextPara implementation currently always
     155             :         // calls GetEditViewForwarder(true) before doing
     156             :         // changes. Thus, we rely on this behabviour here (problem
     157             :         // when that changes: via accessibility API, it would no
     158             :         // longer be possible to enter text in previously empty
     159             :         // shapes).
     160           0 :         bool            Delete( const ESelection& ) SAL_OVERRIDE { return false; }
     161           0 :         bool            InsertText( const OUString&, const ESelection& ) SAL_OVERRIDE { return false; }
     162           0 :         bool            QuickFormatDoc( bool ) SAL_OVERRIDE { return true; }
     163           0 :         sal_Int16       GetDepth( sal_Int32 ) const SAL_OVERRIDE { return -1; }
     164           0 :         bool            SetDepth( sal_Int32, sal_Int16 ) SAL_OVERRIDE { return true; }
     165             : 
     166          12 :         Rectangle       GetVisArea() const SAL_OVERRIDE { return Rectangle(); }
     167          52 :         Point           LogicToPixel( const Point& rPoint, const MapMode& /*rMapMode*/ ) const SAL_OVERRIDE { return rPoint; }
     168           0 :         Point           PixelToLogic( const Point& rPoint, const MapMode& /*rMapMode*/ ) const SAL_OVERRIDE { return rPoint; }
     169             : 
     170             :     };
     171             : 
     172             : 
     173             :     // Implementing AccessibleProxyEditSource_Impl
     174             : 
     175             : 
     176           0 :     AccessibleProxyEditSource_Impl::AccessibleProxyEditSource_Impl( SdrObject&      rObj,
     177             :                                                                     SdrView&        rView,
     178             :                                                                     const vcl::Window&   rViewWindow ) :
     179           0 :         maEditSource( rObj, 0, rView, rViewWindow )
     180             :     {
     181           0 :     }
     182             : 
     183           0 :     AccessibleProxyEditSource_Impl::~AccessibleProxyEditSource_Impl()
     184             :     {
     185           0 :     }
     186             : 
     187           0 :     SvxTextForwarder* AccessibleProxyEditSource_Impl::GetTextForwarder()
     188             :     {
     189           0 :         return maEditSource.GetTextForwarder();
     190             :     }
     191             : 
     192           0 :     SvxViewForwarder* AccessibleProxyEditSource_Impl::GetViewForwarder()
     193             :     {
     194           0 :         return maEditSource.GetViewForwarder();
     195             :     }
     196             : 
     197           0 :     SvxEditViewForwarder* AccessibleProxyEditSource_Impl::GetEditViewForwarder( bool bCreate )
     198             :     {
     199           0 :         return maEditSource.GetEditViewForwarder( bCreate );
     200             :     }
     201             : 
     202           0 :     SvxEditSource* AccessibleProxyEditSource_Impl::Clone() const
     203             :     {
     204           0 :         return maEditSource.Clone();
     205             :     }
     206             : 
     207           0 :     void AccessibleProxyEditSource_Impl::UpdateData()
     208             :     {
     209           0 :         maEditSource.UpdateData();
     210           0 :     }
     211             : 
     212           0 :     SfxBroadcaster& AccessibleProxyEditSource_Impl::GetBroadcaster() const
     213             :     {
     214           0 :         return maEditSource.GetBroadcaster();
     215             :     }
     216             : 
     217             : 
     218             : 
     219             :     // Implementing AccessibleEmptyEditSource
     220             : 
     221             : 
     222           8 :     AccessibleEmptyEditSource::AccessibleEmptyEditSource( SdrObject&    rObj,
     223             :                                                           SdrView&      rView,
     224             :                                                           const vcl::Window& rViewWindow ) :
     225           0 :         mpEditSource( new AccessibleEmptyEditSource_Impl() ),
     226             :         mrObj(rObj),
     227             :         mrView(rView),
     228             :         mrViewWindow(rViewWindow),
     229           8 :         mbEditSourceEmpty( true )
     230             :     {
     231           8 :         if( mrObj.GetModel() )
     232           8 :             StartListening( *mrObj.GetModel() );
     233           8 :     }
     234             : 
     235          24 :     AccessibleEmptyEditSource::~AccessibleEmptyEditSource()
     236             :     {
     237           8 :         if( !mbEditSourceEmpty )
     238             :         {
     239             :             // deregister as listener
     240           0 :             if( mpEditSource.get() )
     241           0 :                 EndListening( mpEditSource->GetBroadcaster() );
     242             :         }
     243             :         else
     244             :         {
     245           8 :             if( mrObj.GetModel() )
     246           8 :                 EndListening( *mrObj.GetModel() );
     247             :         }
     248          16 :     }
     249             : 
     250          78 :     SvxTextForwarder* AccessibleEmptyEditSource::GetTextForwarder()
     251             :     {
     252          78 :         if( !mpEditSource.get() )
     253           0 :             return NULL;
     254             : 
     255          78 :         return mpEditSource->GetTextForwarder();
     256             :     }
     257             : 
     258          26 :     SvxViewForwarder* AccessibleEmptyEditSource::GetViewForwarder()
     259             :     {
     260          26 :         if( !mpEditSource.get() )
     261           0 :             return NULL;
     262             : 
     263          26 :         return mpEditSource->GetViewForwarder();
     264             :     }
     265             : 
     266           0 :     void AccessibleEmptyEditSource::Switch2ProxyEditSource()
     267             :     {
     268             :         // deregister EmptyEditSource model listener
     269           0 :         if( mrObj.GetModel() )
     270           0 :             EndListening( *mrObj.GetModel() );
     271             : 
     272           0 :         ::std::unique_ptr< SvxEditSource > pProxySource( new AccessibleProxyEditSource_Impl(mrObj, mrView, mrViewWindow) );
     273           0 :         mpEditSource.swap(pProxySource);
     274             : 
     275             :         // register as listener
     276           0 :         StartListening( mpEditSource->GetBroadcaster() );
     277             : 
     278             :         // we've irrevocably a full EditSource now.
     279           0 :         mbEditSourceEmpty = false;
     280           0 :     }
     281             : 
     282          18 :     SvxEditViewForwarder* AccessibleEmptyEditSource::GetEditViewForwarder( bool bCreate )
     283             :     {
     284          18 :         if( !mpEditSource.get() )
     285           0 :             return NULL;
     286             : 
     287             :         // switch edit source, if not yet done
     288          18 :         if( mbEditSourceEmpty && bCreate )
     289           0 :             Switch2ProxyEditSource();
     290             : 
     291          18 :         return mpEditSource->GetEditViewForwarder( bCreate );
     292             :     }
     293             : 
     294           0 :     SvxEditSource* AccessibleEmptyEditSource::Clone() const
     295             :     {
     296           0 :         if( !mpEditSource.get() )
     297           0 :             return NULL;
     298             : 
     299           0 :         return mpEditSource->Clone();
     300             :     }
     301             : 
     302           0 :     void AccessibleEmptyEditSource::UpdateData()
     303             :     {
     304           0 :         if( mpEditSource.get() )
     305           0 :             mpEditSource->UpdateData();
     306           0 :     }
     307             : 
     308          16 :     SfxBroadcaster& AccessibleEmptyEditSource::GetBroadcaster() const
     309             :     {
     310          16 :         return *(const_cast<AccessibleEmptyEditSource*>(this));
     311             :     }
     312             : 
     313           4 :     void AccessibleEmptyEditSource::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
     314             :     {
     315           4 :         const SdrHint* pSdrHint = dynamic_cast<const SdrHint*>( &rHint );
     316             : 
     317           8 :         if( pSdrHint && pSdrHint->GetKind() == HINT_BEGEDIT &&
     318           4 :             &mrObj == pSdrHint->GetObject() && mpEditSource.get() )
     319             :         {
     320             :             // switch edit source, if not yet done. This is necessary
     321             :             // to become a full-fledged EditSource the first time a
     322             :             // user start entering text in a previously empty object.
     323           0 :             if( mbEditSourceEmpty )
     324           0 :                 Switch2ProxyEditSource();
     325             :         }
     326           4 :         else if (pSdrHint && pSdrHint->GetObject()!=NULL)
     327             :         {
     328             :             // When the SdrObject just got a para outliner object then
     329             :             // switch the edit source.
     330           4 :             if (pSdrHint->GetObject()->GetOutlinerParaObject() != NULL)
     331           0 :                 Switch2ProxyEditSource();
     332             :         }
     333             : 
     334             :         // forward messages
     335           4 :         Broadcast( rHint );
     336           4 :     }
     337             : 
     338         594 : } // end of namespace accessibility
     339             : 
     340             : 
     341             : 
     342             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10