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(
69 reinterpret_cast<sal_Int64
>(systemdata
->hWnd
), pAccessible
);
71 AddAllListeners(pAccessible
,nullptr,systemdata
->hWnd
);
73 if( window
->GetStyle() & WB_MOVEABLE
)
74 accManagerAgent
.IncreaseState( pAccessible
, static_cast<unsigned short>(-1) /* U_MOVEBLE */ );
76 short role
= pAccessibleContext
->getAccessibleRole();
78 if (role
== css::accessibility::AccessibleRole::POPUP_MENU
||
79 role
== css::accessibility::AccessibleRole::MENU
)
81 accManagerAgent
.NotifyAccEvent(UM_EVENT_MENUPOPUPSTART
, pAccessible
);
84 if (role
== css::accessibility::AccessibleRole::FRAME
||
85 role
== css::accessibility::AccessibleRole::DIALOG
||
86 role
== css::accessibility::AccessibleRole::WINDOW
||
87 role
== css::accessibility::AccessibleRole::ALERT
)
89 accManagerAgent
.NotifyAccEvent(UM_EVENT_SHOW
, pAccessible
);
94 AccTopWindowListener::AccTopWindowListener()
99 AccTopWindowListener::~AccTopWindowListener()
104 * It is invoked when a new window is opened, the source of this EventObject is the window
106 void AccTopWindowListener::windowOpened( const css::lang::EventObject
& e
)
108 SAL_INFO( "iacc2", "windowOpened triggered" );
113 Reference
< css::accessibility::XAccessible
> xAccessible ( e
.Source
, UNO_QUERY
);
114 css::accessibility::XAccessible
* pAccessible
= xAccessible
.get();
120 HandleWindowOpened( pAccessible
);
124 * Add the accessible event listener to object and all its children objects.
125 * @param pAccessible the accessible object
126 * @param pParentXAcc the parent of current accessible object
127 * @param pWND the handle of top window which current object resides
129 void AccTopWindowListener::AddAllListeners(css::accessibility::XAccessible
* pAccessible
, css::accessibility::XAccessible
* pParentXAcc
, HWND pWND
)
131 Reference
<css::accessibility::XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
136 css::accessibility::XAccessibleContext
* pAccessibleContext
= xContext
.get();
137 if(pAccessibleContext
== nullptr)
142 accManagerAgent
.InsertAccObj(pAccessible
, pParentXAcc
,
143 reinterpret_cast<sal_Int64
>(pWND
));
145 if (!accManagerAgent
.IsContainer(pAccessible
))
151 short role
= pAccessibleContext
->getAccessibleRole();
152 if(css::accessibility::AccessibleRole::DOCUMENT
== role
||
153 css::accessibility::AccessibleRole::DOCUMENT_PRESENTATION
== role
||
154 css::accessibility::AccessibleRole::DOCUMENT_SPREADSHEET
== role
||
155 css::accessibility::AccessibleRole::DOCUMENT_TEXT
== role
)
157 if(accManagerAgent
.IsStateManageDescendant(pAccessible
))
164 int count
= pAccessibleContext
->getAccessibleChildCount();
165 for (int i
=0;i
<count
;i
++)
167 Reference
<css::accessibility::XAccessible
> mxAccessible
168 = pAccessibleContext
->getAccessibleChild(i
);
170 css::accessibility::XAccessible
* mpAccessible
= mxAccessible
.get();
171 if(mpAccessible
!= nullptr)
173 Reference
<css::accessibility::XAccessibleContext
> mxAccessibleContext
174 = mpAccessible
->getAccessibleContext();
175 css::accessibility::XAccessibleContext
* mpContext
= mxAccessibleContext
.get();
176 if(mpContext
!= nullptr)
177 AddAllListeners( mpAccessible
, pAccessible
, pWND
);
182 void AccTopWindowListener::windowClosing( const css::lang::EventObject
& )
184 SAL_INFO( "iacc2", "windowClosing triggered" );
188 * Invoke this method when the top window is closed, remove all the objects and its children
189 * from current manager's cache, and remove the COM object and the accessible event listener
190 * assigned to the accessible objects.
192 void AccTopWindowListener::windowClosed( const css::lang::EventObject
& e
)
194 SAL_INFO( "iacc2", "windowClosed triggered" );
199 Reference
< css::accessibility::XAccessible
> xAccessible ( e
.Source
, UNO_QUERY
);
200 css::accessibility::XAccessible
* pAccessible
= xAccessible
.get();
201 if ( pAccessible
== nullptr)
204 Reference
<css::accessibility::XAccessibleContext
> xContext
= pAccessible
->getAccessibleContext();
209 css::accessibility::XAccessibleContext
* pAccessibleContext
= xContext
.get();
212 if(pAccessibleContext
!= nullptr)
214 role
= pAccessibleContext
->getAccessibleRole();
216 if (role
== css::accessibility::AccessibleRole::POPUP_MENU
||
217 role
== css::accessibility::AccessibleRole::MENU
)
219 accManagerAgent
.NotifyAccEvent(UM_EVENT_MENUPOPUPEND
, pAccessible
);
224 accManagerAgent
.DeleteChildrenAccObj( pAccessible
);
225 if( role
!= css::accessibility::AccessibleRole::POPUP_MENU
)
226 accManagerAgent
.DeleteAccObj( pAccessible
);
230 void AccTopWindowListener::windowMinimized( const css::lang::EventObject
& )
234 void AccTopWindowListener::windowNormalized( const css::lang::EventObject
& )
238 void AccTopWindowListener::windowActivated( const css::lang::EventObject
& )
242 void AccTopWindowListener::windowDeactivated( const css::lang::EventObject
& )
246 void AccTopWindowListener::disposing( const css::lang::EventObject
& )
250 sal_Int64
AccTopWindowListener::GetMSComPtr(
251 sal_Int64 hWnd
, sal_Int64 lParam
, sal_Int64 wParam
)
253 return accManagerAgent
.Get_ToATInterface(hWnd
, lParam
, wParam
);
256 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */