1 /************************************************************************* *
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2008 by Sun Microsystems, Inc.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * $RCSfile:  $
10  * $Revision:  $
11  *
12  * This file is part of OpenOffice.org.
13  *
14  * OpenOffice.org is free software: you can redistribute it and/or modify
15  * it under the terms of the GNU Lesser General Public License version 3
16  * only, as published by the Free Software Foundation.
17  *
18  * OpenOffice.org is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
21  * GNU Lesser General Public License version 3 for more details
22  * (a copy is included in the LICENSE file that accompanied this code).
23  *
24  * You should have received a copy of the GNU Lesser General Public License
25  * version 3 along with OpenOffice.org.  If not, see
26  * <http://www.openoffice.org/license.html>
27  * for a copy of the LGPLv3 License.
28  *
29  ************************************************************************/
30 
31 
32 #include "precompiled_sw.hxx"
33 
34 #include <SidebarTxtControlAcc.hxx>
35 
36 #include <SidebarTxtControl.hxx>
37 
38 #include <svl/brdcst.hxx>
39 #include <toolkit/awt/vclxaccessiblecomponent.hxx>
40 #include <editeng/unoedsrc.hxx>
41 #include <editeng/unoforou.hxx>
42 #include <editeng/unoviwou.hxx>
43 #include <editeng/unoedhlp.hxx>
44 #include <svx/AccessibleTextHelper.hxx>
45 #include <editeng/outliner.hxx>
46 
47 
48 namespace css = ::com::sun::star;
49 
50 namespace sw { namespace sidebarwindows {
51 
52 // =============================================================================
53 // declaration and implementation of <SvxEditSource>
54 // for <::accessibiliy::AccessibleTextHelper> instance
55 // =============================================================================
56 class SidebarTextEditSource : public SvxEditSource,
57                               public SfxBroadcaster
58 {
59     public:
60         SidebarTextEditSource( SidebarTxtControl& rSidebarTxtControl );
61         virtual ~SidebarTextEditSource();
62 
63         virtual SvxEditSource* Clone() const;
64 
65         virtual SvxTextForwarder* GetTextForwarder();
66         virtual SvxViewForwarder* GetViewForwarder();
67         virtual SvxEditViewForwarder* GetEditViewForwarder( sal_Bool bCreate = sal_False );
68 
69         virtual void UpdateData();
70 
71         virtual SfxBroadcaster& GetBroadcaster() const;
72         DECL_LINK( NotifyHdl, EENotify* );
73 
74     private:
75         SidebarTxtControl& mrSidebarTxtControl;
76         SvxOutlinerForwarder mTextForwarder;
77         SvxDrawOutlinerViewForwarder mViewForwarder;
78 };
79 
80 SidebarTextEditSource::SidebarTextEditSource( SidebarTxtControl& rSidebarTxtControl )
81     : SvxEditSource()
82     , mrSidebarTxtControl( rSidebarTxtControl )
83     , mTextForwarder( *(rSidebarTxtControl.GetTextView()->GetOutliner()), sal_False )
84     , mViewForwarder( *(rSidebarTxtControl.GetTextView()) )
85 {
86     if ( mrSidebarTxtControl.GetTextView() )
87     {
88         mrSidebarTxtControl.GetTextView()->GetOutliner()->SetNotifyHdl( LINK(this, SidebarTextEditSource, NotifyHdl) );
89     }
90 }
91 
92 SidebarTextEditSource::~SidebarTextEditSource()
93 {
94     if ( mrSidebarTxtControl.GetTextView() )
95     {
96         mrSidebarTxtControl.GetTextView()->GetOutliner()->SetNotifyHdl( Link() );
97     }
98 }
99 
100 SvxEditSource* SidebarTextEditSource::Clone() const
101 {
102     return new SidebarTextEditSource( mrSidebarTxtControl );
103 }
104 
105 SvxTextForwarder* SidebarTextEditSource::GetTextForwarder()
106 {
107     return &mTextForwarder;
108 }
109 
110 SvxViewForwarder* SidebarTextEditSource::GetViewForwarder()
111 {
112     return &mViewForwarder;
113 }
114 
115 SvxEditViewForwarder* SidebarTextEditSource::GetEditViewForwarder( sal_Bool /*bCreate*/ )
116 {
117     return &mViewForwarder;
118 }
119 
120 void SidebarTextEditSource::UpdateData()
121 {
122     // nothing to do
123 }
124 
125 SfxBroadcaster& SidebarTextEditSource::GetBroadcaster() const
126 {
127     return *( const_cast< SidebarTextEditSource* > (this) );
128 }
129 
130 IMPL_LINK(SidebarTextEditSource, NotifyHdl, EENotify*, pNotify)
131 {
132     if ( pNotify )
133     {
134         ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( pNotify ) );
135 
136         if( aHint.get() )
137         {
138             Broadcast( *aHint.get() );
139         }
140     }
141 
142     return 0;
143 }
144 
145 
146 // =============================================================================
147 // declaration and implementation of accessible context for <SidebarTxtControl> instance
148 // =============================================================================
149 class SidebarTxtControlAccessibleContext : public VCLXAccessibleComponent
150 {
151     public:
152         explicit SidebarTxtControlAccessibleContext( SidebarTxtControl& rSidebarTxtControl );
153         virtual ~SidebarTxtControlAccessibleContext();
154 
155         virtual sal_Int32 SAL_CALL
156                 getAccessibleChildCount()
157                 throw (::com::sun::star::uno::RuntimeException);
158         virtual ::com::sun::star::uno::Reference< ::com::sun::star::accessibility::XAccessible > SAL_CALL
159                 getAccessibleChild( sal_Int32 i )
160                 throw (::com::sun::star::lang::IndexOutOfBoundsException, ::com::sun::star::uno::RuntimeException);
161 
162         using WeakAggComponentImplHelperBase::addEventListener;
163         using WeakAggComponentImplHelperBase::removeEventListener;
164 
165         virtual void SAL_CALL
166                 addEventListener (
167                     const ::com::sun::star::uno::Reference<
168                         ::com::sun::star::accessibility::XAccessibleEventListener >& xListener)
169                 throw (::com::sun::star::uno::RuntimeException);
170         virtual void SAL_CALL
171                 removeEventListener (
172                     const ::com::sun::star::uno::Reference<
173                         ::com::sun::star::accessibility::XAccessibleEventListener >& xListener)
174                 throw (::com::sun::star::uno::RuntimeException);
175 
176     protected:
177         virtual void ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent );
178 
179     private:
180         SidebarTxtControl& mrSidebarTxtControl;
181         ::accessibility::AccessibleTextHelper* mpAccessibleTextHelper;
182 
183         ::vos::OMutex maMutex;
184 
185         void defunc();
186 };
187 
188 SidebarTxtControlAccessibleContext::SidebarTxtControlAccessibleContext( SidebarTxtControl& rSidebarTxtControl )
189     : VCLXAccessibleComponent( rSidebarTxtControl.GetWindowPeer() )
190     , mrSidebarTxtControl( rSidebarTxtControl )
191     , mpAccessibleTextHelper( 0 )
192     , maMutex()
193 {
194     ::std::auto_ptr<SvxEditSource> pEditSource(
195                         new SidebarTextEditSource( mrSidebarTxtControl ) );
196     mpAccessibleTextHelper = new ::accessibility::AccessibleTextHelper( pEditSource );
197     mpAccessibleTextHelper->SetEventSource( mrSidebarTxtControl.GetWindowPeer() );
198 }
199 
200 SidebarTxtControlAccessibleContext::~SidebarTxtControlAccessibleContext()
201 {
202     defunc();
203 }
204 
205 void SidebarTxtControlAccessibleContext::defunc()
206 {
207     delete mpAccessibleTextHelper;
208     mpAccessibleTextHelper = 0;
209 }
210 
211 sal_Int32 SAL_CALL SidebarTxtControlAccessibleContext::getAccessibleChildCount()
212     throw (::com::sun::star::uno::RuntimeException)
213 {
214     vos::OGuard aGuard( maMutex );
215 
216     sal_Int32 nChildCount( 0 );
217 
218     if ( mpAccessibleTextHelper )
219     {
220         nChildCount = mpAccessibleTextHelper->GetChildCount();
221     }
222 
223     return nChildCount;
224 }
225 
226 css::uno::Reference< css::accessibility::XAccessible > SAL_CALL SidebarTxtControlAccessibleContext::getAccessibleChild( sal_Int32 i )
227     throw ( css::lang::IndexOutOfBoundsException, css::uno::RuntimeException )
228 {
229     vos::OGuard aGuard( maMutex );
230 
231     css::uno::Reference< css::accessibility::XAccessible > xChild;
232 
233     if ( mpAccessibleTextHelper )
234     {
235         xChild = mpAccessibleTextHelper->GetChild( i );
236     }
237 
238     return xChild;
239 }
240 
241 void SAL_CALL SidebarTxtControlAccessibleContext::addEventListener (
242     const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener)
243     throw (css::uno::RuntimeException)
244 {
245     vos::OGuard aGuard( maMutex );
246 
247     if ( mpAccessibleTextHelper )
248     {
249         mpAccessibleTextHelper->AddEventListener(xListener);
250     }
251 }
252 
253 void SAL_CALL SidebarTxtControlAccessibleContext::removeEventListener (
254     const css::uno::Reference< css::accessibility::XAccessibleEventListener >& xListener)
255     throw (css::uno::RuntimeException)
256 {
257     vos::OGuard aGuard( maMutex );
258 
259     if ( mpAccessibleTextHelper )
260     {
261         mpAccessibleTextHelper->RemoveEventListener(xListener);
262     }
263 }
264 
265 void SidebarTxtControlAccessibleContext::ProcessWindowEvent( const VclWindowEvent& rVclWindowEvent )
266 {
267     if ( mpAccessibleTextHelper )
268     {
269         switch ( rVclWindowEvent.GetId() )
270         {
271             case VCLEVENT_OBJECT_DYING:
272             {
273                 defunc();
274             }
275             break;
276             case VCLEVENT_WINDOW_GETFOCUS:
277             case VCLEVENT_CONTROL_GETFOCUS:
278             {
279                 mpAccessibleTextHelper->SetFocus( sal_True );
280             }
281             break;
282             case VCLEVENT_WINDOW_LOSEFOCUS:
283             case VCLEVENT_CONTROL_LOSEFOCUS:
284             {
285                 mpAccessibleTextHelper->SetFocus( sal_False );
286             }
287             break;
288         }
289     }
290 
291     VCLXAccessibleComponent::ProcessWindowEvent( rVclWindowEvent );
292 }
293 
294 // =============================================================================
295 // implementaion of accessible for <SidebarTxtControl> instance
296 // =============================================================================
297 SidebarTxtControlAccessible::SidebarTxtControlAccessible( SidebarTxtControl& rSidebarTxtControl )
298     : VCLXWindow()
299     , mrSidebarTxtControl( rSidebarTxtControl )
300 {
301     SetWindow( &mrSidebarTxtControl );
302 }
303 
304 SidebarTxtControlAccessible::~SidebarTxtControlAccessible()
305 {
306 }
307 
308 css::uno::Reference< css::accessibility::XAccessibleContext > SidebarTxtControlAccessible::CreateAccessibleContext()
309 {
310     SidebarTxtControlAccessibleContext* pAccContext(
311                         new SidebarTxtControlAccessibleContext( mrSidebarTxtControl ) );
312     css::uno::Reference< css::accessibility::XAccessibleContext > xAcc( pAccContext );
313     return xAcc;
314 }
315 
316 } } // end of namespace sw::sidebarwindows
317 
318