summaryrefslogtreecommitdiff
path: root/sw/source/core/access/accframe.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/access/accframe.cxx')
-rw-r--r--sw/source/core/access/accframe.cxx496
1 files changed, 496 insertions, 0 deletions
diff --git a/sw/source/core/access/accframe.cxx b/sw/source/core/access/accframe.cxx
new file mode 100644
index 000000000000..c19c7cf8ef1d
--- /dev/null
+++ b/sw/source/core/access/accframe.cxx
@@ -0,0 +1,496 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2000, 2010 Oracle and/or its affiliates.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * This file is part of OpenOffice.org.
+ *
+ * OpenOffice.org is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 3
+ * only, as published by the Free Software Foundation.
+ *
+ * OpenOffice.org is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License version 3 for more details
+ * (a copy is included in the LICENSE file that accompanied this code).
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * version 3 along with OpenOffice.org. If not, see
+ * <http://www.openoffice.org/license.html>
+ * for a copy of the LGPLv3 License.
+ *
+ ************************************************************************/
+
+// MARKER(update_precomp.py): autogen include statement, do not remove
+#include "precompiled_sw.hxx"
+
+
+
+#include <hintids.hxx>
+#include <editeng/brshitem.hxx>
+#include <flyfrm.hxx>
+#include <rootfrm.hxx>
+#include <txtfrm.hxx>
+#include <sectfrm.hxx>
+#include <section.hxx>
+#include <viewsh.hxx>
+#include <viewopt.hxx>
+#include <doc.hxx>
+#include <frmatr.hxx>
+#include <pagefrm.hxx>
+#include <pagedesc.hxx>
+#include <fmtanchr.hxx>
+#include <fldbas.hxx>
+#include <dcontact.hxx>
+#include <accmap.hxx>
+#include <accfrmobjslist.hxx>
+#include <accfrmobjmap.hxx>
+#include <accframe.hxx>
+
+using namespace sw::access;
+
+// Regarding visibilily (or in terms of accessibility: regarding the showing
+// state): A frame is visible and therfor contained in the tree if its frame
+// size overlaps with the visible area. The bounding box however is the
+// frame's paint area.
+/* static */ sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap,
+ const SwRect& rVisArea,
+ const SwFrm *pFrm,
+ sal_Bool bInPagePreview )
+{
+ sal_Int32 nCount = 0;
+
+ const SwAccessibleChildSList aVisList( rVisArea, *pFrm, rAccMap );
+ SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() )
+ {
+ const SwAccessibleChild& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ nCount++;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ nCount += GetChildCount( rAccMap,
+ rVisArea, rLower.GetSwFrm(),
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+
+ return nCount;
+}
+
+/* static */ SwAccessibleChild SwAccessibleFrame::GetChild(
+ SwAccessibleMap& rAccMap,
+ const SwRect& rVisArea,
+ const SwFrm& rFrm,
+ sal_Int32& rPos,
+ sal_Bool bInPagePreview )
+{
+ SwAccessibleChild aRet;
+
+ if( rPos >= 0 )
+ {
+ if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
+ {
+ // We need a sorted list here
+ const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() && !aRet.IsValid() )
+ {
+ const SwAccessibleChild& rLower = (*aIter).second;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ if( 0 == rPos )
+ aRet = rLower;
+ else
+ rPos--;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ aRet = GetChild( rAccMap,
+ rVisArea, *(rLower.GetSwFrm()), rPos,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !aRet.IsValid() )
+ {
+ const SwAccessibleChild& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ if( 0 == rPos )
+ aRet = rLower;
+ else
+ rPos--;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ aRet = GetChild( rAccMap,
+ rVisArea, *(rLower.GetSwFrm()), rPos,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+/* static */ sal_Bool SwAccessibleFrame::GetChildIndex(
+ SwAccessibleMap& rAccMap,
+ const SwRect& rVisArea,
+ const SwFrm& rFrm,
+ const SwAccessibleChild& rChild,
+ sal_Int32& rPos,
+ sal_Bool bInPagePreview )
+{
+ sal_Bool bFound = sal_False;
+
+ if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
+ {
+ // We need a sorted list here
+ const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() && !bFound )
+ {
+ const SwAccessibleChild& rLower = (*aIter).second;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ if( rChild == rLower )
+ bFound = sal_True;
+ else
+ rPos++;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ bFound = GetChildIndex( rAccMap,
+ rVisArea, *(rLower.GetSwFrm()), rChild,
+ rPos, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !bFound )
+ {
+ const SwAccessibleChild& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ if( rChild == rLower )
+ bFound = sal_True;
+ else
+ rPos++;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ bFound = GetChildIndex( rAccMap,
+ rVisArea, *(rLower.GetSwFrm()), rChild,
+ rPos, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+
+ return bFound;
+}
+
+SwAccessibleChild SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea,
+ const SwFrm& rFrm,
+ const Point& rPixPos,
+ sal_Bool bInPagePreview,
+ SwAccessibleMap& rAccMap )
+{
+ SwAccessibleChild aRet;
+
+ if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
+ {
+ // We need a sorted list here, and we have to reverse iterate,
+ // because objects in front should be returned.
+ const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildMap::const_reverse_iterator aRIter( aVisMap.rbegin() );
+ while( aRIter != aVisMap.rend() && !aRet.IsValid() )
+ {
+ const SwAccessibleChild& rLower = (*aRIter).second;
+ // A frame is returned if it's frame size is inside the visarea
+ // and the positiion is inside the frame's paint area.
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
+ if( !aLogBounds.IsEmpty() )
+ {
+ Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
+ if( aPixBounds.IsInside( rPixPos ) )
+ aRet = rLower;
+ }
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
+ bInPagePreview, rAccMap );
+ }
+ ++aRIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it returns lower
+ // frames in the correct order. Morover, we can iterate forward,
+ // because the lowers don't overlap!
+ const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !aRet.IsValid() )
+ {
+ const SwAccessibleChild& rLower = *aIter;
+ // A frame is returned if it's frame size is inside the visarea
+ // and the positiion is inside the frame's paint area.
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ SwRect aLogBounds( rLower.GetBounds( rAccMap ) );
+ if( !aLogBounds.IsEmpty() )
+ {
+ Rectangle aPixBounds( rAccMap.CoreToPixel( aLogBounds.SVRect() ) );
+ if( aPixBounds.IsInside( rPixPos ) )
+ aRet = rLower;
+ }
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ aRet = GetChildAtPixel( rVisArea, *(rLower.GetSwFrm()), rPixPos,
+ bInPagePreview, rAccMap );
+ }
+ ++aIter;
+ }
+ }
+
+ return aRet;
+}
+
+/* static */ void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
+ const SwRect& rVisArea,
+ const SwFrm& rFrm,
+ ::std::list< SwAccessibleChild >& rChildren,
+ sal_Bool bInPagePreview )
+{
+ if( SwAccessibleChildMap::IsSortingRequired( rFrm ) )
+ {
+ // We need a sorted list here
+ const SwAccessibleChildMap aVisMap( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() )
+ {
+ const SwAccessibleChild& rLower = (*aIter).second;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ rChildren.push_back( rLower );
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
+ rChildren, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwAccessibleChildSList aVisList( rVisArea, rFrm, rAccMap );
+ SwAccessibleChildSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() )
+ {
+ const SwAccessibleChild& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ rChildren.push_back( rLower );
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ GetChildren( rAccMap, rVisArea, *(rLower.GetSwFrm()),
+ rChildren, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+}
+
+SwRect SwAccessibleFrame::GetBounds( const SwAccessibleMap& rAccMap,
+ const SwFrm *pFrm )
+{
+ if( !pFrm )
+ pFrm = GetFrm();
+
+ SwAccessibleChild aFrm( pFrm );
+ SwRect aBounds( aFrm.GetBounds( rAccMap ).Intersection( maVisArea ) );
+ return aBounds;
+}
+
+sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const
+{
+ const SwFrm *pFrm = GetFrm();
+ if( !pFrm )
+ return sal_False;
+
+ OSL_ENSURE( pVSh, "no view shell" );
+ if( pVSh && (pVSh->GetViewOptions()->IsReadonly() ||
+ pVSh->IsPreView()) )
+ return sal_False;
+
+ if( !pFrm->IsRootFrm() && pFrm->IsProtected() )
+ return sal_False;
+
+ return sal_True;
+}
+
+sal_Bool SwAccessibleFrame::IsOpaque( ViewShell *pVSh ) const
+{
+ SwAccessibleChild aFrm( GetFrm() );
+ if( !aFrm.GetSwFrm() )
+ return sal_False;
+
+ OSL_ENSURE( pVSh, "no view shell" );
+ if( !pVSh )
+ return sal_False;
+
+ const SwViewOption *pVOpt = pVSh->GetViewOptions();
+ do
+ {
+ const SwFrm *pFrm = aFrm.GetSwFrm();
+ if( pFrm->IsRootFrm() )
+ return sal_True;
+
+ if( pFrm->IsPageFrm() && !pVOpt->IsPageBack() )
+ return sal_False;
+
+ const SvxBrushItem &rBack = pFrm->GetAttrSet()->GetBackground();
+ if( !rBack.GetColor().GetTransparency() ||
+ rBack.GetGraphicPos() != GPOS_NONE )
+ return sal_True;
+
+ // If a fly frame has a transparent background color, we have to consider the background.
+ // But a background color "no fill"/"auto fill" has *not* to be considered.
+ if( pFrm->IsFlyFrm() &&
+ (rBack.GetColor().GetTransparency() != 0) &&
+ (rBack.GetColor() != COL_TRANSPARENT)
+ )
+ return sal_True;
+
+ if( pFrm->IsSctFrm() )
+ {
+ const SwSection* pSection = ((SwSectionFrm*)pFrm)->GetSection();
+ if( pSection && ( TOX_HEADER_SECTION == pSection->GetType() ||
+ TOX_CONTENT_SECTION == pSection->GetType() ) &&
+ !pVOpt->IsReadonly() &&
+ SwViewOption::IsIndexShadings() )
+ return sal_True;
+ }
+ if( pFrm->IsFlyFrm() )
+ aFrm = static_cast<const SwFlyFrm*>(pFrm)->GetAnchorFrm();
+ else
+ aFrm = pFrm->GetUpper();
+ } while( aFrm.GetSwFrm() && !aFrm.IsAccessible( IsInPagePreview() ) );
+
+ return sal_False;
+}
+
+SwAccessibleFrame::SwAccessibleFrame( const SwRect& rVisArea,
+ const SwFrm *pF,
+ sal_Bool bIsPagePreview ) :
+ maVisArea( rVisArea ),
+ mpFrm( pF ),
+ mbIsInPagePreview( bIsPagePreview )
+{
+}
+
+SwAccessibleFrame::~SwAccessibleFrame()
+{
+}
+
+/* static */ const SwFrm* SwAccessibleFrame::GetParent( const SwAccessibleChild& rFrmOrObj,
+ sal_Bool bInPagePreview )
+{
+ return rFrmOrObj.GetParent( bInPagePreview );
+}
+
+String SwAccessibleFrame::GetFormattedPageNumber() const
+{
+ sal_uInt16 nPageNum = GetFrm()->GetVirtPageNum();
+ sal_uInt32 nFmt = GetFrm()->FindPageFrm()->GetPageDesc()
+ ->GetNumType().GetNumberingType();
+ if( SVX_NUM_NUMBER_NONE == nFmt )
+ nFmt = SVX_NUM_ARABIC;
+
+ String sRet( FormatNumber( nPageNum, nFmt ) );
+ return sRet;
+}
+
+sal_Int32 SwAccessibleFrame::GetChildCount( SwAccessibleMap& rAccMap ) const
+{
+ return GetChildCount( rAccMap, maVisArea, mpFrm, IsInPagePreview() );
+}
+
+sw::access::SwAccessibleChild SwAccessibleFrame::GetChild(
+ SwAccessibleMap& rAccMap,
+ sal_Int32 nPos ) const
+{
+ return SwAccessibleFrame::GetChild( rAccMap, maVisArea, *mpFrm, nPos, IsInPagePreview() );
+}
+
+sal_Int32 SwAccessibleFrame::GetChildIndex( SwAccessibleMap& rAccMap,
+ const sw::access::SwAccessibleChild& rChild ) const
+{
+ sal_Int32 nPos = 0;
+ return GetChildIndex( rAccMap, maVisArea, *mpFrm, rChild, nPos, IsInPagePreview() )
+ ? nPos
+ : -1L;
+}
+
+sw::access::SwAccessibleChild SwAccessibleFrame::GetChildAtPixel(
+ const Point& rPos,
+ SwAccessibleMap& rAccMap ) const
+{
+ return GetChildAtPixel( maVisArea, *mpFrm, rPos, IsInPagePreview(), rAccMap );
+}
+
+void SwAccessibleFrame::GetChildren( SwAccessibleMap& rAccMap,
+ ::std::list< sw::access::SwAccessibleChild >& rChildren ) const
+{
+ GetChildren( rAccMap, maVisArea, *mpFrm, rChildren, IsInPagePreview() );
+}
+
+sal_Bool SwAccessibleFrame::IsShowing( const SwAccessibleMap& rAccMap,
+ const sw::access::SwAccessibleChild& rFrmOrObj ) const
+{
+ return IsShowing( rFrmOrObj.GetBox( rAccMap ) );
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */