xref: /trunk/main/vcl/source/window/dlgctrl.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
19f62ea84SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
39f62ea84SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
49f62ea84SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
59f62ea84SAndrew Rist  * distributed with this work for additional information
69f62ea84SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
79f62ea84SAndrew Rist  * to you under the Apache License, Version 2.0 (the
89f62ea84SAndrew Rist  * "License"); you may not use this file except in compliance
99f62ea84SAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
119f62ea84SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
139f62ea84SAndrew Rist  * Unless required by applicable law or agreed to in writing,
149f62ea84SAndrew Rist  * software distributed under the License is distributed on an
159f62ea84SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
169f62ea84SAndrew Rist  * KIND, either express or implied.  See the License for the
179f62ea84SAndrew Rist  * specific language governing permissions and limitations
189f62ea84SAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
209f62ea84SAndrew Rist  *************************************************************/
219f62ea84SAndrew Rist 
229f62ea84SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_vcl.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir #include <tools/debug.hxx>
28cdf0e10cSrcweir 
29cdf0e10cSrcweir #include <svdata.hxx>
30cdf0e10cSrcweir #include <window.h>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <vcl/event.hxx>
33cdf0e10cSrcweir #include <vcl/svapp.hxx>
34cdf0e10cSrcweir #include <vcl/tabpage.hxx>
35cdf0e10cSrcweir #include <vcl/tabctrl.hxx>
36cdf0e10cSrcweir #include <vcl/tabdlg.hxx>
37cdf0e10cSrcweir #include <vcl/button.hxx>
38cdf0e10cSrcweir 
39cdf0e10cSrcweir #include <vcl/unohelp.hxx>
40cdf0e10cSrcweir #include <com/sun/star/i18n/XCharacterClassification.hpp>
41cdf0e10cSrcweir 
42cdf0e10cSrcweir using namespace ::com::sun::star;
43cdf0e10cSrcweir 
44cdf0e10cSrcweir // =======================================================================
45cdf0e10cSrcweir 
ImplHasIndirectTabParent(Window * pWindow)46cdf0e10cSrcweir static sal_Bool ImplHasIndirectTabParent( Window* pWindow )
47cdf0e10cSrcweir {
48cdf0e10cSrcweir     // The window has inderect tab parent if it is included in tab hierarchy
49cdf0e10cSrcweir     // of the indirect parent window
50cdf0e10cSrcweir 
51cdf0e10cSrcweir     return ( pWindow && pWindow->GetParent()
52cdf0e10cSrcweir           && ( pWindow->GetParent()->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) );
53cdf0e10cSrcweir }
54cdf0e10cSrcweir 
55cdf0e10cSrcweir // -----------------------------------------------------------------------
56cdf0e10cSrcweir 
ImplGetTopParentOfTabHierarchy(Window * pParent)57cdf0e10cSrcweir static Window* ImplGetTopParentOfTabHierarchy( Window* pParent )
58cdf0e10cSrcweir {
59cdf0e10cSrcweir     // The method allows to find the most close parent containing all the
60cdf0e10cSrcweir     // window from the current tab-hierarchy
61cdf0e10cSrcweir     // The direct parent should be provided as a parameter here
62cdf0e10cSrcweir 
63cdf0e10cSrcweir     Window* pResult = pParent;
64cdf0e10cSrcweir 
65cdf0e10cSrcweir     if ( pResult )
66cdf0e10cSrcweir     {
67cdf0e10cSrcweir         while ( pResult->GetParent() && ( pResult->ImplGetWindow()->GetStyle() & WB_CHILDDLGCTRL ) )
68cdf0e10cSrcweir             pResult = pResult->GetParent();
69cdf0e10cSrcweir     }
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     return pResult;
72cdf0e10cSrcweir }
73cdf0e10cSrcweir 
74cdf0e10cSrcweir // -----------------------------------------------------------------------
75cdf0e10cSrcweir 
ImplGetSubChildWindow(Window * pParent,sal_uInt16 n,sal_uInt16 & nIndex)76cdf0e10cSrcweir static Window* ImplGetSubChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex )
77cdf0e10cSrcweir {
78cdf0e10cSrcweir     Window*     pTabPage = NULL;
79cdf0e10cSrcweir     Window*     pFoundWindow = NULL;
80cdf0e10cSrcweir 
81cdf0e10cSrcweir     Window*     pWindow = pParent->GetWindow( WINDOW_FIRSTCHILD );
82cdf0e10cSrcweir     Window*     pNextWindow = pWindow;
83cdf0e10cSrcweir     while ( pWindow )
84cdf0e10cSrcweir     {
85cdf0e10cSrcweir         pWindow = pWindow->ImplGetWindow();
86cdf0e10cSrcweir 
87cdf0e10cSrcweir         // Unsichtbare und disablte Fenster werden uebersprungen
88cdf0e10cSrcweir         if ( pTabPage || pWindow->IsVisible() )
89cdf0e10cSrcweir         {
90cdf0e10cSrcweir             // Wenn das letzte Control ein TabControl war, wird von
91cdf0e10cSrcweir             // diesem die TabPage genommen
92cdf0e10cSrcweir             if ( pTabPage )
93cdf0e10cSrcweir             {
94cdf0e10cSrcweir                 pFoundWindow = ImplGetSubChildWindow( pTabPage, n, nIndex );
95cdf0e10cSrcweir                 pTabPage = NULL;
96cdf0e10cSrcweir             }
97cdf0e10cSrcweir             else
98cdf0e10cSrcweir             {
99cdf0e10cSrcweir                 pFoundWindow = pWindow;
100cdf0e10cSrcweir 
101cdf0e10cSrcweir                 // Bei einem TabControl sich die aktuelle TabPage merken,
102cdf0e10cSrcweir                 // damit diese dann genommen wird
103cdf0e10cSrcweir                 if ( pWindow->GetType() == WINDOW_TABCONTROL )
104cdf0e10cSrcweir                 {
105cdf0e10cSrcweir                     TabControl* pTabControl = ((TabControl*)pWindow);
106cdf0e10cSrcweir                     // Feststellen, ob TabPage Child vom TabControl ist
107cdf0e10cSrcweir                     // und auch noch existiert (deshalb durch Vergleich,
108cdf0e10cSrcweir                     // indem alle ChildFenster getestet werden). Denn es
109cdf0e10cSrcweir                     // kann sein, das TabPages schon in einem Dialog-Dtor
110cdf0e10cSrcweir                     // zerstoert wurden, obwohl das TabControl noch
111cdf0e10cSrcweir                     // existiert.
112cdf0e10cSrcweir                     TabPage* pTempTabPage = pTabControl->GetTabPage( pTabControl->GetCurPageId() );
113cdf0e10cSrcweir                     if ( pTempTabPage )
114cdf0e10cSrcweir                     {
115cdf0e10cSrcweir                         Window* pTempWindow = pTabControl->GetWindow( WINDOW_FIRSTCHILD );
116cdf0e10cSrcweir                         while ( pTempWindow )
117cdf0e10cSrcweir                         {
118cdf0e10cSrcweir                             if ( pTempWindow->ImplGetWindow() == pTempTabPage )
119cdf0e10cSrcweir                             {
120cdf0e10cSrcweir                                 pTabPage = pTempTabPage;
121cdf0e10cSrcweir                                 break;
122cdf0e10cSrcweir                             }
123cdf0e10cSrcweir                             pTempWindow = pTempWindow->GetWindow( WINDOW_NEXT );
124cdf0e10cSrcweir                         }
125cdf0e10cSrcweir                     }
126cdf0e10cSrcweir                 }
127cdf0e10cSrcweir                 else if ( ( pWindow->GetStyle() & WB_DIALOGCONTROL )
128cdf0e10cSrcweir                        || ( pWindow->GetStyle() & WB_CHILDDLGCTRL ) )
129cdf0e10cSrcweir                     pFoundWindow = ImplGetSubChildWindow( pWindow, n, nIndex );
130cdf0e10cSrcweir             }
131cdf0e10cSrcweir 
132cdf0e10cSrcweir             if ( n == nIndex )
133cdf0e10cSrcweir                 return pFoundWindow;
134cdf0e10cSrcweir             nIndex++;
135cdf0e10cSrcweir         }
136cdf0e10cSrcweir 
137cdf0e10cSrcweir         if ( pTabPage )
138cdf0e10cSrcweir             pWindow = pTabPage;
139cdf0e10cSrcweir         else
140cdf0e10cSrcweir         {
141cdf0e10cSrcweir             pWindow = pNextWindow->GetWindow( WINDOW_NEXT );
142cdf0e10cSrcweir             pNextWindow = pWindow;
143cdf0e10cSrcweir         }
144cdf0e10cSrcweir     }
145cdf0e10cSrcweir 
146cdf0e10cSrcweir     nIndex--;
147cdf0e10cSrcweir     return pFoundWindow;
148cdf0e10cSrcweir }
149cdf0e10cSrcweir 
150cdf0e10cSrcweir // -----------------------------------------------------------------------
151cdf0e10cSrcweir 
ImplGetChildWindow(Window * pParent,sal_uInt16 n,sal_uInt16 & nIndex,sal_Bool bTestEnable)152cdf0e10cSrcweir static Window* ImplGetChildWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
153cdf0e10cSrcweir {
154cdf0e10cSrcweir     pParent = ImplGetTopParentOfTabHierarchy( pParent );
155cdf0e10cSrcweir 
156cdf0e10cSrcweir     nIndex = 0;
157cdf0e10cSrcweir     Window* pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
158cdf0e10cSrcweir     if ( bTestEnable )
159cdf0e10cSrcweir     {
160cdf0e10cSrcweir         sal_uInt16 n2 = nIndex;
161cdf0e10cSrcweir         while ( pWindow && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) )
162cdf0e10cSrcweir         {
163cdf0e10cSrcweir             n2 = nIndex+1;
164cdf0e10cSrcweir             nIndex = 0;
165cdf0e10cSrcweir             pWindow = ImplGetSubChildWindow( pParent, n2, nIndex );
166cdf0e10cSrcweir             if ( nIndex < n2 )
167cdf0e10cSrcweir                 break;
168cdf0e10cSrcweir         }
169cdf0e10cSrcweir 
170cdf0e10cSrcweir         if ( (nIndex < n2) && n )
171cdf0e10cSrcweir         {
172cdf0e10cSrcweir             do
173cdf0e10cSrcweir             {
174cdf0e10cSrcweir                 n--;
175cdf0e10cSrcweir                 nIndex = 0;
176cdf0e10cSrcweir                 pWindow = ImplGetSubChildWindow( pParent, n, nIndex );
177cdf0e10cSrcweir             }
178cdf0e10cSrcweir             while ( pWindow && n && (!pWindow->IsEnabled() || !pWindow->IsInputEnabled()) );
179cdf0e10cSrcweir         }
180cdf0e10cSrcweir     }
181cdf0e10cSrcweir     return pWindow;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir 
184cdf0e10cSrcweir // -----------------------------------------------------------------------
185cdf0e10cSrcweir 
ImplGetNextWindow(Window * pParent,sal_uInt16 n,sal_uInt16 & nIndex,sal_Bool bTestEnable)186cdf0e10cSrcweir static Window* ImplGetNextWindow( Window* pParent, sal_uInt16 n, sal_uInt16& nIndex, sal_Bool bTestEnable )
187cdf0e10cSrcweir {
188cdf0e10cSrcweir     Window* pWindow = ImplGetChildWindow( pParent, n+1, nIndex, bTestEnable );
189cdf0e10cSrcweir     if ( n == nIndex )
190cdf0e10cSrcweir     {
191cdf0e10cSrcweir         n = 0;
192cdf0e10cSrcweir         pWindow = ImplGetChildWindow( pParent, n, nIndex, bTestEnable );
193cdf0e10cSrcweir     }
194cdf0e10cSrcweir     return pWindow;
195cdf0e10cSrcweir }
196cdf0e10cSrcweir 
197cdf0e10cSrcweir // -----------------------------------------------------------------------
198cdf0e10cSrcweir 
ImplGetDlgWindow(sal_uInt16 nIndex,sal_uInt16 nType,sal_uInt16 nFormStart,sal_uInt16 nFormEnd,sal_uInt16 * pIndex)199cdf0e10cSrcweir Window* Window::ImplGetDlgWindow( sal_uInt16 nIndex, sal_uInt16 nType,
200cdf0e10cSrcweir                                   sal_uInt16 nFormStart, sal_uInt16 nFormEnd,
201cdf0e10cSrcweir                                   sal_uInt16* pIndex )
202cdf0e10cSrcweir {
203cdf0e10cSrcweir     DBG_ASSERT( (nIndex >= nFormStart) && (nIndex <= nFormEnd),
204cdf0e10cSrcweir                 "Window::ImplGetDlgWindow() - nIndex not in Form" );
205cdf0e10cSrcweir 
206cdf0e10cSrcweir     Window* pWindow = NULL;
207cdf0e10cSrcweir     sal_uInt16  i;
208cdf0e10cSrcweir     sal_uInt16  nTemp;
209cdf0e10cSrcweir     sal_uInt16  nStartIndex;
210cdf0e10cSrcweir 
211cdf0e10cSrcweir     if ( nType == DLGWINDOW_PREV )
212cdf0e10cSrcweir     {
213cdf0e10cSrcweir         i = nIndex;
214cdf0e10cSrcweir         do
215cdf0e10cSrcweir         {
216cdf0e10cSrcweir             if ( i > nFormStart )
217cdf0e10cSrcweir                 i--;
218cdf0e10cSrcweir             else
219cdf0e10cSrcweir                 i = nFormEnd;
220cdf0e10cSrcweir             pWindow = ImplGetChildWindow( this, i, nTemp, sal_True );
221cdf0e10cSrcweir             if ( !pWindow )
222cdf0e10cSrcweir                 break;
223cdf0e10cSrcweir             if ( (i == nTemp) && (pWindow->GetStyle() & WB_TABSTOP) )
224cdf0e10cSrcweir                 break;
225cdf0e10cSrcweir         }
226cdf0e10cSrcweir         while ( i != nIndex );
227cdf0e10cSrcweir     }
228cdf0e10cSrcweir     else
229cdf0e10cSrcweir     {
230cdf0e10cSrcweir         i = nIndex;
231cdf0e10cSrcweir         pWindow = ImplGetChildWindow( this, i, i, (nType == DLGWINDOW_FIRST) );
232cdf0e10cSrcweir         if ( pWindow )
233cdf0e10cSrcweir         {
234cdf0e10cSrcweir             nStartIndex = i;
235cdf0e10cSrcweir 
236cdf0e10cSrcweir             if ( nType == DLGWINDOW_NEXT )
237cdf0e10cSrcweir             {
238cdf0e10cSrcweir                 if ( i < nFormEnd )
239cdf0e10cSrcweir                 {
240cdf0e10cSrcweir                     pWindow = ImplGetNextWindow( this, i, i, sal_True );
241cdf0e10cSrcweir                     if ( (i > nFormEnd) || (i < nFormStart) )
242cdf0e10cSrcweir                         pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
243cdf0e10cSrcweir                 }
244cdf0e10cSrcweir                 else
245cdf0e10cSrcweir                     pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
246cdf0e10cSrcweir             }
247cdf0e10cSrcweir 
248cdf0e10cSrcweir             if ( i <= nFormEnd )
249cdf0e10cSrcweir             {
250cdf0e10cSrcweir                 // 2ten Index mitfuehren, falls alle Controls disablte
251cdf0e10cSrcweir                 sal_uInt16 nStartIndex2 = i;
252cdf0e10cSrcweir                 sal_uInt16 nOldIndex = i+1;
253cdf0e10cSrcweir 
254cdf0e10cSrcweir                 do
255cdf0e10cSrcweir                 {
256cdf0e10cSrcweir                     if ( pWindow->GetStyle() & WB_TABSTOP )
257cdf0e10cSrcweir                         break;
258cdf0e10cSrcweir                     if( i == nOldIndex ) // only disabled controls ?
259cdf0e10cSrcweir                     {
260cdf0e10cSrcweir                         i = nStartIndex2;
261cdf0e10cSrcweir                         break;
262cdf0e10cSrcweir                     }
263cdf0e10cSrcweir                     nOldIndex = i;
264cdf0e10cSrcweir                     if ( (i > nFormEnd) || (i < nFormStart) )
265cdf0e10cSrcweir                         pWindow = ImplGetChildWindow( this, nFormStart, i, sal_True );
266cdf0e10cSrcweir                     else
267cdf0e10cSrcweir                         pWindow = ImplGetNextWindow( this, i, i, sal_True );
268cdf0e10cSrcweir                 }
269cdf0e10cSrcweir                 while ( (i != nStartIndex) && (i != nStartIndex2) );
270cdf0e10cSrcweir 
271cdf0e10cSrcweir                 if ( (i == nStartIndex2) &&
272cdf0e10cSrcweir                      (!(pWindow->GetStyle() & WB_TABSTOP) || !pWindow->IsEnabled()) )
273cdf0e10cSrcweir                     i = nStartIndex;
274cdf0e10cSrcweir             }
275cdf0e10cSrcweir         }
276cdf0e10cSrcweir 
277cdf0e10cSrcweir         if ( nType == DLGWINDOW_FIRST )
278cdf0e10cSrcweir         {
279cdf0e10cSrcweir             if ( pWindow )
280cdf0e10cSrcweir             {
281cdf0e10cSrcweir                 if ( pWindow->GetType() == WINDOW_TABCONTROL )
282cdf0e10cSrcweir                 {
283cdf0e10cSrcweir                     Window* pNextWindow = ImplGetDlgWindow( i, DLGWINDOW_NEXT );
284cdf0e10cSrcweir                     if ( pNextWindow )
285cdf0e10cSrcweir                     {
286cdf0e10cSrcweir                         if ( pWindow->IsChild( pNextWindow ) )
287cdf0e10cSrcweir                             pWindow = pNextWindow;
288cdf0e10cSrcweir                     }
289cdf0e10cSrcweir                 }
290cdf0e10cSrcweir 
291cdf0e10cSrcweir                 if ( !(pWindow->GetStyle() & WB_TABSTOP) )
292cdf0e10cSrcweir                     pWindow = NULL;
293cdf0e10cSrcweir             }
294cdf0e10cSrcweir         }
295cdf0e10cSrcweir     }
296cdf0e10cSrcweir 
297cdf0e10cSrcweir     if ( pIndex )
298cdf0e10cSrcweir         *pIndex = i;
299cdf0e10cSrcweir 
300cdf0e10cSrcweir     return pWindow;
301cdf0e10cSrcweir }
302cdf0e10cSrcweir 
303cdf0e10cSrcweir // -----------------------------------------------------------------------
304cdf0e10cSrcweir 
ImplFindDlgCtrlWindow(Window * pParent,Window * pWindow,sal_uInt16 & rIndex,sal_uInt16 & rFormStart,sal_uInt16 & rFormEnd)305cdf0e10cSrcweir static Window* ImplFindDlgCtrlWindow( Window* pParent, Window* pWindow, sal_uInt16& rIndex,
306cdf0e10cSrcweir                                       sal_uInt16& rFormStart, sal_uInt16& rFormEnd )
307cdf0e10cSrcweir {
308cdf0e10cSrcweir     Window* pSWindow;
309cdf0e10cSrcweir     Window* pSecondWindow = NULL;
310cdf0e10cSrcweir     Window* pTempWindow = NULL;
311cdf0e10cSrcweir     sal_uInt16  i;
312cdf0e10cSrcweir     sal_uInt16  nSecond_i = 0;
313cdf0e10cSrcweir     sal_uInt16  nFormStart = 0;
314cdf0e10cSrcweir     sal_uInt16  nSecondFormStart = 0;
315cdf0e10cSrcweir     sal_uInt16  nFormEnd;
316cdf0e10cSrcweir 
317cdf0e10cSrcweir     // Focus-Fenster in der Child-Liste suchen
318cdf0e10cSrcweir     Window* pFirstChildWindow = pSWindow = ImplGetChildWindow( pParent, 0, i, sal_False );
319cdf0e10cSrcweir 
320cdf0e10cSrcweir     if( pWindow == NULL )
321cdf0e10cSrcweir         pWindow = pSWindow;
322cdf0e10cSrcweir 
323cdf0e10cSrcweir     while ( pSWindow )
324cdf0e10cSrcweir     {
325cdf0e10cSrcweir         // the DialogControlStart mark is only accepted for the direct children
326cdf0e10cSrcweir         if ( !ImplHasIndirectTabParent( pSWindow )
327cdf0e10cSrcweir           && pSWindow->ImplGetWindow()->IsDialogControlStart() )
328cdf0e10cSrcweir             nFormStart = i;
329cdf0e10cSrcweir 
330cdf0e10cSrcweir         // SecondWindow wegen zusammengesetzten Controls wie
331cdf0e10cSrcweir         // ComboBoxen und Feldern
332cdf0e10cSrcweir         if ( pSWindow->ImplIsWindowOrChild( pWindow ) )
333cdf0e10cSrcweir         {
334cdf0e10cSrcweir             pSecondWindow = pSWindow;
335cdf0e10cSrcweir             nSecond_i = i;
336cdf0e10cSrcweir             nSecondFormStart = nFormStart;
337cdf0e10cSrcweir             if ( pSWindow == pWindow )
338cdf0e10cSrcweir                 break;
339cdf0e10cSrcweir         }
340cdf0e10cSrcweir 
341cdf0e10cSrcweir         pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
342cdf0e10cSrcweir         if ( !i )
343cdf0e10cSrcweir             pSWindow = NULL;
344cdf0e10cSrcweir     }
345cdf0e10cSrcweir 
346cdf0e10cSrcweir     if ( !pSWindow )
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         // Fenster nicht gefunden, dann koennen wir auch keine
349cdf0e10cSrcweir         // Steuerung uebernehmen
350cdf0e10cSrcweir         if ( !pSecondWindow )
351cdf0e10cSrcweir             return NULL;
352cdf0e10cSrcweir         else
353cdf0e10cSrcweir         {
354cdf0e10cSrcweir             pSWindow = pSecondWindow;
355cdf0e10cSrcweir             i = nSecond_i;
356cdf0e10cSrcweir             nFormStart = nSecondFormStart;
357cdf0e10cSrcweir         }
358cdf0e10cSrcweir     }
359cdf0e10cSrcweir 
360cdf0e10cSrcweir     // Start-Daten setzen
361cdf0e10cSrcweir     rIndex = i;
362cdf0e10cSrcweir     rFormStart = nFormStart;
363cdf0e10cSrcweir 
364cdf0e10cSrcweir     // Formularende suchen
365cdf0e10cSrcweir     nFormEnd = nFormStart;
366cdf0e10cSrcweir     pTempWindow = pSWindow;
367cdf0e10cSrcweir     sal_Int32 nIteration = 0;
368cdf0e10cSrcweir     do
369cdf0e10cSrcweir     {
370cdf0e10cSrcweir         nFormEnd = i;
371cdf0e10cSrcweir         pTempWindow = ImplGetNextWindow( pParent, i, i, sal_False );
372cdf0e10cSrcweir 
373cdf0e10cSrcweir         // the DialogControlStart mark is only accepted for the direct children
374cdf0e10cSrcweir         if ( !i
375cdf0e10cSrcweir           || ( pTempWindow && !ImplHasIndirectTabParent( pTempWindow )
376cdf0e10cSrcweir                && pTempWindow->ImplGetWindow()->IsDialogControlStart() ) )
377cdf0e10cSrcweir             break;
378cdf0e10cSrcweir 
379cdf0e10cSrcweir         if ( pTempWindow && pTempWindow == pFirstChildWindow )
380cdf0e10cSrcweir         {
381cdf0e10cSrcweir             // It is possible to go through the begin of hierarchy once
382cdf0e10cSrcweir             // while looking for DialogControlStart mark.
383cdf0e10cSrcweir             // If it happens second time, it looks like an endless loop,
384cdf0e10cSrcweir             // that should be impossible, but just for the case...
385cdf0e10cSrcweir             nIteration++;
386cdf0e10cSrcweir             if ( nIteration >= 2 )
387cdf0e10cSrcweir             {
388cdf0e10cSrcweir                 // this is an unexpected scenario
389cdf0e10cSrcweir                 DBG_ASSERT( sal_False, "It seems to be an endless loop!" );
390cdf0e10cSrcweir                 rFormStart = 0;
391cdf0e10cSrcweir                 break;
392cdf0e10cSrcweir             }
393cdf0e10cSrcweir         }
394cdf0e10cSrcweir     }
395cdf0e10cSrcweir     while ( pTempWindow );
396cdf0e10cSrcweir     rFormEnd = nFormEnd;
397cdf0e10cSrcweir 
398cdf0e10cSrcweir     return pSWindow;
399cdf0e10cSrcweir }
400cdf0e10cSrcweir 
401cdf0e10cSrcweir // -----------------------------------------------------------------------
402cdf0e10cSrcweir 
ImplFindAccelWindow(Window * pParent,sal_uInt16 & rIndex,xub_Unicode cCharCode,sal_uInt16 nFormStart,sal_uInt16 nFormEnd,sal_Bool bCheckEnable=sal_True)403cdf0e10cSrcweir static Window* ImplFindAccelWindow( Window* pParent, sal_uInt16& rIndex, xub_Unicode cCharCode,
404cdf0e10cSrcweir                                     sal_uInt16 nFormStart, sal_uInt16 nFormEnd, sal_Bool bCheckEnable = sal_True )
405cdf0e10cSrcweir {
406cdf0e10cSrcweir     DBG_ASSERT( (rIndex >= nFormStart) && (rIndex <= nFormEnd),
407cdf0e10cSrcweir                 "Window::ImplFindAccelWindow() - rIndex not in Form" );
408cdf0e10cSrcweir 
409cdf0e10cSrcweir     xub_Unicode cCompareChar;
410cdf0e10cSrcweir     sal_uInt16  nStart = rIndex;
411cdf0e10cSrcweir     sal_uInt16  i = rIndex;
412cdf0e10cSrcweir     int     bSearch = sal_True;
413cdf0e10cSrcweir     Window* pWindow;
414cdf0e10cSrcweir 
415cdf0e10cSrcweir     // MT: Where can we keep the CharClass?!
416cdf0e10cSrcweir     static uno::Reference< i18n::XCharacterClassification > xCharClass;
417cdf0e10cSrcweir     if ( !xCharClass.is() )
418cdf0e10cSrcweir         xCharClass = vcl::unohelper::CreateCharacterClassification();
419cdf0e10cSrcweir 
420cdf0e10cSrcweir     const ::com::sun::star::lang::Locale& rLocale = Application::GetSettings().GetUILocale();
421cdf0e10cSrcweir     cCharCode = xCharClass->toUpper( String(cCharCode), 0, 1, rLocale )[0];
422cdf0e10cSrcweir 
423cdf0e10cSrcweir     if ( i < nFormEnd )
424cdf0e10cSrcweir         pWindow = ImplGetNextWindow( pParent, i, i, sal_True );
425cdf0e10cSrcweir     else
426cdf0e10cSrcweir         pWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_True );
427cdf0e10cSrcweir     while( bSearch && pWindow )
428cdf0e10cSrcweir     {
429cdf0e10cSrcweir         const XubString aStr = pWindow->GetText();
430cdf0e10cSrcweir         sal_uInt16 nPos = aStr.Search( '~' );
431cdf0e10cSrcweir         while ( nPos != STRING_NOTFOUND )
432cdf0e10cSrcweir         {
433cdf0e10cSrcweir             cCompareChar = aStr.GetChar( nPos+1 );
434cdf0e10cSrcweir             cCompareChar = xCharClass->toUpper( String(cCompareChar), 0, 1, rLocale )[0];
435cdf0e10cSrcweir             if ( cCompareChar == cCharCode )
436cdf0e10cSrcweir             {
437cdf0e10cSrcweir                 // Bei Static-Controls auf das naechste Controlm weiterschalten
438cdf0e10cSrcweir                 if ( (pWindow->GetType() == WINDOW_FIXEDTEXT)   ||
439cdf0e10cSrcweir                      (pWindow->GetType() == WINDOW_FIXEDLINE)   ||
440cdf0e10cSrcweir                      (pWindow->GetType() == WINDOW_GROUPBOX) )
441cdf0e10cSrcweir                     pWindow = pParent->ImplGetDlgWindow( i, DLGWINDOW_NEXT );
442cdf0e10cSrcweir                 rIndex = i;
443cdf0e10cSrcweir                 return pWindow;
444cdf0e10cSrcweir             }
445cdf0e10cSrcweir             nPos = aStr.Search( '~', nPos+1 );
446cdf0e10cSrcweir         }
447cdf0e10cSrcweir 
448cdf0e10cSrcweir         // #i93011# it would have made sense to have this really recursive
449cdf0e10cSrcweir         // right from the start. However this would cause unpredictable side effects now
450cdf0e10cSrcweir         // so instead we have a style bit for some child windows, that want their
451cdf0e10cSrcweir         // children checked for accelerators
452cdf0e10cSrcweir         if( (pWindow->GetStyle() & WB_CHILDDLGCTRL) != 0 )
453cdf0e10cSrcweir         {
454cdf0e10cSrcweir             sal_uInt16  nChildIndex;
455cdf0e10cSrcweir             sal_uInt16  nChildFormStart;
456cdf0e10cSrcweir             sal_uInt16  nChildFormEnd;
457cdf0e10cSrcweir 
458cdf0e10cSrcweir             // get form start and end
459cdf0e10cSrcweir             ::ImplFindDlgCtrlWindow( pWindow, NULL,
460cdf0e10cSrcweir                                      nChildIndex, nChildFormStart, nChildFormEnd );
461cdf0e10cSrcweir             Window* pAccelWin = ImplFindAccelWindow( pWindow, nChildIndex, cCharCode,
462cdf0e10cSrcweir                                                      nChildFormStart, nChildFormEnd,
463cdf0e10cSrcweir                                                      bCheckEnable );
464cdf0e10cSrcweir             if( pAccelWin )
465cdf0e10cSrcweir                 return pAccelWin;
466cdf0e10cSrcweir         }
467cdf0e10cSrcweir 
468cdf0e10cSrcweir         if ( i == nStart )
469cdf0e10cSrcweir             break;
470cdf0e10cSrcweir 
471cdf0e10cSrcweir         if ( i < nFormEnd )
472cdf0e10cSrcweir         {
473cdf0e10cSrcweir             pWindow = ImplGetNextWindow( pParent, i, i, bCheckEnable );
474cdf0e10cSrcweir             if( ! pWindow )
475cdf0e10cSrcweir                 pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
476cdf0e10cSrcweir         }
477cdf0e10cSrcweir         else
478cdf0e10cSrcweir             pWindow = ImplGetChildWindow( pParent, nFormStart, i, bCheckEnable );
479cdf0e10cSrcweir     }
480cdf0e10cSrcweir 
481cdf0e10cSrcweir     return NULL;
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
484cdf0e10cSrcweir // -----------------------------------------------------------------------
485cdf0e10cSrcweir 
ImplControlFocus(sal_uInt16 nFlags)486cdf0e10cSrcweir void Window::ImplControlFocus( sal_uInt16 nFlags )
487cdf0e10cSrcweir {
488cdf0e10cSrcweir     if ( nFlags & GETFOCUS_MNEMONIC )
489cdf0e10cSrcweir     {
490cdf0e10cSrcweir         if ( GetType() == WINDOW_RADIOBUTTON )
491cdf0e10cSrcweir         {
492cdf0e10cSrcweir             if ( !((RadioButton*)this)->IsChecked() )
493cdf0e10cSrcweir                 ((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
494cdf0e10cSrcweir             else
495cdf0e10cSrcweir                 ImplGrabFocus( nFlags );
496cdf0e10cSrcweir         }
497cdf0e10cSrcweir         else
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             ImplGrabFocus( nFlags );
500cdf0e10cSrcweir             if ( nFlags & GETFOCUS_UNIQUEMNEMONIC )
501cdf0e10cSrcweir             {
502cdf0e10cSrcweir                 if ( GetType() == WINDOW_CHECKBOX )
503cdf0e10cSrcweir                     ((CheckBox*)this)->ImplCheck();
504cdf0e10cSrcweir                 else if ( mpWindowImpl->mbPushButton )
505cdf0e10cSrcweir                 {
506cdf0e10cSrcweir                     ((PushButton*)this)->SetPressed( sal_True );
507cdf0e10cSrcweir                     ((PushButton*)this)->SetPressed( sal_False );
508cdf0e10cSrcweir                     ((PushButton*)this)->Click();
509cdf0e10cSrcweir                 }
510cdf0e10cSrcweir             }
511cdf0e10cSrcweir         }
512cdf0e10cSrcweir     }
513cdf0e10cSrcweir     else
514cdf0e10cSrcweir     {
515cdf0e10cSrcweir         if ( GetType() == WINDOW_RADIOBUTTON )
516cdf0e10cSrcweir         {
517cdf0e10cSrcweir             if ( !((RadioButton*)this)->IsChecked() )
518cdf0e10cSrcweir                 ((RadioButton*)this)->ImplCallClick( sal_True, nFlags );
519cdf0e10cSrcweir             else
520cdf0e10cSrcweir                 ImplGrabFocus( nFlags );
521cdf0e10cSrcweir         }
522cdf0e10cSrcweir         else
523cdf0e10cSrcweir             ImplGrabFocus( nFlags );
524cdf0e10cSrcweir     }
525cdf0e10cSrcweir }
526cdf0e10cSrcweir 
527cdf0e10cSrcweir // -----------------------------------------------------------------------
528cdf0e10cSrcweir 
ImplDlgCtrl(const KeyEvent & rKEvt,sal_Bool bKeyInput)529cdf0e10cSrcweir sal_Bool Window::ImplDlgCtrl( const KeyEvent& rKEvt, sal_Bool bKeyInput )
530cdf0e10cSrcweir {
531cdf0e10cSrcweir     KeyCode aKeyCode = rKEvt.GetKeyCode();
532cdf0e10cSrcweir     sal_uInt16  nKeyCode = aKeyCode.GetCode();
533cdf0e10cSrcweir     Window* pSWindow;
534cdf0e10cSrcweir     Window* pTempWindow;
535cdf0e10cSrcweir     Window* pButtonWindow;
536cdf0e10cSrcweir     sal_uInt16  i;
537cdf0e10cSrcweir     sal_uInt16  iButton;
538cdf0e10cSrcweir     sal_uInt16  iButtonStart;
539cdf0e10cSrcweir     sal_uInt16  iTemp;
540cdf0e10cSrcweir     sal_uInt16  nIndex;
541cdf0e10cSrcweir     sal_uInt16  nFormStart;
542cdf0e10cSrcweir     sal_uInt16  nFormEnd;
543cdf0e10cSrcweir     sal_uInt16  nDlgCtrlFlags;
544cdf0e10cSrcweir 
545cdf0e10cSrcweir     // Ohne Focus-Window koennen wir auch keine Steuerung uebernehmen
546cdf0e10cSrcweir     Window* pFocusWindow = Application::GetFocusWindow();
547cdf0e10cSrcweir     if ( !pFocusWindow || !ImplIsWindowOrChild( pFocusWindow ) )
548cdf0e10cSrcweir         return sal_False;
549cdf0e10cSrcweir 
550cdf0e10cSrcweir     // Focus-Fenster in der Child-Liste suchen
551cdf0e10cSrcweir     pSWindow = ::ImplFindDlgCtrlWindow( this, pFocusWindow,
552cdf0e10cSrcweir                                         nIndex, nFormStart, nFormEnd );
553cdf0e10cSrcweir     if ( !pSWindow )
554cdf0e10cSrcweir         return sal_False;
555cdf0e10cSrcweir     i = nIndex;
556cdf0e10cSrcweir 
557cdf0e10cSrcweir     nDlgCtrlFlags = 0;
558cdf0e10cSrcweir     pTempWindow = pSWindow;
559cdf0e10cSrcweir     do
560cdf0e10cSrcweir     {
561cdf0e10cSrcweir         nDlgCtrlFlags |= pTempWindow->GetDialogControlFlags();
562cdf0e10cSrcweir         if ( pTempWindow == this )
563cdf0e10cSrcweir             break;
564cdf0e10cSrcweir         pTempWindow = pTempWindow->ImplGetParent();
565cdf0e10cSrcweir     }
566cdf0e10cSrcweir     while ( pTempWindow );
567cdf0e10cSrcweir 
568cdf0e10cSrcweir     pButtonWindow = NULL;
569cdf0e10cSrcweir 
570cdf0e10cSrcweir     if ( nKeyCode == KEY_RETURN )
571cdf0e10cSrcweir     {
572cdf0e10cSrcweir         // Wir suchen zuerst nach einem DefPushButton/CancelButton
573cdf0e10cSrcweir         pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
574cdf0e10cSrcweir         iButtonStart = iButton;
575cdf0e10cSrcweir         while ( pButtonWindow )
576cdf0e10cSrcweir         {
577cdf0e10cSrcweir             if ( (pButtonWindow->GetStyle() & WB_DEFBUTTON) &&
578cdf0e10cSrcweir                  pButtonWindow->mpWindowImpl->mbPushButton )
579cdf0e10cSrcweir                 break;
580cdf0e10cSrcweir 
581cdf0e10cSrcweir             pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
582cdf0e10cSrcweir             if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
583cdf0e10cSrcweir                 pButtonWindow = NULL;
584cdf0e10cSrcweir         }
585cdf0e10cSrcweir 
586cdf0e10cSrcweir         if ( bKeyInput && !pButtonWindow && (nDlgCtrlFlags & WINDOW_DLGCTRL_RETURN) )
587cdf0e10cSrcweir         {
588cdf0e10cSrcweir             sal_uInt16  nType;
589cdf0e10cSrcweir             sal_uInt16  nGetFocusFlags = GETFOCUS_TAB;
590cdf0e10cSrcweir             sal_uInt16  nNewIndex;
591cdf0e10cSrcweir             sal_uInt16  iStart;
592cdf0e10cSrcweir             if ( aKeyCode.IsShift() )
593cdf0e10cSrcweir             {
594cdf0e10cSrcweir                 nType = DLGWINDOW_PREV;
595cdf0e10cSrcweir                 nGetFocusFlags |= GETFOCUS_BACKWARD;
596cdf0e10cSrcweir             }
597cdf0e10cSrcweir             else
598cdf0e10cSrcweir             {
599cdf0e10cSrcweir                 nType = DLGWINDOW_NEXT;
600cdf0e10cSrcweir                 nGetFocusFlags |= GETFOCUS_FORWARD;
601cdf0e10cSrcweir             }
602cdf0e10cSrcweir             iStart = i;
603cdf0e10cSrcweir             pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
604cdf0e10cSrcweir             while ( pTempWindow && (pTempWindow != pSWindow) )
605cdf0e10cSrcweir             {
606cdf0e10cSrcweir                 if ( !pTempWindow->mpWindowImpl->mbPushButton )
607cdf0e10cSrcweir                 {
608cdf0e10cSrcweir                     // Around-Flag ermitteln
609cdf0e10cSrcweir                     if ( nType == DLGWINDOW_PREV )
610cdf0e10cSrcweir                     {
611cdf0e10cSrcweir                         if ( nNewIndex > iStart )
612cdf0e10cSrcweir                             nGetFocusFlags |= GETFOCUS_AROUND;
613cdf0e10cSrcweir                     }
614cdf0e10cSrcweir                     else
615cdf0e10cSrcweir                     {
616cdf0e10cSrcweir                         if ( nNewIndex < iStart )
617cdf0e10cSrcweir                             nGetFocusFlags |= GETFOCUS_AROUND;
618cdf0e10cSrcweir                     }
619cdf0e10cSrcweir                     pTempWindow->ImplControlFocus( nGetFocusFlags );
620cdf0e10cSrcweir                     return sal_True;
621cdf0e10cSrcweir                 }
622cdf0e10cSrcweir                 else
623cdf0e10cSrcweir                 {
624cdf0e10cSrcweir                     i = nNewIndex;
625cdf0e10cSrcweir                     pTempWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
626cdf0e10cSrcweir                 }
627cdf0e10cSrcweir                 if ( (i <= iStart) || (i > nFormEnd) )
628cdf0e10cSrcweir                     pTempWindow = NULL;
629cdf0e10cSrcweir             }
630cdf0e10cSrcweir             // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
631cdf0e10cSrcweir             // simulieren, falls AROUND ausgewertet wird
632cdf0e10cSrcweir             if ( pTempWindow && (pTempWindow == pSWindow) )
633cdf0e10cSrcweir             {
634cdf0e10cSrcweir                 NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
635cdf0e10cSrcweir                 if ( !ImplCallPreNotify( aNEvt1 ) )
636cdf0e10cSrcweir                     pSWindow->LoseFocus();
637cdf0e10cSrcweir                 pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
638cdf0e10cSrcweir                 NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
639cdf0e10cSrcweir                 if ( !ImplCallPreNotify( aNEvt2 ) )
640cdf0e10cSrcweir                     pSWindow->GetFocus();
641cdf0e10cSrcweir                 pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
642cdf0e10cSrcweir                 return sal_True;
643cdf0e10cSrcweir             }
644cdf0e10cSrcweir         }
645cdf0e10cSrcweir     }
646cdf0e10cSrcweir     else if ( nKeyCode == KEY_ESCAPE )
647cdf0e10cSrcweir     {
648cdf0e10cSrcweir         // Wir suchen zuerst nach einem DefPushButton/CancelButton
649cdf0e10cSrcweir         pButtonWindow = ImplGetChildWindow( this, nFormStart, iButton, sal_True );
650cdf0e10cSrcweir         iButtonStart = iButton;
651cdf0e10cSrcweir         while ( pButtonWindow )
652cdf0e10cSrcweir         {
653cdf0e10cSrcweir             if ( pButtonWindow->GetType() == WINDOW_CANCELBUTTON )
654cdf0e10cSrcweir                 break;
655cdf0e10cSrcweir 
656cdf0e10cSrcweir             pButtonWindow = ImplGetNextWindow( this, iButton, iButton, sal_True );
657cdf0e10cSrcweir             if ( (iButton <= iButtonStart) || (iButton > nFormEnd) )
658cdf0e10cSrcweir                 pButtonWindow = NULL;
659cdf0e10cSrcweir         }
660cdf0e10cSrcweir 
661cdf0e10cSrcweir         if ( bKeyInput && mpWindowImpl->mpDlgCtrlDownWindow )
662cdf0e10cSrcweir         {
663cdf0e10cSrcweir             if ( mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow )
664cdf0e10cSrcweir             {
665cdf0e10cSrcweir                 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
666cdf0e10cSrcweir                 mpWindowImpl->mpDlgCtrlDownWindow = NULL;
667cdf0e10cSrcweir                 return sal_True;
668cdf0e10cSrcweir             }
669cdf0e10cSrcweir         }
670cdf0e10cSrcweir     }
671cdf0e10cSrcweir     else if ( bKeyInput )
672cdf0e10cSrcweir     {
673cdf0e10cSrcweir         if ( nKeyCode == KEY_TAB )
674cdf0e10cSrcweir         {
675cdf0e10cSrcweir             // keine Alt-Taste abfangen, wegen Windows
676cdf0e10cSrcweir             if ( !aKeyCode.IsMod2() )
677cdf0e10cSrcweir             {
678cdf0e10cSrcweir                 sal_uInt16  nType;
679cdf0e10cSrcweir                 sal_uInt16  nGetFocusFlags = GETFOCUS_TAB;
680cdf0e10cSrcweir                 sal_uInt16  nNewIndex;
681cdf0e10cSrcweir                 sal_Bool    bFormular = sal_False;
682cdf0e10cSrcweir 
683cdf0e10cSrcweir                 // Bei Ctrl-Tab erstmal testen, ob zwischen Formularen
684cdf0e10cSrcweir                 // gesprungen werden soll
685cdf0e10cSrcweir                 if ( aKeyCode.IsMod1() )
686cdf0e10cSrcweir                 {
687cdf0e10cSrcweir                     // Gruppe suchen
688cdf0e10cSrcweir                     Window* pFormularFirstWindow = NULL;
689cdf0e10cSrcweir                     Window* pLastFormularFirstWindow = NULL;
690cdf0e10cSrcweir                     pTempWindow = ImplGetChildWindow( this, 0, iTemp, sal_False );
691cdf0e10cSrcweir                     Window* pPrevFirstFormularFirstWindow = NULL;
692cdf0e10cSrcweir                     Window* pFirstFormularFirstWindow = pTempWindow;
693cdf0e10cSrcweir                     while ( pTempWindow )
694cdf0e10cSrcweir                     {
695cdf0e10cSrcweir                         if ( pTempWindow->ImplGetWindow()->IsDialogControlStart() )
696cdf0e10cSrcweir                         {
697cdf0e10cSrcweir                             if ( iTemp != 0 )
698cdf0e10cSrcweir                                 bFormular = sal_True;
699cdf0e10cSrcweir                             if ( aKeyCode.IsShift() )
700cdf0e10cSrcweir                             {
701cdf0e10cSrcweir                                 if ( iTemp <= nIndex )
702cdf0e10cSrcweir                                     pFormularFirstWindow = pPrevFirstFormularFirstWindow;
703cdf0e10cSrcweir                                 pPrevFirstFormularFirstWindow = pTempWindow;
704cdf0e10cSrcweir                             }
705cdf0e10cSrcweir                             else
706cdf0e10cSrcweir                             {
707cdf0e10cSrcweir                                 if ( (iTemp > nIndex) && !pFormularFirstWindow )
708cdf0e10cSrcweir                                     pFormularFirstWindow = pTempWindow;
709cdf0e10cSrcweir                             }
710cdf0e10cSrcweir                             pLastFormularFirstWindow = pTempWindow;
711cdf0e10cSrcweir                         }
712cdf0e10cSrcweir 
713cdf0e10cSrcweir                         pTempWindow = ImplGetNextWindow( this, iTemp, iTemp, sal_False );
714cdf0e10cSrcweir                         if ( !iTemp )
715cdf0e10cSrcweir                             pTempWindow = NULL;
716cdf0e10cSrcweir                     }
717cdf0e10cSrcweir 
718cdf0e10cSrcweir                     if ( bFormular )
719cdf0e10cSrcweir                     {
720cdf0e10cSrcweir                         if ( !pFormularFirstWindow )
721cdf0e10cSrcweir                         {
722cdf0e10cSrcweir                             if ( aKeyCode.IsShift() )
723cdf0e10cSrcweir                                 pFormularFirstWindow = pLastFormularFirstWindow;
724cdf0e10cSrcweir                             else
725cdf0e10cSrcweir                                 pFormularFirstWindow = pFirstFormularFirstWindow;
726cdf0e10cSrcweir                         }
727cdf0e10cSrcweir 
728cdf0e10cSrcweir                         sal_uInt16 nFoundFormStart = 0;
729cdf0e10cSrcweir                         sal_uInt16 nFoundFormEnd = 0;
730cdf0e10cSrcweir                         sal_uInt16 nTempIndex = 0;
731cdf0e10cSrcweir                         if ( ::ImplFindDlgCtrlWindow( this, pFormularFirstWindow, nTempIndex,
732cdf0e10cSrcweir                                                       nFoundFormStart, nFoundFormEnd ) )
733cdf0e10cSrcweir                         {
734cdf0e10cSrcweir                             nTempIndex = nFoundFormStart;
735cdf0e10cSrcweir                             pFormularFirstWindow = ImplGetDlgWindow( nTempIndex, DLGWINDOW_FIRST, nFoundFormStart, nFoundFormEnd );
736cdf0e10cSrcweir                             if ( pFormularFirstWindow )
737cdf0e10cSrcweir                             {
738cdf0e10cSrcweir                                 pFormularFirstWindow->ImplControlFocus();
739cdf0e10cSrcweir                                 return sal_True;
740cdf0e10cSrcweir                             }
741cdf0e10cSrcweir                         }
742cdf0e10cSrcweir                     }
743cdf0e10cSrcweir                 }
744cdf0e10cSrcweir 
745cdf0e10cSrcweir                 if ( !bFormular )
746cdf0e10cSrcweir                 {
747cdf0e10cSrcweir                     // Only use Ctrl-TAB if it was allowed for the whole
748cdf0e10cSrcweir                     // dialog or for the current control (#103667#)
749cdf0e10cSrcweir                     if ( !aKeyCode.IsMod1() || (nDlgCtrlFlags & WINDOW_DLGCTRL_MOD1TAB) ||
750cdf0e10cSrcweir                         ( pSWindow->GetStyle() & WINDOW_DLGCTRL_MOD1TAB) )
751cdf0e10cSrcweir                     {
752cdf0e10cSrcweir                         if ( aKeyCode.IsShift() )
753cdf0e10cSrcweir                         {
754cdf0e10cSrcweir                             nType = DLGWINDOW_PREV;
755cdf0e10cSrcweir                             nGetFocusFlags |= GETFOCUS_BACKWARD;
756cdf0e10cSrcweir                         }
757cdf0e10cSrcweir                         else
758cdf0e10cSrcweir                         {
759cdf0e10cSrcweir                             nType = DLGWINDOW_NEXT;
760cdf0e10cSrcweir                             nGetFocusFlags |= GETFOCUS_FORWARD;
761cdf0e10cSrcweir                         }
762cdf0e10cSrcweir                         Window* pWindow = ImplGetDlgWindow( i, nType, nFormStart, nFormEnd, &nNewIndex );
763cdf0e10cSrcweir                         // Wenn es das gleiche Fenster ist, ein Get/LoseFocus
764cdf0e10cSrcweir                         // simulieren, falls AROUND ausgewertet wird
765cdf0e10cSrcweir                         if ( pWindow == pSWindow )
766cdf0e10cSrcweir                         {
767cdf0e10cSrcweir                             NotifyEvent aNEvt1( EVENT_LOSEFOCUS, pSWindow );
768cdf0e10cSrcweir                             if ( !ImplCallPreNotify( aNEvt1 ) )
769cdf0e10cSrcweir                                 pSWindow->LoseFocus();
770cdf0e10cSrcweir                             pSWindow->mpWindowImpl->mnGetFocusFlags = nGetFocusFlags | GETFOCUS_AROUND;
771cdf0e10cSrcweir                             NotifyEvent aNEvt2( EVENT_GETFOCUS, pSWindow );
772cdf0e10cSrcweir                             if ( !ImplCallPreNotify( aNEvt2 ) )
773cdf0e10cSrcweir                                 pSWindow->GetFocus();
774cdf0e10cSrcweir                             pSWindow->mpWindowImpl->mnGetFocusFlags = 0;
775cdf0e10cSrcweir                             return sal_True;
776cdf0e10cSrcweir                         }
777cdf0e10cSrcweir                         else if ( pWindow )
778cdf0e10cSrcweir                         {
779cdf0e10cSrcweir                             // Around-Flag ermitteln
780cdf0e10cSrcweir                             if ( nType == DLGWINDOW_PREV )
781cdf0e10cSrcweir                             {
782cdf0e10cSrcweir                                 if ( nNewIndex > i )
783cdf0e10cSrcweir                                     nGetFocusFlags |= GETFOCUS_AROUND;
784cdf0e10cSrcweir                             }
785cdf0e10cSrcweir                             else
786cdf0e10cSrcweir                             {
787cdf0e10cSrcweir                                 if ( nNewIndex < i )
788cdf0e10cSrcweir                                     nGetFocusFlags |= GETFOCUS_AROUND;
789cdf0e10cSrcweir                             }
790cdf0e10cSrcweir                             pWindow->ImplControlFocus( nGetFocusFlags );
791cdf0e10cSrcweir                             return sal_True;
792cdf0e10cSrcweir                         }
793cdf0e10cSrcweir                     }
794cdf0e10cSrcweir                 }
795cdf0e10cSrcweir             }
796cdf0e10cSrcweir         }
797cdf0e10cSrcweir         else if ( (nKeyCode == KEY_LEFT) || (nKeyCode == KEY_UP) )
798cdf0e10cSrcweir         {
799cdf0e10cSrcweir             Window* pWindow = pSWindow;
800cdf0e10cSrcweir             WinBits nStyle = pSWindow->GetStyle();
801cdf0e10cSrcweir             if ( !(nStyle & WB_GROUP) )
802cdf0e10cSrcweir             {
803cdf0e10cSrcweir                 pWindow = pWindow->GetWindow( WINDOW_PREV );
804cdf0e10cSrcweir                 while ( pWindow )
805cdf0e10cSrcweir                 {
806cdf0e10cSrcweir                     pWindow = pWindow->ImplGetWindow();
807cdf0e10cSrcweir 
808cdf0e10cSrcweir                     nStyle = pWindow->GetStyle();
809cdf0e10cSrcweir 
810cdf0e10cSrcweir                     if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
811cdf0e10cSrcweir                     {
812cdf0e10cSrcweir                         if ( pWindow != pSWindow )
813cdf0e10cSrcweir                             pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
814cdf0e10cSrcweir                         return sal_True;
815cdf0e10cSrcweir                     }
816cdf0e10cSrcweir 
817cdf0e10cSrcweir                     if ( nStyle & WB_GROUP )
818cdf0e10cSrcweir                         break;
819cdf0e10cSrcweir 
820cdf0e10cSrcweir                     pWindow = pWindow->GetWindow( WINDOW_PREV );
821cdf0e10cSrcweir                 }
822cdf0e10cSrcweir             }
823cdf0e10cSrcweir         }
824cdf0e10cSrcweir         else if ( (nKeyCode == KEY_RIGHT) || (nKeyCode == KEY_DOWN) )
825cdf0e10cSrcweir         {
826cdf0e10cSrcweir             Window* pWindow;
827cdf0e10cSrcweir             WinBits nStyle;
828cdf0e10cSrcweir             pWindow = pSWindow->GetWindow( WINDOW_NEXT );
829cdf0e10cSrcweir             while ( pWindow )
830cdf0e10cSrcweir             {
831cdf0e10cSrcweir                 pWindow = pWindow->ImplGetWindow();
832cdf0e10cSrcweir 
833cdf0e10cSrcweir                 nStyle = pWindow->GetStyle();
834cdf0e10cSrcweir 
835cdf0e10cSrcweir                 if ( nStyle & WB_GROUP )
836cdf0e10cSrcweir                     break;
837cdf0e10cSrcweir 
838ad3a95a3SSteve Yin                 //Solution:Pure window shouldn't get window after controls such as buttons.
839ad3a95a3SSteve Yin                 //if ( pWindow->IsVisible() && pWindow->IsEnabled() && pWindow->IsInputEnabled() )
840ad3a95a3SSteve Yin                 if ( pWindow->IsVisible() && pWindow->IsEnabled() &&
841ad3a95a3SSteve Yin                      pWindow->IsInputEnabled() && (
842ad3a95a3SSteve Yin                                     pWindow->GetType() != WINDOW_WINDOW &&
843ad3a95a3SSteve Yin                                     pWindow->GetType() != WINDOW_SYSWINDOW &&
844ad3a95a3SSteve Yin                                     pWindow->GetType() != WINDOW_WORKWINDOW &&
845ad3a95a3SSteve Yin                                     pWindow->GetType() != WINDOW_CONTROL
846ad3a95a3SSteve Yin                                    )
847ad3a95a3SSteve Yin        )
848cdf0e10cSrcweir                 {
849cdf0e10cSrcweir                     pWindow->ImplControlFocus( GETFOCUS_CURSOR | GETFOCUS_BACKWARD );
850cdf0e10cSrcweir                     return sal_True;
851cdf0e10cSrcweir                 }
852cdf0e10cSrcweir 
853cdf0e10cSrcweir                 pWindow = pWindow->GetWindow( WINDOW_NEXT );
854cdf0e10cSrcweir             }
855cdf0e10cSrcweir         }
856cdf0e10cSrcweir         else
857cdf0e10cSrcweir         {
858cdf0e10cSrcweir             xub_Unicode c = rKEvt.GetCharCode();
859cdf0e10cSrcweir             if ( c )
860cdf0e10cSrcweir             {
861cdf0e10cSrcweir                 pSWindow = ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd );
862cdf0e10cSrcweir                 if ( pSWindow )
863cdf0e10cSrcweir                 {
864cdf0e10cSrcweir                     sal_uInt16 nGetFocusFlags = GETFOCUS_MNEMONIC;
865cdf0e10cSrcweir                     if ( pSWindow == ::ImplFindAccelWindow( this, i, c, nFormStart, nFormEnd ) )
866cdf0e10cSrcweir                         nGetFocusFlags |= GETFOCUS_UNIQUEMNEMONIC;
867cdf0e10cSrcweir                     pSWindow->ImplControlFocus( nGetFocusFlags );
868cdf0e10cSrcweir                     return sal_True;
869cdf0e10cSrcweir                 }
870cdf0e10cSrcweir             }
871cdf0e10cSrcweir         }
872cdf0e10cSrcweir     }
873cdf0e10cSrcweir 
874cdf0e10cSrcweir     if ( pButtonWindow && pButtonWindow->IsVisible() && pButtonWindow->IsEnabled() && pButtonWindow->IsInputEnabled() )
875cdf0e10cSrcweir     {
876cdf0e10cSrcweir         if ( bKeyInput )
877cdf0e10cSrcweir         {
878cdf0e10cSrcweir             if ( mpWindowImpl->mpDlgCtrlDownWindow && (mpWindowImpl->mpDlgCtrlDownWindow != pButtonWindow) )
879cdf0e10cSrcweir             {
880cdf0e10cSrcweir                 ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
881cdf0e10cSrcweir                 mpWindowImpl->mpDlgCtrlDownWindow = NULL;
882cdf0e10cSrcweir             }
883cdf0e10cSrcweir 
884cdf0e10cSrcweir             ((PushButton*)pButtonWindow)->SetPressed( sal_True );
885cdf0e10cSrcweir             mpWindowImpl->mpDlgCtrlDownWindow = pButtonWindow;
886cdf0e10cSrcweir         }
887cdf0e10cSrcweir         else if ( mpWindowImpl->mpDlgCtrlDownWindow == pButtonWindow )
888cdf0e10cSrcweir         {
889cdf0e10cSrcweir             mpWindowImpl->mpDlgCtrlDownWindow = NULL;
890cdf0e10cSrcweir             ((PushButton*)pButtonWindow)->SetPressed( sal_False );
891cdf0e10cSrcweir             ((PushButton*)pButtonWindow)->Click();
892cdf0e10cSrcweir         }
893cdf0e10cSrcweir 
894cdf0e10cSrcweir         return sal_True;
895cdf0e10cSrcweir     }
896cdf0e10cSrcweir 
897cdf0e10cSrcweir     return sal_False;
898cdf0e10cSrcweir }
899cdf0e10cSrcweir 
900cdf0e10cSrcweir // -----------------------------------------------------------------------
901cdf0e10cSrcweir 
902cdf0e10cSrcweir // checks if this window has dialog control
ImplHasDlgCtrl()903cdf0e10cSrcweir sal_Bool Window::ImplHasDlgCtrl()
904cdf0e10cSrcweir {
905cdf0e10cSrcweir     Window* pDlgCtrlParent;
906cdf0e10cSrcweir     Window* pDlgCtrl;
907cdf0e10cSrcweir 
908cdf0e10cSrcweir     // lookup window for dialog control
909cdf0e10cSrcweir     pDlgCtrl = this;
910cdf0e10cSrcweir     pDlgCtrlParent = ImplGetParent();
911cdf0e10cSrcweir     while ( pDlgCtrlParent &&
912cdf0e10cSrcweir             !pDlgCtrlParent->ImplIsOverlapWindow() &&
913cdf0e10cSrcweir             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
914cdf0e10cSrcweir         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
915cdf0e10cSrcweir 
916cdf0e10cSrcweir     if ( !pDlgCtrlParent || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
917cdf0e10cSrcweir         return sal_False;
918cdf0e10cSrcweir     else
919cdf0e10cSrcweir         return sal_True;
920cdf0e10cSrcweir }
921cdf0e10cSrcweir 
ImplDlgCtrlNextWindow()922cdf0e10cSrcweir void Window::ImplDlgCtrlNextWindow()
923cdf0e10cSrcweir {
924cdf0e10cSrcweir     Window* pDlgCtrlParent;
925cdf0e10cSrcweir     Window* pDlgCtrl;
926cdf0e10cSrcweir     Window* pSWindow;
927cdf0e10cSrcweir     sal_uInt16  nIndex;
928cdf0e10cSrcweir     sal_uInt16  nFormStart;
929cdf0e10cSrcweir     sal_uInt16  nFormEnd;
930cdf0e10cSrcweir 
931cdf0e10cSrcweir     // lookup window for dialog control
932cdf0e10cSrcweir     pDlgCtrl = this;
933cdf0e10cSrcweir     pDlgCtrlParent = ImplGetParent();
934cdf0e10cSrcweir     while ( pDlgCtrlParent &&
935cdf0e10cSrcweir             !pDlgCtrlParent->ImplIsOverlapWindow() &&
936cdf0e10cSrcweir             ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
937cdf0e10cSrcweir         pDlgCtrlParent = pDlgCtrlParent->ImplGetParent();
938cdf0e10cSrcweir 
939cdf0e10cSrcweir if ( !pDlgCtrlParent || (GetStyle() & WB_NODIALOGCONTROL) || ((pDlgCtrlParent->GetStyle() & (WB_DIALOGCONTROL | WB_NODIALOGCONTROL)) != WB_DIALOGCONTROL) )
940cdf0e10cSrcweir         return;
941cdf0e10cSrcweir 
942cdf0e10cSrcweir     // lookup window in child list
943cdf0e10cSrcweir     pSWindow = ::ImplFindDlgCtrlWindow( pDlgCtrlParent, pDlgCtrl,
944cdf0e10cSrcweir                                         nIndex, nFormStart, nFormEnd );
945cdf0e10cSrcweir     if ( !pSWindow )
946cdf0e10cSrcweir         return;
947cdf0e10cSrcweir 
948cdf0e10cSrcweir     Window* pWindow = pDlgCtrlParent->ImplGetDlgWindow( nIndex, DLGWINDOW_NEXT, nFormStart, nFormEnd );
949cdf0e10cSrcweir     if ( pWindow && (pWindow != pSWindow) )
950cdf0e10cSrcweir         pWindow->ImplControlFocus();
951cdf0e10cSrcweir }
952cdf0e10cSrcweir 
953cdf0e10cSrcweir // -----------------------------------------------------------------------
954cdf0e10cSrcweir 
ImplDlgCtrlUpdateDefButton(Window * pParent,Window * pFocusWindow,sal_Bool bGetFocus)955cdf0e10cSrcweir static void ImplDlgCtrlUpdateDefButton( Window* pParent, Window* pFocusWindow,
956cdf0e10cSrcweir                                         sal_Bool bGetFocus )
957cdf0e10cSrcweir {
958cdf0e10cSrcweir     PushButton* pOldDefButton   = NULL;
959cdf0e10cSrcweir     PushButton* pNewDefButton   = NULL;
960cdf0e10cSrcweir     Window*     pSWindow;
961cdf0e10cSrcweir     sal_uInt16      i;
962cdf0e10cSrcweir     sal_uInt16      nFormStart;
963cdf0e10cSrcweir     sal_uInt16      nFormEnd;
964cdf0e10cSrcweir 
965cdf0e10cSrcweir     // Formular suchen
966cdf0e10cSrcweir     pSWindow = ::ImplFindDlgCtrlWindow( pParent, pFocusWindow, i, nFormStart, nFormEnd );
967cdf0e10cSrcweir     if ( !pSWindow )
968cdf0e10cSrcweir     {
969cdf0e10cSrcweir         nFormStart = 0;
970cdf0e10cSrcweir         nFormEnd = 0xFFFF;
971cdf0e10cSrcweir     }
972cdf0e10cSrcweir 
973cdf0e10cSrcweir     pSWindow = ImplGetChildWindow( pParent, nFormStart, i, sal_False );
974cdf0e10cSrcweir     while ( pSWindow )
975cdf0e10cSrcweir     {
976cdf0e10cSrcweir         if ( pSWindow->ImplIsPushButton() )
977cdf0e10cSrcweir         {
978cdf0e10cSrcweir             PushButton* pPushButton = (PushButton*)pSWindow;
979cdf0e10cSrcweir             if ( pPushButton->ImplIsDefButton() )
980cdf0e10cSrcweir                 pOldDefButton = pPushButton;
981cdf0e10cSrcweir             if ( pPushButton->HasChildPathFocus() )
982cdf0e10cSrcweir                 pNewDefButton = pPushButton;
983cdf0e10cSrcweir             else if ( !pNewDefButton && (pPushButton->GetStyle() & WB_DEFBUTTON) )
984cdf0e10cSrcweir                 pNewDefButton = pPushButton;
985cdf0e10cSrcweir         }
986cdf0e10cSrcweir 
987cdf0e10cSrcweir         pSWindow = ImplGetNextWindow( pParent, i, i, sal_False );
988cdf0e10cSrcweir         if ( !i || (i > nFormEnd) )
989cdf0e10cSrcweir             pSWindow = NULL;
990cdf0e10cSrcweir     }
991cdf0e10cSrcweir 
992cdf0e10cSrcweir     if ( !bGetFocus )
993cdf0e10cSrcweir     {
994cdf0e10cSrcweir         sal_uInt16 nDummy;
995cdf0e10cSrcweir         Window* pNewFocusWindow = Application::GetFocusWindow();
996cdf0e10cSrcweir         if ( !pNewFocusWindow || !pParent->ImplIsWindowOrChild( pNewFocusWindow ) )
997cdf0e10cSrcweir             pNewDefButton = NULL;
998cdf0e10cSrcweir         else if ( !::ImplFindDlgCtrlWindow( pParent, pNewFocusWindow, i, nDummy, nDummy ) ||
999cdf0e10cSrcweir                   (i < nFormStart) || (i > nFormEnd) )
1000cdf0e10cSrcweir             pNewDefButton = NULL;
1001cdf0e10cSrcweir     }
1002cdf0e10cSrcweir 
1003cdf0e10cSrcweir     if ( pOldDefButton != pNewDefButton )
1004cdf0e10cSrcweir     {
1005cdf0e10cSrcweir         if ( pOldDefButton )
1006cdf0e10cSrcweir             pOldDefButton->ImplSetDefButton( sal_False );
1007cdf0e10cSrcweir         if ( pNewDefButton )
1008cdf0e10cSrcweir             pNewDefButton->ImplSetDefButton( sal_True );
1009cdf0e10cSrcweir     }
1010cdf0e10cSrcweir }
1011cdf0e10cSrcweir 
1012cdf0e10cSrcweir // -----------------------------------------------------------------------
1013cdf0e10cSrcweir 
ImplDlgCtrlFocusChanged(Window * pWindow,sal_Bool bGetFocus)1014cdf0e10cSrcweir void Window::ImplDlgCtrlFocusChanged( Window* pWindow, sal_Bool bGetFocus )
1015cdf0e10cSrcweir {
1016cdf0e10cSrcweir     if ( mpWindowImpl->mpDlgCtrlDownWindow && !bGetFocus )
1017cdf0e10cSrcweir     {
1018cdf0e10cSrcweir         ((PushButton*)mpWindowImpl->mpDlgCtrlDownWindow)->SetPressed( sal_False );
1019cdf0e10cSrcweir         mpWindowImpl->mpDlgCtrlDownWindow = NULL;
1020cdf0e10cSrcweir     }
1021cdf0e10cSrcweir 
1022cdf0e10cSrcweir     ImplDlgCtrlUpdateDefButton( this, pWindow, bGetFocus );
1023cdf0e10cSrcweir }
1024cdf0e10cSrcweir 
1025cdf0e10cSrcweir // -----------------------------------------------------------------------
1026cdf0e10cSrcweir 
ImplFindDlgCtrlWindow(Window * pWindow)1027cdf0e10cSrcweir Window* Window::ImplFindDlgCtrlWindow( Window* pWindow )
1028cdf0e10cSrcweir {
1029cdf0e10cSrcweir     sal_uInt16  nIndex;
1030cdf0e10cSrcweir     sal_uInt16  nFormStart;
1031cdf0e10cSrcweir     sal_uInt16  nFormEnd;
1032cdf0e10cSrcweir 
1033cdf0e10cSrcweir     // Focus-Fenster in der Child-Liste suchen und zurueckgeben
1034cdf0e10cSrcweir     return ::ImplFindDlgCtrlWindow( this, pWindow, nIndex, nFormStart, nFormEnd );
1035cdf0e10cSrcweir }
1036cdf0e10cSrcweir 
1037cdf0e10cSrcweir 
1038cdf0e10cSrcweir // -----------------------------------------------------------------------
1039cdf0e10cSrcweir 
GetParentLabelFor(const Window *) const1040cdf0e10cSrcweir Window* Window::GetParentLabelFor( const Window* ) const
1041cdf0e10cSrcweir {
1042cdf0e10cSrcweir     return NULL;
1043cdf0e10cSrcweir }
1044cdf0e10cSrcweir 
1045cdf0e10cSrcweir // -----------------------------------------------------------------------
1046cdf0e10cSrcweir 
GetParentLabeledBy(const Window *) const1047cdf0e10cSrcweir Window* Window::GetParentLabeledBy( const Window* ) const
1048cdf0e10cSrcweir {
1049cdf0e10cSrcweir     return NULL;
1050cdf0e10cSrcweir }
1051cdf0e10cSrcweir 
1052cdf0e10cSrcweir // -----------------------------------------------------------------------
1053cdf0e10cSrcweir 
getAccel(const String & rStr)1054cdf0e10cSrcweir static sal_Unicode getAccel( const String& rStr )
1055cdf0e10cSrcweir {
1056cdf0e10cSrcweir     sal_Unicode nChar = 0;
1057cdf0e10cSrcweir     sal_uInt16 nPos = 0;
1058cdf0e10cSrcweir     do
1059cdf0e10cSrcweir     {
1060cdf0e10cSrcweir         nPos = rStr.Search( '~', nPos );
1061cdf0e10cSrcweir         if( nPos != STRING_NOTFOUND && nPos < rStr.Len() )
1062cdf0e10cSrcweir             nChar = rStr.GetChar( ++nPos );
1063cdf0e10cSrcweir         else
1064cdf0e10cSrcweir             nChar = 0;
1065cdf0e10cSrcweir     } while( nChar == '~' );
1066cdf0e10cSrcweir     return nChar;
1067cdf0e10cSrcweir }
1068cdf0e10cSrcweir 
ImplGetLabelFor(Window * pFrameWindow,WindowType nMyType,Window * pLabel,sal_Unicode nAccel)1069cdf0e10cSrcweir static Window* ImplGetLabelFor( Window* pFrameWindow, WindowType nMyType, Window* pLabel, sal_Unicode nAccel )
1070cdf0e10cSrcweir {
1071cdf0e10cSrcweir     Window* pWindow = NULL;
1072cdf0e10cSrcweir 
1073cdf0e10cSrcweir     if( nMyType == WINDOW_FIXEDTEXT     ||
1074cdf0e10cSrcweir         nMyType == WINDOW_FIXEDLINE     ||
1075cdf0e10cSrcweir         nMyType == WINDOW_GROUPBOX )
1076cdf0e10cSrcweir     {
1077*351838c4SJohn Bampton         // #i100833# MT 2010/02: Group box and fixed lines can also label a fixed text.
1078cdf0e10cSrcweir         // See tools/options/print for example.
1079cdf0e10cSrcweir         sal_Bool bThisIsAGroupControl = (nMyType == WINDOW_GROUPBOX) || (nMyType == WINDOW_FIXEDLINE);
1080cdf0e10cSrcweir         Window* pSWindow = NULL;
1081cdf0e10cSrcweir         // get index, form start and form end
1082cdf0e10cSrcweir         sal_uInt16 nIndex=0, nFormStart=0, nFormEnd=0;
1083cdf0e10cSrcweir         pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1084cdf0e10cSrcweir                                            pLabel,
1085cdf0e10cSrcweir                                            nIndex,
1086cdf0e10cSrcweir                                            nFormStart,
1087cdf0e10cSrcweir                                            nFormEnd );
1088cdf0e10cSrcweir         if( nAccel )
1089cdf0e10cSrcweir         {
1090cdf0e10cSrcweir             // find the accelerated window
1091cdf0e10cSrcweir             pWindow = ::ImplFindAccelWindow( pFrameWindow,
1092cdf0e10cSrcweir                                              nIndex,
1093cdf0e10cSrcweir                                              nAccel,
1094cdf0e10cSrcweir                                              nFormStart,
1095cdf0e10cSrcweir                                              nFormEnd,
1096cdf0e10cSrcweir                                              sal_False );
1097cdf0e10cSrcweir         }
1098cdf0e10cSrcweir         else
1099cdf0e10cSrcweir         {
1100cdf0e10cSrcweir             // find the next control; if that is a fixed text
1101cdf0e10cSrcweir             // fixed line or group box, then return NULL
1102cdf0e10cSrcweir             while( nIndex < nFormEnd )
1103cdf0e10cSrcweir             {
1104cdf0e10cSrcweir                 nIndex++;
1105cdf0e10cSrcweir                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1106cdf0e10cSrcweir                                                  nIndex,
1107cdf0e10cSrcweir                                                  nIndex,
1108cdf0e10cSrcweir                                                  sal_False );
1109cdf0e10cSrcweir                 if( pSWindow && pSWindow->IsVisible() && ! (pSWindow->GetStyle() & WB_NOLABEL) )
1110cdf0e10cSrcweir                 {
1111cdf0e10cSrcweir                     WindowType nType = pSWindow->GetType();
1112cdf0e10cSrcweir                     if( nType != WINDOW_FIXEDTEXT   &&
1113cdf0e10cSrcweir                         nType != WINDOW_FIXEDLINE   &&
1114cdf0e10cSrcweir                         nType != WINDOW_GROUPBOX )
1115cdf0e10cSrcweir                     {
1116cdf0e10cSrcweir                         pWindow = pSWindow;
1117cdf0e10cSrcweir                     }
1118cdf0e10cSrcweir                     else if( bThisIsAGroupControl && ( nType == WINDOW_FIXEDTEXT ) )
1119cdf0e10cSrcweir                     {
1120cdf0e10cSrcweir                         pWindow = pSWindow;
1121cdf0e10cSrcweir                     }
1122cdf0e10cSrcweir                     break;
1123cdf0e10cSrcweir                 }
1124cdf0e10cSrcweir             }
1125cdf0e10cSrcweir         }
1126cdf0e10cSrcweir     }
1127cdf0e10cSrcweir 
1128cdf0e10cSrcweir     return pWindow;
1129cdf0e10cSrcweir }
1130cdf0e10cSrcweir 
GetAccessibleRelationLabelFor() const1131cdf0e10cSrcweir Window* Window::GetAccessibleRelationLabelFor() const
1132cdf0e10cSrcweir {
1133cdf0e10cSrcweir     if ( mpWindowImpl->mbDisableAccessibleLabelForRelation )
1134cdf0e10cSrcweir         return NULL;
1135cdf0e10cSrcweir 
1136cdf0e10cSrcweir     if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow )
1137cdf0e10cSrcweir         return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
1138cdf0e10cSrcweir 
1139cdf0e10cSrcweir 
1140cdf0e10cSrcweir     Window* pWindow = NULL;
1141cdf0e10cSrcweir     Window* pFrameWindow = ImplGetFrameWindow();
1142cdf0e10cSrcweir 
1143cdf0e10cSrcweir     WinBits nFrameStyle = pFrameWindow->GetStyle();
1144cdf0e10cSrcweir     if( ! ( nFrameStyle & WB_DIALOGCONTROL )
1145cdf0e10cSrcweir         || ( nFrameStyle & WB_NODIALOGCONTROL )
1146cdf0e10cSrcweir         )
1147cdf0e10cSrcweir         return NULL;
1148cdf0e10cSrcweir 
1149cdf0e10cSrcweir     if ( mpWindowImpl->mpRealParent )
1150cdf0e10cSrcweir         pWindow = mpWindowImpl->mpRealParent->GetParentLabelFor( this );
1151cdf0e10cSrcweir 
1152cdf0e10cSrcweir     if( pWindow )
1153cdf0e10cSrcweir         return pWindow;
1154cdf0e10cSrcweir 
1155cdf0e10cSrcweir     sal_Unicode nAccel = getAccel( GetText() );
1156cdf0e10cSrcweir 
1157cdf0e10cSrcweir     pWindow = ImplGetLabelFor( pFrameWindow, GetType(), const_cast<Window*>(this), nAccel );
1158cdf0e10cSrcweir     if( ! pWindow && mpWindowImpl->mpRealParent )
1159cdf0e10cSrcweir         pWindow = ImplGetLabelFor( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this), nAccel );
1160cdf0e10cSrcweir     return pWindow;
1161cdf0e10cSrcweir }
1162cdf0e10cSrcweir 
1163cdf0e10cSrcweir // -----------------------------------------------------------------------
1164cdf0e10cSrcweir 
ImplGetLabeledBy(Window * pFrameWindow,WindowType nMyType,Window * pLabeled)1165cdf0e10cSrcweir static Window* ImplGetLabeledBy( Window* pFrameWindow, WindowType nMyType, Window* pLabeled )
1166cdf0e10cSrcweir {
1167cdf0e10cSrcweir     Window* pWindow = NULL;
1168cdf0e10cSrcweir     if ( (nMyType != WINDOW_GROUPBOX) && (nMyType != WINDOW_FIXEDLINE) )
1169cdf0e10cSrcweir     {
1170cdf0e10cSrcweir         // search for a control that labels this window
1171cdf0e10cSrcweir         // a label is considered the last fixed text, fixed line or group box
1172cdf0e10cSrcweir         // that comes before this control; with the exception of push buttons
1173cdf0e10cSrcweir         // which are labeled only if the fixed text, fixed line or group box
1174cdf0e10cSrcweir         // is directly before the control
1175cdf0e10cSrcweir 
1176cdf0e10cSrcweir         // get form start and form end and index of this control
1177cdf0e10cSrcweir         sal_uInt16 nIndex, nFormStart, nFormEnd;
1178cdf0e10cSrcweir         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1179cdf0e10cSrcweir                                                     pLabeled,
1180cdf0e10cSrcweir                                                     nIndex,
1181cdf0e10cSrcweir                                                     nFormStart,
1182cdf0e10cSrcweir                                                     nFormEnd );
1183cdf0e10cSrcweir         if( pSWindow && nIndex != nFormStart )
1184cdf0e10cSrcweir         {
1185cdf0e10cSrcweir             if( nMyType == WINDOW_PUSHBUTTON        ||
1186cdf0e10cSrcweir                 nMyType == WINDOW_HELPBUTTON        ||
1187cdf0e10cSrcweir                 nMyType == WINDOW_OKBUTTON      ||
1188cdf0e10cSrcweir                 nMyType == WINDOW_CANCELBUTTON )
1189cdf0e10cSrcweir             {
1190cdf0e10cSrcweir                 nFormStart = nIndex-1;
1191cdf0e10cSrcweir             }
1192cdf0e10cSrcweir             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1193cdf0e10cSrcweir             {
1194cdf0e10cSrcweir                 sal_uInt16 nFoundIndex = 0;
1195cdf0e10cSrcweir                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1196cdf0e10cSrcweir                                                  nSearchIndex,
1197cdf0e10cSrcweir                                                  nFoundIndex,
1198cdf0e10cSrcweir                                                  sal_False );
1199cdf0e10cSrcweir                 if( pSWindow && pSWindow->IsVisible() && !(pSWindow->GetStyle() & WB_NOLABEL) )
1200cdf0e10cSrcweir                 {
1201cdf0e10cSrcweir                     WindowType nType = pSWindow->GetType();
1202cdf0e10cSrcweir                     if ( ( nType == WINDOW_FIXEDTEXT    ||
1203cdf0e10cSrcweir                           nType == WINDOW_FIXEDLINE ||
1204cdf0e10cSrcweir                           nType == WINDOW_GROUPBOX ) )
1205cdf0e10cSrcweir                     {
1206*351838c4SJohn Bampton                         // a fixed text can't be labeled by a fixed text.
1207cdf0e10cSrcweir                         if ( ( nMyType != WINDOW_FIXEDTEXT ) || ( nType != WINDOW_FIXEDTEXT ) )
1208cdf0e10cSrcweir                             pWindow = pSWindow;
1209cdf0e10cSrcweir                         break;
1210cdf0e10cSrcweir                     }
1211cdf0e10cSrcweir                 }
1212cdf0e10cSrcweir                 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1213cdf0e10cSrcweir                     break;
1214cdf0e10cSrcweir             }
1215cdf0e10cSrcweir         }
1216cdf0e10cSrcweir     }
1217cdf0e10cSrcweir     return pWindow;
1218cdf0e10cSrcweir }
1219cdf0e10cSrcweir 
GetAccessibleRelationLabeledBy() const1220cdf0e10cSrcweir Window* Window::GetAccessibleRelationLabeledBy() const
1221cdf0e10cSrcweir {
1222cdf0e10cSrcweir     if ( mpWindowImpl->mbDisableAccessibleLabeledByRelation )
1223cdf0e10cSrcweir         return NULL;
1224cdf0e10cSrcweir 
1225cdf0e10cSrcweir     if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow )
1226cdf0e10cSrcweir         return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
1227cdf0e10cSrcweir 
1228cdf0e10cSrcweir     Window* pWindow = NULL;
1229cdf0e10cSrcweir     Window* pFrameWindow = ImplGetFrameWindow();
1230cdf0e10cSrcweir 
1231cdf0e10cSrcweir     if ( mpWindowImpl->mpRealParent )
1232cdf0e10cSrcweir     {
1233cdf0e10cSrcweir         pWindow = mpWindowImpl->mpRealParent->GetParentLabeledBy( this );
1234cdf0e10cSrcweir 
1235cdf0e10cSrcweir         if( pWindow )
1236cdf0e10cSrcweir             return pWindow;
1237cdf0e10cSrcweir     }
1238cdf0e10cSrcweir 
1239cdf0e10cSrcweir     // #i62723#, #104191# checkboxes and radiobuttons are not supposed to have labels
1240cdf0e10cSrcweir     if( GetType() == WINDOW_CHECKBOX || GetType() == WINDOW_RADIOBUTTON )
1241cdf0e10cSrcweir         return NULL;
1242cdf0e10cSrcweir 
1243cdf0e10cSrcweir //    if( ! ( GetType() == WINDOW_FIXEDTEXT     ||
1244cdf0e10cSrcweir //            GetType() == WINDOW_FIXEDLINE     ||
1245cdf0e10cSrcweir //            GetType() == WINDOW_GROUPBOX ) )
1246*351838c4SJohn Bampton     // #i100833# MT 2010/02: Group box and fixed lines can also label a fixed text.
1247cdf0e10cSrcweir     // See tools/options/print for example.
1248cdf0e10cSrcweir 
1249cdf0e10cSrcweir     pWindow = ImplGetLabeledBy( pFrameWindow, GetType(), const_cast<Window*>(this) );
1250cdf0e10cSrcweir     if( ! pWindow && mpWindowImpl->mpRealParent )
1251cdf0e10cSrcweir         pWindow = ImplGetLabeledBy( mpWindowImpl->mpRealParent, GetType(), const_cast<Window*>(this) );
1252cdf0e10cSrcweir 
1253cdf0e10cSrcweir     return pWindow;
1254cdf0e10cSrcweir }
1255cdf0e10cSrcweir 
GetAccessibleRelationMemberOf() const1256cdf0e10cSrcweir Window* Window::GetAccessibleRelationMemberOf() const
1257cdf0e10cSrcweir {
1258cdf0e10cSrcweir     Window* pWindow = NULL;
1259cdf0e10cSrcweir     Window* pFrameWindow = GetParent();
1260cdf0e10cSrcweir     if ( !pFrameWindow )
1261cdf0e10cSrcweir     {
1262cdf0e10cSrcweir         pFrameWindow = ImplGetFrameWindow();
1263cdf0e10cSrcweir     }
1264cdf0e10cSrcweir     // if( ! ( GetType() == WINDOW_FIXEDTEXT        ||
1265cdf0e10cSrcweir     if( !( GetType() == WINDOW_FIXEDLINE ||
1266cdf0e10cSrcweir         GetType() == WINDOW_GROUPBOX ) )
1267cdf0e10cSrcweir     {
1268cdf0e10cSrcweir         // search for a control that makes member of this window
1269cdf0e10cSrcweir         // it is considered the last fixed line or group box
1270cdf0e10cSrcweir         // that comes before this control; with the exception of push buttons
1271cdf0e10cSrcweir         // which are labeled only if the fixed line or group box
1272cdf0e10cSrcweir         // is directly before the control
1273cdf0e10cSrcweir         // get form start and form end and index of this control
1274cdf0e10cSrcweir         sal_uInt16 nIndex, nFormStart, nFormEnd;
1275cdf0e10cSrcweir         Window* pSWindow = ::ImplFindDlgCtrlWindow( pFrameWindow,
1276cdf0e10cSrcweir             const_cast<Window*>(this),
1277cdf0e10cSrcweir             nIndex,
1278cdf0e10cSrcweir             nFormStart,
1279cdf0e10cSrcweir             nFormEnd );
1280cdf0e10cSrcweir         if( pSWindow && nIndex != nFormStart )
1281cdf0e10cSrcweir         {
1282cdf0e10cSrcweir             if( GetType() == WINDOW_PUSHBUTTON      ||
1283cdf0e10cSrcweir                 GetType() == WINDOW_HELPBUTTON      ||
1284cdf0e10cSrcweir                 GetType() == WINDOW_OKBUTTON        ||
1285cdf0e10cSrcweir                 GetType() == WINDOW_CANCELBUTTON )
1286cdf0e10cSrcweir             {
1287cdf0e10cSrcweir                 nFormStart = nIndex-1;
1288cdf0e10cSrcweir             }
1289cdf0e10cSrcweir             for( sal_uInt16 nSearchIndex = nIndex-1; nSearchIndex >= nFormStart; nSearchIndex-- )
1290cdf0e10cSrcweir             {
1291cdf0e10cSrcweir                 sal_uInt16 nFoundIndex = 0;
1292cdf0e10cSrcweir                 pSWindow = ::ImplGetChildWindow( pFrameWindow,
1293cdf0e10cSrcweir                     nSearchIndex,
1294cdf0e10cSrcweir                     nFoundIndex,
1295cdf0e10cSrcweir                     sal_False );
1296cdf0e10cSrcweir                 if( pSWindow && pSWindow->IsVisible() &&
1297cdf0e10cSrcweir                     ( pSWindow->GetType() == WINDOW_FIXEDLINE   ||
1298cdf0e10cSrcweir                     pSWindow->GetType() == WINDOW_GROUPBOX ) )
1299cdf0e10cSrcweir                 {
1300cdf0e10cSrcweir                     pWindow = pSWindow;
1301cdf0e10cSrcweir                     break;
1302cdf0e10cSrcweir                 }
1303cdf0e10cSrcweir                 if( nFoundIndex > nSearchIndex || nSearchIndex == 0 )
1304cdf0e10cSrcweir                     break;
1305cdf0e10cSrcweir             }
1306cdf0e10cSrcweir         }
1307cdf0e10cSrcweir     }
1308cdf0e10cSrcweir     return pWindow;
1309cdf0e10cSrcweir }
1310cdf0e10cSrcweir 
1311cdf0e10cSrcweir // -----------------------------------------------------------------------
1312cdf0e10cSrcweir 
GetActivationKey() const1313cdf0e10cSrcweir KeyEvent Window::GetActivationKey() const
1314cdf0e10cSrcweir {
1315cdf0e10cSrcweir     KeyEvent aKeyEvent;
1316cdf0e10cSrcweir 
1317cdf0e10cSrcweir     sal_Unicode nAccel = getAccel( GetText() );
1318cdf0e10cSrcweir     if( ! nAccel )
1319cdf0e10cSrcweir     {
1320cdf0e10cSrcweir         Window* pWindow = GetAccessibleRelationLabeledBy();
1321cdf0e10cSrcweir         if( pWindow )
1322cdf0e10cSrcweir             nAccel = getAccel( pWindow->GetText() );
1323cdf0e10cSrcweir     }
1324cdf0e10cSrcweir     if( nAccel )
1325cdf0e10cSrcweir     {
1326cdf0e10cSrcweir         sal_uInt16 nCode = 0;
1327cdf0e10cSrcweir         if( nAccel >= 'a' && nAccel <= 'z' )
1328cdf0e10cSrcweir             nCode = KEY_A + (nAccel-'a');
1329cdf0e10cSrcweir         else if( nAccel >= 'A' && nAccel <= 'Z' )
1330cdf0e10cSrcweir             nCode = KEY_A + (nAccel-'A');
1331cdf0e10cSrcweir         else if( nAccel >= '0' && nAccel <= '9' )
1332cdf0e10cSrcweir             nCode = KEY_0 + (nAccel-'0');
1333cdf0e10cSrcweir         else if( nAccel == '.' )
1334cdf0e10cSrcweir             nCode = KEY_POINT;
1335cdf0e10cSrcweir         else if( nAccel == '-' )
1336cdf0e10cSrcweir             nCode = KEY_SUBTRACT;
1337cdf0e10cSrcweir         KeyCode aKeyCode( nCode, sal_False, sal_False, sal_True, sal_False );
1338cdf0e10cSrcweir         aKeyEvent = KeyEvent( nAccel, aKeyCode );
1339cdf0e10cSrcweir     }
1340cdf0e10cSrcweir     return aKeyEvent;
1341cdf0e10cSrcweir }
1342