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 
56 VCLXAccessibleTextComponent::VCLXAccessibleTextComponent( VCLXWindow* pVCLXWindow )
57 	:VCLXAccessibleComponent( pVCLXWindow )
58 {
59     if ( GetWindow() )
60 		m_sText = OutputDevice::GetNonMnemonicString( GetWindow()->GetText() );
61 }
62 
63 // -----------------------------------------------------------------------------
64 
65 VCLXAccessibleTextComponent::~VCLXAccessibleTextComponent()
66 {
67 }
68 
69 // -----------------------------------------------------------------------------
70 
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 
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 
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 
113 lang::Locale VCLXAccessibleTextComponent::implGetLocale()
114 {
115 	return Application::GetSettings().GetLocale();
116 }
117 
118 // -----------------------------------------------------------------------------
119 
120 void VCLXAccessibleTextComponent::implGetSelection( sal_Int32& nStartIndex, sal_Int32& nEndIndex )
121 {
122 	nStartIndex = 0;
123 	nEndIndex = 0;
124 }
125 
126 // -----------------------------------------------------------------------------
127 // XComponent
128 // -----------------------------------------------------------------------------
129 
130 void VCLXAccessibleTextComponent::disposing()
131 {
132 	VCLXAccessibleComponent::disposing();
133 
134 	m_sText = ::rtl::OUString();
135 }
136 
137 // -----------------------------------------------------------------------------
138 // XInterface
139 // -----------------------------------------------------------------------------
140 
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 
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 
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 
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         sal_Int32 nBackColor = GetWindow()->GetControlBackground().GetColor();
194         sal_Int32 nColor = GetWindow()->GetControlForeground().GetColor();
195         ::std::auto_ptr< CharacterAttributesHelper > pHelper( new CharacterAttributesHelper( aFont, nBackColor, nColor ) );
196 		aValues = pHelper->GetCharacterAttributes( aRequestedAttributes );
197     }
198 
199     return aValues;
200 }
201 
202 // -----------------------------------------------------------------------------
203 
204 awt::Rectangle VCLXAccessibleTextComponent::getCharacterBounds( sal_Int32 nIndex ) throw (IndexOutOfBoundsException, RuntimeException)
205 {
206 	OExternalLockGuard aGuard( this );
207 
208     if ( !implIsValidIndex( nIndex, implGetText().getLength() ) )
209         throw IndexOutOfBoundsException();
210 
211 	awt::Rectangle aRect;
212 	Control* pControl = static_cast< Control* >( GetWindow() );
213 	if ( pControl )
214 		aRect = AWTRectangle( pControl->GetCharacterBounds( nIndex ) );
215 
216     return aRect;
217 }
218 
219 // -----------------------------------------------------------------------------
220 
221 sal_Int32 VCLXAccessibleTextComponent::getCharacterCount() throw (RuntimeException)
222 {
223 	OExternalLockGuard aGuard( this );
224 
225 	return OCommonAccessibleText::getCharacterCount();
226 }
227 
228 // -----------------------------------------------------------------------------
229 
230 sal_Int32 VCLXAccessibleTextComponent::getIndexAtPoint( const awt::Point& aPoint ) throw (RuntimeException)
231 {
232 	OExternalLockGuard aGuard( this );
233 
234 	sal_Int32 nIndex = -1;
235 	Control* pControl = static_cast< Control* >( GetWindow() );
236 	if ( pControl )
237 		nIndex = pControl->GetIndexForPoint( VCLPoint( aPoint ) );
238 
239     return nIndex;
240 }
241 
242 // -----------------------------------------------------------------------------
243 
244 ::rtl::OUString VCLXAccessibleTextComponent::getSelectedText() throw (RuntimeException)
245 {
246 	OExternalLockGuard aGuard( this );
247 
248 	return OCommonAccessibleText::getSelectedText();
249 }
250 
251 // -----------------------------------------------------------------------------
252 
253 sal_Int32 VCLXAccessibleTextComponent::getSelectionStart() throw (RuntimeException)
254 {
255 	OExternalLockGuard aGuard( this );
256 
257 	return OCommonAccessibleText::getSelectionStart();
258 }
259 
260 // -----------------------------------------------------------------------------
261 
262 sal_Int32 VCLXAccessibleTextComponent::getSelectionEnd() throw (RuntimeException)
263 {
264 	OExternalLockGuard aGuard( this );
265 
266 	return OCommonAccessibleText::getSelectionEnd();
267 }
268 
269 // -----------------------------------------------------------------------------
270 
271 sal_Bool VCLXAccessibleTextComponent::setSelection( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
272 {
273 	OExternalLockGuard aGuard( this );
274 
275     if ( !implIsValidRange( nStartIndex, nEndIndex, implGetText().getLength() ) )
276         throw IndexOutOfBoundsException();
277 
278 	return sal_False;
279 }
280 
281 // -----------------------------------------------------------------------------
282 
283 ::rtl::OUString VCLXAccessibleTextComponent::getText() throw (RuntimeException)
284 {
285 	OExternalLockGuard aGuard( this );
286 
287 	return OCommonAccessibleText::getText();
288 }
289 
290 // -----------------------------------------------------------------------------
291 
292 ::rtl::OUString VCLXAccessibleTextComponent::getTextRange( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
293 {
294 	OExternalLockGuard aGuard( this );
295 
296 	return OCommonAccessibleText::getTextRange( nStartIndex, nEndIndex );
297 }
298 
299 // -----------------------------------------------------------------------------
300 
301 ::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)
302 {
303 	OExternalLockGuard aGuard( this );
304 
305 	return OCommonAccessibleText::getTextAtIndex( nIndex, aTextType );
306 }
307 
308 // -----------------------------------------------------------------------------
309 
310 ::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)
311 {
312 	OExternalLockGuard aGuard( this );
313 
314 	return OCommonAccessibleText::getTextBeforeIndex( nIndex, aTextType );
315 }
316 
317 // -----------------------------------------------------------------------------
318 
319 ::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)
320 {
321 	OExternalLockGuard aGuard( this );
322 
323 	return OCommonAccessibleText::getTextBehindIndex( nIndex, aTextType );
324 }
325 
326 // -----------------------------------------------------------------------------
327 
328 sal_Bool VCLXAccessibleTextComponent::copyText( sal_Int32 nStartIndex, sal_Int32 nEndIndex ) throw (IndexOutOfBoundsException, RuntimeException)
329 {
330 	OExternalLockGuard aGuard( this );
331 
332 	sal_Bool bReturn = sal_False;
333 
334 	if ( GetWindow() )
335 	{
336 		Reference< datatransfer::clipboard::XClipboard > xClipboard = GetWindow()->GetClipboard();
337 		if ( xClipboard.is() )
338 		{
339 			::rtl::OUString sText( getTextRange( nStartIndex, nEndIndex ) );
340 
341 			::vcl::unohelper::TextDataObject* pDataObj = new ::vcl::unohelper::TextDataObject( sText );
342 			const sal_uInt32 nRef = Application::ReleaseSolarMutex();
343 			xClipboard->setContents( pDataObj, NULL );
344 
345 			Reference< datatransfer::clipboard::XFlushableClipboard > xFlushableClipboard( xClipboard, uno::UNO_QUERY );
346 			if( xFlushableClipboard.is() )
347 				xFlushableClipboard->flushClipboard();
348 
349 			Application::AcquireSolarMutex( nRef );
350 
351 			bReturn = sal_True;
352 		}
353 	}
354 
355     return bReturn;
356 }
357 
358 // -----------------------------------------------------------------------------
359