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.cxx506
1 files changed, 506 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..f6778c1564b8
--- /dev/null
+++ b/sw/source/core/access/accframe.cxx
@@ -0,0 +1,506 @@
+ /*************************************************************************
+ *
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * Copyright 2008 by Sun Microsystems, Inc.
+ *
+ * OpenOffice.org - a multi-platform office productivity suite
+ *
+ * $RCSfile: accframe.cxx,v $
+ * $Revision: 1.26 $
+ *
+ * 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 <svx/brshitem.hxx>
+#include <flyfrm.hxx>
+#include <rootfrm.hxx>
+#include <txtfrm.hxx>
+#include <sectfrm.hxx>
+#include <pagefrm.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>
+
+
+// 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.
+sal_Int32 SwAccessibleFrame::GetChildCount( const SwRect& rVisArea,
+ const SwFrm *pFrm,
+ sal_Bool bInPagePreview )
+{
+ sal_Int32 nCount = 0;
+
+ const SwFrmOrObjSList aVisList( rVisArea, pFrm );
+ SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() )
+ {
+ const SwFrmOrObj& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ nCount++;
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ nCount += GetChildCount( rVisArea, rLower.GetSwFrm(),
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+
+ return nCount;
+}
+
+SwFrmOrObj SwAccessibleFrame::GetChild( const SwRect& rVisArea,
+ const SwFrm *pFrm,
+ sal_Int32& rPos,
+ sal_Bool bInPagePreview )
+{
+ SwFrmOrObj aRet;
+
+ if( rPos >= 0 )
+ {
+ if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
+ {
+ // We need a sorted list here
+ const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
+ SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() && !aRet.IsValid() )
+ {
+ const SwFrmOrObj& 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( rVisArea, rLower.GetSwFrm(), rPos,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwFrmOrObjSList aVisList( rVisArea, pFrm );
+ SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !aRet.IsValid() )
+ {
+ const SwFrmOrObj& 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( rVisArea, rLower.GetSwFrm(), rPos,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ }
+
+ return aRet;
+}
+
+sal_Bool SwAccessibleFrame::GetChildIndex( const SwRect& rVisArea,
+ const SwFrm *pFrm,
+ const SwFrmOrObj& rChild,
+ sal_Int32& rPos,
+ sal_Bool bInPagePreview )
+{
+ sal_Bool bFound = sal_False;
+
+ if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
+ {
+ // We need a sorted list here
+ const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
+ SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() && !bFound )
+ {
+ const SwFrmOrObj& 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( rVisArea, rLower.GetSwFrm(), rChild,
+ rPos, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwFrmOrObjSList aVisList( rVisArea, pFrm );
+ SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !bFound )
+ {
+ const SwFrmOrObj& 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( rVisArea, rLower.GetSwFrm(), rChild,
+ rPos, bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+
+ return bFound;
+}
+
+SwFrmOrObj SwAccessibleFrame::GetChildAtPixel( const SwRect& rVisArea,
+ const SwFrm *pFrm,
+ const Point& rPixPos,
+ sal_Bool bInPagePreview,
+ const SwAccessibleMap *pMap )
+{
+ SwFrmOrObj aRet;
+
+ if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
+ {
+ // We need a sorted list here, and we have to reverse iterate,
+ // because objects in front should be returned.
+ const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
+ SwFrmOrObjMap::const_reverse_iterator aRIter( aVisMap.rbegin() );
+ while( aRIter != aVisMap.rend() && !aRet.IsValid() )
+ {
+ const SwFrmOrObj& 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( ) );
+ if( !aLogBounds.IsEmpty() )
+ {
+ Rectangle aPixBounds( pMap->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, pMap );
+ }
+ 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 SwFrmOrObjSList aVisList( rVisArea, pFrm );
+ SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() && !aRet.IsValid() )
+ {
+ const SwFrmOrObj& 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( ) );
+ if( !aLogBounds.IsEmpty() )
+ {
+ Rectangle aPixBounds( pMap->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, pMap );
+ }
+ ++aIter;
+ }
+ }
+
+ return aRet;
+}
+
+void SwAccessibleFrame::GetChildren( const SwRect& rVisArea, const SwFrm *pFrm,
+ ::std::list< SwFrmOrObj >& rChildren,
+ sal_Bool bInPagePreview )
+{
+ if( SwFrmOrObjMap::IsSortingRequired( pFrm ) )
+ {
+ // We need a sorted list here
+ const SwFrmOrObjMap aVisMap( rVisArea, pFrm );
+ SwFrmOrObjMap::const_iterator aIter( aVisMap.begin() );
+ while( aIter != aVisMap.end() )
+ {
+ const SwFrmOrObj& rLower = (*aIter).second;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ rChildren.push_back( rLower );
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ GetChildren( rVisArea, rLower.GetSwFrm(), rChildren,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+ else
+ {
+ // The unsorted list is sorted enough, because it return lower
+ // frames in the correct order.
+ const SwFrmOrObjSList aVisList( rVisArea, pFrm );
+ SwFrmOrObjSList::const_iterator aIter( aVisList.begin() );
+ while( aIter != aVisList.end() )
+ {
+ const SwFrmOrObj& rLower = *aIter;
+ if( rLower.IsAccessible( bInPagePreview ) )
+ {
+ rChildren.push_back( rLower );
+ }
+ else if( rLower.GetSwFrm() )
+ {
+ // There are no unaccessible SdrObjects that count
+ GetChildren( rVisArea, rLower.GetSwFrm(), rChildren,
+ bInPagePreview );
+ }
+ ++aIter;
+ }
+ }
+}
+
+SwRect SwAccessibleFrame::GetBounds( const SwFrm *pFrm )
+{
+ if( !pFrm )
+ pFrm = GetFrm();
+
+ SwFrmOrObj aFrm( pFrm );
+ SwRect aBounds( aFrm.GetBounds().Intersection( maVisArea ) );
+ return aBounds;
+}
+
+sal_Bool SwAccessibleFrame::IsEditable( ViewShell *pVSh ) const
+{
+ const SwFrm *pFrm = GetFrm();
+ if( !pFrm )
+ return sal_False;
+
+ ASSERT( 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
+{
+ SwFrmOrObj aFrm( GetFrm() );
+ if( !aFrm.GetSwFrm() )
+ return sal_False;
+
+ ASSERT( 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;
+
+ /// OD 20.08.2002 #99657#
+ /// 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()
+{
+}
+
+const SwFrm *SwAccessibleFrame::GetParent( const SwFrmOrObj& rFrmOrObj,
+ sal_Bool bInPagePreview )
+{
+ SwFrmOrObj aParent;
+ const SwFrm *pFrm = rFrmOrObj.GetSwFrm();
+ if( pFrm )
+ {
+ if( pFrm->IsFlyFrm() )
+ {
+ const SwFlyFrm *pFly = static_cast< const SwFlyFrm *>( pFrm );
+ if( pFly->IsFlyInCntFrm() )
+ {
+ // For FLY_AS_CHAR the parent is the anchor
+ aParent = pFly->GetAnchorFrm();
+ ASSERT( aParent.IsAccessible( bInPagePreview ),
+ "parent is not accessible" );
+ }
+ else
+ {
+ // In any other case the parent is the root frm
+ // (in page preview, the page frame)
+ if( bInPagePreview )
+ aParent = pFly->FindPageFrm();
+ else
+ aParent = pFly->FindRootFrm();
+ }
+ }
+ else
+ {
+ SwFrmOrObj aUpper( pFrm->GetUpper() );
+ while( aUpper.GetSwFrm() && !aUpper.IsAccessible(bInPagePreview) )
+ aUpper = aUpper.GetSwFrm()->GetUpper();
+ aParent = aUpper;
+ }
+ }
+ else if( rFrmOrObj.GetSdrObject() )
+ {
+ const SwDrawContact *pContact =
+ static_cast< const SwDrawContact* >(
+ GetUserCall( rFrmOrObj.GetSdrObject() ) );
+ ASSERT( pContact, "sdr contact is missing" );
+ if( pContact )
+ {
+ const SwFrmFmt *pFrmFmt = pContact->GetFmt();
+ ASSERT( pFrmFmt, "frame format is missing" );
+ if (pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId())
+ {
+ // For FLY_AS_CHAR the parent is the anchor
+ aParent = pContact->GetAnchorFrm();
+ ASSERT( aParent.IsAccessible( bInPagePreview ),
+ "parent is not accessible" );
+
+ }
+ else
+ {
+ // In any other case the parent is the root frm
+ if( bInPagePreview )
+ aParent = pContact->GetAnchorFrm()->FindPageFrm();
+ else
+ aParent = pContact->GetAnchorFrm()->FindRootFrm();
+ }
+ }
+ }
+
+ return aParent.GetSwFrm();
+}
+
+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;
+}