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 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_accessibility.hxx"
26 #include <accessibility/standard/vclxaccessibletextcomponent.hxx>
27 #include <toolkit/helper/macros.hxx>
28 #include <toolkit/helper/convert.hxx>
29 #include <accessibility/helper/characterattributeshelper.hxx>
30
31 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
32 #include <com/sun/star/datatransfer/clipboard/XClipboard.hpp>
33 #include <com/sun/star/datatransfer/clipboard/XFlushableClipboard.hpp>
34 #include <cppuhelper/typeprovider.hxx>
35 #include <comphelper/sequence.hxx>
36 #include <vcl/window.hxx>
37 #include <vcl/svapp.hxx>
38 #include <vcl/unohelp2.hxx>
39 #include <vcl/ctrl.hxx>
40
41 #include <memory>
42 #include <vector>
43
44 using namespace ::com::sun::star;
45 using namespace ::com::sun::star::uno;
46 using namespace ::com::sun::star::lang;
47 using namespace ::com::sun::star::beans;
48 using namespace ::com::sun::star::accessibility;
49 using namespace ::comphelper;
50
51
52 // ----------------------------------------------------
53 // class VCLXAccessibleTextComponent
54 // ----------------------------------------------------
55
VCLXAccessibleTextComponent(VCLXWindow * pVCLXWindow)56 VCLXAccessibleTextComponent::VCLXAccessibleTextComponent( VCLXWindow* pVCLXWindow )
57 :VCLXAccessibleComponent( pVCLXWindow )
58 {
59 if ( GetWindow() )
60 m_sText = OutputDevice::GetNonMnemonicString( GetWindow()->GetText() );
61 }
62
63 // -----------------------------------------------------------------------------
64
~VCLXAccessibleTextComponent()65 VCLXAccessibleTextComponent::~VCLXAccessibleTextComponent()
66 {
67 }
68
69 // -----------------------------------------------------------------------------
70
SetText(const::rtl::OUString & sText)71 void VCLXAccessibleTextComponent::SetText( const ::rtl::OUString& sText )
72 {
73 Any aOldValue, aNewValue;
74 if ( implInitTextChangedEvent( m_sText, sText, aOldValue, aNewValue ) )
75 {
76 m_sText = sText;
77 NotifyAccessibleEvent( AccessibleEventId::TEXT_CHANGED, aOldValue, aNewValue );
78 }
79 }
80
81 // -----------------------------------------------------------------------------
82
ProcessWindowEvent(const VclWindowEvent & rVclWindowEvent)83 void VCLXAccessibleTextComponent::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
84 {
85 switch ( rVclWindowEvent.GetId() )
86 {
87 case VCLEVENT_WINDOW_FRAMETITLECHANGED:
88 {
89 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
90 SetText( implGetText() );
91 }
92 break;
93 default:
94 VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
95 }
96 }
97
98 // -----------------------------------------------------------------------------
99 // OCommonAccessibleText
100 // -----------------------------------------------------------------------------
101
implGetText()102 ::rtl::OUString VCLXAccessibleTextComponent::implGetText()
103 {
104 ::rtl::OUString aText;
105 if ( GetWindow() )
106 aText = OutputDevice::GetNonMnemonicString( GetWindow()->GetText() );
107
108 return aText;
109 }
110
111 // -----------------------------------------------------------------------------
112
implGetLocale()113 lang::Locale VCLXAccessibleTextComponent::implGetLocale()
114 {
115 return Application::GetSettings().GetLocale();
116 }
117
118 // -----------------------------------------------------------------------------
119
implGetSelection(sal_Int32 & nStartIndex,sal_Int32 & nEndIndex)120 void VCLXAccessibleTextComponent::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
121 {
122 nStartIndex = 0;
123 nEndIndex = 0;
124 }
125
126 // -----------------------------------------------------------------------------
127 // XComponent
128 // -----------------------------------------------------------------------------
129
disposing()130 void VCLXAccessibleTextComponent::disposing()
131 {
132 VCLXAccessibleComponent::disposing();
133
134 m_sText = ::rtl::OUString();
135 }
136
137 // -----------------------------------------------------------------------------
138 // XInterface
139 // -----------------------------------------------------------------------------
140
IMPLEMENT_FORWARD_XINTERFACE2(VCLXAccessibleTextComponent,VCLXAccessibleComponent,VCLXAccessibleTextComponent_BASE)141 IMPLEMENT_FORWARD_XINTERFACE2( VCLXAccessibleTextComponent, VCLXAccessibleComponent, VCLXAccessibleTextComponent_BASE )
142
143 // -----------------------------------------------------------------------------
144 // XTypeProvider
145 // -----------------------------------------------------------------------------
146
147 IMPLEMENT_FORWARD_XTYPEPROVIDER2( VCLXAccessibleTextComponent, VCLXAccessibleComponent, VCLXAccessibleTextComponent_BASE )
148
149 // -----------------------------------------------------------------------------
150 // XAccessibleText
151 // -----------------------------------------------------------------------------
152
153 sal_Int32 VCLXAccessibleTextComponent::getCaretPosition() throw (RuntimeException)
154 {
155 OExternalLockGuard aGuard( this );
156
157 return -1;
158 }
159
160 // -----------------------------------------------------------------------------
161
setCaretPosition(sal_Int32 nIndex)162 sal_Bool VCLXAccessibleTextComponent::setCaretPosition( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
163 {
164 OExternalLockGuard aGuard( this );
165
166 return setSelection( nIndex, nIndex );
167 }
168
169 // -----------------------------------------------------------------------------
170
getCharacter(sal_Int32 nIndex)171 sal_Unicode VCLXAccessibleTextComponent::getCharacter( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
172 {
173 OExternalLockGuard aGuard( this );
174
175 return OCommonAccessibleText::getCharacter( nIndex );
176 }
177
178 // -----------------------------------------------------------------------------
179
getCharacterAttributes(sal_Int32 nIndex,const Sequence<::rtl::OUString> & aRequestedAttributes)180 Sequence< PropertyValue > VCLXAccessibleTextComponent::getCharacterAttributes( sal_Int32 nIndex, const Sequence< ::rtl::OUString >& aRequestedAttributes ) throw (IndexOutOfBoundsException, RuntimeException)
181 {
182 OExternalLockGuard aGuard( this );
183
184 Sequence< PropertyValue > aValues;
185 ::rtl::OUString sText( implGetText() );
186
187 if ( !implIsValidIndex( nIndex, sText.getLength() ) )
188 throw IndexOutOfBoundsException();
189
190 if ( GetWindow() )
191 {
192 Font aFont = GetWindow()->GetControlFont();
193
194 sal_Int32 nBackColor = GetWindow()->GetControlBackground().GetColor();
195 sal_Int32 nColor = GetWindow()->GetControlForeground().GetColor();
196
197 // MT: Code with default font was introduced with the IA2 CWS, but I am not convinced that this is the correct font...
198 // Decide what to do when we have a concrete issue.
199 /*
200 Font aDefaultVCLFont;
201 OutputDevice* pDev = Application::GetDefaultDevice();
202 if ( pDev )
203 {
204 aDefaultVCLFont = pDev->GetSettings().GetStyleSettings().GetAppFont();
205 if ( !aFont.GetName().Len() )
206 {
207 String aDefaultName = aDefaultVCLFont.GetName();
208 aFont.SetName( aDefaultName );
209 }
210 if ( !aFont.GetHeight() )
211 {
212 aFont.SetHeight( aDefaultVCLFont.GetHeight() );
213 }
214 if ( aFont.GetWeight() == WEIGHT_DONTKNOW )
215 {
216 aFont.SetWeight( aDefaultVCLFont.GetWeight() );
217 }
218
219 //if nColor is -1, it may indicate that the default color black is using.
220 if ( nColor == -1)
221 {
222 nColor = aDefaultVCLFont.GetColor().GetColor();
223 }
224 }
225 */
226
227 // MT: Adjustment stuff was introduced with the IA2 CWS, but adjustment is not a character attribute...
228 // In case we reintroduce it, use adjustment as extra parameter for the CharacterAttributesHelper...
229 /*
230 WinBits aBits = GetWindow()->GetStyle();
231 sal_Int16 nAdjust = -1;
232 if ( aBits & WB_LEFT )
233 {
234 nAdjust = style::ParagraphAdjust_LEFT;
235 }
236 else if ( aBits & WB_RIGHT )
237 {
238 nAdjust = style::ParagraphAdjust_RIGHT;
239 }
240 else if ( aBits & WB_CENTER )
241 {
242 nAdjust = style::ParagraphAdjust_CENTER;
243 }
244 */
245
246 ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) );
247
248 aValues = pHelper->GetCharacterAttributes( aRequestedAttributes );
249 }
250
251 return aValues;
252 }
253
254 // -----------------------------------------------------------------------------
255
getCharacterBounds(sal_Int32 nIndex)256 awt::Rectangle VCLXAccessibleTextComponent::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
257 {
258 OExternalLockGuard aGuard( this );
259
260 if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
261 throw IndexOutOfBoundsException();
262
263 awt::Rectangle aRect;
264 Control* pControl = static_cast< Control* >( GetWindow() );
265 if ( pControl )
266 aRect = AWTRectangle( pControl->GetCharacterBounds( nIndex ) );
267
268 return aRect;
269 }
270
271 // -----------------------------------------------------------------------------
272
getCharacterCount()273 sal_Int32 VCLXAccessibleTextComponent::getCharacterCount() throw (RuntimeException)
274 {
275 OExternalLockGuard aGuard( this );
276
277 return OCommonAccessibleText::getCharacterCount();
278 }
279
280 // -----------------------------------------------------------------------------
281
getIndexAtPoint(const awt::Point & aPoint)282 sal_Int32 VCLXAccessibleTextComponent::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
283 {
284 OExternalLockGuard aGuard( this );
285
286 sal_Int32 nIndex = -1;
287 Control* pControl = static_cast< Control* >( GetWindow() );
288 if ( pControl )
289 nIndex = pControl->GetIndexForPoint( VCLPoint( aPoint ) );
290
291 return nIndex;
292 }
293
294 // -----------------------------------------------------------------------------
295
getSelectedText()296 ::rtl::OUString VCLXAccessibleTextComponent::getSelectedText() throw (RuntimeException)
297 {
298 OExternalLockGuard aGuard( this );
299
300 return OCommonAccessibleText::getSelectedText();
301 }
302
303 // -----------------------------------------------------------------------------
304
getSelectionStart()305 sal_Int32 VCLXAccessibleTextComponent::getSelectionStart() throw (RuntimeException)
306 {
307 OExternalLockGuard aGuard( this );
308
309 return OCommonAccessibleText::getSelectionStart();
310 }
311
312 // -----------------------------------------------------------------------------
313
getSelectionEnd()314 sal_Int32 VCLXAccessibleTextComponent::getSelectionEnd() throw (RuntimeException)
315 {
316 OExternalLockGuard aGuard( this );
317
318 return OCommonAccessibleText::getSelectionEnd();
319 }
320
321 // -----------------------------------------------------------------------------
322
setSelection(sal_Int32 nStartIndex,sal_Int32 nEndIndex)323 sal_Bool VCLXAccessibleTextComponent::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
324 {
325 OExternalLockGuard aGuard( this );
326
327 if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
328 throw IndexOutOfBoundsException();
329
330 return sal_False;
331 }
332
333 // -----------------------------------------------------------------------------
334
getText()335 ::rtl::OUString VCLXAccessibleTextComponent::getText() throw (RuntimeException)
336 {
337 OExternalLockGuard aGuard( this );
338
339 return OCommonAccessibleText::getText();
340 }
341
342 // -----------------------------------------------------------------------------
343
getTextRange(sal_Int32 nStartIndex,sal_Int32 nEndIndex)344 ::rtl::OUString VCLXAccessibleTextComponent::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
345 {
346 OExternalLockGuard aGuard( this );
347
348 return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
349 }
350
351 // -----------------------------------------------------------------------------
352
getTextAtIndex(sal_Int32 nIndex,sal_Int16 aTextType)353 ::com::sun::star::accessibility::TextSegment VCLXAccessibleTextComponent::getTextAtIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
354 {
355 OExternalLockGuard aGuard( this );
356
357 return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
358 }
359
360 // -----------------------------------------------------------------------------
361
getTextBeforeIndex(sal_Int32 nIndex,sal_Int16 aTextType)362 ::com::sun::star::accessibility::TextSegment VCLXAccessibleTextComponent::getTextBeforeIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
363 {
364 OExternalLockGuard aGuard( this );
365
366 return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
367 }
368
369 // -----------------------------------------------------------------------------
370
getTextBehindIndex(sal_Int32 nIndex,sal_Int16 aTextType)371 ::com::sun::star::accessibility::TextSegment VCLXAccessibleTextComponent::getTextBehindIndex( sal_Int32 nIndex, sal_Int16 aTextType ) throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::lang::IllegalArgumentException, ::com::sun::star::uno::RuntimeException)
372 {
373 OExternalLockGuard aGuard( this );
374
375 return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
376 }
377
378 // -----------------------------------------------------------------------------
379
copyText(sal_Int32 nStartIndex,sal_Int32 nEndIndex)380 sal_Bool VCLXAccessibleTextComponent::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
381 {
382 OExternalLockGuard aGuard( this );
383
384 sal_Bool bReturn = sal_False;
385
386 if ( GetWindow() )
387 {
388 Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow()->GetClipboard();
389 if ( xClipboard.is() )
390 {
391 ::rtl::OUString sText( getTextRange( nStartIndex, nEndIndex ) );
392
393 ::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
394 const sal_uInt32 nRef = Application::ReleaseSolarMutex();
395 xClipboard->setContents( pDataObj, NULL );
396
397 Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
398 if( xFlushableClipboard.is() )
399 xFlushableClipboard->flushClipboard();
400
401 Application::AcquireSolarMutex( nRef );
402
403 bReturn = sal_True;
404 }
405 }
406
407 return bReturn;
408 }
409
410 // -----------------------------------------------------------------------------
411