Line data Source code
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 : #include <config_features.h>
21 :
22 : #include <i18nlangtag/mslangid.hxx>
23 :
24 : #include "tools/time.hxx"
25 : #include "tools/debug.hxx"
26 : #include "tools/rc.h"
27 :
28 : #include "unotools/fontcfg.hxx"
29 : #include "unotools/confignode.hxx"
30 :
31 : #include "vcl/layout.hxx"
32 : #include "vcl/salgtype.hxx"
33 : #include "vcl/event.hxx"
34 : #include "vcl/fixed.hxx"
35 : #include "vcl/help.hxx"
36 : #include "vcl/cursor.hxx"
37 : #include "vcl/svapp.hxx"
38 : #include "vcl/window.hxx"
39 : #include "vcl/syswin.hxx"
40 : #include "vcl/syschild.hxx"
41 : #include "vcl/dockwin.hxx"
42 : #include "vcl/menu.hxx"
43 : #include "vcl/wrkwin.hxx"
44 : #include "vcl/wall.hxx"
45 : #include "vcl/gradient.hxx"
46 : #include "vcl/button.hxx"
47 : #include "vcl/taskpanelist.hxx"
48 : #include "vcl/dialog.hxx"
49 : #include "vcl/unowrap.hxx"
50 : #include "vcl/gdimtf.hxx"
51 : #include "vcl/pdfextoutdevdata.hxx"
52 : #include "vcl/popupmenuwindow.hxx"
53 : #include "vcl/lazydelete.hxx"
54 : #include "vcl/virdev.hxx"
55 : #include "vcl/settings.hxx"
56 :
57 : // declare system types in sysdata.hxx
58 : #include "vcl/sysdata.hxx"
59 :
60 : #include "salframe.hxx"
61 : #include "salobj.hxx"
62 : #include "salinst.hxx"
63 : #include "salgdi.hxx"
64 : #include "svdata.hxx"
65 : #include "dbggui.hxx"
66 : #include "outfont.hxx"
67 : #include "window.h"
68 : #include "toolbox.h"
69 : #include "outdev.h"
70 : #include "PhysicalFontCollection.hxx"
71 : #include "brdwin.hxx"
72 : #include "helpwin.hxx"
73 : #include "sallayout.hxx"
74 : #include "dndlcon.hxx"
75 : #include "dndevdis.hxx"
76 :
77 : #include "com/sun/star/accessibility/XAccessible.hpp"
78 : #include "com/sun/star/accessibility/AccessibleRole.hpp"
79 : #include "com/sun/star/awt/XWindowPeer.hpp"
80 : #include "com/sun/star/awt/XTopWindow.hpp"
81 : #include "com/sun/star/awt/XWindow.hpp"
82 : #include "com/sun/star/awt/XDisplayConnection.hpp"
83 : #include "com/sun/star/datatransfer/dnd/XDragSource.hpp"
84 : #include "com/sun/star/datatransfer/dnd/XDropTarget.hpp"
85 : #include "com/sun/star/datatransfer/clipboard/XClipboard.hpp"
86 : #include "com/sun/star/datatransfer/clipboard/SystemClipboard.hpp"
87 : #include "com/sun/star/lang/XInitialization.hpp"
88 : #include "com/sun/star/lang/XComponent.hpp"
89 : #include "com/sun/star/lang/XServiceName.hpp"
90 : #include "com/sun/star/rendering/CanvasFactory.hpp"
91 : #include "com/sun/star/rendering/XCanvas.hpp"
92 : #include "com/sun/star/rendering/XSpriteCanvas.hpp"
93 : #include "comphelper/processfactory.hxx"
94 :
95 : #include <sal/macros.h>
96 : #include <rtl/strbuf.hxx>
97 :
98 : #include <set>
99 : #include <typeinfo>
100 :
101 : using namespace ::com::sun::star::uno;
102 : using namespace ::com::sun::star::lang;
103 : using namespace ::com::sun::star::datatransfer::clipboard;
104 : using namespace ::com::sun::star::datatransfer::dnd;
105 : using namespace ::com::sun::star;
106 :
107 : using ::com::sun::star::awt::XTopWindow;
108 :
109 26667 : ImplAccessibleInfos::ImplAccessibleInfos()
110 : {
111 26667 : nAccessibleRole = 0xFFFF;
112 26667 : pAccessibleName = NULL;
113 26667 : pAccessibleDescription = NULL;
114 26667 : pLabeledByWindow = NULL;
115 26667 : pLabelForWindow = NULL;
116 26667 : pMemberOfWindow = NULL;
117 26667 : }
118 :
119 26667 : ImplAccessibleInfos::~ImplAccessibleInfos()
120 : {
121 26667 : delete pAccessibleName;
122 26667 : delete pAccessibleDescription;
123 26667 : }
124 :
125 : namespace vcl {
126 :
127 5466 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::GetAccessible( bool bCreate )
128 : {
129 : // do not optimize hierarchy for the top level border win (ie, when there is no parent)
130 : /* // do not optimize accessible hierarchy at all to better reflect real VCL hierarchy
131 : if ( GetParent() && ( GetType() == WINDOW_BORDERWINDOW ) && ( GetChildCount() == 1 ) )
132 : //if( !ImplIsAccessibleCandidate() )
133 : {
134 : vcl::Window* pChild = GetAccessibleChildWindow( 0 );
135 : if ( pChild )
136 : return pChild->GetAccessible();
137 : }
138 : */
139 5466 : if ( !mpWindowImpl->mxAccessible.is() && bCreate )
140 758 : mpWindowImpl->mxAccessible = CreateAccessible();
141 :
142 5466 : return mpWindowImpl->mxAccessible;
143 : }
144 :
145 640 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
146 : {
147 640 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( true ), ::com::sun::star::uno::UNO_QUERY );
148 640 : return xAcc;
149 : }
150 :
151 5562 : void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
152 : {
153 5562 : mpWindowImpl->mxAccessible = x;
154 5562 : }
155 :
156 : // skip all border windows that are no top level frames
157 1613596 : bool Window::ImplIsAccessibleCandidate() const
158 : {
159 1613596 : if( !mpWindowImpl->mbBorderWin )
160 1461068 : return true;
161 : else
162 : // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
163 152528 : if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
164 33892 : return true;
165 : else
166 118636 : return false;
167 : }
168 :
169 1464471 : bool Window::ImplIsAccessibleNativeFrame() const
170 : {
171 1464471 : if( mpWindowImpl->mbFrame )
172 : // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
173 31926 : if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
174 12448 : return true;
175 : else
176 19478 : return false;
177 : else
178 1432545 : return false;
179 : }
180 :
181 0 : sal_uInt16 Window::ImplGetAccessibleCandidateChildWindowCount( sal_uInt16 nFirstWindowType ) const
182 : {
183 0 : sal_uInt16 nChildren = 0;
184 0 : vcl::Window* pChild = GetWindow( nFirstWindowType );
185 0 : while ( pChild )
186 : {
187 0 : if( pChild->ImplIsAccessibleCandidate() )
188 0 : nChildren++;
189 : else
190 0 : nChildren = sal::static_int_cast<sal_uInt16>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( WINDOW_FIRSTCHILD ));
191 0 : pChild = pChild->mpWindowImpl->mpNext;
192 : }
193 0 : return nChildren;
194 : }
195 :
196 0 : vcl::Window* Window::ImplGetAccessibleCandidateChild( sal_uInt16 nChild, sal_uInt16& rChildCount, sal_uInt16 nFirstWindowType, bool bTopLevel ) const
197 : {
198 :
199 0 : if( bTopLevel )
200 0 : rChildCount = 0;
201 :
202 0 : vcl::Window* pChild = GetWindow( nFirstWindowType );
203 0 : while ( pChild )
204 : {
205 0 : vcl::Window *pTmpChild = pChild;
206 :
207 0 : if( !pChild->ImplIsAccessibleCandidate() )
208 0 : pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, WINDOW_FIRSTCHILD, false );
209 :
210 0 : if ( nChild == rChildCount )
211 0 : return pTmpChild;
212 0 : pChild = pChild->mpWindowImpl->mpNext;
213 0 : rChildCount++;
214 : }
215 :
216 0 : return NULL;
217 : }
218 :
219 1018547 : vcl::Window* Window::GetAccessibleParentWindow() const
220 : {
221 1018547 : if ( ImplIsAccessibleNativeFrame() )
222 6232 : return NULL;
223 :
224 1012315 : vcl::Window* pParent = mpWindowImpl->mpParent;
225 1012315 : if( GetType() == WINDOW_MENUBARWINDOW )
226 : {
227 : // report the menubar as a child of THE workwindow
228 11206 : vcl::Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
229 25984 : while( pWorkWin && (pWorkWin == this) )
230 3572 : pWorkWin = pWorkWin->mpWindowImpl->mpNext;
231 11206 : pParent = pWorkWin;
232 : }
233 : // If this is a floating window which has a native border window, then that border should be reported as
234 : // the accessible parent, unless the floating window is a PopupMenuFloatingWindow
235 :
236 : // The logic here has to match that of AccessibleFactory::createAccessibleContext in
237 : // accessibility/source/helper/acc_factory.cxx to avoid PopupMenuFloatingWindow
238 : // becoming a11y parents of themselves
239 2014798 : else if( GetType() == WINDOW_FLOATINGWINDOW &&
240 1001173 : mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
241 32 : !PopupMenuFloatingWindow::isPopupMenu(this))
242 : {
243 32 : pParent = mpWindowImpl->mpBorderWindow;
244 : }
245 1001077 : else if( pParent && !pParent->ImplIsAccessibleCandidate() )
246 : {
247 86384 : pParent = pParent->mpWindowImpl->mpParent;
248 : }
249 1012315 : return pParent;
250 : }
251 :
252 2808 : sal_uInt16 Window::GetAccessibleChildWindowCount()
253 : {
254 2808 : sal_uInt16 nChildren = 0;
255 2808 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
256 20812 : while( pChild )
257 : {
258 15196 : if( pChild->IsVisible() )
259 8836 : nChildren++;
260 15196 : pChild = pChild->mpWindowImpl->mpNext;
261 : }
262 :
263 : // #107176# ignore overlapwindows
264 : // this only affects non-system floating windows
265 : // which are either not accessible (like the HelpAgent) or should be changed to system windows anyway
266 : /*
267 : if( ImplIsOverlapWindow() )
268 : {
269 : vcl::Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
270 : while ( pOverlap )
271 : {
272 : if( pOverlap->IsVisible() )
273 : nChildren++;
274 : pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
275 : }
276 : }
277 : */
278 :
279 : // report the menubarwindow as a child of THE workwindow
280 2808 : if( GetType() == WINDOW_BORDERWINDOW )
281 : {
282 396 : ImplBorderWindow *pBorderWindow = static_cast<ImplBorderWindow*>(this);
283 792 : if( pBorderWindow->mpMenuBarWindow &&
284 396 : pBorderWindow->mpMenuBarWindow->IsVisible()
285 : )
286 396 : --nChildren;
287 : }
288 2412 : else if( GetType() == WINDOW_WORKWINDOW )
289 : {
290 508 : WorkWindow *pWorkWindow = static_cast<WorkWindow*>(this);
291 1524 : if( pWorkWindow->GetMenuBar() &&
292 1016 : pWorkWindow->GetMenuBar()->GetWindow() &&
293 508 : pWorkWindow->GetMenuBar()->GetWindow()->IsVisible()
294 : )
295 508 : ++nChildren;
296 : }
297 :
298 2808 : return nChildren;
299 : }
300 :
301 694 : vcl::Window* Window::GetAccessibleChildWindow( sal_uInt16 n )
302 : {
303 : // report the menubarwindow as a the first child of THE workwindow
304 694 : if( GetType() == WINDOW_WORKWINDOW && static_cast<WorkWindow *>(this)->GetMenuBar() )
305 : {
306 80 : if( n == 0 )
307 : {
308 28 : MenuBar *pMenuBar = static_cast<WorkWindow *>(this)->GetMenuBar();
309 28 : if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
310 28 : return pMenuBar->GetWindow();
311 : }
312 : else
313 52 : --n;
314 : }
315 :
316 : // transform n to child number including invisible children
317 666 : sal_uInt16 nChildren = n;
318 666 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
319 2452 : while( pChild )
320 : {
321 1786 : if( pChild->IsVisible() )
322 : {
323 1258 : if( ! nChildren )
324 666 : break;
325 592 : nChildren--;
326 : }
327 1120 : pChild = pChild->mpWindowImpl->mpNext;
328 : }
329 :
330 666 : if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
331 : {
332 36 : do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
333 : DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
334 : }
335 : if ( !pChild )
336 : {
337 : // #107176# ignore overlapwindows
338 : /*
339 : if( ImplIsOverlapWindow() )
340 : {
341 : vcl::Window* pOverlap = GetWindow( WINDOW_FIRSTOVERLAP );
342 : while ( !pChild && pOverlap )
343 : {
344 : if ( !nChildren && pOverlap->IsVisible() )
345 : {
346 : pChild = pOverlap;
347 : break;
348 : }
349 : pOverlap = pOverlap->GetWindow( WINDOW_NEXT );
350 : if( pOverlap && pOverlap->IsVisible() )
351 : nChildren--;
352 : }
353 : }
354 : */
355 :
356 : }
357 666 : if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
358 : {
359 62 : pChild = pChild->GetChild( 0 );
360 : }
361 666 : return pChild;
362 : }
363 :
364 12530 : void Window::SetAccessibleRole( sal_uInt16 nRole )
365 : {
366 12530 : if ( !mpWindowImpl->mpAccessibleInfos )
367 12518 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
368 :
369 : DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
370 12530 : mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
371 12530 : }
372 :
373 4774 : sal_uInt16 Window::getDefaultAccessibleRole() const
374 : {
375 4774 : sal_uInt16 nRole = 0xFFFF;
376 4774 : switch ( GetType() )
377 : {
378 : case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
379 : case WINDOW_INFOBOX:
380 : case WINDOW_WARNINGBOX:
381 : case WINDOW_ERRORBOX:
382 0 : case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break;
383 :
384 : case WINDOW_MODELESSDIALOG:
385 : case WINDOW_MODALDIALOG:
386 : case WINDOW_SYSTEMDIALOG:
387 : case WINDOW_PRINTERSETUPDIALOG:
388 : case WINDOW_PRINTDIALOG:
389 : case WINDOW_TABDIALOG:
390 : case WINDOW_BUTTONDIALOG:
391 16 : case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
392 :
393 : case WINDOW_PUSHBUTTON:
394 : case WINDOW_OKBUTTON:
395 : case WINDOW_CANCELBUTTON:
396 : case WINDOW_HELPBUTTON:
397 : case WINDOW_IMAGEBUTTON:
398 : case WINDOW_MOREBUTTON:
399 : case WINDOW_SPINBUTTON:
400 0 : case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
401 0 : case WINDOW_MENUBUTTON: nRole = accessibility::AccessibleRole::BUTTON_MENU; break;
402 :
403 0 : case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
404 0 : case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
405 0 : case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
406 0 : case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
407 :
408 72 : case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
409 : case WINDOW_TRISTATEBOX:
410 24 : case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
411 :
412 0 : case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
413 :
414 : case WINDOW_PATTERNFIELD:
415 : case WINDOW_CALCINPUTLINE:
416 0 : case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
417 :
418 : case WINDOW_PATTERNBOX:
419 : case WINDOW_NUMERICBOX:
420 : case WINDOW_METRICBOX:
421 : case WINDOW_CURRENCYBOX:
422 : case WINDOW_LONGCURRENCYBOX:
423 0 : case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break;
424 :
425 : case WINDOW_LISTBOX:
426 0 : case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
427 :
428 0 : case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
429 :
430 36 : case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
431 : case WINDOW_FIXEDLINE:
432 0 : if( !GetText().isEmpty() )
433 0 : nRole = accessibility::AccessibleRole::LABEL;
434 : else
435 0 : nRole = accessibility::AccessibleRole::SEPARATOR;
436 0 : break;
437 :
438 : case WINDOW_FIXEDBITMAP:
439 30 : case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
440 0 : case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
441 100 : case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
442 :
443 : case WINDOW_SLIDER:
444 : case WINDOW_SPLITTER:
445 132 : case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
446 :
447 : case WINDOW_DATEBOX:
448 : case WINDOW_TIMEBOX:
449 : case WINDOW_DATEFIELD:
450 0 : case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
451 :
452 : case WINDOW_NUMERICFIELD:
453 : case WINDOW_METRICFIELD:
454 : case WINDOW_CURRENCYFIELD:
455 : case WINDOW_LONGCURRENCYFIELD:
456 0 : case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
457 :
458 218 : case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
459 6 : case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
460 :
461 0 : case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
462 0 : case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
463 :
464 : case WINDOW_DOCKINGWINDOW:
465 : case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
466 184 : accessibility::AccessibleRole::PANEL; break;
467 :
468 0 : case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
469 0 : (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
470 0 : (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
471 0 : accessibility::AccessibleRole::WINDOW; break;
472 :
473 774 : case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
474 :
475 84 : case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
476 :
477 0 : case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
478 :
479 0 : case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break;
480 :
481 0 : case WINDOW_SCROLLWINDOW: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
482 :
483 : case WINDOW_WINDOW:
484 : case WINDOW_CONTROL:
485 : case WINDOW_BORDERWINDOW:
486 : case WINDOW_SYSTEMCHILDWINDOW:
487 : default:
488 3098 : if (ImplIsAccessibleNativeFrame() )
489 396 : nRole = accessibility::AccessibleRole::FRAME;
490 2702 : else if( IsScrollable() )
491 1426 : nRole = accessibility::AccessibleRole::SCROLL_PANE;
492 1276 : else if( ((vcl::Window*)this)->ImplGetWindow()->IsMenuFloatingWindow() )
493 0 : nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel)
494 : else
495 : // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
496 : // a WINDOW is interpreted as a top-level window, which is typically not the case
497 : //nRole = accessibility::AccessibleRole::WINDOW;
498 1276 : nRole = accessibility::AccessibleRole::PANEL;
499 : }
500 4774 : return nRole;
501 : }
502 :
503 4966 : sal_uInt16 Window::GetAccessibleRole() const
504 : {
505 : using namespace ::com::sun::star;
506 :
507 4966 : sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
508 4966 : if ( nRole == 0xFFFF )
509 4930 : nRole = getDefaultAccessibleRole();
510 4966 : return nRole;
511 : }
512 :
513 14149 : void Window::SetAccessibleName( const OUString& rName )
514 : {
515 14149 : if ( !mpWindowImpl->mpAccessibleInfos )
516 14149 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
517 :
518 14149 : OUString oldName = GetAccessibleName();
519 :
520 14149 : delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
521 14149 : mpWindowImpl->mpAccessibleInfos->pAccessibleName = new OUString( rName );
522 :
523 14149 : ImplCallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldName );
524 14149 : }
525 :
526 15671 : OUString Window::GetAccessibleName() const
527 : {
528 15671 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName)
529 84 : return *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
530 15587 : return getDefaultAccessibleName();
531 : }
532 :
533 15587 : OUString Window::getDefaultAccessibleName() const
534 : {
535 15587 : OUString aAccessibleName;
536 15587 : switch ( GetType() )
537 : {
538 : case WINDOW_MULTILINEEDIT:
539 : case WINDOW_PATTERNFIELD:
540 : case WINDOW_NUMERICFIELD:
541 : case WINDOW_METRICFIELD:
542 : case WINDOW_CURRENCYFIELD:
543 : case WINDOW_LONGCURRENCYFIELD:
544 : case WINDOW_CALCINPUTLINE:
545 : case WINDOW_EDIT:
546 :
547 : case WINDOW_DATEBOX:
548 : case WINDOW_TIMEBOX:
549 : case WINDOW_CURRENCYBOX:
550 : case WINDOW_LONGCURRENCYBOX:
551 : case WINDOW_DATEFIELD:
552 : case WINDOW_TIMEFIELD:
553 : case WINDOW_SPINFIELD:
554 :
555 : case WINDOW_COMBOBOX:
556 : case WINDOW_LISTBOX:
557 : case WINDOW_MULTILISTBOX:
558 : case WINDOW_TREELISTBOX:
559 : case WINDOW_METRICBOX:
560 : {
561 9724 : vcl::Window *pLabel = GetAccessibleRelationLabeledBy();
562 9724 : if ( pLabel && pLabel != this )
563 0 : aAccessibleName = pLabel->GetText();
564 9724 : if (aAccessibleName.isEmpty())
565 9724 : aAccessibleName = GetQuickHelpText();
566 : }
567 9724 : break;
568 :
569 : case WINDOW_IMAGEBUTTON:
570 : case WINDOW_PUSHBUTTON:
571 3672 : aAccessibleName = GetText();
572 3672 : if (aAccessibleName.isEmpty())
573 : {
574 3672 : aAccessibleName = GetQuickHelpText();
575 3672 : if (aAccessibleName.isEmpty())
576 3672 : aAccessibleName = GetHelpText();
577 : }
578 3672 : break;
579 :
580 : case WINDOW_TOOLBOX:
581 554 : aAccessibleName = GetText();
582 554 : if( aAccessibleName.isEmpty() )
583 554 : aAccessibleName = "Tool Bar";
584 554 : break;
585 :
586 : case WINDOW_MOREBUTTON:
587 0 : aAccessibleName = mpWindowImpl->maText;
588 0 : break;
589 :
590 : default:
591 1637 : aAccessibleName = GetText();
592 1637 : break;
593 : }
594 :
595 15587 : return GetNonMnemonicString( aAccessibleName );
596 : }
597 :
598 142 : void Window::SetAccessibleDescription( const OUString& rDescription )
599 : {
600 142 : if ( ! mpWindowImpl->mpAccessibleInfos )
601 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
602 :
603 : DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
604 142 : delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
605 142 : mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new OUString( rDescription );
606 142 : }
607 :
608 1726 : OUString Window::GetAccessibleDescription() const
609 : {
610 1726 : OUString aAccessibleDescription;
611 1726 : if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
612 : {
613 130 : aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
614 : }
615 : else
616 : {
617 : // Special code for help text windows. ZT asks the border window for the
618 : // description so we have to forward this request to our inner window.
619 1596 : const vcl::Window* pWin = ((vcl::Window *)this)->ImplGetWindow();
620 1596 : if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
621 0 : aAccessibleDescription = pWin->GetHelpText();
622 : else
623 1596 : aAccessibleDescription = GetHelpText();
624 : }
625 :
626 1726 : return aAccessibleDescription;
627 : }
628 :
629 0 : void Window::SetAccessibleRelationLabeledBy( vcl::Window* pLabeledBy )
630 : {
631 0 : if ( !mpWindowImpl->mpAccessibleInfos )
632 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
633 0 : mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy;
634 0 : }
635 :
636 0 : void Window::SetAccessibleRelationLabelFor( vcl::Window* pLabelFor )
637 : {
638 0 : if ( !mpWindowImpl->mpAccessibleInfos )
639 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
640 0 : mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor;
641 0 : }
642 :
643 0 : void Window::SetAccessibleRelationMemberOf( vcl::Window* pMemberOfWin )
644 : {
645 0 : if ( !mpWindowImpl->mpAccessibleInfos )
646 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
647 0 : mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin;
648 0 : }
649 :
650 10 : vcl::Window* Window::GetAccessibleRelationMemberOf() const
651 : {
652 10 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pMemberOfWindow)
653 0 : return mpWindowImpl->mpAccessibleInfos->pMemberOfWindow;
654 :
655 10 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
656 10 : return getLegacyNonLayoutAccessibleRelationMemberOf();
657 :
658 0 : return NULL;
659 : }
660 :
661 18640 : vcl::Window* Window::getAccessibleRelationLabelFor() const
662 : {
663 18640 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow)
664 0 : return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
665 :
666 18640 : return NULL;
667 : }
668 :
669 18640 : vcl::Window* Window::GetAccessibleRelationLabelFor() const
670 : {
671 18640 : vcl::Window* pWindow = getAccessibleRelationLabelFor();
672 :
673 18640 : if (pWindow)
674 0 : return pWindow;
675 :
676 18640 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
677 18640 : return getLegacyNonLayoutAccessibleRelationLabelFor();
678 :
679 0 : return NULL;
680 : }
681 :
682 9734 : vcl::Window* Window::GetAccessibleRelationLabeledBy() const
683 : {
684 9734 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow)
685 0 : return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
686 :
687 9734 : std::vector<FixedText*> aMnemonicLabels(list_mnemonic_labels());
688 9734 : if (!aMnemonicLabels.empty())
689 : {
690 : //if we have multiple labels, then prefer the first that is visible
691 0 : for (std::vector<FixedText*>::iterator
692 0 : aI = aMnemonicLabels.begin(), aEnd = aMnemonicLabels.end(); aI != aEnd; ++aI)
693 : {
694 0 : vcl::Window *pCandidate = *aI;
695 0 : if (pCandidate->IsVisible())
696 0 : return pCandidate;
697 : }
698 0 : return aMnemonicLabels[0];
699 : }
700 :
701 9734 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
702 6044 : return getLegacyNonLayoutAccessibleRelationLabeledBy();
703 :
704 3690 : return NULL;
705 : }
706 :
707 88974 : bool Window::IsAccessibilityEventsSuppressed( bool bTraverseParentPath )
708 : {
709 88974 : if( !bTraverseParentPath )
710 1696 : return mpWindowImpl->mbSuppressAccessibilityEvents;
711 : else
712 : {
713 87278 : vcl::Window *pParent = this;
714 979903 : while ( pParent && pParent->mpWindowImpl)
715 : {
716 808291 : if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
717 2944 : return true;
718 : else
719 805347 : pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
720 : }
721 84334 : return false;
722 : }
723 : }
724 :
725 3392 : void Window::SetAccessibilityEventsSuppressed(bool bSuppressed)
726 : {
727 3392 : mpWindowImpl->mbSuppressAccessibilityEvents = bSuppressed;
728 3392 : }
729 :
730 1233 : } /* namespace vcl */
731 :
732 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|