1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ 2 /* 3 * This file is part of the LibreOffice project. 4 * 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/. 8 * 9 * This file incorporates work covered by the following license notice: 10 * 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 . 18 */ 19 20 #ifndef INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX 21 #define INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX 22 23 #include <memory> 24 #include <tools/gen.hxx> 25 #include <cppuhelper/implbase2.hxx> 26 #include <com/sun/star/uno/Reference.hxx> 27 #include <com/sun/star/accessibility/XAccessibleText.hpp> 28 #include <com/sun/star/accessibility/XAccessibleTextAttributes.hpp> 29 #include <com/sun/star/accessibility/TextSegment.hpp> 30 #include <editeng/editengdllapi.h> 31 32 namespace com::sun::star::accessibility { class XAccessible; } 33 34 class SvxEditSource; 35 36 namespace accessibility 37 { 38 39 class AccessibleStaticTextBase_Impl; 40 41 typedef ::cppu::ImplHelper2< 42 css::accessibility::XAccessibleText, 43 css::accessibility::XAccessibleTextAttributes > AccessibleStaticTextBase_BASE; 44 45 /** Helper class for objects containing EditEngine/Outliner text 46 47 This class implements the XAccessibleText interface for static 48 text, somewhat similar to the children of the 49 AccessibleTextHelper class. Currently, there are no children, 50 i.e. the whole text is presented in one big chunk. This might 51 change in the future, if a need for image bullets should 52 arise. These, by convention, would be represented as children 53 of the text. 54 55 You have to implement the SvxEditSource, SvxTextForwarder, 56 SvxViewForwarder and SvxEditViewForwarder interfaces in order 57 to enable your object to cooperate with this 58 class. SvxTextForwarder encapsulates the fact that text 59 objects do not necessarily have an EditEngine at their 60 disposal, SvxViewForwarder and SvxEditViewForwarder do the 61 same for the document and the edit view. The three mentioned 62 forwarder objects are not stored by the AccessibleTextHelper, 63 but fetched every time from the SvxEditSource. So you are best 64 off making your SvxEditSource::Get*Forwarder methods cache the 65 current forwarder. 66 67 As this class is intended for static (i.e. non-changing) text 68 only, no event broadcasting is necessary. You must handle 69 visibility by yourself, the bounding boxes returned by 70 getCharacterBounds() are relative to your accessibility 71 object. 72 73 @attention All public non-UNO methods (those are the uppercase 74 ones) must not be called with any mutex hold, except when 75 calling from the main thread (with holds the solar mutex), 76 unless stated otherwise. This is because they themselves might 77 need the solar mutex in addition to the object mutex, and the 78 ordering of the locking must be: first solar mutex, then 79 object mutex. Furthermore, state change events might be fired 80 internally. 81 82 @derive Use this class as a base for objects containing static 83 edit engine text. To avoid overwriting every interface method 84 to intercept derived object defunc state, just set NULL as the 85 edit source. Every interface method will then properly throw 86 an exception. 87 */ 88 class EDITENG_DLLPUBLIC AccessibleStaticTextBase : public AccessibleStaticTextBase_BASE 89 { 90 91 public: 92 /** Create accessible text object for given edit source 93 94 @param pEditSource 95 The edit source to use. Object ownership is transferred 96 from the caller to the callee. The object listens on the 97 SvxEditSource for object disposal, so no provisions have 98 to be taken if the caller destroys the data (e.g. the 99 model) contained in the given SvxEditSource. 100 101 */ 102 explicit AccessibleStaticTextBase( ::std::unique_ptr< SvxEditSource > && pEditSource ); 103 104 virtual ~AccessibleStaticTextBase(); 105 106 private: 107 AccessibleStaticTextBase( const AccessibleStaticTextBase& ) = delete; 108 AccessibleStaticTextBase& operator= ( const AccessibleStaticTextBase& ) = delete; 109 110 public: 111 112 /** Set the current edit source 113 114 @attention You are required to have the solar mutex 115 locked, when calling this method. Thus, the method should 116 only be called from the main office thread. 117 118 The EditSource set here is required to broadcast out the 119 following hints: SfxHintId::EditSourceParasMoved, 120 SfxHintId::EditSourceSelectionChanged, SfxHintId::TextModified, 121 SfxHintId::TextParaInserted, SfxHintId::TextParaRemoved, 122 SfxHintId::TextHeightChanged, 123 SfxHintId::TextViewScrolled. Otherwise, not all state changes 124 will get noticed by the accessibility object. Further 125 more, when the corresponding core object or the model is 126 dying, either the edit source must be set to NULL or it 127 has to broadcast a SfxHintId::Dying hint. 128 129 This class does not have a dispose method, since it is not 130 a UNO component. Nevertheless, it holds C++ references to 131 several core objects, so you should issue a 132 SetEditSource(::std::unique_ptr<SvxEditSource>()) in 133 your dispose() method. 134 135 @param pEditSource 136 The new edit source to set. Object ownership is transferred 137 from the caller to the callee. 138 */ 139 void SetEditSource( ::std::unique_ptr< SvxEditSource > && pEditSource ); 140 141 /** Set the event source 142 143 @attention When setting a reference here, you should call 144 Dispose() when you as the owner are disposing, since until 145 then this object will hold that reference 146 147 @param rInterface 148 The interface that should be set as the source for 149 accessibility events sent by this object. 150 */ 151 void SetEventSource( const css::uno::Reference< css::accessibility::XAccessible >& rInterface ); 152 153 /** Set offset of EditEngine from parent 154 155 @attention You are required to have the solar mutex 156 locked, when calling this method. Thus, the method should 157 only be called from the main office thread. 158 159 If the origin of the underlying EditEngine does 160 not correspond to the upper left corner of the object 161 using this class, you have to specify the offset. 162 163 @param rPoint 164 The offset in screen coordinates (i.e. pixel) 165 */ 166 void SetOffset( const Point& rPoint ); 167 168 /** Drop all references and enter disposed state 169 170 This method drops all references to external objects (also 171 the event source reference set via SetEventSource()) and 172 sets the object into the disposed state (i.e. the methods 173 return default values or throw a uno::DisposedException 174 exception). 175 */ 176 void Dispose(); 177 178 // XAccessibleText interface implementation 179 virtual sal_Int32 SAL_CALL getCaretPosition() override; 180 virtual sal_Bool SAL_CALL setCaretPosition( sal_Int32 nIndex ) override; 181 virtual sal_Unicode SAL_CALL getCharacter( sal_Int32 nIndex ) override; 182 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getCharacterAttributes( sal_Int32 nIndex, const css::uno::Sequence< OUString >& aRequestedAttributes ) override; 183 virtual css::awt::Rectangle SAL_CALL getCharacterBounds( sal_Int32 nIndex ) override; 184 virtual sal_Int32 SAL_CALL getCharacterCount() override; 185 virtual sal_Int32 SAL_CALL getIndexAtPoint( const css::awt::Point& aPoint ) override; 186 virtual OUString SAL_CALL getSelectedText() override; 187 virtual sal_Int32 SAL_CALL getSelectionStart() override; 188 virtual sal_Int32 SAL_CALL getSelectionEnd() override; 189 /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode 190 virtual sal_Bool SAL_CALL setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; 191 virtual OUString SAL_CALL getText() override; 192 virtual OUString SAL_CALL getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; 193 /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) 194 virtual css::accessibility::TextSegment SAL_CALL getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; 195 /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) 196 virtual css::accessibility::TextSegment SAL_CALL getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; 197 /// Does not support AccessibleTextType::SENTENCE (missing feature in EditEngine) 198 virtual css::accessibility::TextSegment SAL_CALL getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) override; 199 /// This will only work with a functional SvxEditViewForwarder, i.e. an EditEngine/Outliner in edit mode 200 virtual sal_Bool SAL_CALL copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) override; 201 202 // XAccessibleTextAttributes 203 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getDefaultAttributes( const css::uno::Sequence< OUString >& RequestedAttributes ) override; 204 virtual css::uno::Sequence< css::beans::PropertyValue > SAL_CALL getRunAttributes( sal_Int32 Index, const css::uno::Sequence< OUString >& RequestedAttributes ) override; 205 206 // child-related methods from XAccessibleContext 207 /// @throws css::uno::RuntimeException 208 virtual sal_Int32 SAL_CALL getAccessibleChildCount(); 209 /// @throws css::lang::IndexOutOfBoundsException 210 /// @throws css::uno::RuntimeException 211 virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleChild( sal_Int32 i ); 212 213 // child-related methods from XAccessibleComponent 214 /// @throws css::uno::RuntimeException 215 virtual css::uno::Reference< css::accessibility::XAccessible > SAL_CALL getAccessibleAtPoint( const css::awt::Point& aPoint ); 216 217 protected: 218 tools::Rectangle GetParagraphBoundingBox() const; 219 220 private: 221 222 /// @dyn 223 const std::unique_ptr< AccessibleStaticTextBase_Impl > mpImpl; 224 225 }; 226 227 } // end of namespace accessibility 228 229 #endif // INCLUDED_EDITENG_ACCESSIBLESTATICTEXTBASE_HXX 230 231 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 232