1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 
21 #include <window.h>
22 
23 #include "dlgctrl.hxx"
24 
25 using namespace ::com::sun::star;
26 
27 
ImplGetLabelFor(vcl::Window * pFrameWindow,WindowType nMyType,vcl::Window * pLabel,sal_Unicode nAccel)28 static vcl::Window* ImplGetLabelFor( vcl::Window* pFrameWindow, WindowType nMyType, vcl::Window* pLabel, sal_Unicode nAccel )
29 {
30     vcl::Window* pWindow = nullptr;
31 
32     if( nMyType == WindowType::FIXEDTEXT     ||
33         nMyType == WindowType::FIXEDLINE     ||
34         nMyType == WindowType::GROUPBOX )
35     {
36         // #i100833# MT 2010/02: Group box and fixed lines can also label a fixed text.
37         // See tools/options/print for example.
38         bool bThisIsAGroupControl = (nMyType == WindowType::GROUPBOX) || (nMyType == WindowType::FIXEDLINE);
39         // get index, form start and form end
40         sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0;
41         ::ImplFindDlgCtrlWindow( pFrameWindow,
42                                            pLabel,
43                                            nIndex,
44                                            nFormStart,
45                                            nFormEnd );
46         if( nAccel )
47         {
48             // find the accelerated window
49             pWindow = ::ImplFindAccelWindow( pFrameWindow,
50                                              nIndex,
51                                              nAccel,
52                                              nFormStart,
53                                              nFormEnd,
54                                              false );
55         }
56         else
57         {
58             // find the next control; if that is a fixed text
59             // fixed line or group box, then return NULL
60             while( nIndex < nFormEnd )
61             {
62                 nIndex++;
63                 vcl::Window* pSWindow = ::ImplGetChildWindow( pFrameWindow,
64                                                  nIndex,
65                                                  nIndex,
66                                                  false );
67                 if( pSWindow && isVisibleInLayout(pSWindow) && ! (pSWindow->GetStyle() & WB_NOLABEL) )
68                 {
69                     WindowType nType = pSWindow->GetType();
70                     if( nType != WindowType::FIXEDTEXT   &&
71                         nType != WindowType::FIXEDLINE   &&
72                         nType != WindowType::GROUPBOX )
73                     {
74                         pWindow = pSWindow;
75                     }
76                     else if( bThisIsAGroupControl && ( nType == WindowType::FIXEDTEXT ) )
77                     {
78                         pWindow = pSWindow;
79                     }
80                     break;
81                 }
82             }
83         }
84     }
85 
86     return pWindow;
87 }
88 
89 namespace vcl {
90 
getLegacyNonLayoutAccessibleRelationLabelFor() const91 Window* Window::getLegacyNonLayoutAccessibleRelationLabelFor() const
92 {
93     Window* pFrameWindow = ImplGetFrameWindow();
94 
95     WinBits nFrameStyle = pFrameWindow->GetStyle();
96     if( ! ( nFrameStyle & WB_DIALOGCONTROL )
97         || ( nFrameStyle & WB_NODIALOGCONTROL )
98         )
99         return nullptr;
100 
101     sal_Unicode nAccel = getAccel( GetText() );
102 
103     Window* pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel );
104     if( ! pWindow && mpWindowImpl->mpRealParent )
105         pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel );
106     return pWindow;
107 }
108 
ImplGetLabeledBy(Window * pFrameWindow,WindowType nMyType,Window * pLabeled)109 static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
110 {
111     Window* pWindow = nullptr;
112     if ( (nMyType != WindowType::GROUPBOX) && (nMyType != WindowType::FIXEDLINE) )
113     {
114         // search for a control that labels this window
115         // a label is considered the last fixed text, fixed line or group box
116         // that comes before this control; with the exception of push buttons
117         // which are labeled only if the fixed text, fixed line or group box
118         // is directly before the control
119 
120         // get form start and form end and index of this control
121         sal_uInt16 nIndex, nFormStart, nFormEnd;
122         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
123                                                     pLabeled,
124                                                     nIndex,
125                                                     nFormStart,
126                                                     nFormEnd );
127         if( pSWindow && nIndex != nFormStart )
128         {
129             if( nMyType == WindowType::PUSHBUTTON        ||
130                 nMyType == WindowType::HELPBUTTON        ||
131                 nMyType == WindowType::OKBUTTON      ||
132                 nMyType == WindowType::CANCELBUTTON )
133             {
134                 nFormStart = nIndex-1;
135             }
136             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
137             {
138                 sal_uInt16 nFoundIndex = 0;
139                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
140                                                  nSearchIndex,
141                                                  nFoundIndex,
142                                                  false );
143                 if( pSWindow && isVisibleInLayout(pSWindow) && !(pSWindow->GetStyle() & WB_NOLABEL) )
144                 {
145                     WindowType nType = pSWindow->GetType();
146                     if ( nType == WindowType::FIXEDTEXT ||
147                          nType == WindowType::FIXEDLINE ||
148                          nType == WindowType::GROUPBOX )
149                     {
150                         // a fixed text can't be labelled by a fixed text.
151                         if ( ( nMyType != WindowType::FIXEDTEXT ) || ( nType != WindowType::FIXEDTEXT ) )
152                             pWindow = pSWindow;
153                         break;
154                     }
155                 }
156                 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
157                     break;
158             }
159         }
160     }
161     return pWindow;
162 }
163 
getLegacyNonLayoutAccessibleRelationLabeledBy() const164 Window* Window::getLegacyNonLayoutAccessibleRelationLabeledBy() const
165 {
166     Window* pFrameWindow = ImplGetFrameWindow();
167 
168     // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels
169     if( GetType() == WindowType::CHECKBOX || GetType() == WindowType::RADIOBUTTON )
170         return nullptr;
171 
172 //    if( ! ( GetType() == WindowType::FIXEDTEXT     ||
173 //            GetType() == WindowType::FIXEDLINE     ||
174 //            GetType() == WindowType::GROUPBOX ) )
175     // #i100833# MT 2010/02: Group box and fixed lines can also label a fixed text.
176     // See tools/options/print for example.
177 
178     Window* pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) );
179     if( ! pWindow && mpWindowImpl->mpRealParent )
180         pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) );
181 
182     return pWindow;
183 }
184 
getLegacyNonLayoutAccessibleRelationMemberOf() const185 Window* Window::getLegacyNonLayoutAccessibleRelationMemberOf() const
186 {
187     Window* pWindow = nullptr;
188     Window* pFrameWindow = GetParent();
189     if ( !pFrameWindow )
190     {
191         pFrameWindow = ImplGetFrameWindow();
192     }
193     // if( ! ( GetType() == WindowType::FIXEDTEXT        ||
194     if( !( GetType() == WindowType::FIXEDLINE ||
195         GetType() == WindowType::GROUPBOX ) )
196     {
197         // search for a control that makes member of this window
198         // it is considered the last fixed line or group box
199         // that comes before this control; with the exception of push buttons
200         // which are labeled only if the fixed line or group box
201         // is directly before the control
202         // get form start and form end and index of this control
203         sal_uInt16 nIndex, nFormStart, nFormEnd;
204         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
205             const_cast<Window*>(this),
206             nIndex,
207             nFormStart,
208             nFormEnd );
209         if( pSWindow && nIndex != nFormStart )
210         {
211             if( GetType() == WindowType::PUSHBUTTON      ||
212                 GetType() == WindowType::HELPBUTTON      ||
213                 GetType() == WindowType::OKBUTTON        ||
214                 GetType() == WindowType::CANCELBUTTON )
215             {
216                 nFormStart = nIndex-1;
217             }
218             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
219             {
220                 sal_uInt16 nFoundIndex = 0;
221                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
222                     nSearchIndex,
223                     nFoundIndex,
224                     false );
225                 if( pSWindow && pSWindow->IsVisible() &&
226                     ( pSWindow->GetType() == WindowType::FIXEDLINE   ||
227                     pSWindow->GetType() == WindowType::GROUPBOX ) )
228                 {
229                     pWindow = pSWindow;
230                     break;
231                 }
232                 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
233                     break;
234             }
235         }
236     }
237     return pWindow;
238 }
239 
240 } /* namespace vcl */
241 
242 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
243