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 17220 : ImplAccessibleInfos::ImplAccessibleInfos()
110 : {
111 17220 : nAccessibleRole = 0xFFFF;
112 17220 : pAccessibleName = NULL;
113 17220 : pAccessibleDescription = NULL;
114 17220 : pLabeledByWindow = NULL;
115 17220 : pLabelForWindow = NULL;
116 17220 : pMemberOfWindow = NULL;
117 17220 : }
118 :
119 34416 : ImplAccessibleInfos::~ImplAccessibleInfos()
120 : {
121 17208 : delete pAccessibleName;
122 17208 : delete pAccessibleDescription;
123 17208 : }
124 :
125 : namespace vcl {
126 :
127 3756 : ::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 3756 : if ( !mpWindowImpl )
140 0 : return css::uno::Reference< css::accessibility::XAccessible >();
141 3756 : if ( !mpWindowImpl->mxAccessible.is() && bCreate )
142 320 : mpWindowImpl->mxAccessible = CreateAccessible();
143 :
144 3756 : return mpWindowImpl->mxAccessible;
145 : }
146 :
147 272 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > Window::CreateAccessible()
148 : {
149 272 : ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > xAcc( GetComponentInterface( true ), ::com::sun::star::uno::UNO_QUERY );
150 272 : return xAcc;
151 : }
152 :
153 3232 : void Window::SetAccessible( ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > x )
154 : {
155 3232 : mpWindowImpl->mxAccessible = x;
156 3232 : }
157 :
158 : // skip all border windows that are no top level frames
159 834318 : bool Window::ImplIsAccessibleCandidate() const
160 : {
161 834318 : if( !mpWindowImpl->mbBorderWin )
162 758854 : return true;
163 : else
164 : // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
165 75464 : if( mpWindowImpl->mbFrame && mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE) )
166 19807 : return true;
167 : else
168 55657 : return false;
169 : }
170 :
171 860484 : bool Window::ImplIsAccessibleNativeFrame() const
172 : {
173 860484 : if( mpWindowImpl->mbFrame )
174 : // #101741 do not check for WB_CLOSEABLE because undecorated floaters (like menus!) are closeable
175 17612 : if( (mpWindowImpl->mnStyle & (WB_MOVEABLE | WB_SIZEABLE)) )
176 7305 : return true;
177 : else
178 10307 : return false;
179 : else
180 842872 : return false;
181 : }
182 :
183 0 : sal_uInt16 Window::ImplGetAccessibleCandidateChildWindowCount( GetWindowType nFirstWindowType ) const
184 : {
185 0 : sal_uInt16 nChildren = 0;
186 0 : vcl::Window* pChild = GetWindow( nFirstWindowType );
187 0 : while ( pChild )
188 : {
189 0 : if( pChild->ImplIsAccessibleCandidate() )
190 0 : nChildren++;
191 : else
192 0 : nChildren = sal::static_int_cast<sal_uInt16>(nChildren + pChild->ImplGetAccessibleCandidateChildWindowCount( GetWindowType::FirstChild ));
193 0 : pChild = pChild->mpWindowImpl->mpNext;
194 : }
195 0 : return nChildren;
196 : }
197 :
198 0 : vcl::Window* Window::ImplGetAccessibleCandidateChild( sal_uInt16 nChild, sal_uInt16& rChildCount, GetWindowType nFirstWindowType, bool bTopLevel ) const
199 : {
200 :
201 0 : if( bTopLevel )
202 0 : rChildCount = 0;
203 :
204 0 : vcl::Window* pChild = GetWindow( nFirstWindowType );
205 0 : while ( pChild )
206 : {
207 0 : vcl::Window *pTmpChild = pChild;
208 :
209 0 : if( !pChild->ImplIsAccessibleCandidate() )
210 0 : pTmpChild = pChild->ImplGetAccessibleCandidateChild( nChild, rChildCount, GetWindowType::FirstChild, false );
211 :
212 0 : if ( nChild == rChildCount )
213 0 : return pTmpChild;
214 0 : pChild = pChild->mpWindowImpl->mpNext;
215 0 : rChildCount++;
216 : }
217 :
218 0 : return NULL;
219 : }
220 :
221 591583 : vcl::Window* Window::GetAccessibleParentWindow() const
222 : {
223 591583 : if ( ImplIsAccessibleNativeFrame() )
224 3660 : return NULL;
225 :
226 587923 : vcl::Window* pParent = mpWindowImpl->mpParent;
227 587923 : if( GetType() == WINDOW_MENUBARWINDOW )
228 : {
229 : // report the menubar as a child of THE workwindow
230 6485 : vcl::Window *pWorkWin = GetParent()->mpWindowImpl->mpFirstChild;
231 14750 : while( pWorkWin && (pWorkWin == this) )
232 1780 : pWorkWin = pWorkWin->mpWindowImpl->mpNext;
233 6485 : pParent = pWorkWin;
234 : }
235 : // If this is a floating window which has a native border window, then that border should be reported as
236 : // the accessible parent, unless the floating window is a PopupMenuFloatingWindow
237 :
238 : // The logic here has to match that of AccessibleFactory::createAccessibleContext in
239 : // accessibility/source/helper/acc_factory.cxx to avoid PopupMenuFloatingWindow
240 : // becoming a11y parents of themselves
241 1169463 : else if( GetType() == WINDOW_FLOATINGWINDOW &&
242 581452 : mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame &&
243 7 : !PopupMenuFloatingWindow::isPopupMenu(this))
244 : {
245 7 : pParent = mpWindowImpl->mpBorderWindow;
246 : }
247 581431 : else if( pParent && !pParent->ImplIsAccessibleCandidate() )
248 : {
249 44872 : pParent = pParent->mpWindowImpl->mpParent;
250 : }
251 587923 : return pParent;
252 : }
253 :
254 1282 : sal_uInt16 Window::GetAccessibleChildWindowCount()
255 : {
256 1282 : sal_uInt16 nChildren = 0;
257 1282 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
258 10168 : while( pChild )
259 : {
260 7604 : if( pChild->IsVisible() )
261 4212 : nChildren++;
262 7604 : pChild = pChild->mpWindowImpl->mpNext;
263 : }
264 :
265 : // report the menubarwindow as a child of THE workwindow
266 1282 : if( GetType() == WINDOW_BORDERWINDOW )
267 : {
268 228 : ImplBorderWindow *pBorderWindow = static_cast<ImplBorderWindow*>(this);
269 456 : if( pBorderWindow->mpMenuBarWindow &&
270 456 : pBorderWindow->mpMenuBarWindow->IsVisible()
271 : )
272 228 : --nChildren;
273 : }
274 1054 : else if( GetType() == WINDOW_WORKWINDOW )
275 : {
276 286 : WorkWindow *pWorkWindow = static_cast<WorkWindow*>(this);
277 858 : if( pWorkWindow->GetMenuBar() &&
278 572 : pWorkWindow->GetMenuBar()->GetWindow() &&
279 286 : pWorkWindow->GetMenuBar()->GetWindow()->IsVisible()
280 : )
281 286 : ++nChildren;
282 : }
283 :
284 1282 : return nChildren;
285 : }
286 :
287 288 : vcl::Window* Window::GetAccessibleChildWindow( sal_uInt16 n )
288 : {
289 : // report the menubarwindow as a the first child of THE workwindow
290 288 : if( GetType() == WINDOW_WORKWINDOW && static_cast<WorkWindow *>(this)->GetMenuBar() )
291 : {
292 42 : if( n == 0 )
293 : {
294 14 : MenuBar *pMenuBar = static_cast<WorkWindow *>(this)->GetMenuBar();
295 14 : if( pMenuBar->GetWindow() && pMenuBar->GetWindow()->IsVisible() )
296 14 : return pMenuBar->GetWindow();
297 : }
298 : else
299 28 : --n;
300 : }
301 :
302 : // transform n to child number including invisible children
303 274 : sal_uInt16 nChildren = n;
304 274 : vcl::Window* pChild = mpWindowImpl->mpFirstChild;
305 1096 : while( pChild )
306 : {
307 822 : if( pChild->IsVisible() )
308 : {
309 518 : if( ! nChildren )
310 274 : break;
311 244 : nChildren--;
312 : }
313 548 : pChild = pChild->mpWindowImpl->mpNext;
314 : }
315 :
316 274 : if( GetType() == WINDOW_BORDERWINDOW && pChild && pChild->GetType() == WINDOW_MENUBARWINDOW )
317 : {
318 18 : do pChild = pChild->mpWindowImpl->mpNext; while( pChild && ! pChild->IsVisible() );
319 : DBG_ASSERT( pChild, "GetAccessibleChildWindow(): wrong index in border window");
320 : }
321 :
322 274 : if ( pChild && ( pChild->GetType() == WINDOW_BORDERWINDOW ) && ( pChild->GetChildCount() == 1 ) )
323 : {
324 26 : pChild = pChild->GetChild( 0 );
325 : }
326 274 : return pChild;
327 : }
328 :
329 6565 : void Window::SetAccessibleRole( sal_uInt16 nRole )
330 : {
331 6565 : if ( !mpWindowImpl->mpAccessibleInfos )
332 6565 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
333 :
334 : DBG_ASSERT( mpWindowImpl->mpAccessibleInfos->nAccessibleRole == 0xFFFF, "AccessibleRole already set!" );
335 6565 : mpWindowImpl->mpAccessibleInfos->nAccessibleRole = nRole;
336 6565 : }
337 :
338 2261 : sal_uInt16 Window::getDefaultAccessibleRole() const
339 : {
340 2261 : sal_uInt16 nRole = 0xFFFF;
341 2261 : switch ( GetType() )
342 : {
343 : case WINDOW_MESSBOX: // MT: Would be nice to have special roles!
344 : case WINDOW_INFOBOX:
345 : case WINDOW_WARNINGBOX:
346 : case WINDOW_ERRORBOX:
347 0 : case WINDOW_QUERYBOX: nRole = accessibility::AccessibleRole::ALERT; break;
348 :
349 : case WINDOW_MODELESSDIALOG:
350 : case WINDOW_MODALDIALOG:
351 : case WINDOW_SYSTEMDIALOG:
352 : case WINDOW_PRINTERSETUPDIALOG:
353 : case WINDOW_PRINTDIALOG:
354 : case WINDOW_TABDIALOG:
355 : case WINDOW_BUTTONDIALOG:
356 8 : case WINDOW_DIALOG: nRole = accessibility::AccessibleRole::DIALOG; break;
357 :
358 : case WINDOW_PUSHBUTTON:
359 : case WINDOW_OKBUTTON:
360 : case WINDOW_CANCELBUTTON:
361 : case WINDOW_HELPBUTTON:
362 : case WINDOW_IMAGEBUTTON:
363 : case WINDOW_MOREBUTTON:
364 : case WINDOW_SPINBUTTON:
365 0 : case WINDOW_BUTTON: nRole = accessibility::AccessibleRole::PUSH_BUTTON; break;
366 0 : case WINDOW_MENUBUTTON: nRole = accessibility::AccessibleRole::BUTTON_MENU; break;
367 :
368 0 : case WINDOW_PATHDIALOG: nRole = accessibility::AccessibleRole::DIRECTORY_PANE; break;
369 0 : case WINDOW_FILEDIALOG: nRole = accessibility::AccessibleRole::FILE_CHOOSER; break;
370 0 : case WINDOW_COLORDIALOG: nRole = accessibility::AccessibleRole::COLOR_CHOOSER; break;
371 0 : case WINDOW_FONTDIALOG: nRole = accessibility::AccessibleRole::FONT_CHOOSER; break;
372 :
373 45 : case WINDOW_RADIOBUTTON: nRole = accessibility::AccessibleRole::RADIO_BUTTON; break;
374 : case WINDOW_TRISTATEBOX:
375 9 : case WINDOW_CHECKBOX: nRole = accessibility::AccessibleRole::CHECK_BOX; break;
376 :
377 0 : case WINDOW_MULTILINEEDIT: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
378 :
379 : case WINDOW_PATTERNFIELD:
380 : case WINDOW_CALCINPUTLINE:
381 0 : case WINDOW_EDIT: nRole = ( GetStyle() & WB_PASSWORD ) ? (accessibility::AccessibleRole::PASSWORD_TEXT) : (accessibility::AccessibleRole::TEXT); break;
382 :
383 : case WINDOW_PATTERNBOX:
384 : case WINDOW_NUMERICBOX:
385 : case WINDOW_METRICBOX:
386 : case WINDOW_CURRENCYBOX:
387 : case WINDOW_LONGCURRENCYBOX:
388 0 : case WINDOW_COMBOBOX: nRole = accessibility::AccessibleRole::COMBO_BOX; break;
389 :
390 : case WINDOW_LISTBOX:
391 0 : case WINDOW_MULTILISTBOX: nRole = accessibility::AccessibleRole::LIST; break;
392 :
393 0 : case WINDOW_TREELISTBOX: nRole = accessibility::AccessibleRole::TREE; break;
394 :
395 12 : case WINDOW_FIXEDTEXT: nRole = accessibility::AccessibleRole::LABEL; break;
396 : case WINDOW_FIXEDLINE:
397 0 : if( !GetText().isEmpty() )
398 0 : nRole = accessibility::AccessibleRole::LABEL;
399 : else
400 0 : nRole = accessibility::AccessibleRole::SEPARATOR;
401 0 : break;
402 :
403 : case WINDOW_FIXEDBITMAP:
404 9 : case WINDOW_FIXEDIMAGE: nRole = accessibility::AccessibleRole::ICON; break;
405 0 : case WINDOW_GROUPBOX: nRole = accessibility::AccessibleRole::GROUP_BOX; break;
406 47 : case WINDOW_SCROLLBAR: nRole = accessibility::AccessibleRole::SCROLL_BAR; break;
407 :
408 : case WINDOW_SLIDER:
409 : case WINDOW_SPLITTER:
410 58 : case WINDOW_SPLITWINDOW: nRole = accessibility::AccessibleRole::SPLIT_PANE; break;
411 :
412 : case WINDOW_DATEBOX:
413 : case WINDOW_TIMEBOX:
414 : case WINDOW_DATEFIELD:
415 0 : case WINDOW_TIMEFIELD: nRole = accessibility::AccessibleRole::DATE_EDITOR; break;
416 :
417 : case WINDOW_NUMERICFIELD:
418 : case WINDOW_METRICFIELD:
419 : case WINDOW_CURRENCYFIELD:
420 : case WINDOW_LONGCURRENCYFIELD:
421 0 : case WINDOW_SPINFIELD: nRole = accessibility::AccessibleRole::SPIN_BOX; break;
422 :
423 55 : case WINDOW_TOOLBOX: nRole = accessibility::AccessibleRole::TOOL_BAR; break;
424 3 : case WINDOW_STATUSBAR: nRole = accessibility::AccessibleRole::STATUS_BAR; break;
425 :
426 0 : case WINDOW_TABPAGE: nRole = accessibility::AccessibleRole::PANEL; break;
427 0 : case WINDOW_TABCONTROL: nRole = accessibility::AccessibleRole::PAGE_TAB_LIST; break;
428 :
429 : case WINDOW_DOCKINGWINDOW:
430 : case WINDOW_SYSWINDOW: nRole = (mpWindowImpl->mbFrame) ? accessibility::AccessibleRole::FRAME :
431 74 : accessibility::AccessibleRole::PANEL; break;
432 :
433 0 : case WINDOW_FLOATINGWINDOW: nRole = ( mpWindowImpl->mbFrame ||
434 0 : (mpWindowImpl->mpBorderWindow && mpWindowImpl->mpBorderWindow->mpWindowImpl->mbFrame) ||
435 0 : (GetStyle() & WB_OWNERDRAWDECORATION) ) ? accessibility::AccessibleRole::FRAME :
436 0 : accessibility::AccessibleRole::WINDOW; break;
437 :
438 411 : case WINDOW_WORKWINDOW: nRole = accessibility::AccessibleRole::ROOT_PANE; break;
439 :
440 42 : case WINDOW_SCROLLBARBOX: nRole = accessibility::AccessibleRole::FILLER; break;
441 :
442 0 : case WINDOW_HELPTEXTWINDOW: nRole = accessibility::AccessibleRole::TOOL_TIP; break;
443 :
444 0 : case WINDOW_RULER: nRole = accessibility::AccessibleRole::RULER; break;
445 :
446 0 : case WINDOW_SCROLLWINDOW: nRole = accessibility::AccessibleRole::SCROLL_PANE; break;
447 :
448 : case WINDOW_WINDOW:
449 : case WINDOW_CONTROL:
450 : case WINDOW_BORDERWINDOW:
451 : case WINDOW_SYSTEMCHILDWINDOW:
452 : default:
453 1488 : if (ImplIsAccessibleNativeFrame() )
454 228 : nRole = accessibility::AccessibleRole::FRAME;
455 1260 : else if( IsScrollable() )
456 704 : nRole = accessibility::AccessibleRole::SCROLL_PANE;
457 556 : else if( const_cast<vcl::Window*>(this)->ImplGetWindow()->IsMenuFloatingWindow() )
458 0 : nRole = accessibility::AccessibleRole::WINDOW; // #106002#, contextmenus are windows (i.e. toplevel)
459 : else
460 : // #104051# WINDOW seems to be a bad default role, use LAYEREDPANE instead
461 : // a WINDOW is interpreted as a top-level window, which is typically not the case
462 : //nRole = accessibility::AccessibleRole::WINDOW;
463 556 : nRole = accessibility::AccessibleRole::PANEL;
464 : }
465 2261 : return nRole;
466 : }
467 :
468 2273 : sal_uInt16 Window::GetAccessibleRole() const
469 : {
470 : using namespace ::com::sun::star;
471 :
472 2273 : sal_uInt16 nRole = mpWindowImpl->mpAccessibleInfos ? mpWindowImpl->mpAccessibleInfos->nAccessibleRole : 0xFFFF;
473 2273 : if ( nRole == 0xFFFF )
474 2273 : nRole = getDefaultAccessibleRole();
475 2273 : return nRole;
476 : }
477 :
478 10198 : void Window::SetAccessibleName( const OUString& rName )
479 : {
480 10198 : if ( !mpWindowImpl->mpAccessibleInfos )
481 10198 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
482 :
483 10198 : OUString oldName = GetAccessibleName();
484 :
485 10198 : delete mpWindowImpl->mpAccessibleInfos->pAccessibleName;
486 10198 : mpWindowImpl->mpAccessibleInfos->pAccessibleName = new OUString( rName );
487 :
488 10198 : CallEventListeners( VCLEVENT_WINDOW_FRAMETITLECHANGED, &oldName );
489 10198 : }
490 :
491 10968 : OUString Window::GetAccessibleName() const
492 : {
493 10968 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleName)
494 40 : return *mpWindowImpl->mpAccessibleInfos->pAccessibleName;
495 10928 : return getDefaultAccessibleName();
496 : }
497 :
498 10928 : OUString Window::getDefaultAccessibleName() const
499 : {
500 10928 : OUString aAccessibleName;
501 10928 : switch ( GetType() )
502 : {
503 : case WINDOW_MULTILINEEDIT:
504 : case WINDOW_PATTERNFIELD:
505 : case WINDOW_NUMERICFIELD:
506 : case WINDOW_METRICFIELD:
507 : case WINDOW_CURRENCYFIELD:
508 : case WINDOW_LONGCURRENCYFIELD:
509 : case WINDOW_CALCINPUTLINE:
510 : case WINDOW_EDIT:
511 :
512 : case WINDOW_DATEBOX:
513 : case WINDOW_TIMEBOX:
514 : case WINDOW_CURRENCYBOX:
515 : case WINDOW_LONGCURRENCYBOX:
516 : case WINDOW_DATEFIELD:
517 : case WINDOW_TIMEFIELD:
518 : case WINDOW_SPINFIELD:
519 :
520 : case WINDOW_COMBOBOX:
521 : case WINDOW_LISTBOX:
522 : case WINDOW_MULTILISTBOX:
523 : case WINDOW_TREELISTBOX:
524 : case WINDOW_METRICBOX:
525 : {
526 5151 : vcl::Window *pLabel = GetAccessibleRelationLabeledBy();
527 5151 : if ( pLabel && pLabel != this )
528 459 : aAccessibleName = pLabel->GetText();
529 5151 : if (aAccessibleName.isEmpty())
530 4692 : aAccessibleName = GetQuickHelpText();
531 : }
532 5151 : break;
533 :
534 : case WINDOW_IMAGEBUTTON:
535 : case WINDOW_PUSHBUTTON:
536 1572 : aAccessibleName = GetText();
537 1572 : if (aAccessibleName.isEmpty())
538 : {
539 1572 : aAccessibleName = GetQuickHelpText();
540 1572 : if (aAccessibleName.isEmpty())
541 1572 : aAccessibleName = GetHelpText();
542 : }
543 1572 : break;
544 :
545 : case WINDOW_TOOLBOX:
546 344 : aAccessibleName = GetText();
547 344 : if( aAccessibleName.isEmpty() )
548 338 : aAccessibleName = "Tool Bar";
549 344 : break;
550 :
551 : case WINDOW_MOREBUTTON:
552 0 : aAccessibleName = mpWindowImpl->maText;
553 0 : break;
554 :
555 : default:
556 3861 : aAccessibleName = GetText();
557 3861 : break;
558 : }
559 :
560 10928 : return GetNonMnemonicString( aAccessibleName );
561 : }
562 :
563 3104 : void Window::SetAccessibleDescription( const OUString& rDescription )
564 : {
565 3104 : if ( ! mpWindowImpl->mpAccessibleInfos )
566 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
567 :
568 : DBG_ASSERT( !mpWindowImpl->mpAccessibleInfos->pAccessibleDescription, "AccessibleDescription already set!" );
569 3104 : delete mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
570 3104 : mpWindowImpl->mpAccessibleInfos->pAccessibleDescription = new OUString( rDescription );
571 3104 : }
572 :
573 919 : OUString Window::GetAccessibleDescription() const
574 : {
575 919 : OUString aAccessibleDescription;
576 919 : if ( mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pAccessibleDescription )
577 : {
578 84 : aAccessibleDescription = *mpWindowImpl->mpAccessibleInfos->pAccessibleDescription;
579 : }
580 : else
581 : {
582 : // Special code for help text windows. ZT asks the border window for the
583 : // description so we have to forward this request to our inner window.
584 835 : const vcl::Window* pWin = const_cast<vcl::Window *>(this)->ImplGetWindow();
585 835 : if ( pWin->GetType() == WINDOW_HELPTEXTWINDOW )
586 0 : aAccessibleDescription = pWin->GetHelpText();
587 : else
588 835 : aAccessibleDescription = GetHelpText();
589 : }
590 :
591 919 : return aAccessibleDescription;
592 : }
593 :
594 772 : void Window::SetAccessibleRelationLabeledBy( vcl::Window* pLabeledBy )
595 : {
596 772 : if ( !mpWindowImpl->mpAccessibleInfos )
597 457 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
598 772 : mpWindowImpl->mpAccessibleInfos->pLabeledByWindow = pLabeledBy;
599 772 : }
600 :
601 0 : void Window::SetAccessibleRelationLabelFor( vcl::Window* pLabelFor )
602 : {
603 0 : if ( !mpWindowImpl->mpAccessibleInfos )
604 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
605 0 : mpWindowImpl->mpAccessibleInfos->pLabelForWindow = pLabelFor;
606 0 : }
607 :
608 0 : void Window::SetAccessibleRelationMemberOf( vcl::Window* pMemberOfWin )
609 : {
610 0 : if ( !mpWindowImpl->mpAccessibleInfos )
611 0 : mpWindowImpl->mpAccessibleInfos = new ImplAccessibleInfos;
612 0 : mpWindowImpl->mpAccessibleInfos->pMemberOfWindow = pMemberOfWin;
613 0 : }
614 :
615 5 : vcl::Window* Window::GetAccessibleRelationMemberOf() const
616 : {
617 5 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pMemberOfWindow)
618 0 : return mpWindowImpl->mpAccessibleInfos->pMemberOfWindow;
619 :
620 5 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
621 5 : return getLegacyNonLayoutAccessibleRelationMemberOf();
622 :
623 0 : return NULL;
624 : }
625 :
626 11061 : vcl::Window* Window::getAccessibleRelationLabelFor() const
627 : {
628 11061 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabelForWindow)
629 0 : return mpWindowImpl->mpAccessibleInfos->pLabelForWindow;
630 :
631 11061 : return NULL;
632 : }
633 :
634 11061 : vcl::Window* Window::GetAccessibleRelationLabelFor() const
635 : {
636 11061 : vcl::Window* pWindow = getAccessibleRelationLabelFor();
637 :
638 11061 : if (pWindow)
639 0 : return pWindow;
640 :
641 11061 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
642 11059 : return getLegacyNonLayoutAccessibleRelationLabelFor();
643 :
644 2 : return NULL;
645 : }
646 :
647 5156 : vcl::Window* Window::GetAccessibleRelationLabeledBy() const
648 : {
649 5156 : if (mpWindowImpl->mpAccessibleInfos && mpWindowImpl->mpAccessibleInfos->pLabeledByWindow)
650 0 : return mpWindowImpl->mpAccessibleInfos->pLabeledByWindow;
651 :
652 5156 : std::vector<VclPtr<FixedText> > aMnemonicLabels(list_mnemonic_labels());
653 5156 : if (!aMnemonicLabels.empty())
654 : {
655 : //if we have multiple labels, then prefer the first that is visible
656 459 : for (auto aI = aMnemonicLabels.begin(), aEnd = aMnemonicLabels.end(); aI != aEnd; ++aI)
657 : {
658 459 : vcl::Window *pCandidate = *aI;
659 459 : if (pCandidate->IsVisible())
660 459 : return pCandidate;
661 : }
662 0 : return aMnemonicLabels[0];
663 : }
664 :
665 4697 : if (!isContainerWindow(this) && !isContainerWindow(GetParent()))
666 2697 : return getLegacyNonLayoutAccessibleRelationLabeledBy();
667 :
668 2000 : return NULL;
669 : }
670 :
671 54136 : bool Window::IsAccessibilityEventsSuppressed( bool bTraverseParentPath )
672 : {
673 54136 : if( !bTraverseParentPath )
674 1311 : return mpWindowImpl->mbSuppressAccessibilityEvents;
675 : else
676 : {
677 52825 : vcl::Window *pParent = this;
678 599229 : while ( pParent && pParent->mpWindowImpl)
679 : {
680 494685 : if( pParent->mpWindowImpl->mbSuppressAccessibilityEvents )
681 1106 : return true;
682 : else
683 493579 : pParent = pParent->mpWindowImpl->mpParent; // do not use GetParent() to find borderwindows that are frames
684 : }
685 51719 : return false;
686 : }
687 : }
688 :
689 2622 : void Window::SetAccessibilityEventsSuppressed(bool bSuppressed)
690 : {
691 2622 : mpWindowImpl->mbSuppressAccessibilityEvents = bSuppressed;
692 2622 : }
693 :
694 801 : } /* namespace vcl */
695 :
696 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|