LCOV - code coverage report
Current view: top level - sc/source/ui/Accessibility - AccessiblePageHeader.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 157 194 80.9 %
Date: 2015-06-13 12:38:46 Functions: 22 24 91.7 %
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             : #include "AccessiblePageHeader.hxx"
      21             : #include "AccessiblePageHeaderArea.hxx"
      22             : #include "AccessibilityHints.hxx"
      23             : #include "prevwsh.hxx"
      24             : #include "miscuno.hxx"
      25             : #include "prevloc.hxx"
      26             : #include "document.hxx"
      27             : #include "stlpool.hxx"
      28             : #include "scitems.hxx"
      29             : #include "attrib.hxx"
      30             : #include "scresid.hxx"
      31             : #include "sc.hrc"
      32             : 
      33             : #include <com/sun/star/accessibility/AccessibleRole.hpp>
      34             : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      35             : #include <com/sun/star/accessibility/AccessibleEventId.hpp>
      36             : 
      37             : #include <vcl/window.hxx>
      38             : #include <svl/smplhint.hxx>
      39             : #include <vcl/svapp.hxx>
      40             : #include <unotools/accessiblestatesethelper.hxx>
      41             : #include <svl/style.hxx>
      42             : #include <svl/itempool.hxx>
      43             : #include <editeng/editobj.hxx>
      44             : #include <toolkit/helper/convert.hxx>
      45             : 
      46             : #include <algorithm>
      47             : 
      48             : using namespace ::com::sun::star;
      49             : using namespace ::com::sun::star::accessibility;
      50             : 
      51             : const sal_uInt8     MAX_AREAS = 3;
      52             : 
      53             : //=====  internal  ============================================================
      54             : struct Acquire
      55             : {
      56          24 :     void operator() (ScAccessiblePageHeaderArea* pArea)
      57             :     {
      58          24 :         if (pArea)
      59          13 :             pArea->acquire();
      60          24 :     }
      61             : };
      62             : 
      63             : struct Release
      64             : {
      65          24 :     void operator() (ScAccessiblePageHeaderArea*& pArea)
      66             :     {
      67          24 :         if (pArea)
      68          13 :             pArea->release();
      69          24 :     }
      70             : };
      71             : 
      72             : struct Dispose
      73             : {
      74          33 :     void operator() (ScAccessiblePageHeaderArea*& pArea)
      75             :     {
      76          33 :         if (pArea)
      77             :         {
      78          13 :             pArea->dispose();
      79          13 :             pArea->release();
      80             :         }
      81          33 :         pArea = NULL;
      82          33 :     }
      83             : };
      84             : 
      85          11 : ScAccessiblePageHeader::ScAccessiblePageHeader( const ::com::sun::star::uno::Reference<
      86             :                                 ::com::sun::star::accessibility::XAccessible>& rxParent,
      87             :                             ScPreviewShell* pViewShell, bool bHeader, sal_Int32 nIndex ) :
      88             : ScAccessibleContextBase( rxParent, bHeader ? AccessibleRole::HEADER : AccessibleRole::FOOTER ),
      89             :     mpViewShell( pViewShell ),
      90             :     mnIndex( nIndex ),
      91             :     mbHeader( bHeader ),
      92             :     maAreas(MAX_AREAS, NULL),
      93          11 :     mnChildCount(-1)
      94             : {
      95          11 :     if (mpViewShell)
      96          11 :         mpViewShell->AddAccessibilityObject(*this);
      97          11 : }
      98             : 
      99          33 : ScAccessiblePageHeader::~ScAccessiblePageHeader()
     100             : {
     101          11 :     if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
     102             :     {
     103             :         // increment refcount to prevent double call off dtor
     104           0 :         osl_atomic_increment( &m_refCount );
     105           0 :         dispose();
     106             :     }
     107          22 : }
     108             : 
     109          11 : void SAL_CALL ScAccessiblePageHeader::disposing()
     110             : {
     111          11 :     SolarMutexGuard aGuard;
     112          11 :     if (mpViewShell)
     113             :     {
     114          11 :         mpViewShell->RemoveAccessibilityObject(*this);
     115          11 :         mpViewShell = NULL;
     116             :     }
     117          11 :     std::for_each(maAreas.begin(), maAreas.end(), Dispose());
     118             : 
     119          11 :     ScAccessibleContextBase::disposing();
     120          11 : }
     121             : 
     122             : //=====  SfxListener  =====================================================
     123             : 
     124          40 : void ScAccessiblePageHeader::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     125             : {
     126          40 :     const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>( &rHint );
     127          40 :     if (pSimpleHint)
     128             :     {
     129             :         // only notify if child exist, otherwise it is not necessary
     130          29 :         if (pSimpleHint->GetId() == SC_HINT_DATACHANGED)
     131             :         {
     132           8 :             ScHFAreas aOldAreas(maAreas);
     133           8 :             std::for_each(aOldAreas.begin(), aOldAreas.end(), Acquire());
     134           8 :             mnChildCount = -1;
     135           8 :             getAccessibleChildCount();
     136          32 :             for (sal_uInt8 i = 0; i < MAX_AREAS; ++i)
     137             :             {
     138          85 :                 if ((aOldAreas[i] && maAreas[i] && !ScGlobal::EETextObjEqual(aOldAreas[i]->GetEditTextObject(), maAreas[i]->GetEditTextObject())) ||
     139          61 :                     (aOldAreas[i] && !maAreas[i]) || (!aOldAreas[i] && maAreas[i]))
     140             :                 {
     141           3 :                     if (aOldAreas[i] && aOldAreas[i]->GetEditTextObject())
     142             :                     {
     143           0 :                         AccessibleEventObject aEvent;
     144           0 :                         aEvent.EventId = AccessibleEventId::CHILD;
     145           0 :                         aEvent.Source = uno::Reference< XAccessibleContext >(this);
     146           0 :                         aEvent.OldValue = uno::makeAny(uno::Reference<XAccessible>(aOldAreas[i]));
     147             : 
     148           0 :                         CommitChange(aEvent); // child gone - event
     149           0 :                         aOldAreas[i]->dispose();
     150             :                     }
     151           3 :                     if (maAreas[i] && maAreas[i]->GetEditTextObject())
     152             :                     {
     153           3 :                         AccessibleEventObject aEvent;
     154           3 :                         aEvent.EventId = AccessibleEventId::CHILD;
     155           3 :                         aEvent.Source = uno::Reference< XAccessibleContext >(this);
     156           3 :                         aEvent.NewValue = uno::makeAny(uno::Reference<XAccessible>(maAreas[i]));
     157             : 
     158           3 :                         CommitChange(aEvent); // new child - event
     159             :                     }
     160             :                 }
     161             :             }
     162           8 :             std::for_each(aOldAreas.begin(), aOldAreas.end(), Release());
     163             :         }
     164          21 :         else if (pSimpleHint->GetId() == SC_HINT_ACC_VISAREACHANGED)
     165             :         {
     166          10 :             AccessibleEventObject aEvent;
     167          10 :             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
     168          10 :             aEvent.Source = uno::Reference< XAccessibleContext >(this);
     169          10 :             CommitChange(aEvent);
     170             :         }
     171             :     }
     172             : 
     173          40 :     ScAccessibleContextBase::Notify(rBC, rHint);
     174          40 : }
     175             : 
     176             : //=====  XAccessibleComponent  ============================================
     177             : 
     178           0 : uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleAtPoint( const awt::Point& aPoint )
     179             :                                 throw (uno::RuntimeException, std::exception)
     180             : {
     181           0 :     uno::Reference<XAccessible> xRet;
     182             : 
     183           0 :     if (containsPoint(aPoint))
     184             :     {
     185           0 :         SolarMutexGuard aGuard;
     186           0 :         IsObjectValid();
     187             : 
     188           0 :         sal_Int32 nCount(getAccessibleChildCount()); // fill the areas
     189             : 
     190           0 :         if (nCount)
     191             :         {
     192             :             // return the first with content, because they have all the same Bounding Box
     193           0 :             sal_uInt8 i(0);
     194           0 :             while(!xRet.is() && i < MAX_AREAS)
     195             :             {
     196           0 :                 if (maAreas[i])
     197           0 :                     xRet = maAreas[i];
     198             :                 else
     199           0 :                     ++i;
     200             :             }
     201           0 :         }
     202             :     }
     203             : 
     204           0 :     return xRet;
     205             : }
     206             : 
     207           1 : void SAL_CALL ScAccessiblePageHeader::grabFocus() throw (uno::RuntimeException, std::exception)
     208             : {
     209           1 :      SolarMutexGuard aGuard;
     210           1 :     IsObjectValid();
     211           1 :     if (getAccessibleParent().is())
     212             :     {
     213           1 :         uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
     214           1 :         if (xAccessibleComponent.is())
     215           1 :             xAccessibleComponent->grabFocus();
     216           1 :     }
     217           1 : }
     218             : 
     219             : //=====  XAccessibleContext  ==============================================
     220             : 
     221          47 : sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleChildCount() throw (uno::RuntimeException, std::exception)
     222             : {
     223          47 :     SolarMutexGuard aGuard;
     224          47 :     IsObjectValid();
     225             : 
     226          47 :     if((mnChildCount < 0) && mpViewShell)
     227             :     {
     228          18 :         mnChildCount = 0;
     229          18 :         ScDocument& rDoc = mpViewShell->GetDocument();
     230             :         // find out how many regions (left,center, right) are with content
     231             : 
     232          18 :         SfxStyleSheetBase* pStyle = rDoc.GetStyleSheetPool()->Find(rDoc.GetPageStyle(mpViewShell->GetLocationData().GetPrintTab()), SFX_STYLE_FAMILY_PAGE);
     233          18 :         if (pStyle)
     234             :         {
     235          18 :             sal_uInt16 nPageWhichId(0);
     236          18 :             if (mbHeader)
     237          15 :                 nPageWhichId = mpViewShell->GetLocationData().IsHeaderLeft() ? ATTR_PAGE_HEADERLEFT : ATTR_PAGE_HEADERRIGHT;
     238             :             else
     239           3 :                 nPageWhichId = mpViewShell->GetLocationData().IsFooterLeft() ? ATTR_PAGE_FOOTERLEFT : ATTR_PAGE_FOOTERRIGHT;
     240             : 
     241          18 :             const ScPageHFItem& rPageItem = static_cast<const ScPageHFItem&>(pStyle->GetItemSet().Get(nPageWhichId));
     242          18 :             AddChild(rPageItem.GetLeftArea(), 0, SVX_ADJUST_LEFT);
     243          18 :             AddChild(rPageItem.GetCenterArea(), 1, SVX_ADJUST_CENTER);
     244          18 :             AddChild(rPageItem.GetRightArea(), 2, SVX_ADJUST_RIGHT);
     245             :         }
     246             :     }
     247             : 
     248          47 :     return mnChildCount;
     249             : }
     250             : 
     251          28 : uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleChild( sal_Int32 nIndex )
     252             :                                 throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     253             : {
     254          28 :     SolarMutexGuard aGuard;
     255          28 :     IsObjectValid();
     256             : 
     257          28 :     uno::Reference<XAccessible> xRet;
     258             : 
     259          28 :     if(mnChildCount < 0)
     260           0 :         getAccessibleChildCount();
     261             : 
     262          28 :     ScHFAreas::iterator aItr = maAreas.begin();
     263          28 :     ScHFAreas::iterator aEndItr = maAreas.end();
     264         112 :     while (!xRet.is() && (nIndex >= 0) && (aItr != aEndItr))
     265             :     {
     266          56 :         if (*aItr)
     267             :         {
     268          43 :             if (nIndex == 0)
     269          28 :                 xRet = *aItr;
     270             :             else
     271          15 :                 --nIndex;
     272             :         }
     273             :         else
     274          13 :             ++aItr;
     275             :     }
     276             : 
     277          28 :     if ( !xRet.is() )
     278           0 :         throw lang::IndexOutOfBoundsException();
     279             : 
     280          28 :     return xRet;
     281             : }
     282             : 
     283           1 : sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleIndexInParent() throw (uno::RuntimeException, std::exception)
     284             : {
     285           1 :     return mnIndex;
     286             : }
     287             : 
     288          27 : uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePageHeader::getAccessibleStateSet()
     289             :                                 throw (uno::RuntimeException, std::exception)
     290             : {
     291          27 :     SolarMutexGuard aGuard;
     292          54 :     uno::Reference<XAccessibleStateSet> xParentStates;
     293          27 :     if (getAccessibleParent().is())
     294             :     {
     295          27 :         uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
     296          27 :         xParentStates = xParentContext->getAccessibleStateSet();
     297             :     }
     298          27 :     utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
     299          27 :     if (IsDefunc(xParentStates))
     300           0 :         pStateSet->AddState(AccessibleStateType::DEFUNC);
     301             :     else
     302             :     {
     303          27 :         pStateSet->AddState(AccessibleStateType::ENABLED);
     304          27 :         pStateSet->AddState(AccessibleStateType::OPAQUE);
     305          27 :         if (isShowing())
     306          27 :             pStateSet->AddState(AccessibleStateType::SHOWING);
     307          27 :         if (isVisible())
     308          27 :             pStateSet->AddState(AccessibleStateType::VISIBLE);
     309             :     }
     310          54 :     return pStateSet;
     311             : }
     312             : 
     313             : //=====  XServiceInfo  ====================================================
     314             : 
     315           2 : OUString SAL_CALL ScAccessiblePageHeader::getImplementationName() throw(uno::RuntimeException, std::exception)
     316             : {
     317           2 :     return OUString("ScAccessiblePageHeader");
     318             : }
     319             : 
     320           0 : uno::Sequence<OUString> SAL_CALL ScAccessiblePageHeader::getSupportedServiceNames()
     321             :                                                     throw(uno::RuntimeException, std::exception)
     322             : {
     323           0 :     uno::Sequence< OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
     324           0 :     sal_Int32 nOldSize(aSequence.getLength());
     325           0 :     aSequence.realloc(nOldSize + 1);
     326             : 
     327           0 :     aSequence[nOldSize] = "com.sun.star.text.AccessibleHeaderFooterView";
     328             : 
     329           0 :     return aSequence;
     330             : }
     331             : 
     332             : //====  internal  =========================================================
     333             : 
     334           9 : OUString SAL_CALL ScAccessiblePageHeader::createAccessibleDescription()
     335             :                     throw (uno::RuntimeException)
     336             : {
     337           9 :     OUString sDesc(SC_RESSTR(mbHeader ? STR_ACC_HEADER_DESCR : STR_ACC_FOOTER_DESCR));
     338           9 :     return sDesc.replaceFirst("%1", SC_RESSTR(SCSTR_UNKNOWN));
     339             : }
     340             : 
     341           1 : OUString SAL_CALL ScAccessiblePageHeader::createAccessibleName()
     342             :                     throw (uno::RuntimeException, std::exception)
     343             : {
     344           1 :     OUString sName(SC_RESSTR(mbHeader ? STR_ACC_HEADER_NAME : STR_ACC_FOOTER_NAME));
     345           1 :     return sName.replaceFirst("%1", SC_RESSTR(SCSTR_UNKNOWN));
     346             : }
     347             : 
     348           1 : Rectangle ScAccessiblePageHeader::GetBoundingBoxOnScreen() const throw (uno::RuntimeException, std::exception)
     349             : {
     350           1 :     Rectangle aCellRect(GetBoundingBox());
     351           1 :     if (mpViewShell)
     352             :     {
     353           1 :         vcl::Window* pWindow = mpViewShell->GetWindow();
     354           1 :         if (pWindow)
     355             :         {
     356           1 :             Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
     357           1 :             aCellRect.setX(aCellRect.getX() + aRect.getX());
     358           1 :             aCellRect.setY(aCellRect.getY() + aRect.getY());
     359             :         }
     360             :     }
     361           1 :     return aCellRect;
     362             : }
     363             : 
     364         642 : Rectangle ScAccessiblePageHeader::GetBoundingBox() const throw (uno::RuntimeException, std::exception)
     365             : {
     366         642 :     Rectangle aRect;
     367         642 :     if (mpViewShell)
     368             :     {
     369         642 :         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
     370         642 :         if ( mbHeader )
     371         621 :             rData.GetHeaderPosition( aRect );
     372             :         else
     373          21 :             rData.GetFooterPosition( aRect );
     374             : 
     375             :         // the Rectangle could contain negative coordinates so it should be cliped
     376         642 :         Rectangle aClipRect(Point(0, 0), aRect.GetSize());
     377         642 :         vcl::Window* pWindow = mpViewShell->GetWindow();
     378         642 :         if (pWindow)
     379         642 :             aClipRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
     380         642 :         aRect = aClipRect.GetIntersection(aRect);
     381             :     }
     382         642 :     if (aRect.IsEmpty())
     383           0 :         aRect.SetSize(Size(-1, -1));
     384             : 
     385         642 :     return aRect;
     386             : }
     387             : 
     388          27 : bool ScAccessiblePageHeader::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
     389             : {
     390         108 :     return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
     391         108 :         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
     392             : }
     393             : 
     394          54 : void ScAccessiblePageHeader::AddChild(const EditTextObject* pArea, sal_uInt32 nIndex, SvxAdjust eAdjust)
     395             : {
     396          54 :     if (pArea && (!pArea->GetText(0).isEmpty() || (pArea->GetParagraphCount() > 1)))
     397             :     {
     398          26 :         if (maAreas[nIndex])
     399             :         {
     400          13 :             if (!ScGlobal::EETextObjEqual(maAreas[nIndex]->GetEditTextObject(), pArea))
     401             :             {
     402           0 :                 maAreas[nIndex]->release();
     403           0 :                 maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
     404           0 :                 maAreas[nIndex]->acquire();
     405             :             }
     406             :         }
     407             :         else
     408             :         {
     409          13 :             maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
     410          13 :             maAreas[nIndex]->acquire();
     411             :         }
     412          26 :         ++mnChildCount;
     413             :     }
     414             :     else
     415             :     {
     416          28 :         if (maAreas[nIndex])
     417             :         {
     418           0 :             maAreas[nIndex]->release();
     419           0 :             maAreas[nIndex] = NULL;
     420             :         }
     421             :     }
     422         210 : }
     423             : 
     424             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11