LCOV - code coverage report
Current view: top level - svx/source/accessibility - ChildrenManagerImpl.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 249 393 63.4 %
Date: 2012-08-25 Functions: 29 38 76.3 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 266 778 34.2 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include "ChildrenManagerImpl.hxx"
      31                 :            : #include <svx/ShapeTypeHandler.hxx>
      32                 :            : #include <svx/AccessibleShapeInfo.hxx>
      33                 :            : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
      34                 :            : #include <com/sun/star/view/XSelectionSupplier.hpp>
      35                 :            : #include <com/sun/star/container/XChild.hpp>
      36                 :            : #include <comphelper/uno3.hxx>
      37                 :            : 
      38                 :            : #include <rtl/ustring.hxx>
      39                 :            : #include <tools/debug.hxx>
      40                 :            : 
      41                 :            : using namespace ::com::sun::star;
      42                 :            : using namespace ::com::sun::star::accessibility;
      43                 :            : using ::com::sun::star::uno::Reference;
      44                 :            : 
      45                 :            : 
      46                 :            : namespace accessibility {
      47                 :            : 
      48                 :            : namespace
      49                 :            : {
      50                 :         34 : void adjustIndexInParentOfShapes(ChildDescriptorListType& _rList)
      51                 :            : {
      52                 :         34 :     ChildDescriptorListType::iterator aEnd = _rList.end();
      53                 :         34 :     sal_Int32 i=0;
      54 [ +  - ][ +  + ]:         84 :     for ( ChildDescriptorListType::iterator aIter = _rList.begin(); aIter != aEnd; ++aIter,++i)
      55         [ +  - ]:         50 :         aIter->setIndexAtAccessibleShape(i);
      56                 :         34 : }
      57                 :            : }
      58                 :            : 
      59                 :            : //=====  AccessibleChildrenManager  ===========================================
      60                 :            : 
      61                 :          6 : ChildrenManagerImpl::ChildrenManagerImpl (
      62                 :            :     const uno::Reference<XAccessible>& rxParent,
      63                 :            :     const uno::Reference<drawing::XShapes>& rxShapeList,
      64                 :            :     const AccessibleShapeTreeInfo& rShapeTreeInfo,
      65                 :            :     AccessibleContextBase& rContext)
      66                 :            :     : ::cppu::WeakComponentImplHelper2<
      67                 :            :           ::com::sun::star::document::XEventListener,
      68                 :            :           ::com::sun::star::view::XSelectionChangeListener>(maMutex),
      69                 :            :       mxShapeList (rxShapeList),
      70                 :            :       mxParent (rxParent),
      71                 :            :       maShapeTreeInfo (rShapeTreeInfo),
      72                 :            :       mrContext (rContext),
      73                 :            :       mnNewNameIndex(1),
      74 [ +  - ][ +  - ]:          6 :       mpFocusedShape(NULL)
         [ +  - ][ +  - ]
      75                 :            : {
      76                 :          6 : }
      77                 :            : 
      78                 :            : 
      79                 :            : 
      80                 :            : 
      81 [ +  - ][ +  - ]:          6 : ChildrenManagerImpl::~ChildrenManagerImpl (void)
      82                 :            : {
      83                 :            :     DBG_ASSERT (rBHelper.bDisposed || rBHelper.bInDispose,
      84                 :            :         "~AccessibleDrawDocumentView: object has not been disposed");
      85         [ -  + ]:         12 : }
      86                 :            : 
      87                 :            : 
      88                 :            : 
      89                 :            : 
      90                 :          6 : void ChildrenManagerImpl::Init (void)
      91                 :            : {
      92                 :            :     // Register as view::XSelectionChangeListener.
      93         [ +  - ]:          6 :     Reference<frame::XController> xController(maShapeTreeInfo.GetController());
      94                 :            :     Reference<view::XSelectionSupplier> xSelectionSupplier (
      95         [ +  - ]:          6 :         xController, uno::UNO_QUERY);
      96         [ +  - ]:          6 :     if (xSelectionSupplier.is())
      97                 :            :     {
      98         [ +  - ]:          6 :         xController->addEventListener(
      99 [ +  - ][ +  - ]:          6 :             static_cast<document::XEventListener*>(this));
     100                 :            : 
     101         [ +  - ]:          6 :         xSelectionSupplier->addSelectionChangeListener (
     102 [ +  - ][ +  - ]:          6 :             static_cast<view::XSelectionChangeListener*>(this));
     103                 :            :     }
     104                 :            : 
     105                 :            :     // Register at model as document::XEventListener.
     106 [ +  - ][ +  - ]:          6 :     if (maShapeTreeInfo.GetModelBroadcaster().is())
     107 [ +  - ][ +  - ]:         12 :         maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
     108 [ +  - ][ +  - ]:         12 :             static_cast<document::XEventListener*>(this));
     109                 :          6 : }
     110                 :            : 
     111                 :            : 
     112                 :            : 
     113                 :            : 
     114                 :         26 : long ChildrenManagerImpl::GetChildCount (void) const throw ()
     115                 :            : {
     116                 :         26 :     return maVisibleChildren.size();
     117                 :            : }
     118                 :            : 
     119                 :            : 
     120                 :            : 
     121                 :            : 
     122                 :            : /** Return the requested accessible child object.  Create it if it is not
     123                 :            :     yet in the cache.
     124                 :            : */
     125                 :            : uno::Reference<XAccessible>
     126                 :         16 :     ChildrenManagerImpl::GetChild (long nIndex)
     127                 :            :     throw (::com::sun::star::uno::RuntimeException,
     128                 :            :            ::com::sun::star::lang::IndexOutOfBoundsException)
     129                 :            : {
     130                 :            :     // Check whether the given index is valid.
     131 [ +  - ][ -  + ]:         16 :     if (nIndex < 0 || (unsigned long)nIndex >= maVisibleChildren.size())
                 [ -  + ]
     132                 :            :         throw lang::IndexOutOfBoundsException (
     133                 :            :             ::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(
     134                 :            :                 "no accessible child with index ")) + ::rtl::OUString::valueOf(nIndex),
     135 [ #  # ][ #  # ]:          0 :             mxParent);
     136                 :            : 
     137                 :         16 :     return GetChild (maVisibleChildren[nIndex],nIndex);
     138                 :            : }
     139                 :            : 
     140                 :            : 
     141                 :            : 
     142                 :            : 
     143                 :            : /** Return the requested accessible child object.  Create it if it is not
     144                 :            :     yet in the cache.
     145                 :            : */
     146                 :            : uno::Reference<XAccessible>
     147                 :         22 :     ChildrenManagerImpl::GetChild (ChildDescriptor& rChildDescriptor,sal_Int32 _nIndex)
     148                 :            :     throw (::com::sun::star::uno::RuntimeException)
     149                 :            : {
     150         [ +  + ]:         22 :     if ( ! rChildDescriptor.mxAccessibleShape.is())
     151                 :            :     {
     152         [ +  - ]:          8 :         ::osl::MutexGuard aGuard (maMutex);
     153                 :            :         // Make sure that the requested accessible object has not been
     154                 :            :         // created while locking the global mutex.
     155         [ +  - ]:          8 :         if ( ! rChildDescriptor.mxAccessibleShape.is())
     156                 :            :         {
     157                 :            :             AccessibleShapeInfo aShapeInfo(
     158                 :            :                         rChildDescriptor.mxShape,
     159                 :            :                         mxParent,
     160                 :            :                         this,
     161         [ +  - ]:          8 :                         mnNewNameIndex++);
     162                 :            :             // Create accessible object that corresponds to the descriptor's
     163                 :            :             // shape.
     164                 :            :             AccessibleShape* pShape =
     165         [ +  - ]:          8 :                 ShapeTypeHandler::Instance().CreateAccessibleObject (
     166                 :            :                     aShapeInfo,
     167         [ +  - ]:          8 :                     maShapeTreeInfo);
     168                 :            :             rChildDescriptor.mxAccessibleShape = uno::Reference<XAccessible> (
     169                 :            :                 static_cast<uno::XWeak*>(pShape),
     170 [ +  - ][ +  - ]:          8 :                 uno::UNO_QUERY);
     171                 :            :             // Now that there is a reference to the new accessible shape we
     172                 :            :             // can safely call its Init() method.
     173         [ +  - ]:          8 :             if ( pShape != NULL )
     174                 :            :             {
     175         [ +  - ]:          8 :                 pShape->Init();
     176                 :          8 :                 pShape->setIndexInParent(_nIndex);
     177         [ +  - ]:          8 :             }
     178         [ +  - ]:          8 :         }
     179                 :            :     }
     180                 :            : 
     181                 :         22 :     return rChildDescriptor.mxAccessibleShape;
     182                 :            : }
     183                 :            : 
     184                 :            : 
     185                 :            : 
     186                 :            : 
     187                 :            : /** Find all shapes among the specified shapes that lie fully or partially
     188                 :            :     inside the visible area.  Put those shapes into the cleared cache. The
     189                 :            :     corresponding accessible objects will be created on demand.
     190                 :            : 
     191                 :            :     At the moment, first all accessible objects are removed from the cache
     192                 :            :     and the appropriate listeners are informed of this.  Next, the list is
     193                 :            :     created again.  This should be optimized in the future to not remove and
     194                 :            :     create objects that will be in the list before and after the update
     195                 :            :     method.
     196                 :            : */
     197                 :         34 : void ChildrenManagerImpl::Update (bool bCreateNewObjectsOnDemand)
     198                 :            : {
     199 [ +  - ][ +  - ]:         34 :     if (maShapeTreeInfo.GetViewForwarder() == NULL)
     200                 :         34 :         return;
     201 [ +  - ][ +  - ]:         34 :     Rectangle aVisibleArea = maShapeTreeInfo.GetViewForwarder()->GetVisibleArea();
     202                 :            : 
     203                 :            :     // 1. Create a local list of visible shapes.
     204         [ +  - ]:         34 :     ChildDescriptorListType aChildList;
     205         [ +  - ]:         34 :     CreateListOfVisibleShapes (aChildList);
     206                 :            : 
     207                 :            :     // 2. Merge the information that is already known about the visible
     208                 :            :     // shapes from the current list into the new list.
     209         [ +  - ]:         34 :     MergeAccessibilityInformation (aChildList);
     210                 :            : 
     211                 :            :     // 3. Replace the current list of visible shapes with the new one.  Do
     212                 :            :     // the same with the visible area.
     213                 :            :     {
     214         [ +  - ]:         34 :         ::osl::MutexGuard aGuard (maMutex);
     215         [ +  - ]:         34 :         adjustIndexInParentOfShapes(aChildList);
     216                 :            : 
     217                 :            :         // Use swap to copy the contents of the new list in constant time.
     218                 :         34 :         maVisibleChildren.swap (aChildList);
     219                 :            : 
     220                 :            :         // aChildList now contains all the old children, while maVisibleChildren
     221                 :            :         // contains all the current children
     222                 :            : 
     223                 :            :         // 4. Find all shapes in the old list that are not in the current list,
     224                 :            :         // send appropriate events and remove the accessible shape.
     225                 :            :         //
     226                 :            :         // Do this *after* we have set our new list of children, because
     227                 :            :         // removing a child may cause
     228                 :            :         //
     229                 :            :         // ChildDescriptor::disposeAccessibleObject -->
     230                 :            :         // AccessibleContextBase::CommitChange -->
     231                 :            :         // AtkListener::notifyEvent ->
     232                 :            :         // AtkListener::handleChildRemoved ->
     233                 :            :         // AtkListener::updateChildList
     234                 :            :         // AccessibleDrawDocumentView::getAccessibleChildCount ->
     235                 :            :         // ChildrenManagerImpl::GetChildCount ->
     236                 :            :         // maVisibleChildren.size()
     237                 :            :         //
     238                 :            :         // to be fired, and so the operations will take place on
     239                 :            :         // the list we are trying to replace
     240                 :            :         //
     241         [ +  - ]:         34 :         RemoveNonVisibleChildren (maVisibleChildren, aChildList);
     242                 :            : 
     243                 :         34 :         aChildList.clear();
     244                 :            : 
     245         [ +  - ]:         34 :         maVisibleArea = aVisibleArea;
     246                 :            :     }
     247                 :            : 
     248                 :            :     // 5. If the visible area has changed then send events that signal a
     249                 :            :     // change of their bounding boxes for all shapes that are members of
     250                 :            :     // both the current and the new list of visible shapes.
     251 [ +  - ][ -  + ]:         34 :     if (maVisibleArea != aVisibleArea)
     252         [ #  # ]:          0 :         SendVisibleAreaEvents (maVisibleChildren);
     253                 :            : 
     254                 :            :     // 6. If children have to be created immediately and not on demand then
     255                 :            :     // create the missing accessible objects now.
     256         [ +  + ]:         34 :     if ( ! bCreateNewObjectsOnDemand)
     257         [ +  - ]:         34 :         CreateAccessibilityObjects (maVisibleChildren);
     258                 :            : }
     259                 :            : 
     260                 :            : 
     261                 :            : 
     262                 :            : 
     263                 :         34 : void ChildrenManagerImpl::CreateListOfVisibleShapes (
     264                 :            :     ChildDescriptorListType& raDescriptorList)
     265                 :            : {
     266         [ +  - ]:         34 :     ::osl::MutexGuard aGuard (maMutex);
     267                 :            : 
     268                 :            :     OSL_ASSERT (maShapeTreeInfo.GetViewForwarder() != NULL);
     269                 :            : 
     270 [ +  - ][ +  - ]:         34 :     Rectangle aVisibleArea = maShapeTreeInfo.GetViewForwarder()->GetVisibleArea();
     271                 :            : 
     272                 :            :     // Add the visible shapes for wich the accessible objects already exist.
     273                 :         34 :     AccessibleShapeList::iterator I,aEnd = maAccessibleShapes.end();
     274 [ +  - ][ +  + ]:         68 :     for (I=maAccessibleShapes.begin(); I != aEnd; ++I)
     275                 :            :     {
     276         [ +  - ]:         34 :         if (I->is())
     277                 :            :         {
     278                 :            :             uno::Reference<XAccessibleComponent> xComponent (
     279 [ +  - ][ +  - ]:         34 :                 (*I)->getAccessibleContext(), uno::UNO_QUERY);
                 [ +  - ]
     280         [ +  - ]:         34 :             if (xComponent.is())
     281                 :            :             {
     282                 :            :                 // The bounding box of the object already is clipped to the
     283                 :            :                 // visible area.  The object is therefore visible if the
     284                 :            :                 // bounding box has non-zero extensions.
     285 [ +  - ][ +  - ]:         34 :                 awt::Rectangle aPixelBBox (xComponent->getBounds());
     286 [ +  - ][ +  - ]:         34 :                 if ((aPixelBBox.Width > 0) && (aPixelBBox.Height > 0))
     287 [ +  - ][ +  - ]:         34 :                     raDescriptorList.push_back (ChildDescriptor (*I));
                 [ +  - ]
     288                 :         34 :             }
     289                 :            :         }
     290                 :            :     }
     291                 :            : 
     292                 :            :     // Add the visible shapes for which only the XShapes exist.
     293         [ +  - ]:         34 :     uno::Reference<container::XIndexAccess> xShapeAccess (mxShapeList, uno::UNO_QUERY);
     294         [ +  - ]:         34 :     if (xShapeAccess.is())
     295                 :            :     {
     296 [ +  - ][ +  - ]:         34 :         sal_Int32 nShapeCount = xShapeAccess->getCount();
     297         [ +  - ]:         34 :         raDescriptorList.reserve( nShapeCount );
     298                 :         34 :         awt::Point aPos;
     299                 :         34 :         awt::Size aSize;
     300         [ +  - ]:         34 :         Rectangle aBoundingBox;
     301                 :         34 :         uno::Reference<drawing::XShape> xShape;
     302         [ +  + ]:         50 :         for (sal_Int32 i=0; i<nShapeCount; ++i)
     303                 :            :         {
     304 [ +  - ][ +  - ]:         16 :             xShapeAccess->getByIndex(i) >>= xShape;
                 [ +  - ]
     305 [ +  - ][ +  - ]:         16 :             aPos = xShape->getPosition();
     306 [ +  - ][ +  - ]:         16 :             aSize = xShape->getSize();
     307                 :            : 
     308                 :         16 :             aBoundingBox.nLeft = aPos.X;
     309                 :         16 :             aBoundingBox.nTop = aPos.Y;
     310                 :         16 :             aBoundingBox.nRight = aPos.X + aSize.Width;
     311                 :         16 :             aBoundingBox.nBottom = aPos.Y + aSize.Height;
     312                 :            : 
     313                 :            :             // Insert shape if it is visible, i.e. its bounding box overlaps
     314                 :            :             // the visible area.
     315 [ +  - ][ +  - ]:         16 :             if ( aBoundingBox.IsOver (aVisibleArea) )
     316 [ +  - ][ +  - ]:         16 :                 raDescriptorList.push_back (ChildDescriptor (xShape));
                 [ +  - ]
     317                 :         34 :         }
     318         [ +  - ]:         34 :     }
     319                 :         34 : }
     320                 :            : 
     321                 :            : 
     322                 :            : 
     323                 :            : 
     324                 :         34 : void ChildrenManagerImpl::RemoveNonVisibleChildren (
     325                 :            :     const ChildDescriptorListType& rNewChildList,
     326                 :            :     ChildDescriptorListType& rOldChildList)
     327                 :            : {
     328                 :            :     // Iterate over list of formerly visible children and remove those that
     329                 :            :     // are not visible anymore, i.e. member of the new list of visible
     330                 :            :     // children.
     331                 :         34 :     ChildDescriptorListType::iterator I, aEnd = rOldChildList.end();
     332 [ +  - ][ +  + ]:         62 :     for (I=rOldChildList.begin(); I != aEnd; ++I)
     333                 :            :     {
     334 [ +  - ][ +  - ]:         28 :         if (::std::find(rNewChildList.begin(), rNewChildList.end(), *I) == rNewChildList.end())
                 [ -  + ]
     335                 :            :         {
     336                 :            :             // The child is disposed when there is a UNO shape from which
     337                 :            :             // the accessible shape can be created when the shape becomes
     338                 :            :             // visible again.  When there is no such UNO shape then simply
     339                 :            :             // reset the descriptor but keep the accessibility object.
     340         [ #  # ]:          0 :             if (I->mxShape.is())
     341                 :            :             {
     342         [ #  # ]:          0 :                 UnregisterAsDisposeListener (I->mxShape);
     343         [ #  # ]:          0 :                 I->disposeAccessibleObject (mrContext);
     344                 :            :             }
     345                 :            :             else
     346                 :            :             {
     347         [ #  # ]:          0 :                 AccessibleShape* pAccessibleShape = I->GetAccessibleShape();
     348         [ #  # ]:          0 :                 pAccessibleShape->ResetState (AccessibleStateType::VISIBLE);
     349         [ #  # ]:          0 :                 I->mxAccessibleShape = NULL;
     350                 :            :             }
     351                 :            :         }
     352                 :            :     }
     353                 :         34 : }
     354                 :            : 
     355                 :            : 
     356                 :            : 
     357                 :            : 
     358                 :         34 : void ChildrenManagerImpl::MergeAccessibilityInformation (
     359                 :            :     ChildDescriptorListType& raNewChildList)
     360                 :            : {
     361                 :         34 :     ChildDescriptorListType::iterator aOldChildDescriptor;
     362                 :         34 :     ChildDescriptorListType::iterator I, aEnd = raNewChildList.end();
     363 [ +  - ][ +  + ]:         84 :     for (I=raNewChildList.begin(); I != aEnd; ++I)
     364                 :            :     {
     365         [ +  - ]:         50 :         aOldChildDescriptor = ::std::find (maVisibleChildren.begin(), maVisibleChildren.end(), *I);
     366                 :            : 
     367                 :            :         // Copy accessible shape if that exists in the old descriptor.
     368                 :         50 :         bool bRegistrationIsNecessary = true;
     369 [ +  - ][ +  + ]:         50 :         if (aOldChildDescriptor != maVisibleChildren.end())
     370         [ +  + ]:         28 :             if (aOldChildDescriptor->mxAccessibleShape.is())
     371                 :            :             {
     372         [ +  - ]:         26 :                 I->mxAccessibleShape = aOldChildDescriptor->mxAccessibleShape;
     373                 :         26 :                 I->mbCreateEventPending = false;
     374                 :         26 :                 bRegistrationIsNecessary = false;
     375                 :            :             }
     376         [ +  + ]:         50 :         if (bRegistrationIsNecessary)
     377         [ +  - ]:         24 :             RegisterAsDisposeListener (I->mxShape);
     378                 :            :     }
     379                 :         34 : }
     380                 :            : 
     381                 :            : 
     382                 :            : 
     383                 :            : 
     384                 :          0 : void ChildrenManagerImpl::SendVisibleAreaEvents (
     385                 :            :     ChildDescriptorListType& raNewChildList)
     386                 :            : {
     387                 :          0 :     ChildDescriptorListType::iterator I,aEnd = raNewChildList.end();
     388 [ #  # ][ #  # ]:          0 :     for (I=raNewChildList.begin(); I != aEnd; ++I)
     389                 :            :     {
     390                 :            :         // Tell shape of changed visible area.  To do this, fake a
     391                 :            :         // change of the view forwarder.  (Actually we usually get here
     392                 :            :         // as a result of a change of the view forwarder).
     393         [ #  # ]:          0 :         AccessibleShape* pShape = I->GetAccessibleShape ();
     394         [ #  # ]:          0 :         if (pShape != NULL)
     395                 :            :             pShape->ViewForwarderChanged (
     396                 :            :                 IAccessibleViewForwarderListener::VISIBLE_AREA,
     397 [ #  # ][ #  # ]:          0 :                 maShapeTreeInfo.GetViewForwarder());
     398                 :            :     }
     399                 :          0 : }
     400                 :            : 
     401                 :            : 
     402                 :            : 
     403                 :            : 
     404                 :         28 : void ChildrenManagerImpl::CreateAccessibilityObjects (
     405                 :            :     ChildDescriptorListType& raNewChildList)
     406                 :            : {
     407                 :         28 :     ChildDescriptorListType::iterator I, aEnd = raNewChildList.end();
     408                 :         28 :     sal_Int32 nPos = 0;
     409 [ +  - ][ +  + ]:         68 :     for ( I = raNewChildList.begin(); I != aEnd; ++I,++nPos)
     410                 :            :     {
     411                 :            :         // Create the associated accessible object when the flag says so and
     412                 :            :         // it does not yet exist.
     413         [ +  + ]:         40 :         if ( ! I->mxAccessibleShape.is() )
     414         [ +  - ]:          6 :             GetChild (*I,nPos);
     415 [ +  - ][ +  + ]:         40 :         if (I->mxAccessibleShape.is() && I->mbCreateEventPending)
                 [ +  + ]
     416                 :            :         {
     417                 :         14 :             I->mbCreateEventPending = false;
     418                 :            :             mrContext.CommitChange (
     419                 :            :                 AccessibleEventId::CHILD,
     420                 :         14 :                 uno::makeAny(I->mxAccessibleShape),
     421 [ +  - ][ +  - ]:         28 :                 uno::Any());
     422                 :            :         }
     423                 :            :     }
     424                 :         28 : }
     425                 :            : 
     426                 :            : 
     427                 :            : 
     428                 :            : 
     429                 :          0 : void ChildrenManagerImpl::AddShape (const Reference<drawing::XShape>& rxShape)
     430                 :            : {
     431         [ #  # ]:          0 :     if (rxShape.is())
     432                 :            :     {
     433         [ #  # ]:          0 :         ::osl::ClearableMutexGuard aGuard (maMutex);
     434                 :            : 
     435                 :            :         // Test visibility of the shape.
     436 [ #  # ][ #  # ]:          0 :         Rectangle aVisibleArea = maShapeTreeInfo.GetViewForwarder()->GetVisibleArea();
     437 [ #  # ][ #  # ]:          0 :         awt::Point aPos = rxShape->getPosition();
     438 [ #  # ][ #  # ]:          0 :         awt::Size aSize = rxShape->getSize();
     439                 :            : 
     440                 :            :         Rectangle aBoundingBox (
     441                 :            :             aPos.X,
     442                 :            :             aPos.Y,
     443                 :            :             aPos.X + aSize.Width,
     444         [ #  # ]:          0 :             aPos.Y + aSize.Height);
     445                 :            : 
     446                 :            :         // Add the shape only when it belongs to the list of shapes stored
     447                 :            :         // in mxShapeList (which is either a page or a group shape).
     448         [ #  # ]:          0 :         Reference<container::XChild> xChild (rxShape, uno::UNO_QUERY);
     449         [ #  # ]:          0 :         if (xChild.is())
     450                 :            :         {
     451 [ #  # ][ #  # ]:          0 :             Reference<drawing::XShapes> xParent (xChild->getParent(), uno::UNO_QUERY);
                 [ #  # ]
     452 [ #  # ][ #  # ]:          0 :             if (xParent == mxShapeList)
     453 [ #  # ][ #  # ]:          0 :                 if (aBoundingBox.IsOver (aVisibleArea))
     454                 :            :                 {
     455                 :            :                     // Add shape to list of visible shapes.
     456 [ #  # ][ #  # ]:          0 :                     maVisibleChildren.push_back (ChildDescriptor (rxShape));
                 [ #  # ]
     457                 :            : 
     458                 :            :                     // Create accessibility object.
     459         [ #  # ]:          0 :                     ChildDescriptor& rDescriptor = maVisibleChildren.back();
     460         [ #  # ]:          0 :                     GetChild (rDescriptor, maVisibleChildren.size()-1);
     461                 :            : 
     462                 :            :                     // Inform listeners about new child.
     463                 :          0 :                     uno::Any aNewShape;
     464         [ #  # ]:          0 :                     aNewShape <<= rDescriptor.mxAccessibleShape;
     465         [ #  # ]:          0 :                     aGuard.clear();
     466                 :            :                     mrContext.CommitChange (
     467                 :            :                         AccessibleEventId::CHILD,
     468                 :            :                         aNewShape,
     469         [ #  # ]:          0 :                         uno::Any());
     470         [ #  # ]:          0 :                     RegisterAsDisposeListener (rDescriptor.mxShape);
     471                 :          0 :                 }
     472         [ #  # ]:          0 :         }
     473                 :            :     }
     474                 :          0 : }
     475                 :            : 
     476                 :            : 
     477                 :            : 
     478                 :            : 
     479                 :          0 : void ChildrenManagerImpl::RemoveShape (const Reference<drawing::XShape>& rxShape)
     480                 :            : {
     481         [ #  # ]:          0 :     if (rxShape.is())
     482                 :            :     {
     483         [ #  # ]:          0 :         ::osl::ClearableMutexGuard aGuard (maMutex);
     484                 :            : 
     485                 :            :         // Search shape in list of visible children.
     486                 :            :         ChildDescriptorListType::iterator I (
     487                 :            :             ::std::find (maVisibleChildren.begin(), maVisibleChildren.end(),
     488 [ #  # ][ #  # ]:          0 :                 ChildDescriptor (rxShape)));
                 [ #  # ]
     489 [ #  # ][ #  # ]:          0 :         if (I != maVisibleChildren.end())
     490                 :            :         {
     491                 :            :             // Remove descriptor from that list.
     492                 :          0 :             Reference<XAccessible> xAccessibleShape (I->mxAccessibleShape);
     493                 :            : 
     494         [ #  # ]:          0 :             UnregisterAsDisposeListener (I->mxShape);
     495                 :            :             // Dispose the accessible object.
     496         [ #  # ]:          0 :             I->disposeAccessibleObject (mrContext);
     497                 :            : 
     498                 :            :             // Now we can safely remove the child descriptor and thus
     499                 :            :             // invalidate the iterator.
     500         [ #  # ]:          0 :             maVisibleChildren.erase (I);
     501                 :            : 
     502         [ #  # ]:          0 :             adjustIndexInParentOfShapes(maVisibleChildren);
     503         [ #  # ]:          0 :         }
     504                 :            :     }
     505                 :          0 : }
     506                 :            : 
     507                 :            : 
     508                 :            : 
     509                 :            : 
     510                 :         14 : void ChildrenManagerImpl::SetShapeList (const ::com::sun::star::uno::Reference<
     511                 :            :     ::com::sun::star::drawing::XShapes>& xShapeList)
     512                 :            : {
     513                 :         14 :     mxShapeList = xShapeList;
     514                 :         14 : }
     515                 :            : 
     516                 :            : 
     517                 :            : 
     518                 :            : 
     519                 :         14 : void ChildrenManagerImpl::AddAccessibleShape (std::auto_ptr<AccessibleShape> pShape)
     520                 :            : {
     521         [ +  - ]:         14 :     if (pShape.get() != NULL)
     522 [ +  - ][ +  - ]:         14 :         maAccessibleShapes.push_back (pShape.release());
     523                 :         14 : }
     524                 :            : 
     525                 :            : 
     526                 :            : 
     527                 :            : 
     528                 :         14 : void ChildrenManagerImpl::ClearAccessibleShapeList (void)
     529                 :            : {
     530                 :            :     // Copy the list of (visible) shapes to local lists and clear the
     531                 :            :     // originals.
     532         [ +  - ]:         14 :     ChildDescriptorListType aLocalVisibleChildren;
     533                 :         14 :     aLocalVisibleChildren.swap(maVisibleChildren);
     534         [ +  - ]:         14 :     AccessibleShapeList aLocalAccessibleShapes;
     535                 :         14 :     aLocalAccessibleShapes.swap(maAccessibleShapes);
     536                 :            : 
     537                 :            :     // Tell the listeners that all children are gone.
     538                 :            :     mrContext.CommitChange (
     539                 :            :         AccessibleEventId::INVALIDATE_ALL_CHILDREN,
     540                 :            :         uno::Any(),
     541         [ +  - ]:         14 :         uno::Any());
     542                 :            : 
     543                 :            :     // There are no accessible shapes left so the index assigned to new
     544                 :            :     // accessible shapes can be reset.
     545                 :         14 :     mnNewNameIndex = 1;
     546                 :            : 
     547                 :            :     // Now the objects in the local lists can be safely disposed without
     548                 :            :     // having problems with callers that want to update their child lists.
     549                 :            : 
     550                 :            :     // Clear the list of visible accessible objects.  Objects not created on
     551                 :            :     // demand for XShapes are treated below.
     552                 :         14 :     ChildDescriptorListType::iterator I,aEnd = aLocalVisibleChildren.end();
     553 [ +  - ][ +  + ]:         36 :     for (I=aLocalVisibleChildren.begin(); I != aEnd; ++I)
     554 [ +  - ][ +  + ]:         22 :         if ( I->mxAccessibleShape.is() && I->mxShape.is() )
                 [ +  + ]
     555                 :            :         {
     556         [ +  - ]:          8 :             ::comphelper::disposeComponent(I->mxAccessibleShape);
     557         [ +  - ]:          8 :             I->mxAccessibleShape = NULL;
     558                 :            :         }
     559                 :            : 
     560                 :            :     // Dispose all objects in the accessible shape list.
     561                 :         14 :     AccessibleShapeList::iterator J,aEnd2 = aLocalAccessibleShapes.end();
     562 [ +  - ][ +  + ]:         28 :     for (J=aLocalAccessibleShapes.begin(); J != aEnd2; ++J)
     563         [ +  - ]:         14 :         if (J->is())
     564                 :            :         {
     565                 :            :             // Dispose the object.
     566         [ +  - ]:         14 :             ::comphelper::disposeComponent(*J);
     567         [ +  - ]:         14 :             *J = NULL;
     568                 :         14 :         }
     569                 :         14 : }
     570                 :            : 
     571                 :            : 
     572                 :            : 
     573                 :            : 
     574                 :            : /** If the broadcasters change at which this object is registered then
     575                 :            :     unregister at old and register at new broadcasters.
     576                 :            : */
     577                 :          0 : void ChildrenManagerImpl::SetInfo (const AccessibleShapeTreeInfo& rShapeTreeInfo)
     578                 :            : {
     579                 :            :     // Remember the current broadcasters and exchange the shape tree info.
     580                 :          0 :     Reference<document::XEventBroadcaster> xCurrentBroadcaster;
     581                 :          0 :     Reference<frame::XController> xCurrentController;
     582                 :          0 :     Reference<view::XSelectionSupplier> xCurrentSelectionSupplier;
     583                 :            :     {
     584         [ #  # ]:          0 :         ::osl::MutexGuard aGuard (maMutex);
     585 [ #  # ][ #  # ]:          0 :         xCurrentBroadcaster = maShapeTreeInfo.GetModelBroadcaster();
     586 [ #  # ][ #  # ]:          0 :         xCurrentController = maShapeTreeInfo.GetController();
     587                 :            :         xCurrentSelectionSupplier = Reference<view::XSelectionSupplier> (
     588 [ #  # ][ #  # ]:          0 :             xCurrentController, uno::UNO_QUERY);
     589 [ #  # ][ #  # ]:          0 :         maShapeTreeInfo = rShapeTreeInfo;
     590                 :            :     }
     591                 :            : 
     592                 :            :     // Move registration to new model.
     593 [ #  # ][ #  # ]:          0 :     if (maShapeTreeInfo.GetModelBroadcaster() != xCurrentBroadcaster)
                 [ #  # ]
     594                 :            :     {
     595                 :            :         // Register at new broadcaster.
     596 [ #  # ][ #  # ]:          0 :         if (maShapeTreeInfo.GetModelBroadcaster().is())
     597 [ #  # ][ #  # ]:          0 :             maShapeTreeInfo.GetModelBroadcaster()->addEventListener (
     598 [ #  # ][ #  # ]:          0 :                 static_cast<document::XEventListener*>(this));
     599                 :            : 
     600                 :            :         // Unregister at old broadcaster.
     601         [ #  # ]:          0 :         if (xCurrentBroadcaster.is())
     602         [ #  # ]:          0 :             xCurrentBroadcaster->removeEventListener (
     603 [ #  # ][ #  # ]:          0 :                 static_cast<document::XEventListener*>(this));
     604                 :            :     }
     605                 :            : 
     606                 :            :     // Move registration to new selection supplier.
     607         [ #  # ]:          0 :     Reference<frame::XController> xNewController(maShapeTreeInfo.GetController());
     608                 :            :     Reference<view::XSelectionSupplier> xNewSelectionSupplier (
     609         [ #  # ]:          0 :         xNewController, uno::UNO_QUERY);
     610 [ #  # ][ #  # ]:          0 :     if (xNewSelectionSupplier != xCurrentSelectionSupplier)
     611                 :            :     {
     612                 :            :         // Register at new broadcaster.
     613         [ #  # ]:          0 :         if (xNewSelectionSupplier.is())
     614                 :            :         {
     615         [ #  # ]:          0 :             xNewController->addEventListener(
     616 [ #  # ][ #  # ]:          0 :                 static_cast<document::XEventListener*>(this));
     617                 :            : 
     618         [ #  # ]:          0 :             xNewSelectionSupplier->addSelectionChangeListener (
     619 [ #  # ][ #  # ]:          0 :                 static_cast<view::XSelectionChangeListener*>(this));
     620                 :            :         }
     621                 :            : 
     622                 :            :         // Unregister at old broadcaster.
     623         [ #  # ]:          0 :         if (xCurrentSelectionSupplier.is())
     624                 :            :         {
     625         [ #  # ]:          0 :             xCurrentSelectionSupplier->removeSelectionChangeListener (
     626 [ #  # ][ #  # ]:          0 :                 static_cast<view::XSelectionChangeListener*>(this));
     627                 :            : 
     628         [ #  # ]:          0 :             xCurrentController->removeEventListener(
     629 [ #  # ][ #  # ]:          0 :                 static_cast<document::XEventListener*>(this));
     630                 :            :         }
     631                 :          0 :     }
     632                 :          0 : }
     633                 :            : 
     634                 :            : 
     635                 :            : 
     636                 :            : 
     637                 :            : //=====  lang::XEventListener  ================================================
     638                 :            : 
     639                 :            : void SAL_CALL
     640                 :         16 :     ChildrenManagerImpl::disposing (const lang::EventObject& rEventObject)
     641                 :            :     throw (uno::RuntimeException)
     642                 :            : {
     643 [ +  - ][ +  - ]:         48 :     if (rEventObject.Source == maShapeTreeInfo.GetModelBroadcaster()
         [ +  - ][ -  + ]
                 [ +  - ]
           [ -  +  #  # ]
     644 [ +  - ][ +  - ]:         32 :             || rEventObject.Source == maShapeTreeInfo.GetController())
         [ +  - ][ #  # ]
     645                 :            :     {
     646                 :          0 :         impl_dispose();
     647                 :            :     }
     648                 :            : 
     649                 :            :     // Handle disposing UNO shapes.
     650                 :            :     else
     651                 :            :     {
     652         [ +  - ]:         16 :         Reference<drawing::XShape> xShape (rEventObject.Source, uno::UNO_QUERY);
     653                 :            : 
     654                 :            :         // Find the descriptor for the given shape.
     655                 :            :         ChildDescriptorListType::iterator I (
     656                 :            :             ::std::find (maVisibleChildren.begin(), maVisibleChildren.end(),
     657 [ +  - ][ +  - ]:         16 :                 ChildDescriptor (xShape)));
                 [ +  - ]
     658 [ +  - ][ -  + ]:         16 :         if (I != maVisibleChildren.end())
     659                 :            :         {
     660                 :            :             // Clear the descriptor.
     661         [ #  # ]:          0 :             I->disposeAccessibleObject (mrContext);
     662         [ #  # ]:          0 :             I->mxShape = NULL;
     663                 :         16 :         }
     664                 :            :     }
     665                 :         16 : }
     666                 :            : 
     667                 :            : 
     668                 :            : 
     669                 :            : 
     670                 :            : //=====  document::XEventListener  ============================================
     671                 :            : 
     672                 :            : /** Listen for new and removed shapes.
     673                 :            : */
     674                 :            : void SAL_CALL
     675                 :         18 :     ChildrenManagerImpl::notifyEvent (
     676                 :            :         const document::EventObject& rEventObject)
     677                 :            :     throw (uno::RuntimeException)
     678                 :            : {
     679                 :            :     static const ::rtl::OUString sShapeInserted (
     680 [ +  + ][ +  - ]:         18 :         RTL_CONSTASCII_USTRINGPARAM("ShapeInserted"));
         [ +  - ][ #  # ]
     681                 :            :     static const ::rtl::OUString sShapeRemoved (
     682 [ +  + ][ +  - ]:         18 :         RTL_CONSTASCII_USTRINGPARAM("ShapeRemoved"));
         [ +  - ][ #  # ]
     683                 :            : 
     684                 :            : 
     685         [ -  + ]:         18 :     if (rEventObject.EventName.equals (sShapeInserted))
     686         [ #  # ]:          0 :         AddShape (Reference<drawing::XShape>(rEventObject.Source, uno::UNO_QUERY));
     687         [ -  + ]:         18 :     else if (rEventObject.EventName.equals (sShapeRemoved))
     688         [ #  # ]:          0 :         RemoveShape (Reference<drawing::XShape>(rEventObject.Source, uno::UNO_QUERY));
     689                 :            :     // else ignore unknown event.
     690                 :         18 : }
     691                 :            : 
     692                 :            : 
     693                 :            : 
     694                 :            : 
     695                 :            : //=====  view::XSelectionChangeListener  ======================================
     696                 :            : 
     697                 :            : void  SAL_CALL
     698                 :          8 :     ChildrenManagerImpl::selectionChanged (const lang::EventObject& /*rEvent*/)
     699                 :            :         throw (uno::RuntimeException)
     700                 :            : {
     701                 :          8 :     UpdateSelection ();
     702                 :          2 : }
     703                 :            : 
     704                 :            : 
     705                 :            : 
     706                 :            : 
     707                 :          6 : void ChildrenManagerImpl::impl_dispose (void)
     708                 :            : {
     709         [ +  - ]:          6 :     Reference<frame::XController> xController(maShapeTreeInfo.GetController());
     710                 :            :     // Remove from broadcasters.
     711                 :            :     try
     712                 :            :     {
     713                 :            :         Reference<view::XSelectionSupplier> xSelectionSupplier (
     714         [ +  - ]:          6 :             xController, uno::UNO_QUERY);
     715         [ +  - ]:          6 :         if (xSelectionSupplier.is())
     716                 :            :         {
     717         [ +  - ]:          6 :             xSelectionSupplier->removeSelectionChangeListener (
     718 [ +  - ][ +  - ]:          6 :                 static_cast<view::XSelectionChangeListener*>(this));
     719         [ #  # ]:          6 :         }
     720                 :            :     }
     721         [ #  # ]:          0 :     catch( uno::RuntimeException&)
     722                 :            :     {}
     723                 :            : 
     724                 :            :     try
     725                 :            :     {
     726         [ +  - ]:          6 :         if (xController.is())
     727         [ +  - ]:          6 :             xController->removeEventListener(
     728 [ +  - ][ +  - ]:          6 :                 static_cast<document::XEventListener*>(this));
                 [ #  # ]
     729                 :            :     }
     730         [ #  # ]:          0 :     catch( uno::RuntimeException&)
     731                 :            :     {}
     732                 :            : 
     733 [ +  - ][ +  - ]:          6 :     maShapeTreeInfo.SetController (NULL);
     734                 :            : 
     735                 :            :     try
     736                 :            :     {
     737                 :            :         // Remove from broadcaster.
     738 [ +  - ][ +  - ]:          6 :         if (maShapeTreeInfo.GetModelBroadcaster().is())
     739 [ +  - ][ +  - ]:         12 :             maShapeTreeInfo.GetModelBroadcaster()->removeEventListener (
     740 [ +  - ][ +  - ]:          6 :                 static_cast<document::XEventListener*>(this));
     741 [ +  - ][ +  - ]:          6 :         maShapeTreeInfo.SetModelBroadcaster (NULL);
                 [ #  # ]
     742                 :            :     }
     743         [ #  # ]:          0 :     catch( uno::RuntimeException& )
     744                 :            :     {}
     745                 :            : 
     746         [ +  - ]:          6 :     ClearAccessibleShapeList ();
     747 [ +  - ][ +  - ]:          6 :     SetShapeList (NULL);
     748                 :          6 : }
     749                 :            : 
     750                 :            : 
     751                 :            : 
     752                 :          6 : void SAL_CALL ChildrenManagerImpl::disposing (void)
     753                 :            : {
     754                 :          6 :     impl_dispose();
     755                 :          6 : }
     756                 :            : 
     757                 :            : //=====  IAccessibleViewForwarderListener  ====================================
     758                 :            : 
     759                 :         20 : void ChildrenManagerImpl::ViewForwarderChanged (ChangeType aChangeType,
     760                 :            :         const IAccessibleViewForwarder* pViewForwarder)
     761                 :            : {
     762         [ +  - ]:         20 :     if (aChangeType == IAccessibleViewForwarderListener::VISIBLE_AREA)
     763                 :         20 :         Update (false);
     764                 :            :     else
     765                 :            :     {
     766         [ #  # ]:          0 :         ::osl::MutexGuard aGuard (maMutex);
     767                 :          0 :         ChildDescriptorListType::iterator I, aEnd = maVisibleChildren.end();
     768 [ #  # ][ #  # ]:          0 :         for (I=maVisibleChildren.begin(); I != aEnd; ++I)
     769                 :            :         {
     770         [ #  # ]:          0 :             AccessibleShape* pShape = I->GetAccessibleShape();
     771         [ #  # ]:          0 :             if (pShape != NULL)
     772         [ #  # ]:          0 :                 pShape->ViewForwarderChanged (aChangeType, pViewForwarder);
     773         [ #  # ]:          0 :         }
     774                 :            :     }
     775                 :         20 : }
     776                 :            : 
     777                 :            : 
     778                 :            : 
     779                 :            : 
     780                 :            : //=====  IAccessibleParent  ===================================================
     781                 :            : 
     782                 :          0 : sal_Bool ChildrenManagerImpl::ReplaceChild (
     783                 :            :     AccessibleShape* pCurrentChild,
     784                 :            :     const ::com::sun::star::uno::Reference< ::com::sun::star::drawing::XShape >& _rxShape,
     785                 :            :     const long _nIndex,
     786                 :            :     const AccessibleShapeTreeInfo& _rShapeTreeInfo)
     787                 :            :     throw (uno::RuntimeException)
     788                 :            : {
     789 [ #  # ][ #  # ]:          0 :     AccessibleShapeInfo aShapeInfo( _rxShape, pCurrentChild->getAccessibleParent(), this, _nIndex );
     790                 :            :     // create the new child
     791         [ #  # ]:          0 :     AccessibleShape* pNewChild = ShapeTypeHandler::Instance().CreateAccessibleObject (
     792                 :            :         aShapeInfo,
     793                 :            :         _rShapeTreeInfo
     794         [ #  # ]:          0 :     );
     795 [ #  # ][ #  # ]:          0 :     Reference< XAccessible > xNewChild( pNewChild );    // keep this alive (do this before calling Init!)
     796         [ #  # ]:          0 :     if ( pNewChild )
     797         [ #  # ]:          0 :         pNewChild->Init();
     798                 :            : 
     799                 :          0 :     sal_Bool bResult = sal_False;
     800                 :            : 
     801                 :            :     // Iterate over the visible children.  If one of them has an already
     802                 :            :     // created accessible object that matches pCurrentChild then replace
     803                 :            :     // it.  Otherwise the child to replace is either not in the list or has
     804                 :            :     // not ye been created (and is therefore not in the list, too) and a
     805                 :            :     // replacement is not necessary.
     806                 :          0 :     ChildDescriptorListType::iterator I,aEnd = maVisibleChildren.end();
     807 [ #  # ][ #  # ]:          0 :     for (I=maVisibleChildren.begin(); I != aEnd; ++I)
     808                 :            :     {
     809 [ #  # ][ #  # ]:          0 :         if (I->GetAccessibleShape() == pCurrentChild)
     810                 :            :         {
     811                 :            :             // Dispose the current child and send an event about its deletion.
     812         [ #  # ]:          0 :             pCurrentChild->dispose();
     813                 :            :             mrContext.CommitChange (
     814                 :            :                 AccessibleEventId::CHILD,
     815                 :            :                 uno::Any(),
     816 [ #  # ][ #  # ]:          0 :                 uno::makeAny (I->mxAccessibleShape));
     817                 :            : 
     818                 :            :             // Replace with replacement and send an event about existance
     819                 :            :             // of the new child.
     820 [ #  # ][ #  # ]:          0 :             I->mxAccessibleShape = pNewChild;
     821                 :            :             mrContext.CommitChange (
     822                 :            :                 AccessibleEventId::CHILD,
     823                 :          0 :                 uno::makeAny (I->mxAccessibleShape),
     824 [ #  # ][ #  # ]:          0 :                 uno::Any());
     825                 :          0 :             bResult = sal_True;
     826                 :          0 :             break;
     827                 :            :         }
     828                 :            :     }
     829                 :            : 
     830                 :            :     // When not found among the visible children we have to search the list
     831                 :            :     // of accessible shapes.  This is not yet implemented.
     832                 :            : 
     833         [ #  # ]:          0 :     return bResult;
     834                 :            : }
     835                 :            : 
     836                 :            : 
     837                 :            : 
     838                 :            : 
     839                 :            : /** Update the <const>SELECTED</const> and the <const>FOCUSED</const> state
     840                 :            :     of all visible children.  Maybe this should be changed to all children.
     841                 :            : 
     842                 :            :     Iterate over all descriptors of visible accessible shapes and look them
     843                 :            :     up in the selection.
     844                 :            : 
     845                 :            :     If there is no valid controller then all shapes are deselected and
     846                 :            :     unfocused.  If the controller's frame is not active then all shapes are
     847                 :            :     unfocused.
     848                 :            : */
     849                 :         14 : void ChildrenManagerImpl::UpdateSelection (void)
     850                 :            : {
     851         [ +  - ]:         14 :     Reference<frame::XController> xController(maShapeTreeInfo.GetController());
     852                 :            :     Reference<view::XSelectionSupplier> xSelectionSupplier (
     853         [ +  - ]:         14 :         xController, uno::UNO_QUERY);
     854                 :            : 
     855                 :            :     // Try to cast the selection both to a multi selection and to a single
     856                 :            :     // selection.
     857                 :         14 :     Reference<container::XIndexAccess> xSelectedShapeAccess;
     858                 :         14 :     Reference<drawing::XShape> xSelectedShape;
     859         [ +  - ]:         14 :     if (xSelectionSupplier.is())
     860                 :            :     {
     861                 :            :         xSelectedShapeAccess = Reference<container::XIndexAccess> (
     862 [ +  - ][ +  + ]:         14 :             xSelectionSupplier->getSelection(), uno::UNO_QUERY);
         [ +  - ][ +  - ]
     863                 :            :         xSelectedShape = Reference<drawing::XShape> (
     864 [ +  - ][ +  - ]:          8 :             xSelectionSupplier->getSelection(), uno::UNO_QUERY);
         [ +  - ][ +  - ]
     865                 :            :     }
     866                 :            : 
     867                 :            :     // Remember the current and new focused shape.
     868                 :          8 :     AccessibleShape* pCurrentlyFocusedShape = NULL;
     869                 :          8 :     AccessibleShape* pNewFocusedShape = NULL;
     870                 :            : 
     871                 :          8 :     ChildDescriptorListType::iterator I, aEnd = maVisibleChildren.end();
     872 [ +  - ][ +  + ]:         22 :     for (I=maVisibleChildren.begin(); I != aEnd; ++I)
     873                 :            :     {
     874         [ +  - ]:         14 :         AccessibleShape* pAccessibleShape = I->GetAccessibleShape();
     875 [ +  + ][ +  + ]:         14 :         if (I->mxAccessibleShape.is() && I->mxShape.is() && pAccessibleShape!=NULL)
         [ +  - ][ +  + ]
     876                 :            :         {
     877                 :          2 :             bool bShapeIsSelected = false;
     878                 :            : 
     879                 :            :             // Look up the shape in the (single or multi-) selection.
     880         [ -  + ]:          2 :             if (xSelectedShape.is())
     881                 :            :             {
     882 [ #  # ][ #  # ]:          0 :                 if  (I->mxShape == xSelectedShape)
     883                 :            :                 {
     884                 :          0 :                     bShapeIsSelected = true;
     885                 :          0 :                     pNewFocusedShape = pAccessibleShape;
     886                 :            :                 }
     887                 :            :             }
     888         [ +  - ]:          2 :             else if (xSelectedShapeAccess.is())
     889                 :            :             {
     890 [ +  - ][ +  - ]:          2 :                 sal_Int32 nCount=xSelectedShapeAccess->getCount();
     891 [ +  + ][ +  - ]:          4 :                 for (sal_Int32 i=0; i<nCount&&!bShapeIsSelected; i++)
                 [ +  + ]
     892 [ +  - ][ +  - ]:          2 :                     if (xSelectedShapeAccess->getByIndex(i) == I->mxShape)
         [ +  - ][ +  - ]
     893                 :            :                     {
     894                 :          2 :                         bShapeIsSelected = true;
     895                 :            :                         // In a multi-selection no shape has the focus.
     896         [ +  - ]:          2 :                         if (nCount == 1)
     897                 :          2 :                             pNewFocusedShape = pAccessibleShape;
     898                 :            :                     }
     899                 :            :             }
     900                 :            : 
     901                 :            :             // Set or reset the SELECTED state.
     902         [ +  - ]:          2 :             if (bShapeIsSelected)
     903         [ +  - ]:          2 :                 pAccessibleShape->SetState (AccessibleStateType::SELECTED);
     904                 :            :             else
     905         [ #  # ]:          0 :                 pAccessibleShape->ResetState (AccessibleStateType::SELECTED);
     906                 :            : 
     907                 :            :             // Does the shape have the current selection?
     908 [ +  - ][ -  + ]:          2 :             if (pAccessibleShape->GetState (AccessibleStateType::FOCUSED))
     909                 :          0 :                 pCurrentlyFocusedShape = pAccessibleShape;
     910                 :            :         }
     911                 :            :     }
     912                 :            : 
     913                 :            :     // Check if the frame we are in is currently active.  If not then make
     914                 :            :     // sure to not send a FOCUSED state change.
     915         [ +  - ]:          8 :     if (xController.is())
     916                 :            :     {
     917 [ +  - ][ +  - ]:          8 :         Reference<frame::XFrame> xFrame (xController->getFrame());
     918         [ +  - ]:          8 :         if (xFrame.is())
     919 [ +  - ][ +  - ]:          8 :             if ( ! xFrame->isActive())
                 [ -  + ]
     920                 :          8 :                 pNewFocusedShape = NULL;
     921                 :            :     }
     922                 :            : 
     923                 :            :     // Move focus from current to newly focused shape.
     924         [ +  + ]:          8 :     if (pCurrentlyFocusedShape != pNewFocusedShape)
     925                 :            :     {
     926         [ -  + ]:          2 :         if (pCurrentlyFocusedShape != NULL)
     927         [ #  # ]:          0 :             pCurrentlyFocusedShape->ResetState (AccessibleStateType::FOCUSED);
     928         [ +  - ]:          2 :         if (pNewFocusedShape != NULL)
     929         [ +  - ]:          2 :             pNewFocusedShape->SetState (AccessibleStateType::FOCUSED);
     930                 :            :     }
     931                 :            : 
     932                 :            :     // Remember whether there is a shape that now has the focus.
     933                 :         14 :     mpFocusedShape = pNewFocusedShape;
     934                 :          8 : }
     935                 :            : 
     936                 :            : 
     937                 :            : 
     938                 :            : 
     939                 :          0 : bool ChildrenManagerImpl::HasFocus (void)
     940                 :            : {
     941                 :          0 :     return mpFocusedShape != NULL;
     942                 :            : }
     943                 :            : 
     944                 :            : 
     945                 :            : 
     946                 :            : 
     947                 :          0 : void ChildrenManagerImpl::RemoveFocus (void)
     948                 :            : {
     949         [ #  # ]:          0 :     if (mpFocusedShape != NULL)
     950                 :            :     {
     951                 :          0 :         mpFocusedShape->ResetState (AccessibleStateType::FOCUSED);
     952                 :          0 :         mpFocusedShape = NULL;
     953                 :            :     }
     954                 :          0 : }
     955                 :            : 
     956                 :            : 
     957                 :            : 
     958                 :         24 : void ChildrenManagerImpl::RegisterAsDisposeListener (
     959                 :            :     const Reference<drawing::XShape>& xShape)
     960                 :            : {
     961         [ +  - ]:         24 :     Reference<lang::XComponent> xComponent (xShape, uno::UNO_QUERY);
     962         [ +  + ]:         24 :     if (xComponent.is())
     963         [ +  - ]:         10 :         xComponent->addEventListener (
     964 [ +  - ][ +  - ]:         24 :             static_cast<document::XEventListener*>(this));
     965                 :         24 : }
     966                 :            : 
     967                 :            : 
     968                 :            : 
     969                 :            : 
     970                 :          0 : void ChildrenManagerImpl::UnregisterAsDisposeListener (
     971                 :            :     const Reference<drawing::XShape>& xShape)
     972                 :            : {
     973         [ #  # ]:          0 :     Reference<lang::XComponent> xComponent (xShape, uno::UNO_QUERY);
     974         [ #  # ]:          0 :     if (xComponent.is())
     975         [ #  # ]:          0 :         xComponent->removeEventListener (
     976 [ #  # ][ #  # ]:          0 :             static_cast<document::XEventListener*>(this));
     977                 :          0 : }
     978                 :            : 
     979                 :            : 
     980                 :            : 
     981                 :            : 
     982                 :            : //=====  AccessibleChildDescriptor  ===========================================
     983                 :            : 
     984                 :         32 : ChildDescriptor::ChildDescriptor (const Reference<drawing::XShape>& xShape)
     985                 :            :     : mxShape (xShape),
     986                 :            :       mxAccessibleShape (NULL),
     987         [ +  - ]:         32 :       mbCreateEventPending (true)
     988                 :            : {
     989                 :            :     // Empty.
     990                 :         32 : }
     991                 :            : 
     992                 :            : 
     993                 :            : 
     994                 :            : 
     995                 :         34 : ChildDescriptor::ChildDescriptor (const Reference<XAccessible>& rxAccessibleShape)
     996                 :            :     : mxShape (NULL),
     997                 :            :       mxAccessibleShape (rxAccessibleShape),
     998                 :         34 :       mbCreateEventPending (true)
     999                 :            : {
    1000                 :            :     // Make sure that the accessible object has the <const>VISIBLE</const>
    1001                 :            :     // state set.
    1002         [ +  - ]:         34 :     AccessibleShape* pAccessibleShape = GetAccessibleShape();
    1003         [ +  - ]:         34 :     pAccessibleShape->SetState (AccessibleStateType::VISIBLE);
    1004                 :         34 : }
    1005                 :            : 
    1006                 :            : 
    1007                 :            : 
    1008                 :            : 
    1009                 :        132 : ChildDescriptor::~ChildDescriptor (void)
    1010                 :            : {
    1011                 :        132 : }
    1012                 :            : 
    1013                 :            : 
    1014                 :            : 
    1015                 :            : 
    1016                 :         98 : AccessibleShape* ChildDescriptor::GetAccessibleShape (void) const
    1017                 :            : {
    1018         [ +  + ]:         98 :     return static_cast<AccessibleShape*> (mxAccessibleShape.get());
    1019                 :            : }
    1020                 :            : // -----------------------------------------------------------------------------
    1021                 :         50 : void ChildDescriptor::setIndexAtAccessibleShape(sal_Int32 _nIndex)
    1022                 :            : {
    1023                 :         50 :     AccessibleShape* pShape = GetAccessibleShape();
    1024         [ +  + ]:         50 :     if ( pShape )
    1025                 :         40 :         pShape->setIndexInParent(_nIndex);
    1026                 :         50 : }
    1027                 :            : // -----------------------------------------------------------------------------
    1028                 :            : 
    1029                 :            : 
    1030                 :            : 
    1031                 :            : 
    1032                 :          0 : void ChildDescriptor::disposeAccessibleObject (AccessibleContextBase& rParent)
    1033                 :            : {
    1034         [ #  # ]:          0 :     if (mxAccessibleShape.is())
    1035                 :            :     {
    1036                 :            :         // Send event that the shape has been removed.
    1037                 :          0 :         uno::Any aOldValue;
    1038         [ #  # ]:          0 :         aOldValue <<= mxAccessibleShape;
    1039                 :            :         rParent.CommitChange (
    1040                 :            :             AccessibleEventId::CHILD,
    1041                 :            :             uno::Any(),
    1042         [ #  # ]:          0 :             aOldValue);
    1043                 :            : 
    1044                 :            :         // Dispose and remove the object.
    1045         [ #  # ]:          0 :         Reference<lang::XComponent> xComponent (mxAccessibleShape, uno::UNO_QUERY);
    1046         [ #  # ]:          0 :         if (xComponent.is())
    1047 [ #  # ][ #  # ]:          0 :             xComponent->dispose ();
    1048                 :            : 
    1049         [ #  # ]:          0 :         mxAccessibleShape = NULL;
    1050                 :            :     }
    1051                 :          0 : }
    1052                 :            : 
    1053                 :            : 
    1054                 :            : } // end of namespace accessibility
    1055                 :            : 
    1056                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10