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_sc.hxx"
26 #include <tools/gen.hxx>
27 #include "AccessiblePageHeaderArea.hxx"
28 #include "AccessibleText.hxx"
29 #include "AccessibilityHints.hxx"
30 #include "unoguard.hxx"
31 #include "editsrc.hxx"
32 #include "prevwsh.hxx"
33 #include "prevloc.hxx"
34 #include "scresid.hxx"
35 #ifndef SC_SC_HRC
36 #include "sc.hrc"
37 #endif
38 
39 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLEROLE_HPP_
40 #include <com/sun/star/accessibility/AccessibleRole.hpp>
41 #endif
42 #ifndef _COM_SUN_STAR_ACCESSIBILITY_XACCESSIBLESTATETYPE_HPP_
43 #include <com/sun/star/accessibility/AccessibleStateType.hpp>
44 #endif
45 #include <com/sun/star/accessibility/AccessibleEventId.hpp>
46 #include <editeng/editobj.hxx>
47 #include <svx/AccessibleTextHelper.hxx>
48 #include <rtl/uuid.h>
49 #include <unotools/accessiblestatesethelper.hxx>
50 #include <rtl/ustrbuf.hxx>
51 #include <toolkit/helper/convert.hxx>
52 
53 using namespace	::com::sun::star;
54 using namespace	::com::sun::star::accessibility;
55 
56 	//=====  internal  ========================================================
57 
ScAccessiblePageHeaderArea(const uno::Reference<XAccessible> & rxParent,ScPreviewShell * pViewShell,const EditTextObject * pEditObj,sal_Bool bHeader,SvxAdjust eAdjust)58 ScAccessiblePageHeaderArea::ScAccessiblePageHeaderArea(
59         const uno::Reference<XAccessible>& rxParent,
60         ScPreviewShell* pViewShell,
61         const EditTextObject* pEditObj,
62         sal_Bool bHeader,
63         SvxAdjust eAdjust)
64         : ScAccessibleContextBase(rxParent, AccessibleRole::TEXT),
65         mpEditObj(pEditObj->Clone()),
66     	mpTextHelper(NULL),
67         mpViewShell(pViewShell),
68         mbHeader(bHeader),
69         meAdjust(eAdjust)
70 {
71 	if (mpViewShell)
72 		mpViewShell->AddAccessibilityObject(*this);
73 }
74 
~ScAccessiblePageHeaderArea(void)75 ScAccessiblePageHeaderArea::~ScAccessiblePageHeaderArea(void)
76 {
77 	if (!ScAccessibleContextBase::IsDefunc() && !rBHelper.bInDispose)
78 	{
79 		// increment refcount to prevent double call off dtor
80 		osl_incrementInterlockedCount( &m_refCount );
81 		dispose();
82 	}
83 }
84 
disposing()85 void SAL_CALL ScAccessiblePageHeaderArea::disposing()
86 {
87     ScUnoGuard aGuard;
88 	if (mpViewShell)
89 	{
90 		mpViewShell->RemoveAccessibilityObject(*this);
91 		mpViewShell = NULL;
92 	}
93 	if (mpTextHelper)
94 		DELETEZ(mpTextHelper);
95     if (mpEditObj)
96         DELETEZ(mpEditObj);
97 
98 	ScAccessibleContextBase::disposing();
99 }
100 
101 //=====  SfxListener  =====================================================
102 
Notify(SfxBroadcaster & rBC,const SfxHint & rHint)103 void ScAccessiblePageHeaderArea::Notify( SfxBroadcaster& rBC, const SfxHint& rHint )
104 {
105 	if (rHint.ISA( SfxSimpleHint ) )
106 	{
107 		const SfxSimpleHint& rRef = (const SfxSimpleHint&)rHint;
108 		// only notify if child exist, otherwise it is not necessary
109         if (rRef.GetId() == SC_HINT_ACC_VISAREACHANGED)
110         {
111             if (mpTextHelper)
112                 mpTextHelper->UpdateChildren();
113 
114             AccessibleEventObject aEvent;
115             aEvent.EventId = AccessibleEventId::VISIBLE_DATA_CHANGED;
116 			aEvent.Source = uno::Reference< XAccessibleContext >(this);
117             CommitChange(aEvent);
118         }
119     }
120 	ScAccessibleContextBase::Notify(rBC, rHint);
121 }
122 	//=====  XAccessibleComponent  ============================================
123 
getAccessibleAtPoint(const awt::Point & rPoint)124 uno::Reference< XAccessible > SAL_CALL ScAccessiblePageHeaderArea::getAccessibleAtPoint(
125 		const awt::Point& rPoint )
126 		throw (uno::RuntimeException)
127 {
128     uno::Reference<XAccessible> xRet;
129     if (containsPoint(rPoint))
130     {
131  	    ScUnoGuard aGuard;
132         IsObjectValid();
133 
134     	if(!mpTextHelper)
135 	    	CreateTextHelper();
136 
137         xRet = mpTextHelper->GetAt(rPoint);
138     }
139 
140     return xRet;
141 }
142 
143 	//=====  XAccessibleContext  ==============================================
144 
145 sal_Int32 SAL_CALL
getAccessibleChildCount(void)146 	ScAccessiblePageHeaderArea::getAccessibleChildCount(void)
147     				throw (uno::RuntimeException)
148 {
149 	ScUnoGuard aGuard;
150     IsObjectValid();
151 	if (!mpTextHelper)
152 		CreateTextHelper();
153 	return mpTextHelper->GetChildCount();
154 }
155 
156 uno::Reference< XAccessible > SAL_CALL
getAccessibleChild(sal_Int32 nIndex)157 	ScAccessiblePageHeaderArea::getAccessibleChild(sal_Int32 nIndex)
158         throw (uno::RuntimeException,
159 		lang::IndexOutOfBoundsException)
160 {
161 	ScUnoGuard aGuard;
162     IsObjectValid();
163 	if (!mpTextHelper)
164 		CreateTextHelper();
165 	return mpTextHelper->GetChild(nIndex);
166 }
167 
168 uno::Reference<XAccessibleStateSet> SAL_CALL
getAccessibleStateSet(void)169 	ScAccessiblePageHeaderArea::getAccessibleStateSet(void)
170     throw (uno::RuntimeException)
171 {
172 	ScUnoGuard aGuard;
173 	uno::Reference<XAccessibleStateSet> xParentStates;
174 	if (getAccessibleParent().is())
175 	{
176 		uno::Reference<XAccessibleContext> xParentContext = getAccessibleParent()->getAccessibleContext();
177 		xParentStates = xParentContext->getAccessibleStateSet();
178 	}
179 	utl::AccessibleStateSetHelper* pStateSet = new utl::AccessibleStateSetHelper();
180 	if (IsDefunc())
181 		pStateSet->AddState(AccessibleStateType::DEFUNC);
182     else
183     {
184 	    pStateSet->AddState(AccessibleStateType::ENABLED);
185 	    pStateSet->AddState(AccessibleStateType::MULTI_LINE);
186 	    if (isShowing())
187 		    pStateSet->AddState(AccessibleStateType::SHOWING);
188 	    if (isVisible())
189 		    pStateSet->AddState(AccessibleStateType::VISIBLE);
190     }
191 	return pStateSet;
192 }
193 
194 //=====  XServiceInfo  ========================================================
195 
196 ::rtl::OUString SAL_CALL
getImplementationName(void)197    	ScAccessiblePageHeaderArea::getImplementationName(void)
198     throw (uno::RuntimeException)
199 {
200     return rtl::OUString(RTL_CONSTASCII_USTRINGPARAM ("ScAccessiblePageHeaderArea"));
201 }
202 
203 uno::Sequence< ::rtl::OUString> SAL_CALL
getSupportedServiceNames(void)204    	ScAccessiblePageHeaderArea::getSupportedServiceNames(void)
205     throw (uno::RuntimeException)
206 {
207 	uno::Sequence< ::rtl::OUString > aSequence = ScAccessibleContextBase::getSupportedServiceNames();
208     sal_Int32 nOldSize(aSequence.getLength());
209     aSequence.realloc(nOldSize + 1);
210     ::rtl::OUString* pNames = aSequence.getArray();
211 
212 	pNames[nOldSize] = rtl::OUString(RTL_CONSTASCII_USTRINGPARAM("com.sun.star.sheet.AccessiblePageHeaderFooterAreasView"));
213 
214 	return aSequence;
215 }
216 
217 //=====  XTypeProvider  =======================================================
218 
219 uno::Sequence<sal_Int8> SAL_CALL
getImplementationId(void)220 	ScAccessiblePageHeaderArea::getImplementationId(void)
221     throw (uno::RuntimeException)
222 {
223     ScUnoGuard aGuard;
224     IsObjectValid();
225 	static uno::Sequence<sal_Int8> aId;
226 	if (aId.getLength() == 0)
227 	{
228 		aId.realloc (16);
229 		rtl_createUuid (reinterpret_cast<sal_uInt8 *>(aId.getArray()), 0, sal_True);
230 	}
231 	return aId;
232 }
233 
234 //===== internal ==============================================================
createAccessibleDescription(void)235 rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleDescription(void)
236     throw(uno::RuntimeException)
237 {
238     rtl::OUString sDesc;
239     switch (meAdjust)
240     {
241     case SVX_ADJUST_LEFT :
242         sDesc = String(ScResId(STR_ACC_LEFTAREA_DESCR));
243         break;
244     case SVX_ADJUST_RIGHT:
245         sDesc = String(ScResId(STR_ACC_RIGHTAREA_DESCR));
246         break;
247     case SVX_ADJUST_CENTER:
248         sDesc = String(ScResId(STR_ACC_CENTERAREA_DESCR));
249         break;
250     default:
251         DBG_ERRORFILE("wrong adjustment found");
252     }
253 
254     return sDesc;
255 }
256 
createAccessibleName(void)257 rtl::OUString SAL_CALL ScAccessiblePageHeaderArea::createAccessibleName(void)
258     throw (uno::RuntimeException)
259 {
260     rtl::OUString sName;
261     switch (meAdjust)
262     {
263     case SVX_ADJUST_LEFT :
264         sName = String(ScResId(STR_ACC_LEFTAREA_NAME));
265         break;
266     case SVX_ADJUST_RIGHT:
267         sName = String(ScResId(STR_ACC_RIGHTAREA_NAME));
268         break;
269     case SVX_ADJUST_CENTER:
270         sName = String(ScResId(STR_ACC_CENTERAREA_NAME));
271         break;
272     default:
273         DBG_ERRORFILE("wrong adjustment found");
274     }
275 
276     return sName;
277 }
278 
GetBoundingBoxOnScreen(void) const279 Rectangle ScAccessiblePageHeaderArea::GetBoundingBoxOnScreen(void) const
280     throw(::com::sun::star::uno::RuntimeException)
281 {
282 	Rectangle aRect;
283     if (mxParent.is())
284     {
285         uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
286         uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
287         if (xComp.is())
288         {
289             // has the same size and position on screen like the parent
290             aRect = Rectangle(VCLPoint(xComp->getLocationOnScreen()), VCLRectangle(xComp->getBounds()).GetSize());
291         }
292     }
293 	return aRect;
294 }
295 
GetBoundingBox(void) const296 Rectangle ScAccessiblePageHeaderArea::GetBoundingBox(void) const
297     throw (::com::sun::star::uno::RuntimeException)
298 {
299 	Rectangle aRect;
300     if (mxParent.is())
301     {
302         uno::Reference<XAccessibleContext> xContext = mxParent->getAccessibleContext();
303         uno::Reference<XAccessibleComponent> xComp(xContext, uno::UNO_QUERY);
304         if (xComp.is())
305         {
306             // has the same size and position on screen like the parent and so the pos is (0, 0)
307             Rectangle aNewRect(Point(0, 0), VCLRectangle(xComp->getBounds()).GetSize());
308             aRect = aNewRect;
309         }
310     }
311 
312 	return aRect;
313 }
314 
CreateTextHelper()315 void ScAccessiblePageHeaderArea::CreateTextHelper()
316 {
317 	if (!mpTextHelper)
318 	{
319 		::std::auto_ptr < ScAccessibleTextData > pAccessibleHeaderTextData
320 			(new ScAccessibleHeaderTextData(mpViewShell, mpEditObj, mbHeader, meAdjust));
321 		::std::auto_ptr< SvxEditSource > pEditSource (new ScAccessibilityEditSource(pAccessibleHeaderTextData));
322 
323 		mpTextHelper = new ::accessibility::AccessibleTextHelper(pEditSource );
324         mpTextHelper->SetEventSource(this);
325 	}
326 }
327