1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 #include <vos/mutex.hxx> 29 #include <vcl/image.hxx> 30 #include <vcl/menu.hxx> 31 32 #include <cppuhelper/compbase4.hxx> 33 #include <cppuhelper/compbase5.hxx> 34 #include <comphelper/broadcasthelper.hxx> 35 36 #include <com/sun/star/frame/XFrame.hpp> 37 #include <com/sun/star/accessibility/XAccessible.hpp> 38 #include <com/sun/star/accessibility/XAccessibleContext.hpp> 39 #include <com/sun/star/accessibility/XAccessibleComponent.hpp> 40 #include <com/sun/star/accessibility/XAccessibleSelection.hpp> 41 #include <com/sun/star/accessibility/XAccessibleEventBroadcaster.hpp> 42 #include <com/sun/star/lang/DisposedException.hpp> 43 44 #include <rtl/ref.hxx> 45 46 #include <vector> 47 48 #include "framestatuslistener.hxx" 49 50 #include "svtools/valueset.hxx" 51 52 namespace svtools { 53 54 struct ToolbarMenu_Impl; 55 class ToolbarMenu; 56 class ToolbarMenuEntry; 57 58 typedef ::std::vector< ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener > > EventListenerVector; 59 typedef std::vector< ToolbarMenuEntry * > ToolbarMenuEntryVector; 60 61 const int EXTRAITEMHEIGHT = 0; // 4; 62 const int SEPARATOR_HEIGHT = 4; 63 const int TITLE_ID = -1; 64 const int BORDER_X = 0; 65 const int BORDER_Y = 0; 66 67 // -------------------- 68 // - ToolbarMenuEntry - 69 // -------------------- 70 71 class ToolbarMenuEntry 72 { 73 public: 74 ToolbarMenu& mrMenu; 75 76 int mnEntryId; 77 MenuItemBits mnBits; 78 Size maSize; 79 80 bool mbHasText; 81 bool mbHasImage; 82 bool mbChecked; 83 bool mbEnabled; 84 85 String maText; 86 Image maImage; 87 Control* mpControl; 88 Rectangle maRect; 89 90 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > mxAccContext; 91 92 public: 93 ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const String& rText, MenuItemBits nBits ); 94 ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, MenuItemBits nBits ); 95 ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, const Image& rImage, const String& rText, MenuItemBits nBits ); 96 ToolbarMenuEntry( ToolbarMenu& rMenu, int nEntryId, Control* pControl, MenuItemBits nBits ); 97 ~ToolbarMenuEntry(); 98 99 void init( int nEntryId, MenuItemBits nBits ); 100 101 const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext >& GetAccessible( bool bCreate = false ); 102 103 sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); 104 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 105 void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 106 107 bool HasCheck() const 108 { 109 return mbChecked || ( mnBits & ( MIB_RADIOCHECK | MIB_CHECKABLE | MIB_AUTOCHECK ) ); 110 } 111 }; 112 113 // --------------- 114 // - ToolbarMenuAcc - 115 // --------------- 116 117 typedef ::cppu::WeakComponentImplHelper5< 118 ::com::sun::star::accessibility::XAccessible, 119 ::com::sun::star::accessibility::XAccessibleEventBroadcaster, 120 ::com::sun::star::accessibility::XAccessibleContext, 121 ::com::sun::star::accessibility::XAccessibleComponent, 122 ::com::sun::star::accessibility::XAccessibleSelection > 123 ToolbarMenuAccComponentBase; 124 125 class ToolbarMenuAcc : 126 public ::comphelper::OBaseMutex, 127 public ToolbarMenuAccComponentBase 128 { 129 public: 130 131 ToolbarMenuAcc( ToolbarMenu_Impl& rParent ); 132 ~ToolbarMenuAcc(); 133 134 void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); 135 bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); } 136 137 public: 138 // XAccessible 139 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); 140 141 // XAccessibleEventBroadcaster 142 using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::addEventListener; 143 virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); 144 using cppu::WeakComponentImplHelper5<com::sun::star::accessibility::XAccessible, com::sun::star::accessibility::XAccessibleEventBroadcaster, com::sun::star::accessibility::XAccessibleContext, com::sun::star::accessibility::XAccessibleComponent, com::sun::star::accessibility::XAccessibleSelection>::removeEventListener; 145 virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); 146 147 // XAccessibleContext 148 virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); 149 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 150 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException); 151 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); 152 virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException); 153 virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException); 154 virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); 155 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); 156 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException); 157 virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); 158 159 // XAccessibleComponent 160 virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); 161 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); 162 virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); 163 virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); 164 virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); 165 virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); 166 virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); 167 virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); 168 virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException); 169 virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException); 170 171 // XAccessibleSelection 172 virtual void SAL_CALL selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 173 virtual sal_Bool SAL_CALL isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 174 virtual void SAL_CALL clearAccessibleSelection( ) throw (::com::sun::star::uno::RuntimeException); 175 virtual void SAL_CALL selectAllAccessibleChildren( ) throw (::com::sun::star::uno::RuntimeException); 176 virtual sal_Int32 SAL_CALL getSelectedAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); 177 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getSelectedAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 178 virtual void SAL_CALL deselectAccessibleChild( sal_Int32 nSelectedChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 179 180 DECL_LINK( WindowEventListener, VclSimpleEvent* ); 181 182 private: 183 EventListenerVector mxEventListeners; 184 ToolbarMenu_Impl* mpParent; 185 /// The current FOCUSED state. 186 bool mbIsFocused; 187 188 void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent ); 189 190 /** Tell all listeners that the object is dying. This callback is 191 usually called from the WeakComponentImplHelper class. 192 */ 193 virtual void SAL_CALL disposing (void); 194 195 /** Check whether or not the object has been disposed (or is in the 196 state of beeing disposed). If that is the case then 197 DisposedException is thrown to inform the (indirect) caller of the 198 foul deed. 199 */ 200 void ThrowIfDisposed (void) throw (::com::sun::star::lang::DisposedException); 201 }; 202 203 // ----------------------- 204 // - ToolbarMenuEntryAcc - 205 // ----------------------- 206 207 typedef ::cppu::WeakComponentImplHelper4< ::com::sun::star::accessibility::XAccessible, 208 ::com::sun::star::accessibility::XAccessibleEventBroadcaster, 209 ::com::sun::star::accessibility::XAccessibleContext, 210 ::com::sun::star::accessibility::XAccessibleComponent > ToolbarMenuEntryAccBase; 211 212 class ToolbarMenuEntryAcc : public ::comphelper::OBaseMutex, 213 public ToolbarMenuEntryAccBase 214 { 215 public: 216 ToolbarMenuEntryAcc( ToolbarMenuEntry* pParent ); 217 ~ToolbarMenuEntryAcc(); 218 219 void FireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); 220 bool HasAccessibleListeners() const { return( mxEventListeners.size() > 0 ); } 221 222 // XAccessible 223 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleContext > SAL_CALL getAccessibleContext( ) throw (::com::sun::star::uno::RuntimeException); 224 225 // XAccessibleEventBroadcaster 226 using ToolbarMenuEntryAccBase::addEventListener; 227 virtual void SAL_CALL addEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); 228 using ToolbarMenuEntryAccBase::removeEventListener; 229 virtual void SAL_CALL removeEventListener( const ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleEventListener >& xListener ) throw (::com::sun::star::uno::RuntimeException); 230 231 // XAccessibleContext 232 virtual sal_Int32 SAL_CALL getAccessibleChildCount( ) throw (::com::sun::star::uno::RuntimeException); 233 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 234 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleParent( ) throw (::com::sun::star::uno::RuntimeException); 235 virtual sal_Int32 SAL_CALL getAccessibleIndexInParent( ) throw (::com::sun::star::uno::RuntimeException); 236 virtual sal_Int16 SAL_CALL getAccessibleRole( ) throw (::com::sun::star::uno::RuntimeException); 237 virtual ::rtl::OUString SAL_CALL getAccessibleDescription( ) throw (::com::sun::star::uno::RuntimeException); 238 virtual ::rtl::OUString SAL_CALL getAccessibleName( ) throw (::com::sun::star::uno::RuntimeException); 239 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleRelationSet > SAL_CALL getAccessibleRelationSet( ) throw (::com::sun::star::uno::RuntimeException); 240 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessibleStateSet > SAL_CALL getAccessibleStateSet( ) throw (::com::sun::star::uno::RuntimeException); 241 virtual ::com::sun::star::lang::Locale SAL_CALL getLocale( ) throw (::com::sun::star::accessibility::IllegalAccessibleComponentStateException, ::com::sun::star::uno::RuntimeException); 242 243 // XAccessibleComponent 244 virtual sal_Bool SAL_CALL containsPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); 245 virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const ::com::sun::star::awt::Point& aPoint ) throw (::com::sun::star::uno::RuntimeException); 246 virtual ::com::sun::star::awt::Rectangle SAL_CALL getBounds( ) throw (::com::sun::star::uno::RuntimeException); 247 virtual ::com::sun::star::awt::Point SAL_CALL getLocation( ) throw (::com::sun::star::uno::RuntimeException); 248 virtual ::com::sun::star::awt::Point SAL_CALL getLocationOnScreen( ) throw (::com::sun::star::uno::RuntimeException); 249 virtual ::com::sun::star::awt::Size SAL_CALL getSize( ) throw (::com::sun::star::uno::RuntimeException); 250 virtual void SAL_CALL grabFocus( ) throw (::com::sun::star::uno::RuntimeException); 251 virtual ::com::sun::star::uno::Any SAL_CALL getAccessibleKeyBinding( ) throw (::com::sun::star::uno::RuntimeException); 252 virtual sal_Int32 SAL_CALL getForeground( ) throw (::com::sun::star::uno::RuntimeException); 253 virtual sal_Int32 SAL_CALL getBackground( ) throw (::com::sun::star::uno::RuntimeException); 254 255 private: 256 EventListenerVector mxEventListeners; 257 ::vos::OMutex maMutex; 258 ToolbarMenuEntry* mpParent; 259 260 /** Tell all listeners that the object is dying. This callback is 261 usually called from the WeakComponentImplHelper class. 262 */ 263 virtual void SAL_CALL disposing (void); 264 }; 265 266 // ----------------------------------------------------------------------------- 267 268 struct ToolbarMenu_Impl 269 { 270 ToolbarMenu& mrMenu; 271 272 ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame > mxFrame; 273 rtl::Reference< svt::FrameStatusListener > mxStatusListener; 274 ::com::sun::star::uno::Reference< ::com::sun::star::lang::XMultiServiceFactory > mxServiceManager; 275 rtl::Reference< ToolbarMenuAcc > mxAccessible; 276 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > mxOldSelection; 277 278 ToolbarMenuEntryVector maEntryVector; 279 280 int mnCheckPos; 281 int mnImagePos; 282 int mnTextPos; 283 284 int mnHighlightedEntry; 285 int mnSelectedEntry; 286 int mnLastColumn; 287 288 Size maSize; 289 290 Link maSelectHdl; 291 292 ToolbarMenu_Impl( ToolbarMenu& rMenu, const ::com::sun::star::uno::Reference< ::com::sun::star::frame::XFrame >& xFrame ); 293 ~ToolbarMenu_Impl(); 294 295 void setAccessible( ToolbarMenuAcc* pAccessible ); 296 297 void fireAccessibleEvent( short nEventId, const ::com::sun::star::uno::Any& rOldValue, const ::com::sun::star::uno::Any& rNewValue ); 298 bool hasAccessibleListeners(); 299 300 sal_Int32 getAccessibleChildCount() throw (::com::sun::star::uno::RuntimeException); 301 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( sal_Int32 index ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 302 ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > getAccessibleChild( Control* pControl, sal_Int32 childIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 303 304 void selectAccessibleChild( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 305 sal_Bool isAccessibleChildSelected( sal_Int32 nChildIndex ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException); 306 void clearAccessibleSelection(); 307 308 ToolbarMenuEntry* implGetEntry( int nEntry ) const; 309 void notifyHighlightedEntry(); 310 311 void implHighlightControl( sal_uInt16 nCode, Control* pControl ); 312 }; 313 314 } 315