Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : : #include "AccessibleEditObject.hxx"
30 : : #include "scitems.hxx"
31 : : #include <editeng/eeitem.hxx>
32 : : #include "AccessibleText.hxx"
33 : : #include "editsrc.hxx"
34 : : #include "scmod.hxx"
35 : : #include "inputhdl.hxx"
36 : :
37 : : #include <unotools/accessiblestatesethelper.hxx>
38 : : #include <com/sun/star/accessibility/AccessibleRole.hpp>
39 : : #include <com/sun/star/accessibility/AccessibleStateType.hpp>
40 : : #include <comphelper/servicehelper.hxx>
41 : : #include <svx/AccessibleTextHelper.hxx>
42 : : #include <editeng/editview.hxx>
43 : : #include <editeng/editeng.hxx>
44 : : #include <svx/svdmodel.hxx>
45 : : #include <vcl/svapp.hxx>
46 : :
47 : : using namespace ::com::sun::star;
48 : : using namespace ::com::sun::star::accessibility;
49 : :
50 : : //===== internal ============================================================
51 : :
52 : 0 : ScAccessibleEditObject::ScAccessibleEditObject(
53 : : const uno::Reference<XAccessible>& rxParent,
54 : : EditView* pEditView, Window* pWin, const rtl::OUString& rName,
55 : : const rtl::OUString& rDescription, EditObjectType eObjectType)
56 : : :
57 : : ScAccessibleContextBase(rxParent, AccessibleRole::TEXT_FRAME),
58 : : mpTextHelper(NULL),
59 : : mpEditView(pEditView),
60 : : mpWindow(pWin),
61 : : meObjectType(eObjectType),
62 : 0 : mbHasFocus(false)
63 : : {
64 [ # # ]: 0 : CreateTextHelper();
65 : 0 : SetName(rName);
66 : 0 : SetDescription(rDescription);
67 : 0 : }
68 : :
69 : 0 : ScAccessibleEditObject::~ScAccessibleEditObject()
70 : : {
71 [ # # ][ # # ]: 0 : if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
[ # # ]
72 : : {
73 : : // increment refcount to prevent double call off dtor
74 [ # # ]: 0 : osl_incrementInterlockedCount( &m_refCount );
75 : : // call dispose to inform object wich have a weak reference to this object
76 [ # # ]: 0 : dispose();
77 : : }
78 [ # # ]: 0 : }
79 : :
80 : 0 : void SAL_CALL ScAccessibleEditObject::disposing()
81 : : {
82 [ # # ]: 0 : SolarMutexGuard aGuard;
83 [ # # ]: 0 : if (mpTextHelper)
84 [ # # ][ # # ]: 0 : DELETEZ(mpTextHelper);
85 : :
86 [ # # ][ # # ]: 0 : ScAccessibleContextBase::disposing();
87 : 0 : }
88 : :
89 : 0 : void ScAccessibleEditObject::LostFocus()
90 : : {
91 : 0 : mbHasFocus = false;
92 [ # # ]: 0 : if (mpTextHelper)
93 : 0 : mpTextHelper->SetFocus(false);
94 : 0 : CommitFocusLost();
95 : 0 : }
96 : :
97 : 0 : void ScAccessibleEditObject::GotFocus()
98 : : {
99 : 0 : mbHasFocus = sal_True;
100 : 0 : CommitFocusGained();
101 [ # # ]: 0 : if (mpTextHelper)
102 : 0 : mpTextHelper->SetFocus(sal_True);
103 : 0 : }
104 : :
105 : : //===== XAccessibleComponent ============================================
106 : :
107 : 0 : uno::Reference< XAccessible > SAL_CALL ScAccessibleEditObject::getAccessibleAtPoint(
108 : : const awt::Point& rPoint )
109 : : throw (uno::RuntimeException)
110 : : {
111 : 0 : uno::Reference<XAccessible> xRet;
112 [ # # ][ # # ]: 0 : if (containsPoint(rPoint))
113 : : {
114 [ # # ]: 0 : SolarMutexGuard aGuard;
115 [ # # ]: 0 : IsObjectValid();
116 : :
117 [ # # ]: 0 : if(!mpTextHelper)
118 [ # # ]: 0 : CreateTextHelper();
119 : :
120 [ # # ][ # # ]: 0 : xRet = mpTextHelper->GetAt(rPoint);
[ # # ]
121 : : }
122 : :
123 : 0 : return xRet;
124 : : }
125 : :
126 : 0 : Rectangle ScAccessibleEditObject::GetBoundingBoxOnScreen(void) const
127 : : throw (uno::RuntimeException)
128 : : {
129 : 0 : Rectangle aScreenBounds;
130 : :
131 [ # # ]: 0 : if ( mpWindow )
132 : : {
133 [ # # ]: 0 : if ( meObjectType == CellInEditMode )
134 : : {
135 [ # # ][ # # ]: 0 : if ( mpEditView && mpEditView->GetEditEngine() )
[ # # ]
136 : : {
137 [ # # ][ # # ]: 0 : MapMode aMapMode( mpEditView->GetEditEngine()->GetRefMapMode() );
138 [ # # ][ # # ]: 0 : aScreenBounds = mpWindow->LogicToPixel( mpEditView->GetOutputArea(), aMapMode );
139 : 0 : Point aCellLoc = aScreenBounds.TopLeft();
140 [ # # ]: 0 : Rectangle aWindowRect = mpWindow->GetWindowExtentsRelative( NULL );
141 : 0 : Point aWindowLoc = aWindowRect.TopLeft();
142 : 0 : Point aPos( aCellLoc.getX() + aWindowLoc.getX(), aCellLoc.getY() + aWindowLoc.getY() );
143 [ # # ]: 0 : aScreenBounds.SetPos( aPos );
144 : : }
145 : : }
146 : : else
147 : : {
148 : 0 : aScreenBounds = mpWindow->GetWindowExtentsRelative( NULL );
149 : : }
150 : : }
151 : :
152 : 0 : return aScreenBounds;
153 : : }
154 : :
155 : 0 : Rectangle ScAccessibleEditObject::GetBoundingBox(void) const
156 : : throw (uno::RuntimeException)
157 : : {
158 : 0 : Rectangle aBounds( GetBoundingBoxOnScreen() );
159 : :
160 [ # # ]: 0 : if ( mpWindow )
161 : : {
162 [ # # ]: 0 : uno::Reference< XAccessible > xThis( mpWindow->GetAccessible() );
163 [ # # ]: 0 : if ( xThis.is() )
164 : : {
165 [ # # ][ # # ]: 0 : uno::Reference< XAccessibleContext > xContext( xThis->getAccessibleContext() );
166 [ # # ]: 0 : if ( xContext.is() )
167 : : {
168 [ # # ][ # # ]: 0 : uno::Reference< XAccessible > xParent( xContext->getAccessibleParent() );
169 [ # # ]: 0 : if ( xParent.is() )
170 : : {
171 [ # # ][ # # ]: 0 : uno::Reference< XAccessibleComponent > xParentComponent( xParent->getAccessibleContext(), uno::UNO_QUERY );
[ # # ]
172 [ # # ]: 0 : if ( xParentComponent.is() )
173 : : {
174 : 0 : Point aScreenLoc = aBounds.TopLeft();
175 [ # # ][ # # ]: 0 : awt::Point aParentScreenLoc = xParentComponent->getLocationOnScreen();
176 : 0 : Point aPos( aScreenLoc.getX() - aParentScreenLoc.X, aScreenLoc.getY() - aParentScreenLoc.Y );
177 : 0 : aBounds.SetPos( aPos );
178 : 0 : }
179 : 0 : }
180 : 0 : }
181 : 0 : }
182 : : }
183 : :
184 : 0 : return aBounds;
185 : : }
186 : :
187 : : //===== XAccessibleContext ==============================================
188 : :
189 : : sal_Int32 SAL_CALL
190 : 0 : ScAccessibleEditObject::getAccessibleChildCount(void)
191 : : throw (uno::RuntimeException)
192 : : {
193 [ # # ]: 0 : SolarMutexGuard aGuard;
194 [ # # ]: 0 : IsObjectValid();
195 [ # # ]: 0 : if (!mpTextHelper)
196 [ # # ]: 0 : CreateTextHelper();
197 [ # # ][ # # ]: 0 : return mpTextHelper->GetChildCount();
198 : : }
199 : :
200 : : uno::Reference< XAccessible > SAL_CALL
201 : 0 : ScAccessibleEditObject::getAccessibleChild(sal_Int32 nIndex)
202 : : throw (uno::RuntimeException,
203 : : lang::IndexOutOfBoundsException)
204 : : {
205 [ # # ]: 0 : SolarMutexGuard aGuard;
206 [ # # ]: 0 : IsObjectValid();
207 [ # # ]: 0 : if (!mpTextHelper)
208 [ # # ]: 0 : CreateTextHelper();
209 [ # # ][ # # ]: 0 : return mpTextHelper->GetChild(nIndex);
210 : : }
211 : :
212 : : uno::Reference<XAccessibleStateSet> SAL_CALL
213 : 0 : ScAccessibleEditObject::getAccessibleStateSet(void)
214 : : throw (uno::RuntimeException)
215 : : {
216 [ # # ]: 0 : SolarMutexGuard aGuard;
217 : 0 : uno::Reference<XAccessibleStateSet> xParentStates;
218 [ # # ][ # # ]: 0 : if (getAccessibleParent().is())
219 : : {
220 [ # # ][ # # ]: 0 : uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
[ # # ]
221 [ # # ][ # # ]: 0 : xParentStates = xParentContext->getAccessibleStateSet();
[ # # ]
222 : : }
223 [ # # ]: 0 : utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
224 [ # # ][ # # ]: 0 : if (IsDefunc(xParentStates))
225 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::DEFUNC);
226 : : else
227 : : {
228 : : // all states are const, because this object exists only in one state
229 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::EDITABLE);
230 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::ENABLED);
231 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::SENSITIVE);
232 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::MULTI_LINE);
233 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::MULTI_SELECTABLE);
234 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::SHOWING);
235 [ # # ]: 0 : pStateSet->AddState(AccessibleStateType::VISIBLE);
236 : : }
237 [ # # ][ # # ]: 0 : return pStateSet;
[ # # ]
238 : : }
239 : :
240 : : ::rtl::OUString SAL_CALL
241 : 0 : ScAccessibleEditObject::createAccessibleDescription(void)
242 : : throw (uno::RuntimeException)
243 : : {
244 : : // OSL_FAIL("Should never be called, because is set in the constructor.")
245 : 0 : return rtl::OUString();
246 : : }
247 : :
248 : : ::rtl::OUString SAL_CALL
249 : 0 : ScAccessibleEditObject::createAccessibleName(void)
250 : : throw (uno::RuntimeException)
251 : : {
252 : : OSL_FAIL("Should never be called, because is set in the constructor.");
253 : 0 : return rtl::OUString();
254 : : }
255 : :
256 : : ///===== XAccessibleEventBroadcaster =====================================
257 : :
258 : : void SAL_CALL
259 : 0 : ScAccessibleEditObject::addEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
260 : : throw (uno::RuntimeException)
261 : : {
262 [ # # ]: 0 : if (!mpTextHelper)
263 : 0 : CreateTextHelper();
264 : :
265 : 0 : mpTextHelper->AddEventListener(xListener);
266 : :
267 : 0 : ScAccessibleContextBase::addEventListener(xListener);
268 : 0 : }
269 : :
270 : : void SAL_CALL
271 : 0 : ScAccessibleEditObject::removeEventListener(const uno::Reference<XAccessibleEventListener>& xListener)
272 : : throw (uno::RuntimeException)
273 : : {
274 [ # # ]: 0 : if (!mpTextHelper)
275 : 0 : CreateTextHelper();
276 : :
277 : 0 : mpTextHelper->RemoveEventListener(xListener);
278 : :
279 : 0 : ScAccessibleContextBase::removeEventListener(xListener);
280 : 0 : }
281 : :
282 : : //===== XServiceInfo ====================================================
283 : :
284 : 0 : ::rtl::OUString SAL_CALL ScAccessibleEditObject::getImplementationName(void)
285 : : throw (uno::RuntimeException)
286 : : {
287 : 0 : return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessibleEditObject"));
288 : : }
289 : :
290 : : //===== XTypeProvider =======================================================
291 : :
292 : : namespace
293 : : {
294 : : class theScAccessibleEditObjectImplementationId : public rtl::Static< UnoTunnelIdInit, theScAccessibleEditObjectImplementationId > {};
295 : : }
296 : :
297 : : uno::Sequence<sal_Int8> SAL_CALL
298 : 0 : ScAccessibleEditObject::getImplementationId(void)
299 : : throw (uno::RuntimeException)
300 : : {
301 : 0 : return theScAccessibleEditObjectImplementationId::get().getSeq();
302 : : }
303 : :
304 : : //==== internal =========================================================
305 : :
306 : 0 : sal_Bool ScAccessibleEditObject::IsDefunc(
307 : : const uno::Reference<XAccessibleStateSet>& rxParentStates)
308 : : {
309 [ # # ][ # # ]: 0 : return ScAccessibleContextBase::IsDefunc() || !getAccessibleParent().is() ||
[ # # ]
310 [ # # ][ # # ]: 0 : (rxParentStates.is() && rxParentStates->contains(AccessibleStateType::DEFUNC));
[ # # ][ # # ]
[ # # # # ]
311 : : }
312 : :
313 : 0 : void ScAccessibleEditObject::CreateTextHelper()
314 : : {
315 [ # # ]: 0 : if (!mpTextHelper)
316 : : {
317 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
318 : 0 : ::std::auto_ptr < ScAccessibleTextData > pAccessibleTextData;
319 : : SAL_WNODEPRECATED_DECLARATIONS_POP
320 [ # # ][ # # ]: 0 : if (meObjectType == CellInEditMode || meObjectType == EditControl)
321 : : {
322 : : pAccessibleTextData.reset
323 [ # # ][ # # ]: 0 : (new ScAccessibleEditObjectTextData(mpEditView, mpWindow));
324 : : }
325 : : else
326 : : {
327 : : pAccessibleTextData.reset
328 [ # # ][ # # ]: 0 : (new ScAccessibleEditLineTextData(NULL, mpWindow));
329 : : }
330 : :
331 : : SAL_WNODEPRECATED_DECLARATIONS_PUSH
332 [ # # ][ # # ]: 0 : ::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleTextData));
[ # # ]
333 : : SAL_WNODEPRECATED_DECLARATIONS_POP
334 [ # # ][ # # ]: 0 : mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
[ # # ]
335 [ # # ][ # # ]: 0 : mpTextHelper->SetEventSource(this);
336 [ # # ]: 0 : mpTextHelper->SetFocus(mbHasFocus);
337 : :
338 : : // #i54814# activate cell in edit mode
339 [ # # ]: 0 : if( meObjectType == CellInEditMode )
340 : : {
341 : : // do not activate cell object, if top edit line is active
342 [ # # ][ # # ]: 0 : const ScInputHandler* pInputHdl = SC_MOD()->GetInputHdl();
343 [ # # ][ # # ]: 0 : if( pInputHdl && !pInputHdl->IsTopMode() )
[ # # ]
344 : : {
345 [ # # ]: 0 : SdrHint aHint( HINT_BEGEDIT );
346 [ # # ][ # # ]: 0 : mpTextHelper->GetEditSource().GetBroadcaster().Broadcast( aHint );
[ # # ][ # # ]
347 : : }
348 [ # # ][ # # ]: 0 : }
349 : : }
350 : 0 : }
351 : :
352 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|