1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
21 #include <sal/log.hxx>
22 #include <vcl/window.hxx>
23 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
24 #include <toolkit/awt/vclxwindow.hxx>
26 #include <vcl/sysdata.hxx>
27 #include <vcl/svapp.hxx>
29 #include <AccTopWindowListener.hxx>
30 #include <unomsaaevent.hxx>
32 #include <com/sun/star/accessibility/AccessibleRole.hpp>
34 using namespace com::sun::star::uno
;
37 * For the new opened window, generate all the UNO accessible's object, COM object and add
38 * accessible listener to monitor all these objects.
39 * @param pAccessible the accessible of the new opened window
41 void AccTopWindowListener::HandleWindowOpened( css::accessibility::XAccessible
* pAccessible
)
43 //get SystemData from window
44 VclPtr
<vcl::Window
> window
;
45 if (auto pvclwindow
= dynamic_cast<VCLXWindow
*>(pAccessible
))
46 window
= pvclwindow
->GetWindow();
47 else if (auto pvclxcomponent
= dynamic_cast<VCLXAccessibleComponent
*>(pAccessible
))
48 window
= pvclxcomponent
->GetWindow();
50 // The SalFrame of window may be destructed at this time
51 const SystemEnvData
* systemdata
= nullptr;
54 systemdata
= window
->GetSystemData();
60 Reference
<css::accessibility::XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
64 css::accessibility::XAccessibleContext
* pAccessibleContext
= xContext
.get();
65 //Only AccessibleContext exist, add all listeners
66 if(pAccessibleContext
!= nullptr && systemdata
!= nullptr)
68 accManagerAgent
.SaveTopWindowHandle(systemdata
->hWnd
, pAccessible
);
70 AddAllListeners(pAccessible
,nullptr,systemdata
->hWnd
);
72 if( window
->GetStyle() & WB_MOVEABLE
)
73 accManagerAgent
.IncreaseState( pAccessible
, static_cast<unsigned short>(-1) /* U_MOVEBLE */ );
75 short role
= pAccessibleContext
->getAccessibleRole();
77 if (role
== css::accessibility::AccessibleRole::POPUP_MENU
||
78 role
== css::accessibility::AccessibleRole::MENU
)
80 accManagerAgent
.NotifyAccEvent(UnoMSAAEvent::MENUPOPUPSTART
, pAccessible
);
83 if (role
== css::accessibility::AccessibleRole::FRAME
||
84 role
== css::accessibility::AccessibleRole::DIALOG
||
85 role
== css::accessibility::AccessibleRole::WINDOW
||
86 role
== css::accessibility::AccessibleRole::ALERT
)
88 accManagerAgent
.NotifyAccEvent(UnoMSAAEvent::SHOW
, pAccessible
);
93 AccTopWindowListener::AccTopWindowListener()
98 AccTopWindowListener::~AccTopWindowListener()
103 * It is invoked when a new window is opened, the source of this EventObject is the window
105 void AccTopWindowListener::windowOpened( const css::lang::EventObject
& e
)
107 SAL_INFO( "iacc2", "windowOpened triggered" );
112 Reference
< css::accessibility::XAccessible
> xAccessible ( e
.Source
, UNO_QUERY
);
113 css::accessibility::XAccessible
* pAccessible
= xAccessible
.get();
119 HandleWindowOpened( pAccessible
);
123 * Add the accessible event listener to object and all its children objects.
124 * @param pAccessible the accessible object
125 * @param pParentXAcc the parent of current accessible object
126 * @param pWND the handle of top window which current object resides
128 void AccTopWindowListener::AddAllListeners(css::accessibility::XAccessible
* pAccessible
, css::accessibility::XAccessible
* pParentXAcc
, HWND pWND
)
130 Reference
<css::accessibility::XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
135 css::accessibility::XAccessibleContext
* pAccessibleContext
= xContext
.get();
136 if(pAccessibleContext
== nullptr)
141 accManagerAgent
.InsertAccObj(pAccessible
, pParentXAcc
, pWND
);
143 if (!accManagerAgent
.IsContainer(pAccessible
))
149 short role
= pAccessibleContext
->getAccessibleRole();
150 if(css::accessibility::AccessibleRole::DOCUMENT
== role
||
151 css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
152 css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
153 css::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
155 if(accManagerAgent
.IsStateManageDescendant(pAccessible
))
161 sal_Int64 nCount
= pAccessibleContext
->getAccessibleChildCount();
162 for (sal_Int64 i
= 0; i
< nCount
; i
++)
164 Reference
<css::accessibility::XAccessible
> mxAccessible
165 = pAccessibleContext
->getAccessibleChild(i
);
167 css::accessibility::XAccessible
* mpAccessible
= mxAccessible
.get();
168 if(mpAccessible
!= nullptr)
170 Reference
<css::accessibility::XAccessibleContext
> mxAccessibleContext
171 = mpAccessible
->getAccessibleContext();
172 css::accessibility::XAccessibleContext
* mpContext
= mxAccessibleContext
.get();
173 if(mpContext
!= nullptr)
174 AddAllListeners( mpAccessible
, pAccessible
, pWND
);
179 void AccTopWindowListener::windowClosing( const css::lang::EventObject
& )
181 SAL_INFO( "iacc2", "windowClosing triggered" );
185 * Invoke this method when the top window is closed, remove all the objects and its children
186 * from current manager's cache, and remove the COM object and the accessible event listener
187 * assigned to the accessible objects.
189 void AccTopWindowListener::windowClosed( const css::lang::EventObject
& e
)
191 SAL_INFO( "iacc2", "windowClosed triggered" );
196 Reference
< css::accessibility::XAccessible
> xAccessible ( e
.Source
, UNO_QUERY
);
197 css::accessibility::XAccessible
* pAccessible
= xAccessible
.get();
198 if ( pAccessible
== nullptr)
201 Reference
<css::accessibility::XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
206 css::accessibility::XAccessibleContext
* pAccessibleContext
= xContext
.get();
209 if(pAccessibleContext
!= nullptr)
211 role
= pAccessibleContext
->getAccessibleRole();
213 if (role
== css::accessibility::AccessibleRole::POPUP_MENU
||
214 role
== css::accessibility::AccessibleRole::MENU
)
216 accManagerAgent
.NotifyAccEvent(UnoMSAAEvent::MENUPOPUPEND
, pAccessible
);
221 accManagerAgent
.DeleteChildrenAccObj( pAccessible
);
222 if( role
!= css::accessibility::AccessibleRole::POPUP_MENU
)
223 accManagerAgent
.DeleteAccObj( pAccessible
);
227 void AccTopWindowListener::windowMinimized( const css::lang::EventObject
& )
231 void AccTopWindowListener::windowNormalized( const css::lang::EventObject
& )
235 void AccTopWindowListener::windowActivated( const css::lang::EventObject
& )
239 void AccTopWindowListener::windowDeactivated( const css::lang::EventObject
& )
243 void AccTopWindowListener::disposing( const css::lang::EventObject
& )
247 sal_Int64
AccTopWindowListener::GetMSComPtr(
248 sal_Int64 hWnd
, sal_Int64 lParam
, sal_Int64 wParam
)
250 return accManagerAgent
.Get_ToATInterface(hWnd
, lParam
, wParam
);
253 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */