1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
26 #include <svl/itemset.hxx>
27 #include <editeng/editdata.hxx>
28 #include <editeng/outliner.hxx>
29 #include <svx/svdmodel.hxx>
30 #include <svx/svdobj.hxx>
31 #include <svx/svdpool.hxx>
35 // Project-local header
39 #include "AccessibleEmptyEditSource.hxx"
40 #include <svx/unoshtxt.hxx>
42 namespace accessibility
45 /** This class simply wraps a SvxTextEditSource, forwarding all
46 methods except the GetBroadcaster() call
48 class AccessibleProxyEditSource_Impl
: public SvxEditSource
51 /** Construct AccessibleEmptyEditSource_Impl
55 Proxy broadcaster to allow seamless flipping of edit source implementations. ProxyEditSource and EmptyEditSource
57 AccessibleProxyEditSource_Impl( SdrObject
& rObj
,
59 const Window
& rViewWindow
);
60 virtual ~AccessibleProxyEditSource_Impl();
62 // from the SvxEditSource interface
63 SvxTextForwarder
* GetTextForwarder() SAL_OVERRIDE
;
64 SvxViewForwarder
* GetViewForwarder() SAL_OVERRIDE
;
65 SvxEditViewForwarder
* GetEditViewForwarder( bool bCreate
= false ) SAL_OVERRIDE
;
67 SvxEditSource
* Clone() const SAL_OVERRIDE
;
69 void UpdateData() SAL_OVERRIDE
;
71 SfxBroadcaster
& GetBroadcaster() const SAL_OVERRIDE
;
74 SvxTextEditSource maEditSource
;
78 /** Dummy class, faking exactly one empty paragraph for EditEngine accessibility
80 class AccessibleEmptyEditSource_Impl
: public SvxEditSource
, public SvxViewForwarder
, public SvxTextForwarder
, public SfxBroadcaster
84 AccessibleEmptyEditSource_Impl() {}
85 virtual ~AccessibleEmptyEditSource_Impl() {}
88 SvxTextForwarder
* GetTextForwarder() SAL_OVERRIDE
{ return this; }
89 SvxViewForwarder
* GetViewForwarder() SAL_OVERRIDE
{ return this; }
90 SvxEditSource
* Clone() const SAL_OVERRIDE
{ return NULL
; }
91 void UpdateData() SAL_OVERRIDE
{}
92 SfxBroadcaster
& GetBroadcaster() const SAL_OVERRIDE
{ return *(const_cast<AccessibleEmptyEditSource_Impl
*>(this)); }
95 sal_Int32
GetParagraphCount() const SAL_OVERRIDE
{ return 1; }
96 sal_Int32
GetTextLen( sal_Int32
/*nParagraph*/ ) const SAL_OVERRIDE
{ return 0; }
97 OUString
GetText( const ESelection
& /*rSel*/ ) const SAL_OVERRIDE
{ return OUString(); }
98 SfxItemSet
GetAttribs( const ESelection
& /*rSel*/, EditEngineAttribs
/*nOnlyHardAttrib*/ = EditEngineAttribs_All
) const SAL_OVERRIDE
100 // AW: Very dangerous: The former implementation used a SfxItemPool created on the
101 // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
102 // a deleted Pool by design.
103 return SfxItemSet(SdrObject::GetGlobalDrawObjectItemPool());
105 SfxItemSet
GetParaAttribs( sal_Int32
/*nPara*/ ) const SAL_OVERRIDE
{ return GetAttribs(ESelection()); }
106 void SetParaAttribs( sal_Int32
/*nPara*/, const SfxItemSet
& /*rSet*/ ) SAL_OVERRIDE
{}
107 void RemoveAttribs( const ESelection
& /*rSelection*/, bool /*bRemoveParaAttribs*/, sal_uInt16
/*nWhich*/ ) SAL_OVERRIDE
{}
108 void GetPortions( sal_Int32
/*nPara*/, std::vector
<sal_Int32
>& /*rList*/ ) const SAL_OVERRIDE
{}
110 sal_uInt16
GetItemState( const ESelection
& /*rSel*/, sal_uInt16
/*nWhich*/ ) const SAL_OVERRIDE
{ return 0; }
111 sal_uInt16
GetItemState( sal_Int32
/*nPara*/, sal_uInt16
/*nWhich*/ ) const SAL_OVERRIDE
{ return 0; }
113 SfxItemPool
* GetPool() const SAL_OVERRIDE
{ return NULL
; }
115 void QuickInsertText( const OUString
& /*rText*/, const ESelection
& /*rSel*/ ) SAL_OVERRIDE
{}
116 void QuickInsertField( const SvxFieldItem
& /*rFld*/, const ESelection
& /*rSel*/ ) SAL_OVERRIDE
{}
117 void QuickSetAttribs( const SfxItemSet
& /*rSet*/, const ESelection
& /*rSel*/ ) SAL_OVERRIDE
{}
118 void QuickInsertLineBreak( const ESelection
& /*rSel*/ ) SAL_OVERRIDE
{}
120 const SfxItemSet
* GetEmptyItemSetPtr() SAL_OVERRIDE
{ return 0; }
122 void AppendParagraph() SAL_OVERRIDE
{}
123 sal_Int32
AppendTextPortion( sal_Int32
/*nPara*/, const OUString
& /*rText*/, const SfxItemSet
& /*rSet*/ ) SAL_OVERRIDE
{ return 0; }
126 void CopyText(const SvxTextForwarder
& ) SAL_OVERRIDE
{}
128 OUString
CalcFieldValue( const SvxFieldItem
& /*rField*/, sal_Int32
/*nPara*/, sal_Int32
/*nPos*/, Color
*& /*rpTxtColor*/, Color
*& /*rpFldColor*/ ) SAL_OVERRIDE
132 void FieldClicked( const SvxFieldItem
&, sal_Int32
, sal_Int32
) SAL_OVERRIDE
{;}
134 bool IsValid() const SAL_OVERRIDE
{ return true; }
136 LanguageType
GetLanguage( sal_Int32
, sal_Int32
) const SAL_OVERRIDE
{ return LANGUAGE_DONTKNOW
; }
137 sal_Int32
GetFieldCount( sal_Int32
) const SAL_OVERRIDE
{ return 0; }
138 EFieldInfo
GetFieldInfo( sal_Int32
, sal_uInt16
) const SAL_OVERRIDE
{ return EFieldInfo(); }
139 EBulletInfo
GetBulletInfo( sal_Int32
) const SAL_OVERRIDE
{ return EBulletInfo(); }
140 Rectangle
GetCharBounds( sal_Int32
, sal_Int32
) const SAL_OVERRIDE
{ return Rectangle(); }
141 Rectangle
GetParaBounds( sal_Int32
) const SAL_OVERRIDE
{ return Rectangle(); }
142 MapMode
GetMapMode() const SAL_OVERRIDE
{ return MapMode(); }
143 OutputDevice
* GetRefDevice() const SAL_OVERRIDE
{ return NULL
; }
144 bool GetIndexAtPoint( const Point
&, sal_Int32
&, sal_Int32
& ) const SAL_OVERRIDE
{ return false; }
145 bool GetWordIndices( sal_Int32
, sal_Int32
, sal_Int32
&, sal_Int32
& ) const SAL_OVERRIDE
{ return false; }
146 bool GetAttributeRun( sal_Int32
&, sal_Int32
&, sal_Int32
, sal_Int32
, bool ) const SAL_OVERRIDE
{ return false; }
147 sal_Int32
GetLineCount( sal_Int32 nPara
) const SAL_OVERRIDE
{ return nPara
== 0 ? 1 : 0; }
148 sal_Int32
GetLineLen( sal_Int32
, sal_Int32
) const SAL_OVERRIDE
{ return 0; }
149 void GetLineBoundaries( /*out*/sal_Int32
& rStart
, /*out*/sal_Int32
& rEnd
, sal_Int32
/*nParagraph*/, sal_Int32
/*nLine*/ ) const SAL_OVERRIDE
{ rStart
= rEnd
= 0; }
150 sal_Int32
GetLineNumberAtIndex( sal_Int32
/*nPara*/, sal_Int32
/*nIndex*/ ) const SAL_OVERRIDE
{ return 0; }
152 // the following two methods would, strictly speaking, require
153 // a switch to a real EditSource, too. Fortunately, the
154 // AccessibleEditableTextPara implementation currently always
155 // calls GetEditViewForwarder(true) before doing
156 // changes. Thus, we rely on this behabviour here (problem
157 // when that changes: via accessibility API, it would no
158 // longer be possible to enter text in previously empty
160 bool Delete( const ESelection
& ) SAL_OVERRIDE
{ return false; }
161 bool InsertText( const OUString
&, const ESelection
& ) SAL_OVERRIDE
{ return false; }
162 bool QuickFormatDoc( bool ) SAL_OVERRIDE
{ return true; }
163 sal_Int16
GetDepth( sal_Int32
) const SAL_OVERRIDE
{ return -1; }
164 bool SetDepth( sal_Int32
, sal_Int16
) SAL_OVERRIDE
{ return true; }
166 Rectangle
GetVisArea() const SAL_OVERRIDE
{ return Rectangle(); }
167 Point
LogicToPixel( const Point
& rPoint
, const MapMode
& /*rMapMode*/ ) const SAL_OVERRIDE
{ return rPoint
; }
168 Point
PixelToLogic( const Point
& rPoint
, const MapMode
& /*rMapMode*/ ) const SAL_OVERRIDE
{ return rPoint
; }
173 // Implementing AccessibleProxyEditSource_Impl
176 AccessibleProxyEditSource_Impl::AccessibleProxyEditSource_Impl( SdrObject
& rObj
,
178 const Window
& rViewWindow
) :
179 maEditSource( rObj
, 0, rView
, rViewWindow
)
183 AccessibleProxyEditSource_Impl::~AccessibleProxyEditSource_Impl()
187 SvxTextForwarder
* AccessibleProxyEditSource_Impl::GetTextForwarder()
189 return maEditSource
.GetTextForwarder();
192 SvxViewForwarder
* AccessibleProxyEditSource_Impl::GetViewForwarder()
194 return maEditSource
.GetViewForwarder();
197 SvxEditViewForwarder
* AccessibleProxyEditSource_Impl::GetEditViewForwarder( bool bCreate
)
199 return maEditSource
.GetEditViewForwarder( bCreate
);
202 SvxEditSource
* AccessibleProxyEditSource_Impl::Clone() const
204 return maEditSource
.Clone();
207 void AccessibleProxyEditSource_Impl::UpdateData()
209 maEditSource
.UpdateData();
212 SfxBroadcaster
& AccessibleProxyEditSource_Impl::GetBroadcaster() const
214 return maEditSource
.GetBroadcaster();
219 // Implementing AccessibleEmptyEditSource
222 AccessibleEmptyEditSource::AccessibleEmptyEditSource( SdrObject
& rObj
,
224 const Window
& rViewWindow
) :
225 mpEditSource( new AccessibleEmptyEditSource_Impl() ),
228 mrViewWindow(rViewWindow
),
229 mbEditSourceEmpty( true )
231 if( mrObj
.GetModel() )
232 StartListening( *mrObj
.GetModel() );
235 AccessibleEmptyEditSource::~AccessibleEmptyEditSource()
237 if( !mbEditSourceEmpty
)
239 // deregister as listener
240 if( mpEditSource
.get() )
241 EndListening( mpEditSource
->GetBroadcaster() );
245 if( mrObj
.GetModel() )
246 EndListening( *mrObj
.GetModel() );
250 SvxTextForwarder
* AccessibleEmptyEditSource::GetTextForwarder()
252 if( !mpEditSource
.get() )
255 return mpEditSource
->GetTextForwarder();
258 SvxViewForwarder
* AccessibleEmptyEditSource::GetViewForwarder()
260 if( !mpEditSource
.get() )
263 return mpEditSource
->GetViewForwarder();
266 void AccessibleEmptyEditSource::Switch2ProxyEditSource()
268 // deregister EmptyEditSource model listener
269 if( mrObj
.GetModel() )
270 EndListening( *mrObj
.GetModel() );
272 SAL_WNODEPRECATED_DECLARATIONS_PUSH
273 ::std::auto_ptr
< SvxEditSource
> pProxySource( new AccessibleProxyEditSource_Impl(mrObj
, mrView
, mrViewWindow
) );
274 ::std::auto_ptr
< SvxEditSource
> tmp
= mpEditSource
;
275 SAL_WNODEPRECATED_DECLARATIONS_POP
276 mpEditSource
= pProxySource
;
279 // register as listener
280 StartListening( mpEditSource
->GetBroadcaster() );
282 // we've irrevocably a full EditSource now.
283 mbEditSourceEmpty
= false;
286 SvxEditViewForwarder
* AccessibleEmptyEditSource::GetEditViewForwarder( bool bCreate
)
288 if( !mpEditSource
.get() )
291 // switch edit source, if not yet done
292 if( mbEditSourceEmpty
&& bCreate
)
293 Switch2ProxyEditSource();
295 return mpEditSource
->GetEditViewForwarder( bCreate
);
298 SvxEditSource
* AccessibleEmptyEditSource::Clone() const
300 if( !mpEditSource
.get() )
303 return mpEditSource
->Clone();
306 void AccessibleEmptyEditSource::UpdateData()
308 if( mpEditSource
.get() )
309 mpEditSource
->UpdateData();
312 SfxBroadcaster
& AccessibleEmptyEditSource::GetBroadcaster() const
314 return *(const_cast<AccessibleEmptyEditSource
*>(this));
317 void AccessibleEmptyEditSource::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
319 const SdrHint
* pSdrHint
= PTR_CAST( SdrHint
, &rHint
);
321 if( pSdrHint
&& pSdrHint
->GetKind() == HINT_BEGEDIT
&&
322 &mrObj
== pSdrHint
->GetObject() && mpEditSource
.get() )
324 // switch edit source, if not yet done. This is necessary
325 // to become a full-fledged EditSource the first time a
326 // user start entering text in a previously empty object.
327 if( mbEditSourceEmpty
)
328 Switch2ProxyEditSource();
330 else if (pSdrHint
&& pSdrHint
->GetObject()!=NULL
)
332 // When the SdrObject just got a para outliner object then
333 // switch the edit source.
334 if (pSdrHint
->GetObject()->GetOutlinerParaObject() != NULL
)
335 Switch2ProxyEditSource();
342 } // end of namespace accessibility
346 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */