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 .
20 #include "AccessibleGlobal.hxx"
21 #include "AccessibleFilterMenu.hxx"
22 #include "AccessibleFilterMenuItem.hxx"
24 #include "docpool.hxx"
26 #include <tools/gen.hxx>
27 #include <editeng/unoedsrc.hxx>
28 #include <editeng/editdata.hxx>
29 #include <editeng/outliner.hxx>
30 #include <vcl/unohelp.hxx>
31 #include "checklistmenu.hxx"
33 #include <com/sun/star/accessibility/XAccessible.hpp>
34 #include <com/sun/star/accessibility/XAccessibleStateSet.hpp>
35 #include <com/sun/star/accessibility/AccessibleRole.hpp>
36 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
37 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
39 using namespace ::com::sun::star
;
40 using namespace ::com::sun::star::accessibility
;
41 using namespace ::com::sun::star::accessibility::AccessibleStateType
;
43 using ::com::sun::star::uno::Any
;
44 using ::com::sun::star::uno::Reference
;
45 using ::com::sun::star::uno::Sequence
;
46 using ::com::sun::star::uno::UNO_QUERY
;
47 using ::com::sun::star::lang::IndexOutOfBoundsException
;
48 using ::com::sun::star::lang::IllegalArgumentException
;
49 using ::com::sun::star::uno::RuntimeException
;
50 using ::std::for_each
;
55 class AddRemoveEventListener
: public ::std::unary_function
<void, Reference
<XAccessible
> >
58 explicit AddRemoveEventListener(const Reference
<XAccessibleEventListener
>& rListener
, bool bAdd
) :
59 mxListener(rListener
), mbAdd(bAdd
) {}
61 void operator() (const Reference
<XAccessible
>& xAccessible
) const
63 if (!xAccessible
.is())
66 Reference
<XAccessibleEventBroadcaster
> xBc(xAccessible
, UNO_QUERY
);
70 xBc
->addAccessibleEventListener(mxListener
);
72 xBc
->removeAccessibleEventListener(mxListener
);
76 Reference
<XAccessibleEventListener
> mxListener
;
82 ScAccessibleFilterMenu::ScAccessibleFilterMenu(const Reference
<XAccessible
>& rxParent
, ScMenuFloatingWindow
* pWin
, const OUString
& rName
, size_t nMenuPos
) :
83 ScAccessibleContextBase(rxParent
, AccessibleRole::MENU
),
91 ScAccessibleFilterMenu::~ScAccessibleFilterMenu()
95 // XAccessibleComponent
97 Reference
<XAccessible
> ScAccessibleFilterMenu::getAccessibleAtPoint( const ::com::sun::star::awt::Point
& /*rPoint*/ )
98 throw (RuntimeException
, std::exception
)
103 bool ScAccessibleFilterMenu::isVisible() throw (RuntimeException
, std::exception
)
105 return mpWindow
->IsVisible();
108 void ScAccessibleFilterMenu::grabFocus()
109 throw (RuntimeException
, std::exception
)
113 sal_Int32
ScAccessibleFilterMenu::getForeground()
114 throw (RuntimeException
, std::exception
)
119 sal_Int32
ScAccessibleFilterMenu::getBackground()
120 throw (RuntimeException
, std::exception
)
125 // XAccessibleContext
127 OUString
ScAccessibleFilterMenu::getAccessibleName() throw (RuntimeException
, std::exception
)
129 return ScAccessibleContextBase::getAccessibleName();
132 sal_Int32
ScAccessibleFilterMenu::getAccessibleChildCount()
133 throw (RuntimeException
, std::exception
)
135 return getMenuItemCount();
138 Reference
<XAccessible
> ScAccessibleFilterMenu::getAccessibleChild(sal_Int32 nIndex
)
139 throw (RuntimeException
, IndexOutOfBoundsException
, std::exception
)
141 if (maMenuItems
.size() <= static_cast<size_t>(nIndex
))
142 throw IndexOutOfBoundsException();
144 return maMenuItems
[nIndex
];
147 Reference
<XAccessibleStateSet
> ScAccessibleFilterMenu::getAccessibleStateSet()
148 throw (RuntimeException
, std::exception
)
154 OUString
ScAccessibleFilterMenu::getImplementationName()
155 throw (RuntimeException
, std::exception
)
157 return OUString("ScAccessibleFilterMenu");
160 // XAccessibleEventBroadcaster
162 void ScAccessibleFilterMenu::addAccessibleEventListener(
163 const ::com::sun::star::uno::Reference
<
164 ::com::sun::star::accessibility::XAccessibleEventListener
>& xListener
)
165 throw (com::sun::star::uno::RuntimeException
, std::exception
)
167 ScAccessibleContextBase::addAccessibleEventListener(xListener
);
168 for_each(maMenuItems
.begin(), maMenuItems
.end(), AddRemoveEventListener(xListener
, true));
171 void ScAccessibleFilterMenu::removeAccessibleEventListener(
172 const ::com::sun::star::uno::Reference
<
173 ::com::sun::star::accessibility::XAccessibleEventListener
>& xListener
)
174 throw (com::sun::star::uno::RuntimeException
, std::exception
)
176 ScAccessibleContextBase::removeAccessibleEventListener(xListener
);
177 for_each(maMenuItems
.begin(), maMenuItems
.end(), AddRemoveEventListener(xListener
, false));
180 // XAccessibleSelection
182 void ScAccessibleFilterMenu::selectAccessibleChild(sal_Int32 nChildIndex
)
183 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
185 if (static_cast<size_t>(nChildIndex
) >= maMenuItems
.size())
186 throw IndexOutOfBoundsException();
188 mpWindow
->setSelectedMenuItem(nChildIndex
, false, true);
191 sal_Bool
ScAccessibleFilterMenu::isAccessibleChildSelected(sal_Int32 nChildIndex
)
192 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
194 if (static_cast<size_t>(nChildIndex
) >= maMenuItems
.size())
195 throw IndexOutOfBoundsException();
197 return mpWindow
->isMenuItemSelected(static_cast<size_t>(nChildIndex
));
200 void ScAccessibleFilterMenu::clearAccessibleSelection() throw (RuntimeException
, std::exception
)
202 mpWindow
->clearSelectedMenuItem();
205 void ScAccessibleFilterMenu::selectAllAccessibleChildren() throw (RuntimeException
, std::exception
)
207 // not supported - this is a menu, you can't select all menu items.
210 sal_Int32
ScAccessibleFilterMenu::getSelectedAccessibleChildCount() throw (RuntimeException
, std::exception
)
212 // Since this is a menu, either one menu item is selected, or none at all.
213 return mpWindow
->getSelectedMenuItem() == ScMenuFloatingWindow::MENU_NOT_SELECTED
? 0 : 1;
216 Reference
<XAccessible
> ScAccessibleFilterMenu::getSelectedAccessibleChild(sal_Int32 nChildIndex
)
217 throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
219 if (static_cast<size_t>(nChildIndex
) >= maMenuItems
.size())
220 throw IndexOutOfBoundsException();
222 return maMenuItems
[nChildIndex
];
225 void ScAccessibleFilterMenu::deselectAccessibleChild(sal_Int32 nChildIndex
) throw (IndexOutOfBoundsException
, RuntimeException
, std::exception
)
227 if (static_cast<size_t>(nChildIndex
) >= maMenuItems
.size())
228 throw IndexOutOfBoundsException();
230 mpWindow
->selectMenuItem(nChildIndex
, false, false);
235 uno::Any SAL_CALL
ScAccessibleFilterMenu::queryInterface( uno::Type
const & rType
)
236 throw (RuntimeException
, std::exception
)
238 Any any
= ScAccessibleContextBase::queryInterface(rType
);
242 return ScAccessibleFilterMenu_BASE::queryInterface(rType
);
245 void SAL_CALL
ScAccessibleFilterMenu::acquire() throw ()
247 ScAccessibleContextBase::acquire();
250 void SAL_CALL
ScAccessibleFilterMenu::release() throw ()
252 ScAccessibleContextBase::release();
257 Sequence
<sal_Int8
> ScAccessibleFilterMenu::getImplementationId()
258 throw (RuntimeException
, std::exception
)
260 return css::uno::Sequence
<sal_Int8
>();
263 Rectangle
ScAccessibleFilterMenu::GetBoundingBoxOnScreen() const
264 throw (RuntimeException
, std::exception
)
266 if (mnMenuPos
== ScMenuFloatingWindow::MENU_NOT_SELECTED
)
269 // Menu object's bounding box is the bounding box of the menu item that
270 // launches the menu, which belongs to the parent window.
271 ScMenuFloatingWindow
* pParentWin
= mpWindow
->getParentMenuWindow();
275 if (!pParentWin
->IsVisible())
278 Point aPos
= pParentWin
->OutputToAbsoluteScreenPixel(Point(0,0));
281 pParentWin
->getMenuItemPosSize(mnMenuPos
, aMenuPos
, aMenuSize
);
282 Rectangle
aRect(aPos
+ aMenuPos
, aMenuSize
);
286 Rectangle
ScAccessibleFilterMenu::GetBoundingBox() const
287 throw (RuntimeException
, std::exception
)
289 if (mnMenuPos
== ScMenuFloatingWindow::MENU_NOT_SELECTED
)
292 // Menu object's bounding box is the bounding box of the menu item that
293 // launches the menu, which belongs to the parent window.
294 ScMenuFloatingWindow
* pParentWin
= mpWindow
->getParentMenuWindow();
298 if (!pParentWin
->IsVisible())
303 pParentWin
->getMenuItemPosSize(mnMenuPos
, aMenuPos
, aMenuSize
);
304 Rectangle
aRect(aMenuPos
, aMenuSize
);
308 void ScAccessibleFilterMenu::appendMenuItem(const OUString
& rName
, bool bEnabled
, size_t nMenuPos
)
310 // Check whether this menu item is a sub menu or a regular menu item.
311 ScMenuFloatingWindow
* pSubMenu
= mpWindow
->getSubMenuWindow(nMenuPos
);
312 Reference
<XAccessible
> xAccessible
;
315 xAccessible
= pSubMenu
->CreateAccessible();
316 ScAccessibleFilterMenu
* p
=
317 static_cast<ScAccessibleFilterMenu
*>(xAccessible
.get());
318 p
->setEnabled(bEnabled
);
319 p
->setMenuPos(nMenuPos
);
323 xAccessible
.set(new ScAccessibleFilterMenuItem(this, mpWindow
, rName
, nMenuPos
));
324 ScAccessibleFilterMenuItem
* p
=
325 static_cast<ScAccessibleFilterMenuItem
*>(xAccessible
.get());
326 p
->setEnabled(bEnabled
);
328 maMenuItems
.push_back(xAccessible
);
331 void ScAccessibleFilterMenu::setMenuPos(size_t nMenuPos
)
333 mnMenuPos
= nMenuPos
;
336 void ScAccessibleFilterMenu::setEnabled(bool bEnabled
)
338 mbEnabled
= bEnabled
;
341 sal_Int32
ScAccessibleFilterMenu::getMenuItemCount() const
343 return maMenuItems
.size();
346 bool ScAccessibleFilterMenu::isSelected() const
348 // Check to see if any of the child menu items is selected.
349 return mpWindow
->isMenuItemSelected(mnMenuPos
);
352 bool ScAccessibleFilterMenu::isFocused() const
357 void ScAccessibleFilterMenu::updateStates()
359 if (!mxStateSet
.is())
360 mxStateSet
.set(new ScAccessibleStateSet
);
362 ScAccessibleStateSet
* p
= static_cast<ScAccessibleStateSet
*>(
368 p
->insert(FOCUSABLE
);
369 p
->insert(SELECTABLE
);
370 p
->insert(SENSITIVE
);
380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */