summaryrefslogtreecommitdiffstats
path: root/sw/source/core/access/accfrmobj.cxx
diff options
context:
space:
mode:
Diffstat (limited to 'sw/source/core/access/accfrmobj.cxx')
-rw-r--r--sw/source/core/access/accfrmobj.cxx408
1 files changed, 408 insertions, 0 deletions
diff --git a/sw/source/core/access/accfrmobj.cxx b/sw/source/core/access/accfrmobj.cxx
new file mode 100644
index 000000000..c09c0215e
--- /dev/null
+++ b/sw/source/core/access/accfrmobj.cxx
@@ -0,0 +1,408 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ *
+ * This file incorporates work covered by the following license notice:
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed
+ * with this work for additional information regarding copyright
+ * ownership. The ASF licenses this file to you under the Apache
+ * License, Version 2.0 (the "License"); you may not use this file
+ * except in compliance with the License. You may obtain a copy of
+ * the License at http://www.apache.org/licenses/LICENSE-2.0 .
+ */
+
+#include "accfrmobj.hxx"
+
+#include <accmap.hxx>
+#include "acccontext.hxx"
+
+#include <viewsh.hxx>
+#include <rootfrm.hxx>
+#include <flyfrm.hxx>
+#include <pagefrm.hxx>
+#include <cellfrm.hxx>
+#include <swtable.hxx>
+#include <dflyobj.hxx>
+#include <frmfmt.hxx>
+#include <fmtanchr.hxx>
+#include <dcontact.hxx>
+
+#include <vcl/window.hxx>
+
+namespace sw::access {
+
+SwAccessibleChild::SwAccessibleChild()
+ : mpFrame( nullptr )
+ , mpDrawObj( nullptr )
+ , mpWindow( nullptr )
+{}
+
+SwAccessibleChild::SwAccessibleChild( const SdrObject* pDrawObj )
+ : mpFrame( nullptr )
+ , mpDrawObj( nullptr )
+ , mpWindow( nullptr )
+{
+ Init( pDrawObj );
+}
+
+SwAccessibleChild::SwAccessibleChild( const SwFrame* pFrame )
+ : mpFrame( nullptr )
+ , mpDrawObj( nullptr )
+ , mpWindow( nullptr )
+{
+ Init( pFrame );
+}
+
+SwAccessibleChild::SwAccessibleChild( vcl::Window* pWindow )
+ : mpFrame( nullptr )
+ , mpDrawObj( nullptr )
+ , mpWindow( nullptr )
+{
+ Init( pWindow );
+}
+
+SwAccessibleChild::SwAccessibleChild( const SwFrame* pFrame,
+ const SdrObject* pDrawObj,
+ vcl::Window* pWindow )
+ : mpFrame( nullptr )
+ , mpDrawObj( nullptr )
+ , mpWindow( nullptr )
+{
+ if ( pFrame )
+ {
+ Init( pFrame );
+ }
+ else if ( pDrawObj )
+ {
+ Init( pDrawObj );
+ }
+ else if ( pWindow )
+ {
+ Init( pWindow );
+ }
+ OSL_ENSURE( (!pFrame || pFrame == mpFrame) &&
+ (!pDrawObj || pDrawObj == mpDrawObj) &&
+ (!pWindow || pWindow == mpWindow),
+ "invalid frame/object/window combination" );
+
+}
+
+SwAccessibleChild::~SwAccessibleChild() = default;
+
+void SwAccessibleChild::Init( const SdrObject* pDrawObj )
+{
+ mpDrawObj = pDrawObj;
+ const SwVirtFlyDrawObj* pFlyDrawObj = dynamic_cast<const SwVirtFlyDrawObj*>(mpDrawObj);
+ mpFrame = pFlyDrawObj ? pFlyDrawObj->GetFlyFrame() : nullptr;
+ mpWindow = nullptr;
+}
+
+void SwAccessibleChild::Init( const SwFrame* pFrame )
+{
+ mpFrame = pFrame;
+ mpDrawObj = mpFrame && mpFrame->IsFlyFrame()
+ ? static_cast < const SwFlyFrame * >( mpFrame )->GetVirtDrawObj()
+ : nullptr;
+ mpWindow = nullptr;
+}
+
+void SwAccessibleChild::Init( vcl::Window* pWindow )
+{
+ mpWindow = pWindow;
+ mpFrame = nullptr;
+ mpDrawObj = nullptr;
+}
+
+bool SwAccessibleChild::IsAccessible( bool bPagePreview ) const
+{
+ bool bRet( false );
+
+ if ( mpFrame )
+ {
+ bRet = mpFrame->IsAccessibleFrame() &&
+ ( !mpFrame->IsCellFrame() ||
+ static_cast<const SwCellFrame *>( mpFrame )->GetTabBox()->GetSttNd() != nullptr ) &&
+ !mpFrame->IsInCoveredCell() &&
+ ( bPagePreview ||
+ !mpFrame->IsPageFrame() );
+ }
+ else if ( mpDrawObj )
+ {
+ bRet = true;
+ }
+ else if ( mpWindow )
+ {
+ bRet = true;
+ }
+
+ return bRet;
+}
+
+bool SwAccessibleChild::IsBoundAsChar() const
+{
+ bool bRet( false );
+
+ if ( mpFrame )
+ {
+ bRet = mpFrame->IsFlyFrame() &&
+ static_cast< const SwFlyFrame *>(mpFrame)->IsFlyInContentFrame();
+ }
+ else if ( mpDrawObj )
+ {
+ const SwFrameFormat* pFrameFormat = ::FindFrameFormat( mpDrawObj );
+ bRet = pFrameFormat
+ && (RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId());
+ }
+ else if ( mpWindow )
+ {
+ bRet = false;
+ }
+
+ return bRet;
+}
+
+SwAccessibleChild& SwAccessibleChild::operator=( const SdrObject* pDrawObj )
+{
+ Init( pDrawObj );
+ return *this;
+}
+
+SwAccessibleChild& SwAccessibleChild::operator=( const SwFrame* pFrame )
+{
+ Init( pFrame );
+ return *this;
+}
+
+SwAccessibleChild& SwAccessibleChild::operator=( vcl::Window* pWindow )
+{
+ Init( pWindow );
+ return *this;
+}
+
+bool SwAccessibleChild::operator==( const SwAccessibleChild& r ) const
+{
+ return mpFrame == r.mpFrame &&
+ mpDrawObj == r.mpDrawObj &&
+ mpWindow == r.mpWindow;
+}
+
+bool SwAccessibleChild::IsValid() const
+{
+ return mpFrame != nullptr ||
+ mpDrawObj != nullptr ||
+ mpWindow != nullptr;
+}
+
+bool SwAccessibleChild::IsVisibleChildrenOnly() const
+{
+ bool bRet( false );
+
+ if ( !mpFrame )
+ {
+ bRet = true;
+ }
+ else
+ {
+ bRet = mpFrame->IsRootFrame() ||
+ !( mpFrame->IsTabFrame() ||
+ mpFrame->IsInTab() ||
+ ( IsBoundAsChar() &&
+ static_cast<const SwFlyFrame*>(mpFrame)->GetAnchorFrame()->IsInTab() ) );
+ }
+
+ return bRet;
+}
+
+SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const
+{
+ SwRect aBox;
+
+ if ( mpFrame )
+ {
+ if ( mpFrame->IsPageFrame() &&
+ static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
+ {
+ aBox = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 1, 1 );
+ }
+ else if ( mpFrame->IsTabFrame() )
+ {
+ aBox = mpFrame->getFrameArea();
+ aBox.Intersection( mpFrame->GetUpper()->getFrameArea() );
+ }
+ else
+ {
+ aBox = mpFrame->getFrameArea();
+ }
+ }
+ else if( mpDrawObj )
+ {
+ const SwContact* const pContact = ::GetUserCall(mpDrawObj);
+ // assume that a) the SwVirt* objects that don't have this are handled
+ // by the mpFrame case above b) for genuine SdrObject this must be set
+ // if it's connected to layout
+ assert(dynamic_cast<SwDrawContact const*>(pContact));
+ SwPageFrame const*const pPage(const_cast<SwAnchoredObject *>(
+ pContact->GetAnchoredObj(mpDrawObj))->FindPageFrameOfAnchor());
+ if (pPage) // may end up here with partial layout -> not visible
+ {
+ aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
+ // tdf#91260 drawing object may be partially off-page
+ aBox.Intersection(pPage->getFrameArea());
+ }
+ }
+ else if ( mpWindow )
+ {
+ vcl::Window *pWin = rAccMap.GetShell()->GetWin();
+ if (pWin)
+ {
+ aBox = SwRect( pWin->PixelToLogic(
+ tools::Rectangle( mpWindow->GetPosPixel(),
+ mpWindow->GetSizePixel() ) ) );
+ }
+ }
+
+ return aBox;
+}
+
+SwRect SwAccessibleChild::GetBounds( const SwAccessibleMap& rAccMap ) const
+{
+ SwRect aBound;
+
+ if( mpFrame )
+ {
+ if( mpFrame->IsPageFrame() &&
+ static_cast< const SwPageFrame * >( mpFrame )->IsEmptyPage() )
+ {
+ aBound = SwRect( mpFrame->getFrameArea().Left(), mpFrame->getFrameArea().Top()-1, 0, 0 );
+ }
+ else
+ aBound = mpFrame->GetPaintArea();
+ }
+ else if( mpDrawObj )
+ {
+ aBound = GetBox( rAccMap );
+ }
+ else if ( mpWindow )
+ {
+ aBound = GetBox( rAccMap );
+ }
+
+ return aBound;
+}
+
+bool SwAccessibleChild::AlwaysIncludeAsChild() const
+{
+ bool bAlwaysIncludedAsChild( false );
+
+ if ( mpWindow )
+ {
+ bAlwaysIncludedAsChild = true;
+ }
+
+ return bAlwaysIncludedAsChild;
+}
+
+const SwFrame* SwAccessibleChild::GetParent( const bool bInPagePreview ) const
+{
+ const SwFrame* pParent( nullptr );
+
+ if ( mpFrame )
+ {
+ if( mpFrame->IsFlyFrame() )
+ {
+ const SwFlyFrame* pFly = static_cast< const SwFlyFrame *>( mpFrame );
+ if( pFly->IsFlyInContentFrame() )
+ {
+ // For RndStdIds::FLY_AS_CHAR the parent is the anchor
+ pParent = pFly->GetAnchorFrame();
+ OSL_ENSURE( SwAccessibleChild( pParent ).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 )
+ pParent = pFly->FindPageFrame();
+ else
+ pParent = pFly->getRootFrame();
+ }
+ }
+ else
+ {
+ SwAccessibleChild aUpper( mpFrame->GetUpper() );
+ while( aUpper.GetSwFrame() && !aUpper.IsAccessible(bInPagePreview) )
+ {
+ aUpper = aUpper.GetSwFrame()->GetUpper();
+ }
+ pParent = aUpper.GetSwFrame();
+ }
+ }
+ else if( mpDrawObj )
+ {
+ const SwDrawContact *pContact =
+ static_cast< const SwDrawContact* >( GetUserCall( mpDrawObj ) );
+ OSL_ENSURE( pContact, "sdr contact is missing" );
+ if( pContact )
+ {
+ const SwFrameFormat *pFrameFormat = pContact->GetFormat();
+ OSL_ENSURE( pFrameFormat, "frame format is missing" );
+ if( pFrameFormat && RndStdIds::FLY_AS_CHAR == pFrameFormat->GetAnchor().GetAnchorId() )
+ {
+ // For RndStdIds::FLY_AS_CHAR the parent is the anchor
+ pParent = pContact->GetAnchorFrame();
+ OSL_ENSURE( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
+ "parent is not accessible" );
+
+ }
+ else
+ {
+ // In any other case the parent is the root frm
+ SwFrame const*const pAnchor(pContact->GetAnchorFrame());
+ if (pAnchor) // null if object removed from layout
+ {
+ if (bInPagePreview)
+ pParent = pAnchor->FindPageFrame();
+ else
+ pParent = pAnchor->getRootFrame();
+ }
+ }
+ }
+ }
+ else if ( mpWindow )
+ {
+ css::uno::Reference < css::accessibility::XAccessible > xAcc =
+ mpWindow->GetAccessible();
+ if ( xAcc.is() )
+ {
+ css::uno::Reference < css::accessibility::XAccessibleContext > xAccContext =
+ xAcc->getAccessibleContext();
+ if ( xAccContext.is() )
+ {
+ css::uno::Reference < css::accessibility::XAccessible > xAccParent =
+ xAccContext->getAccessibleParent();
+ if ( xAccParent.is() )
+ {
+ SwAccessibleContext* pAccParentImpl =
+ dynamic_cast< SwAccessibleContext *>( xAccParent.get() );
+ if ( pAccParentImpl )
+ {
+ pParent = pAccParentImpl->GetFrame();
+ }
+ }
+ }
+ }
+ }
+
+ return pParent;
+}
+
+} // namespace sw::access
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */