xref: /aoo42x/main/sw/source/core/access/accfrmobj.cxx (revision cdf0e10c)
1  /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sw.hxx"
30 
31 #include <accfrmobj.hxx>
32 
33 #include <accmap.hxx>
34 #include <acccontext.hxx>
35 
36 #include <viewsh.hxx>
37 #include <rootfrm.hxx>
38 #include <flyfrm.hxx>
39 #include <pagefrm.hxx>
40 #include <cellfrm.hxx>
41 #include <swtable.hxx>
42 #include <dflyobj.hxx>
43 #include <frmfmt.hxx>
44 #include <fmtanchr.hxx>
45 #include <dcontact.hxx>
46 
47 #include <vcl/window.hxx>
48 
49 namespace css = ::com::sun::star;
50 
51 namespace sw { namespace access {
52 
53 SwAccessibleChild::SwAccessibleChild()
54     : mpFrm( 0 )
55     , mpDrawObj( 0 )
56     , mpWindow( 0 )
57 {}
58 
59 SwAccessibleChild::SwAccessibleChild( const SdrObject* pDrawObj )
60     : mpFrm( 0 )
61     , mpDrawObj( 0 )
62     , mpWindow( 0 )
63 {
64     Init( pDrawObj );
65 }
66 
67 SwAccessibleChild::SwAccessibleChild( const SwFrm* pFrm )
68     : mpFrm( 0 )
69     , mpDrawObj( 0 )
70     , mpWindow( 0 )
71 {
72     Init( pFrm );
73 }
74 
75 SwAccessibleChild::SwAccessibleChild( Window* pWindow )
76     : mpFrm( 0 )
77     , mpDrawObj( 0 )
78     , mpWindow( 0 )
79 {
80     Init( pWindow );
81 }
82 
83 
84 SwAccessibleChild::SwAccessibleChild( const SwFrm* pFrm,
85                                       const SdrObject* pDrawObj,
86                                       Window* pWindow )
87 {
88     if ( pFrm )
89     {
90         Init( pFrm );
91     }
92     else if ( pDrawObj )
93     {
94         Init( pDrawObj );
95     }
96     else if ( pWindow )
97     {
98         Init( pWindow );
99     }
100     ASSERT( (!pFrm || pFrm == mpFrm) &&
101             (!pDrawObj || pDrawObj == mpDrawObj) &&
102             (!pWindow || pWindow == mpWindow),
103             "invalid frame/object/window combination" );
104 
105 }
106 
107 void SwAccessibleChild::Init( const SdrObject* pDrawObj )
108 {
109     mpDrawObj = pDrawObj;
110     mpFrm = mpDrawObj && mpDrawObj->ISA(SwVirtFlyDrawObj)
111             ? static_cast < const SwVirtFlyDrawObj * >( mpDrawObj )->GetFlyFrm()
112             : 0;
113     mpWindow = 0;
114 }
115 
116 void SwAccessibleChild::Init( const SwFrm* pFrm )
117 {
118     mpFrm = pFrm;
119     mpDrawObj = mpFrm && mpFrm->IsFlyFrm()
120                 ? static_cast < const SwFlyFrm * >( mpFrm )->GetVirtDrawObj()
121                 : 0;
122     mpWindow = 0;
123 }
124 
125 void SwAccessibleChild::Init( Window* pWindow )
126 {
127     mpWindow = pWindow;
128     mpFrm = 0;
129     mpDrawObj = 0;
130 }
131 
132 bool SwAccessibleChild::IsAccessible( sal_Bool bPagePreview ) const
133 {
134     bool bRet( false );
135 
136     if ( mpFrm )
137     {
138         bRet = mpFrm->IsAccessibleFrm() &&
139                ( !mpFrm->IsCellFrm() ||
140                  static_cast<const SwCellFrm *>( mpFrm )->GetTabBox()->GetSttNd() != 0 ) &&
141                !mpFrm->IsInCoveredCell() &&
142                ( bPagePreview ||
143                  !mpFrm->IsPageFrm() );
144     }
145     else if ( mpDrawObj )
146     {
147         bRet = true;
148     }
149     else if ( mpWindow )
150     {
151         bRet = true;
152     }
153 
154     return bRet;
155 }
156 
157 bool SwAccessibleChild::IsBoundAsChar() const
158 {
159     bool bRet( false );
160 
161     if ( mpFrm )
162 	{
163         bRet = mpFrm->IsFlyFrm() &&
164                static_cast< const SwFlyFrm *>(mpFrm)->IsFlyInCntFrm();
165 	}
166     else if ( mpDrawObj )
167 	{
168         const SwFrmFmt* mpFrmFmt = ::FindFrmFmt( mpDrawObj );
169         bRet = mpFrmFmt
170                ? (FLY_AS_CHAR == mpFrmFmt->GetAnchor().GetAnchorId())
171                : false;
172 	}
173     else if ( mpWindow )
174     {
175         bRet = false;
176     }
177 
178     return bRet;
179 }
180 
181 SwAccessibleChild::SwAccessibleChild( const SwAccessibleChild& r )
182     : mpFrm( r.mpFrm )
183     , mpDrawObj( r.mpDrawObj )
184     , mpWindow( r.mpWindow )
185 {}
186 
187 SwAccessibleChild& SwAccessibleChild::operator=( const SwAccessibleChild& r )
188 {
189     mpDrawObj = r.mpDrawObj;
190     mpFrm = r.mpFrm;
191     mpWindow = r.mpWindow;
192 
193     return *this;
194 }
195 
196 SwAccessibleChild& SwAccessibleChild::operator=( const SdrObject* pDrawObj )
197 {
198     Init( pDrawObj );
199     return *this;
200 }
201 
202 SwAccessibleChild& SwAccessibleChild::operator=( const SwFrm* pFrm )
203 {
204     Init( pFrm );
205     return *this;
206 }
207 
208 SwAccessibleChild& SwAccessibleChild::operator=( Window* pWindow )
209 {
210     Init( pWindow );
211     return *this;
212 }
213 
214 bool SwAccessibleChild::operator==( const SwAccessibleChild& r ) const
215 {
216     return mpFrm == r.mpFrm &&
217            mpDrawObj == r.mpDrawObj &&
218            mpWindow == r.mpWindow;
219 }
220 
221 bool SwAccessibleChild::IsValid() const
222 {
223     return mpFrm != 0 ||
224            mpDrawObj != 0 ||
225            mpWindow != 0;
226 }
227 
228 const SdrObject* SwAccessibleChild::GetDrawObject() const
229 {
230     return mpDrawObj;
231 }
232 
233 const SwFrm *SwAccessibleChild::GetSwFrm() const
234 {
235     return mpFrm;
236 }
237 
238 Window* SwAccessibleChild::GetWindow() const
239 {
240     return mpWindow;
241 }
242 
243 bool SwAccessibleChild::IsVisibleChildrenOnly() const
244 {
245     bool bRet( false );
246 
247     if ( !mpFrm )
248     {
249         bRet = true;
250     }
251     else
252     {
253         bRet = mpFrm->IsRootFrm() ||
254                !( mpFrm->IsTabFrm() ||
255                   mpFrm->IsInTab() ||
256                   ( IsBoundAsChar() &&
257                     static_cast<const SwFlyFrm*>(mpFrm)->GetAnchorFrm()->IsInTab() ) );
258     }
259 
260     return bRet;
261 }
262 
263 SwRect SwAccessibleChild::GetBox( const SwAccessibleMap& rAccMap ) const
264 {
265     SwRect aBox;
266 
267     if ( mpFrm )
268     {
269         if ( mpFrm->IsPageFrm() &&
270              static_cast< const SwPageFrm * >( mpFrm )->IsEmptyPage() )
271         {
272             aBox = SwRect( mpFrm->Frm().Left(), mpFrm->Frm().Top()-1, 1, 1 );
273         }
274         else if ( mpFrm->IsTabFrm() )
275         {
276             aBox = SwRect( mpFrm->Frm() );
277             aBox.Intersection( mpFrm->GetUpper()->Frm() );
278         }
279         else
280         {
281             aBox = mpFrm->Frm();
282         }
283     }
284     else if( mpDrawObj )
285     {
286         aBox = SwRect( mpDrawObj->GetCurrentBoundRect() );
287     }
288     else if ( mpWindow )
289     {
290         aBox = SwRect( rAccMap.GetShell()->GetWin()->PixelToLogic(
291                                         Rectangle( mpWindow->GetPosPixel(),
292                                                    mpWindow->GetSizePixel() ) ) );
293 }
294 
295     return aBox;
296 }
297 
298 SwRect SwAccessibleChild::GetBounds( const SwAccessibleMap& rAccMap ) const
299 {
300     SwRect aBound;
301 
302     if( mpFrm )
303     {
304         if( mpFrm->IsPageFrm() &&
305             static_cast< const SwPageFrm * >( mpFrm )->IsEmptyPage() )
306         {
307             aBound = SwRect( mpFrm->Frm().Left(), mpFrm->Frm().Top()-1, 0, 0 );
308         }
309         else
310             aBound = mpFrm->PaintArea();
311     }
312     else if( mpDrawObj )
313     {
314         aBound = GetBox( rAccMap );
315     }
316     else if ( mpWindow )
317     {
318         aBound = GetBox( rAccMap );
319     }
320 
321     return aBound;
322 }
323 
324 bool SwAccessibleChild::AlwaysIncludeAsChild() const
325 {
326     bool bAlwaysIncludedAsChild( false );
327 
328     if ( mpWindow )
329     {
330         bAlwaysIncludedAsChild = true;
331     }
332 
333     return bAlwaysIncludedAsChild;
334 }
335 
336 const SwFrm* SwAccessibleChild::GetParent( const sal_Bool bInPagePreview ) const
337 {
338     const SwFrm* pParent( 0 );
339 
340     if ( mpFrm )
341     {
342         if( mpFrm->IsFlyFrm() )
343         {
344             const SwFlyFrm* pFly = static_cast< const SwFlyFrm *>( mpFrm );
345             if( pFly->IsFlyInCntFrm() )
346             {
347                 // For FLY_AS_CHAR the parent is the anchor
348                 pParent = pFly->GetAnchorFrm();
349                 ASSERT( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
350                         "parent is not accessible" );
351             }
352             else
353             {
354                 // In any other case the parent is the root frm
355                 // (in page preview, the page frame)
356                 if( bInPagePreview )
357                     pParent = pFly->FindPageFrm();
358                 else
359                     pParent = pFly->getRootFrm();
360             }
361         }
362         else
363         {
364             SwAccessibleChild aUpper( mpFrm->GetUpper() );
365             while( aUpper.GetSwFrm() && !aUpper.IsAccessible(bInPagePreview) )
366             {
367                 aUpper = aUpper.GetSwFrm()->GetUpper();
368             }
369             pParent = aUpper.GetSwFrm();
370         }
371     }
372     else if( mpDrawObj )
373     {
374         const SwDrawContact *pContact =
375             static_cast< const SwDrawContact* >( GetUserCall( mpDrawObj ) );
376         ASSERT( pContact, "sdr contact is missing" );
377         if( pContact )
378         {
379             const SwFrmFmt *pFrmFmt = pContact->GetFmt();
380             ASSERT( pFrmFmt, "frame format is missing" );
381             if( pFrmFmt && FLY_AS_CHAR == pFrmFmt->GetAnchor().GetAnchorId() )
382             {
383                 // For FLY_AS_CHAR the parent is the anchor
384                 pParent = pContact->GetAnchorFrm();
385                 ASSERT( SwAccessibleChild( pParent ).IsAccessible( bInPagePreview ),
386                         "parent is not accessible" );
387 
388             }
389             else
390             {
391                 // In any other case the parent is the root frm
392                 if( bInPagePreview )
393                     pParent = pContact->GetAnchorFrm()->FindPageFrm();
394                 else
395                     pParent = pContact->GetAnchorFrm()->getRootFrm();
396             }
397         }
398     }
399     else if ( mpWindow )
400     {
401         css::uno::Reference < css::accessibility::XAccessible > xAcc =
402                                                     mpWindow->GetAccessible();
403         if ( xAcc.is() )
404         {
405             css::uno::Reference < css::accessibility::XAccessibleContext > xAccContext =
406                                                 xAcc->getAccessibleContext();
407             if ( xAccContext.is() )
408             {
409                 css::uno::Reference < css::accessibility::XAccessible > xAccParent =
410                                                 xAccContext->getAccessibleParent();
411                 if ( xAccParent.is() )
412                 {
413                     SwAccessibleContext* pAccParentImpl =
414                                 dynamic_cast< SwAccessibleContext *>( xAccParent.get() );
415                     if ( pAccParentImpl )
416                     {
417                         pParent = pAccParentImpl->GetFrm();
418                     }
419                 }
420             }
421         }
422     }
423 
424     return pParent;
425 }
426 
427 } } // eof of namespace sw::access
428 
429