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