LCOV - code coverage report
Current view: top level - sc/source/ui/Accessibility - AccessiblePageHeader.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 157 194 80.9 %
Date: 2014-11-03 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          48 :     void operator() (ScAccessiblePageHeaderArea* pArea)
      57             :     {
      58          48 :         if (pArea)
      59          26 :             pArea->acquire();
      60          48 :     }
      61             : };
      62             : 
      63             : struct Release
      64             : {
      65          48 :     void operator() (ScAccessiblePageHeaderArea*& pArea)
      66             :     {
      67          48 :         if (pArea)
      68          26 :             pArea->release();
      69          48 :     }
      70             : };
      71             : 
      72             : struct Dispose
      73             : {
      74          66 :     void operator() (ScAccessiblePageHeaderArea*& pArea)
      75             :     {
      76          66 :         if (pArea)
      77             :         {
      78          26 :             pArea->dispose();
      79          26 :             pArea->release();
      80             :         }
      81          66 :         pArea = NULL;
      82          66 :     }
      83             : };
      84             : 
      85          22 : 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          22 :     mnChildCount(-1)
      94             : {
      95          22 :     if (mpViewShell)
      96          22 :         mpViewShell->AddAccessibilityObject(*this);
      97          22 : }
      98             : 
      99          66 : ScAccessiblePageHeader::~ScAccessiblePageHeader()
     100             : {
     101          22 :     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          44 : }
     108             : 
     109          22 : void SAL_CALL ScAccessiblePageHeader::disposing()
     110             : {
     111          22 :     SolarMutexGuard aGuard;
     112          22 :     if (mpViewShell)
     113             :     {
     114          22 :         mpViewShell->RemoveAccessibilityObject(*this);
     115          22 :         mpViewShell = NULL;
     116             :     }
     117          22 :     std::for_each(maAreas.begin(), maAreas.end(), Dispose());
     118             : 
     119          22 :     ScAccessibleContextBase::disposing();
     120          22 : }
     121             : 
     122             : //=====  SfxListener  =====================================================
     123             : 
     124          80 : void ScAccessiblePageHeader::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
     125             : {
     126          80 :     const SfxSimpleHint* pSimpleHint = dynamic_cast<const SfxSimpleHint*>( &rHint );
     127          80 :     if (pSimpleHint)
     128             :     {
     129             :         // only notify if child exist, otherwise it is not necessary
     130          58 :         if (pSimpleHint->GetId() == SC_HINT_DATACHANGED)
     131             :         {
     132          16 :             ScHFAreas aOldAreas(maAreas);
     133          16 :             std::for_each(aOldAreas.begin(), aOldAreas.end(), Acquire());
     134          16 :             mnChildCount = -1;
     135          16 :             getAccessibleChildCount();
     136          64 :             for (sal_uInt8 i = 0; i < MAX_AREAS; ++i)
     137             :             {
     138         170 :                 if ((aOldAreas[i] && maAreas[i] && !ScGlobal::EETextObjEqual(aOldAreas[i]->GetEditTextObject(), maAreas[i]->GetEditTextObject())) ||
     139         122 :                     (aOldAreas[i] && !maAreas[i]) || (!aOldAreas[i] && maAreas[i]))
     140             :                 {
     141           6 :                     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           6 :                     if (maAreas[i] && maAreas[i]->GetEditTextObject())
     152             :                     {
     153           6 :                         AccessibleEventObject aEvent;
     154           6 :                         aEvent.EventId = AccessibleEventId::CHILD;
     155           6 :                         aEvent.Source = uno::Reference< XAccessibleContext >(this);
     156           6 :                         aEvent.NewValue = uno::makeAny(uno::Reference<XAccessible>(maAreas[i]));
     157             : 
     158           6 :                         CommitChange(aEvent); // new child - event
     159             :                     }
     160             :                 }
     161             :             }
     162          16 :             std::for_each(aOldAreas.begin(), aOldAreas.end(), Release());
     163             :         }
     164          42 :         else if (pSimpleHint->GetId() == SC_HINT_ACC_VISAREACHANGED)
     165             :         {
     166          20 :             AccessibleEventObject aEvent;
     167          20 :             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
     168          20 :             aEvent.Source = uno::Reference< XAccessibleContext >(this);
     169          20 :             CommitChange(aEvent);
     170             :         }
     171             :     }
     172             : 
     173          80 :     ScAccessibleContextBase::Notify(rBC, rHint);
     174          80 : }
     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           2 : void SAL_CALL ScAccessiblePageHeader::grabFocus() throw (uno::RuntimeException, std::exception)
     208             : {
     209           2 :      SolarMutexGuard aGuard;
     210           2 :     IsObjectValid();
     211           2 :     if (getAccessibleParent().is())
     212             :     {
     213           2 :         uno::Reference<XAccessibleComponent> xAccessibleComponent(getAccessibleParent()->getAccessibleContext(), uno::UNO_QUERY);
     214           2 :         if (xAccessibleComponent.is())
     215           2 :             xAccessibleComponent->grabFocus();
     216           2 :     }
     217           2 : }
     218             : 
     219             : //=====  XAccessibleContext  ==============================================
     220             : 
     221          94 : sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleChildCount() throw (uno::RuntimeException, std::exception)
     222             : {
     223          94 :     SolarMutexGuard aGuard;
     224          94 :     IsObjectValid();
     225             : 
     226          94 :     if((mnChildCount < 0) && mpViewShell)
     227             :     {
     228          36 :         mnChildCount = 0;
     229          36 :         ScDocument& rDoc = mpViewShell->GetDocument();
     230             :         // find out how many regions (left,center, right) are with content
     231             : 
     232          36 :         SfxStyleSheetBase* pStyle = rDoc.GetStyleSheetPool()->Find(rDoc.GetPageStyle(mpViewShell->GetLocationData().GetPrintTab()), SFX_STYLE_FAMILY_PAGE);
     233          36 :         if (pStyle)
     234             :         {
     235          36 :             sal_uInt16 nPageWhichId(0);
     236          36 :             if (mbHeader)
     237          30 :                 nPageWhichId = mpViewShell->GetLocationData().IsHeaderLeft() ? ATTR_PAGE_HEADERLEFT : ATTR_PAGE_HEADERRIGHT;
     238             :             else
     239           6 :                 nPageWhichId = mpViewShell->GetLocationData().IsFooterLeft() ? ATTR_PAGE_FOOTERLEFT : ATTR_PAGE_FOOTERRIGHT;
     240             : 
     241          36 :             const ScPageHFItem& rPageItem = static_cast<const ScPageHFItem&>(pStyle->GetItemSet().Get(nPageWhichId));
     242          36 :             AddChild(rPageItem.GetLeftArea(), 0, SVX_ADJUST_LEFT);
     243          36 :             AddChild(rPageItem.GetCenterArea(), 1, SVX_ADJUST_CENTER);
     244          36 :             AddChild(rPageItem.GetRightArea(), 2, SVX_ADJUST_RIGHT);
     245             :         }
     246             :     }
     247             : 
     248          94 :     return mnChildCount;
     249             : }
     250             : 
     251          56 : uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeader::getAccessibleChild( sal_Int32 nIndex )
     252             :                                 throw (lang::IndexOutOfBoundsException, uno::RuntimeException, std::exception)
     253             : {
     254          56 :     SolarMutexGuard aGuard;
     255          56 :     IsObjectValid();
     256             : 
     257          56 :     uno::Reference<XAccessible> xRet;
     258             : 
     259          56 :     if(mnChildCount < 0)
     260           0 :         getAccessibleChildCount();
     261             : 
     262          56 :     ScHFAreas::iterator aItr = maAreas.begin();
     263          56 :     ScHFAreas::iterator aEndItr = maAreas.end();
     264         224 :     while (!xRet.is() && (nIndex >= 0) && (aItr != aEndItr))
     265             :     {
     266         112 :         if (*aItr)
     267             :         {
     268          86 :             if (nIndex == 0)
     269          56 :                 xRet = *aItr;
     270             :             else
     271          30 :                 --nIndex;
     272             :         }
     273             :         else
     274          26 :             ++aItr;
     275             :     }
     276             : 
     277          56 :     if ( !xRet.is() )
     278           0 :         throw lang::IndexOutOfBoundsException();
     279             : 
     280          56 :     return xRet;
     281             : }
     282             : 
     283           2 : sal_Int32 SAL_CALL ScAccessiblePageHeader::getAccessibleIndexInParent() throw (uno::RuntimeException, std::exception)
     284             : {
     285           2 :     return mnIndex;
     286             : }
     287             : 
     288          54 : uno::Reference< XAccessibleStateSet > SAL_CALL ScAccessiblePageHeader::getAccessibleStateSet()
     289             :                                 throw (uno::RuntimeException, std::exception)
     290             : {
     291          54 :     SolarMutexGuard aGuard;
     292         108 :     uno::Reference<XAccessibleStateSet> xParentStates;
     293          54 :     if (getAccessibleParent().is())
     294             :     {
     295          54 :         uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
     296          54 :         xParentStates = xParentContext->getAccessibleStateSet();
     297             :     }
     298          54 :     utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
     299          54 :     if (IsDefunc(xParentStates))
     300           0 :         pStateSet->AddState(AccessibleStateType::DEFUNC);
     301             :     else
     302             :     {
     303          54 :         pStateSet->AddState(AccessibleStateType::ENABLED);
     304          54 :         pStateSet->AddState(AccessibleStateType::OPAQUE);
     305          54 :         if (isShowing())
     306          54 :             pStateSet->AddState(AccessibleStateType::SHOWING);
     307          54 :         if (isVisible())
     308          54 :             pStateSet->AddState(AccessibleStateType::VISIBLE);
     309             :     }
     310         108 :     return pStateSet;
     311             : }
     312             : 
     313             : //=====  XServiceInfo  ====================================================
     314             : 
     315           4 : OUString SAL_CALL ScAccessiblePageHeader::getImplementationName() throw(uno::RuntimeException, std::exception)
     316             : {
     317           4 :     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          18 : OUString SAL_CALL ScAccessiblePageHeader::createAccessibleDescription(void)
     335             :                     throw (uno::RuntimeException)
     336             : {
     337          18 :     OUString sDesc(SC_RESSTR(mbHeader ? STR_ACC_HEADER_DESCR : STR_ACC_FOOTER_DESCR));
     338          18 :     return sDesc.replaceFirst("%1", SC_RESSTR(SCSTR_UNKNOWN));
     339             : }
     340             : 
     341           2 : OUString SAL_CALL ScAccessiblePageHeader::createAccessibleName(void)
     342             :                     throw (uno::RuntimeException, std::exception)
     343             : {
     344           2 :     OUString sName(SC_RESSTR(mbHeader ? STR_ACC_HEADER_NAME : STR_ACC_FOOTER_NAME));
     345           2 :     return sName.replaceFirst("%1", SC_RESSTR(SCSTR_UNKNOWN));
     346             : }
     347             : 
     348           2 : Rectangle ScAccessiblePageHeader::GetBoundingBoxOnScreen() const throw (uno::RuntimeException, std::exception)
     349             : {
     350           2 :     Rectangle aCellRect(GetBoundingBox());
     351           2 :     if (mpViewShell)
     352             :     {
     353           2 :         vcl::Window* pWindow = mpViewShell->GetWindow();
     354           2 :         if (pWindow)
     355             :         {
     356           2 :             Rectangle aRect = pWindow->GetWindowExtentsRelative(NULL);
     357           2 :             aCellRect.setX(aCellRect.getX() + aRect.getX());
     358           2 :             aCellRect.setY(aCellRect.getY() + aRect.getY());
     359             :         }
     360             :     }
     361           2 :     return aCellRect;
     362             : }
     363             : 
     364        1284 : Rectangle ScAccessiblePageHeader::GetBoundingBox() const throw (uno::RuntimeException, std::exception)
     365             : {
     366        1284 :     Rectangle aRect;
     367        1284 :     if (mpViewShell)
     368             :     {
     369        1284 :         const ScPreviewLocationData& rData = mpViewShell->GetLocationData();
     370        1284 :         if ( mbHeader )
     371        1242 :             rData.GetHeaderPosition( aRect );
     372             :         else
     373          42 :             rData.GetFooterPosition( aRect );
     374             : 
     375             :         // the Rectangle could contain negative coordinates so it should be cliped
     376        1284 :         Rectangle aClipRect(Point(0, 0), aRect.GetSize());
     377        1284 :         vcl::Window* pWindow = mpViewShell->GetWindow();
     378        1284 :         if (pWindow)
     379        1284 :             aClipRect = pWindow->GetWindowExtentsRelative(pWindow->GetAccessibleParentWindow());
     380        1284 :         aRect = aClipRect.GetIntersection(aRect);
     381             :     }
     382        1284 :     if (aRect.IsEmpty())
     383           0 :         aRect.SetSize(Size(-1, -1));
     384             : 
     385        1284 :     return aRect;
     386             : }
     387             : 
     388          54 : bool ScAccessiblePageHeader::IsDefunc( const uno::Reference<XAccessibleStateSet>& rxParentStates )
     389             : {
     390         216 :     return ScAccessibleContextBase::IsDefunc() || (mpViewShell == NULL) || !getAccessibleParent().is() ||
     391         216 :         (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
     392             : }
     393             : 
     394         108 : void ScAccessiblePageHeader::AddChild(const EditTextObject* pArea, sal_uInt32 nIndex, SvxAdjust eAdjust)
     395             : {
     396         108 :     if (pArea && (!pArea->GetText(0).isEmpty() || (pArea->GetParagraphCount() > 1)))
     397             :     {
     398          52 :         if (maAreas[nIndex])
     399             :         {
     400          26 :             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          26 :             maAreas[nIndex] = new ScAccessiblePageHeaderArea(this, mpViewShell, pArea, mbHeader, eAdjust);
     410          26 :             maAreas[nIndex]->acquire();
     411             :         }
     412          52 :         ++mnChildCount;
     413             :     }
     414             :     else
     415             :     {
     416          56 :         if (maAreas[nIndex])
     417             :         {
     418           0 :             maAreas[nIndex]->release();
     419           0 :             maAreas[nIndex] = NULL;
     420             :         }
     421             :     }
     422         336 : }
     423             : 
     424             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10