1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: AccessibleEmptyEditSource.cxx,v $
12 * This file is part of OpenOffice.org.
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.
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).
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.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_svx.hxx"
34 //------------------------------------------------------------------------
38 //------------------------------------------------------------------------
39 #include <svtools/itemset.hxx>
40 #include <svx/editdata.hxx>
41 #include <svx/outliner.hxx>
42 #include <svx/svdmodel.hxx>
43 #include <svx/svdobj.hxx>
44 #include <svx/svdpool.hxx>
46 //------------------------------------------------------------------------
48 // Project-local header
50 //------------------------------------------------------------------------
52 #include "AccessibleEmptyEditSource.hxx"
53 #include <svx/unoshtxt.hxx>
55 namespace accessibility
58 /** This class simply wraps a SvxTextEditSource, forwarding all
59 methods except the GetBroadcaster() call
61 class AccessibleProxyEditSource_Impl
: public SvxEditSource
64 /** Construct AccessibleEmptyEditSource_Impl
68 Proxy broadcaster to allow seamless flipping of edit source implementations. ProxyEditSource and EmptyEditSource
70 AccessibleProxyEditSource_Impl( SdrObject
& rObj
,
72 const Window
& rViewWindow
);
73 ~AccessibleProxyEditSource_Impl();
75 // from the SvxEditSource interface
76 SvxTextForwarder
* GetTextForwarder();
77 SvxViewForwarder
* GetViewForwarder();
78 SvxEditViewForwarder
* GetEditViewForwarder( sal_Bool bCreate
= sal_False
);
80 SvxEditSource
* Clone() const;
84 SfxBroadcaster
& GetBroadcaster() const;
87 SvxTextEditSource maEditSource
;
91 /** Dummy class, faking exactly one empty paragraph for EditEngine accessibility
93 class AccessibleEmptyEditSource_Impl
: public SvxEditSource
, public SvxViewForwarder
, public SvxTextForwarder
, public SfxBroadcaster
97 AccessibleEmptyEditSource_Impl() {}
98 ~AccessibleEmptyEditSource_Impl() {}
100 // from the SfxListener interface
101 void Notify( SfxBroadcaster
& rBC
, const SfxHint
& rHint
);
104 SvxTextForwarder
* GetTextForwarder() { return this; }
105 SvxViewForwarder
* GetViewForwarder() { return this; }
106 SvxEditSource
* Clone() const { return NULL
; }
108 SfxBroadcaster
& GetBroadcaster() const { return *(const_cast<AccessibleEmptyEditSource_Impl
*>(this)); }
111 USHORT
GetParagraphCount() const { return 1; }
112 USHORT
GetTextLen( USHORT
/*nParagraph*/ ) const { return 0; }
113 String
GetText( const ESelection
& /*rSel*/ ) const { return String(); }
114 SfxItemSet
GetAttribs( const ESelection
& /*rSel*/, BOOL
/*bOnlyHardAttrib*/ = 0 ) const
116 // AW: Very dangerous: The former implementation used a SfxItemPool created on the
117 // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
118 // a deleted Pool by design.
119 return SfxItemSet(SdrObject::GetGlobalDrawObjectItemPool());
121 SfxItemSet
GetParaAttribs( USHORT
/*nPara*/ ) const { return GetAttribs(ESelection()); }
122 void SetParaAttribs( USHORT
/*nPara*/, const SfxItemSet
& /*rSet*/ ) {}
123 void RemoveAttribs( const ESelection
& /*rSelection*/, sal_Bool
/*bRemoveParaAttribs*/, sal_uInt16
/*nWhich*/ ){}
124 void GetPortions( USHORT
/*nPara*/, SvUShorts
& /*rList*/ ) const {}
126 USHORT
GetItemState( const ESelection
& /*rSel*/, USHORT
/*nWhich*/ ) const { return 0; }
127 USHORT
GetItemState( USHORT
/*nPara*/, USHORT
/*nWhich*/ ) const { return 0; }
129 SfxItemPool
* GetPool() const { return NULL
; }
131 void QuickInsertText( const String
& /*rText*/, const ESelection
& /*rSel*/ ) {}
132 void QuickInsertField( const SvxFieldItem
& /*rFld*/, const ESelection
& /*rSel*/ ) {}
133 void QuickSetAttribs( const SfxItemSet
& /*rSet*/, const ESelection
& /*rSel*/ ) {}
134 void QuickInsertLineBreak( const ESelection
& /*rSel*/ ) {}
136 const SfxItemSet
* GetEmptyItemSetPtr() { return 0; }
138 void AppendParagraph() {}
139 xub_StrLen
AppendTextPortion( USHORT
/*nPara*/, const String
& /*rText*/, const SfxItemSet
& /*rSet*/ ) { return 0; }
142 void CopyText(const SvxTextForwarder
& ){}
144 XubString
CalcFieldValue( const SvxFieldItem
& /*rField*/, USHORT
/*nPara*/, USHORT
/*nPos*/, Color
*& /*rpTxtColor*/, Color
*& /*rpFldColor*/ )
148 BOOL
IsValid() const { return sal_True
; }
150 void SetNotifyHdl( const Link
& ) {}
151 LanguageType
GetLanguage( USHORT
, USHORT
) const { return LANGUAGE_DONTKNOW
; }
152 USHORT
GetFieldCount( USHORT
) const { return 0; }
153 EFieldInfo
GetFieldInfo( USHORT
, USHORT
) const { return EFieldInfo(); }
154 EBulletInfo
GetBulletInfo( USHORT
) const { return EBulletInfo(); }
155 Rectangle
GetCharBounds( USHORT
, USHORT
) const { return Rectangle(); }
156 Rectangle
GetParaBounds( USHORT
) const { return Rectangle(); }
157 MapMode
GetMapMode() const { return MapMode(); }
158 OutputDevice
* GetRefDevice() const { return NULL
; }
159 sal_Bool
GetIndexAtPoint( const Point
&, USHORT
&, USHORT
& ) const { return sal_False
; }
160 sal_Bool
GetWordIndices( USHORT
, USHORT
, USHORT
&, USHORT
& ) const { return sal_False
; }
161 sal_Bool
GetAttributeRun( USHORT
&, USHORT
&, USHORT
, USHORT
) const { return sal_False
; }
162 USHORT
GetLineCount( USHORT nPara
) const { return nPara
== 0 ? 1 : 0; }
163 USHORT
GetLineLen( USHORT
, USHORT
) const { return 0; }
164 void GetLineBoundaries( /*out*/USHORT
& rStart
, /*out*/USHORT
& rEnd
, USHORT
/*nParagraph*/, USHORT
/*nLine*/ ) const { rStart
= rEnd
= 0; }
165 USHORT
GetLineNumberAtIndex( USHORT
/*nPara*/, USHORT
/*nIndex*/ ) const { return 0; }
167 // the following two methods would, strictly speaking, require
168 // a switch to a real EditSource, too. Fortunately, the
169 // AccessibleEditableTextPara implementation currently always
170 // calls GetEditViewForwarder(true) before doing
171 // changes. Thus, we rely on this behabviour here (problem
172 // when that changes: via accessibility API, it would no
173 // longer be possible to enter text in previously empty
175 sal_Bool
Delete( const ESelection
& ) { return sal_False
; }
176 sal_Bool
InsertText( const String
&, const ESelection
& ) { return sal_False
; }
177 sal_Bool
QuickFormatDoc( BOOL
) { return sal_True
; }
178 sal_Int16
GetDepth( USHORT
) const { return -1; }
179 sal_Bool
SetDepth( USHORT
, sal_Int16
) { return sal_True
; }
181 Rectangle
GetVisArea() const { return Rectangle(); }
182 Point
LogicToPixel( const Point
& rPoint
, const MapMode
& /*rMapMode*/ ) const { return rPoint
; }
183 Point
PixelToLogic( const Point
& rPoint
, const MapMode
& /*rMapMode*/ ) const { return rPoint
; }
187 // -------------------------------------------------------------------------
188 // Implementing AccessibleProxyEditSource_Impl
189 // -------------------------------------------------------------------------
191 AccessibleProxyEditSource_Impl::AccessibleProxyEditSource_Impl( SdrObject
& rObj
,
193 const Window
& rViewWindow
) :
194 maEditSource( rObj
, 0, rView
, rViewWindow
)
198 AccessibleProxyEditSource_Impl::~AccessibleProxyEditSource_Impl()
202 SvxTextForwarder
* AccessibleProxyEditSource_Impl::GetTextForwarder()
204 return maEditSource
.GetTextForwarder();
207 SvxViewForwarder
* AccessibleProxyEditSource_Impl::GetViewForwarder()
209 return maEditSource
.GetViewForwarder();
212 SvxEditViewForwarder
* AccessibleProxyEditSource_Impl::GetEditViewForwarder( sal_Bool bCreate
)
214 return maEditSource
.GetEditViewForwarder( bCreate
);
217 SvxEditSource
* AccessibleProxyEditSource_Impl::Clone() const
219 return maEditSource
.Clone();
222 void AccessibleProxyEditSource_Impl::UpdateData()
224 maEditSource
.UpdateData();
227 SfxBroadcaster
& AccessibleProxyEditSource_Impl::GetBroadcaster() const
229 return maEditSource
.GetBroadcaster();
233 // -------------------------------------------------------------------------
234 // Implementing AccessibleEmptyEditSource
235 // -------------------------------------------------------------------------
237 AccessibleEmptyEditSource::AccessibleEmptyEditSource( SdrObject
& rObj
,
239 const Window
& rViewWindow
) :
240 mpEditSource( new AccessibleEmptyEditSource_Impl() ),
243 mrViewWindow(rViewWindow
),
244 mbEditSourceEmpty( true )
246 if( mrObj
.GetModel() )
247 StartListening( *mrObj
.GetModel() );
250 AccessibleEmptyEditSource::~AccessibleEmptyEditSource()
252 if( !mbEditSourceEmpty
)
254 // deregister as listener
255 if( mpEditSource
.get() )
256 EndListening( mpEditSource
->GetBroadcaster() );
260 if( mrObj
.GetModel() )
261 EndListening( *mrObj
.GetModel() );
265 SvxTextForwarder
* AccessibleEmptyEditSource::GetTextForwarder()
267 if( !mpEditSource
.get() )
270 return mpEditSource
->GetTextForwarder();
273 SvxViewForwarder
* AccessibleEmptyEditSource::GetViewForwarder()
275 if( !mpEditSource
.get() )
278 return mpEditSource
->GetViewForwarder();
281 void AccessibleEmptyEditSource::Switch2ProxyEditSource()
283 // deregister EmptyEditSource model listener
284 if( mrObj
.GetModel() )
285 EndListening( *mrObj
.GetModel() );
287 ::std::auto_ptr
< SvxEditSource
> pProxySource( new AccessibleProxyEditSource_Impl(mrObj
, mrView
, mrViewWindow
) );
288 ::std::auto_ptr
< SvxEditSource
> tmp
= mpEditSource
;
289 mpEditSource
= pProxySource
;
292 // register as listener
293 StartListening( mpEditSource
->GetBroadcaster() );
295 // we've irrevocably a full EditSource now.
296 mbEditSourceEmpty
= false;
299 SvxEditViewForwarder
* AccessibleEmptyEditSource::GetEditViewForwarder( sal_Bool bCreate
)
301 if( !mpEditSource
.get() )
304 // switch edit source, if not yet done
305 if( mbEditSourceEmpty
&& bCreate
)
306 Switch2ProxyEditSource();
308 return mpEditSource
->GetEditViewForwarder( bCreate
);
311 SvxEditSource
* AccessibleEmptyEditSource::Clone() const
313 if( !mpEditSource
.get() )
316 return mpEditSource
->Clone();
319 void AccessibleEmptyEditSource::UpdateData()
321 if( mpEditSource
.get() )
322 mpEditSource
->UpdateData();
325 SfxBroadcaster
& AccessibleEmptyEditSource::GetBroadcaster() const
327 return *(const_cast<AccessibleEmptyEditSource
*>(this));
330 void AccessibleEmptyEditSource::Notify( SfxBroadcaster
& /*rBC*/, const SfxHint
& rHint
)
332 const SdrHint
* pSdrHint
= PTR_CAST( SdrHint
, &rHint
);
334 if( pSdrHint
&& pSdrHint
->GetKind() == HINT_BEGEDIT
&&
335 &mrObj
== pSdrHint
->GetObject() && mpEditSource
.get() )
337 // switch edit source, if not yet done. This is necessary
338 // to become a full-fledged EditSource the first time a
339 // user start entering text in a previously empty object.
340 if( mbEditSourceEmpty
)
341 Switch2ProxyEditSource();
348 } // end of namespace accessibility
350 //------------------------------------------------------------------------