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