Bump version to 6.4.7.2.M8
[LibreOffice.git] / svx / source / accessibility / AccessibleEmptyEditSource.cxx
blobc39bbc26b6acdce36eabc7a50b7c7e4cdcea1a04
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
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 .
21 // Global header
24 #include <memory>
25 #include <svl/itemset.hxx>
26 #include <editeng/editdata.hxx>
27 #include <editeng/outliner.hxx>
28 #include <svx/svdmodel.hxx>
29 #include <svx/svdobj.hxx>
30 #include <svx/svdpool.hxx>
33 // Project-local header
36 #include "AccessibleEmptyEditSource.hxx"
37 #include <svx/unoshtxt.hxx>
39 namespace accessibility
42 /** This class simply wraps a SvxTextEditSource, forwarding all
43 methods except the GetBroadcaster() call
45 class AccessibleProxyEditSource_Impl : public SvxEditSource
47 public:
48 /** Construct AccessibleEmptyEditSource_Impl
50 @param rBrdCast
52 Proxy broadcaster to allow seamless flipping of edit source implementations. ProxyEditSource and EmptyEditSource
54 AccessibleProxyEditSource_Impl( SdrObject& rObj,
55 SdrView& rView,
56 const OutputDevice& rViewWindow );
58 // from the SvxEditSource interface
59 SvxTextForwarder* GetTextForwarder() override;
60 SvxViewForwarder* GetViewForwarder() override;
61 SvxEditViewForwarder* GetEditViewForwarder( bool bCreate = false ) override;
63 std::unique_ptr<SvxEditSource> Clone() const override;
65 void UpdateData() override;
67 SfxBroadcaster& GetBroadcaster() const override;
69 private:
70 SvxTextEditSource maEditSource;
74 /** Dummy class, faking exactly one empty paragraph for EditEngine accessibility
76 class AccessibleEmptyEditSource_Impl : public SvxEditSource, public SvxViewForwarder, public SvxTextForwarder, public SfxBroadcaster
78 public:
80 AccessibleEmptyEditSource_Impl() {}
82 // SvxEditSource
83 SvxTextForwarder* GetTextForwarder() override { return this; }
84 SvxViewForwarder* GetViewForwarder() override { return this; }
85 std::unique_ptr<SvxEditSource> Clone() const override { return nullptr; }
86 void UpdateData() override {}
87 SfxBroadcaster& GetBroadcaster() const override { return *const_cast<AccessibleEmptyEditSource_Impl*>(this); }
89 // SvxTextForwarder
90 sal_Int32 GetParagraphCount() const override { return 1; }
91 sal_Int32 GetTextLen( sal_Int32 /*nParagraph*/ ) const override { return 0; }
92 OUString GetText( const ESelection& /*rSel*/ ) const override { return OUString(); }
93 SfxItemSet GetAttribs( const ESelection& /*rSel*/, EditEngineAttribs /*nOnlyHardAttrib*/ = EditEngineAttribs::All ) const override
95 // AW: Very dangerous: The former implementation used a SfxItemPool created on the
96 // fly which of course was deleted again ASAP. Thus, the returned SfxItemSet was using
97 // a deleted Pool by design.
98 return SfxItemSet(SdrObject::GetGlobalDrawObjectItemPool());
100 SfxItemSet GetParaAttribs( sal_Int32 /*nPara*/ ) const override { return GetAttribs(ESelection()); }
101 void SetParaAttribs( sal_Int32 /*nPara*/, const SfxItemSet& /*rSet*/ ) override {}
102 void RemoveAttribs( const ESelection& /*rSelection*/ ) override {}
103 void GetPortions( sal_Int32 /*nPara*/, std::vector<sal_Int32>& /*rList*/ ) const override {}
105 SfxItemState GetItemState( const ESelection& /*rSel*/, sal_uInt16 /*nWhich*/ ) const override { return SfxItemState::UNKNOWN; }
106 SfxItemState GetItemState( sal_Int32 /*nPara*/, sal_uInt16 /*nWhich*/ ) const override { return SfxItemState::UNKNOWN; }
108 SfxItemPool* GetPool() const override { return nullptr; }
110 void QuickInsertText( const OUString& /*rText*/, const ESelection& /*rSel*/ ) override {}
111 void QuickInsertField( const SvxFieldItem& /*rFld*/, const ESelection& /*rSel*/ ) override {}
112 void QuickSetAttribs( const SfxItemSet& /*rSet*/, const ESelection& /*rSel*/ ) override {}
113 void QuickInsertLineBreak( const ESelection& /*rSel*/ ) override {}
115 const SfxItemSet * GetEmptyItemSetPtr() override { return nullptr; }
117 void AppendParagraph() override {}
118 sal_Int32 AppendTextPortion( sal_Int32 /*nPara*/, const OUString & /*rText*/, const SfxItemSet & /*rSet*/ ) override { return 0; }
120 //XTextCopy
121 void CopyText(const SvxTextForwarder& ) override {}
123 OUString CalcFieldValue( const SvxFieldItem& /*rField*/, sal_Int32 /*nPara*/, sal_Int32 /*nPos*/, boost::optional<Color>& /*rpTxtColor*/, boost::optional<Color>& /*rpFldColor*/ ) override
125 return OUString();
127 void FieldClicked( const SvxFieldItem& ) override {}
129 bool IsValid() const override { return true; }
131 LanguageType GetLanguage( sal_Int32, sal_Int32 ) const override { return LANGUAGE_DONTKNOW; }
132 sal_Int32 GetFieldCount( sal_Int32 ) const override { return 0; }
133 EFieldInfo GetFieldInfo( sal_Int32, sal_uInt16 ) const override { return EFieldInfo(); }
134 EBulletInfo GetBulletInfo( sal_Int32 ) const override { return EBulletInfo(); }
135 tools::Rectangle GetCharBounds( sal_Int32, sal_Int32 ) const override { return tools::Rectangle(); }
136 tools::Rectangle GetParaBounds( sal_Int32 ) const override { return tools::Rectangle(); }
137 MapMode GetMapMode() const override { return MapMode(); }
138 OutputDevice* GetRefDevice() const override { return nullptr; }
139 bool GetIndexAtPoint( const Point&, sal_Int32&, sal_Int32& ) const override { return false; }
140 bool GetWordIndices( sal_Int32, sal_Int32, sal_Int32&, sal_Int32& ) const override { return false; }
141 bool GetAttributeRun( sal_Int32&, sal_Int32&, sal_Int32, sal_Int32, bool ) const override { return false; }
142 sal_Int32 GetLineCount( sal_Int32 nPara ) const override { return nPara == 0 ? 1 : 0; }
143 sal_Int32 GetLineLen( sal_Int32, sal_Int32 ) const override { return 0; }
144 void GetLineBoundaries( /*out*/sal_Int32 & rStart, /*out*/sal_Int32 & rEnd, sal_Int32 /*nParagraph*/, sal_Int32 /*nLine*/ ) const override { rStart = rEnd = 0; }
145 sal_Int32 GetLineNumberAtIndex( sal_Int32 /*nPara*/, sal_Int32 /*nIndex*/ ) const override { return 0; }
147 // the following two methods would, strictly speaking, require
148 // a switch to a real EditSource, too. Fortunately, the
149 // AccessibleEditableTextPara implementation currently always
150 // calls GetEditViewForwarder(true) before doing
151 // changes. Thus, we rely on this behaviour here (problem
152 // when that changes: via accessibility API, it would no
153 // longer be possible to enter text in previously empty
154 // shapes).
155 bool Delete( const ESelection& ) override { return false; }
156 bool InsertText( const OUString&, const ESelection& ) override { return false; }
157 bool QuickFormatDoc( bool ) override { return true; }
158 sal_Int16 GetDepth( sal_Int32 ) const override { return -1; }
159 bool SetDepth( sal_Int32, sal_Int16 ) override { return true; }
161 Point LogicToPixel( const Point& rPoint, const MapMode& /*rMapMode*/ ) const override { return rPoint; }
162 Point PixelToLogic( const Point& rPoint, const MapMode& /*rMapMode*/ ) const override { return rPoint; }
167 // Implementing AccessibleProxyEditSource_Impl
170 AccessibleProxyEditSource_Impl::AccessibleProxyEditSource_Impl( SdrObject& rObj,
171 SdrView& rView,
172 const OutputDevice& rViewWindow ) :
173 maEditSource( rObj, nullptr, rView, rViewWindow )
177 SvxTextForwarder* AccessibleProxyEditSource_Impl::GetTextForwarder()
179 return maEditSource.GetTextForwarder();
182 SvxViewForwarder* AccessibleProxyEditSource_Impl::GetViewForwarder()
184 return maEditSource.GetViewForwarder();
187 SvxEditViewForwarder* AccessibleProxyEditSource_Impl::GetEditViewForwarder( bool bCreate )
189 return maEditSource.GetEditViewForwarder( bCreate );
192 std::unique_ptr<SvxEditSource> AccessibleProxyEditSource_Impl::Clone() const
194 return maEditSource.Clone();
197 void AccessibleProxyEditSource_Impl::UpdateData()
199 maEditSource.UpdateData();
202 SfxBroadcaster& AccessibleProxyEditSource_Impl::GetBroadcaster() const
204 return maEditSource.GetBroadcaster();
208 // Implementing AccessibleEmptyEditSource
211 AccessibleEmptyEditSource::AccessibleEmptyEditSource( SdrObject& rObj,
212 SdrView& rView,
213 const OutputDevice& rViewWindow ) :
214 mpEditSource( new AccessibleEmptyEditSource_Impl() ),
215 mrObj(rObj),
216 mrView(rView),
217 mrViewWindow(rViewWindow),
218 mbEditSourceEmpty( true )
220 StartListening( mrObj.getSdrModelFromSdrObject() );
223 AccessibleEmptyEditSource::~AccessibleEmptyEditSource()
225 if( !mbEditSourceEmpty )
227 // deregister as listener
228 if (mpEditSource)
229 EndListening( mpEditSource->GetBroadcaster() );
231 else
233 EndListening( mrObj.getSdrModelFromSdrObject() );
237 SvxTextForwarder* AccessibleEmptyEditSource::GetTextForwarder()
239 if (!mpEditSource)
240 return nullptr;
242 return mpEditSource->GetTextForwarder();
245 SvxViewForwarder* AccessibleEmptyEditSource::GetViewForwarder()
247 if (!mpEditSource)
248 return nullptr;
250 return mpEditSource->GetViewForwarder();
253 void AccessibleEmptyEditSource::Switch2ProxyEditSource()
255 // deregister EmptyEditSource model listener
256 EndListening( mrObj.getSdrModelFromSdrObject() );
258 ::std::unique_ptr< SvxEditSource > pProxySource( new AccessibleProxyEditSource_Impl(mrObj, mrView, mrViewWindow) );
259 mpEditSource.swap(pProxySource);
261 // register as listener
262 StartListening( mpEditSource->GetBroadcaster() );
264 // we've irrevocably a full EditSource now.
265 mbEditSourceEmpty = false;
268 SvxEditViewForwarder* AccessibleEmptyEditSource::GetEditViewForwarder( bool bCreate )
270 if (!mpEditSource)
271 return nullptr;
273 // switch edit source, if not yet done
274 if( mbEditSourceEmpty && bCreate )
275 Switch2ProxyEditSource();
277 return mpEditSource->GetEditViewForwarder( bCreate );
280 std::unique_ptr<SvxEditSource> AccessibleEmptyEditSource::Clone() const
282 if (!mpEditSource)
283 return nullptr;
285 return mpEditSource->Clone();
288 void AccessibleEmptyEditSource::UpdateData()
290 if (mpEditSource)
291 mpEditSource->UpdateData();
294 SfxBroadcaster& AccessibleEmptyEditSource::GetBroadcaster() const
296 return *const_cast<AccessibleEmptyEditSource*>(this);
299 void AccessibleEmptyEditSource::Notify( SfxBroadcaster& /*rBC*/, const SfxHint& rHint )
301 const SdrHint* pSdrHint = ( rHint.GetId() == SfxHintId::ThisIsAnSdrHint ? static_cast<const SdrHint*>(&rHint) : nullptr );
303 if( pSdrHint && pSdrHint->GetKind() == SdrHintKind::BeginEdit &&
304 &mrObj == pSdrHint->GetObject() && mpEditSource.get() )
306 // switch edit source, if not yet done. This is necessary
307 // to become a full-fledged EditSource the first time a
308 // user start entering text in a previously empty object.
309 if( mbEditSourceEmpty )
310 Switch2ProxyEditSource();
312 else if (pSdrHint && pSdrHint->GetObject()!=nullptr)
314 // When the SdrObject just got a para outliner object then
315 // switch the edit source.
316 if (pSdrHint->GetObject()->GetOutlinerParaObject() != nullptr)
317 Switch2ProxyEditSource();
320 // forward messages
321 Broadcast( rHint );
324 } // end of namespace accessibility
327 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */