xref: /AOO41X/main/svx/source/table/celleditsource.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
29*cdf0e10cSrcweir #include "precompiled_svx.hxx"
30*cdf0e10cSrcweir 
31*cdf0e10cSrcweir #include <com/sun/star/linguistic2/XLinguServiceManager.hpp>
32*cdf0e10cSrcweir 
33*cdf0e10cSrcweir #include <rtl/ref.hxx>
34*cdf0e10cSrcweir #include <osl/mutex.hxx>
35*cdf0e10cSrcweir #include <vos/mutex.hxx>
36*cdf0e10cSrcweir #include <vcl/svapp.hxx>
37*cdf0e10cSrcweir #include <comphelper/processfactory.hxx>
38*cdf0e10cSrcweir #include <svl/lstner.hxx>
39*cdf0e10cSrcweir #include <svl/hint.hxx>
40*cdf0e10cSrcweir #include <svl/style.hxx>
41*cdf0e10cSrcweir 
42*cdf0e10cSrcweir #include "celleditsource.hxx"
43*cdf0e10cSrcweir #include "cell.hxx"
44*cdf0e10cSrcweir #include "svx/svdmodel.hxx"
45*cdf0e10cSrcweir #include "svx/svdoutl.hxx"
46*cdf0e10cSrcweir #include "svx/svdobj.hxx"
47*cdf0e10cSrcweir #include "editeng/unoedhlp.hxx"
48*cdf0e10cSrcweir #include "svx/svdview.hxx"
49*cdf0e10cSrcweir #include "svx/svdetc.hxx"
50*cdf0e10cSrcweir #include "editeng/outliner.hxx"
51*cdf0e10cSrcweir #include "editeng/unoforou.hxx"
52*cdf0e10cSrcweir #include "editeng/unoviwou.hxx"
53*cdf0e10cSrcweir #include "editeng/outlobj.hxx"
54*cdf0e10cSrcweir #include "svx/svdotext.hxx"
55*cdf0e10cSrcweir #include "svx/svdpage.hxx"
56*cdf0e10cSrcweir #include "editeng/editeng.hxx"
57*cdf0e10cSrcweir #include "editeng/unotext.hxx"
58*cdf0e10cSrcweir #include "svx/sdrpaintwindow.hxx"
59*cdf0e10cSrcweir 
60*cdf0e10cSrcweir //------------------------------------------------------------------------
61*cdf0e10cSrcweir 
62*cdf0e10cSrcweir using ::rtl::OUString;
63*cdf0e10cSrcweir using namespace ::osl;
64*cdf0e10cSrcweir using namespace ::vos;
65*cdf0e10cSrcweir 
66*cdf0e10cSrcweir using namespace ::com::sun::star::uno;
67*cdf0e10cSrcweir using namespace ::com::sun::star::linguistic2;
68*cdf0e10cSrcweir using namespace ::com::sun::star::lang;
69*cdf0e10cSrcweir 
70*cdf0e10cSrcweir //------------------------------------------------------------------------
71*cdf0e10cSrcweir 
72*cdf0e10cSrcweir namespace sdr { namespace table {
73*cdf0e10cSrcweir 
74*cdf0e10cSrcweir //------------------------------------------------------------------------
75*cdf0e10cSrcweir // CellEditSourceImpl
76*cdf0e10cSrcweir //------------------------------------------------------------------------
77*cdf0e10cSrcweir 
78*cdf0e10cSrcweir /** @descr
79*cdf0e10cSrcweir     <p>This class essentially provides the text and view forwarders. If
80*cdf0e10cSrcweir     no SdrView is given, this class handles the UNO objects, which are
81*cdf0e10cSrcweir     currently not concerned with view issues. In this case,
82*cdf0e10cSrcweir     GetViewForwarder() always returns NULL and the underlying
83*cdf0e10cSrcweir     EditEngine of the SvxTextForwarder is a background one (i.e. not
84*cdf0e10cSrcweir     the official DrawOutliner, but one created exclusively for this
85*cdf0e10cSrcweir     object, with no relation to a view).
86*cdf0e10cSrcweir     </p>
87*cdf0e10cSrcweir 
88*cdf0e10cSrcweir     <p>If a SdrView is given at construction time, the caller is
89*cdf0e10cSrcweir     responsible for destroying this object when the view becomes
90*cdf0e10cSrcweir     invalid (the views cannot notify). If GetViewForwarder(sal_True)
91*cdf0e10cSrcweir     is called, the underlying shape is put into edit mode, the view
92*cdf0e10cSrcweir     forwarder returned encapsulates the OutlinerView and the next call
93*cdf0e10cSrcweir     to GetTextForwarder() yields a forwarder encapsulating the actual
94*cdf0e10cSrcweir     DrawOutliner. Thus, changes on that Outliner are immediately
95*cdf0e10cSrcweir     reflected on the screen. If the object leaves edit mode, the old
96*cdf0e10cSrcweir     behaviour is restored.</p>
97*cdf0e10cSrcweir  */
98*cdf0e10cSrcweir class CellEditSourceImpl : public SfxListener, public SfxBroadcaster
99*cdf0e10cSrcweir {
100*cdf0e10cSrcweir private:
101*cdf0e10cSrcweir 	oslInterlockedCount				maRefCount;
102*cdf0e10cSrcweir 
103*cdf0e10cSrcweir 	SdrView*						mpView;
104*cdf0e10cSrcweir     const Window*					mpWindow;
105*cdf0e10cSrcweir 	SdrModel*						mpModel;
106*cdf0e10cSrcweir 	SdrOutliner*					mpOutliner;
107*cdf0e10cSrcweir 	SvxOutlinerForwarder*			mpTextForwarder;
108*cdf0e10cSrcweir 	SvxDrawOutlinerViewForwarder*	mpViewForwarder;
109*cdf0e10cSrcweir 	Reference< ::com::sun::star::linguistic2::XLinguServiceManager > mxLinguServiceManager;
110*cdf0e10cSrcweir     Point							maTextOffset;
111*cdf0e10cSrcweir 	bool							mbDataValid;
112*cdf0e10cSrcweir 	bool							mbDisposed;
113*cdf0e10cSrcweir 	bool							mbIsLocked;
114*cdf0e10cSrcweir 	bool							mbNeedsUpdate;
115*cdf0e10cSrcweir 	bool							mbOldUndoMode;
116*cdf0e10cSrcweir     bool							mbForwarderIsEditMode;		// have to reflect that, since ENDEDIT can happen more often
117*cdf0e10cSrcweir     bool							mbShapeIsEditMode;			// #104157# only true, if HINT_BEGEDIT was received
118*cdf0e10cSrcweir     bool							mbNotificationsDisabled;	// prevent EditEngine/Outliner notifications (e.g. when setting up forwarder)
119*cdf0e10cSrcweir 
120*cdf0e10cSrcweir 	CellRef							mxCell;
121*cdf0e10cSrcweir 	SvxUnoTextRangeBaseList			maTextRanges;
122*cdf0e10cSrcweir 
123*cdf0e10cSrcweir     SvxTextForwarder*				GetBackgroundTextForwarder();
124*cdf0e10cSrcweir     SvxTextForwarder*				GetEditModeTextForwarder();
125*cdf0e10cSrcweir     SvxDrawOutlinerViewForwarder*	CreateViewForwarder();
126*cdf0e10cSrcweir 
127*cdf0e10cSrcweir     void 							SetupOutliner();
128*cdf0e10cSrcweir     void 							UpdateOutliner();
129*cdf0e10cSrcweir 
130*cdf0e10cSrcweir     bool							HasView() const { return mpView != 0; }
131*cdf0e10cSrcweir 	bool							IsEditMode() const { return mxCell->IsTextEditActive(); };
132*cdf0e10cSrcweir 	void							dispose();
133*cdf0e10cSrcweir 
134*cdf0e10cSrcweir public:
135*cdf0e10cSrcweir 	CellEditSourceImpl( const CellRef& xCell );
136*cdf0e10cSrcweir 	CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow );
137*cdf0e10cSrcweir 	~CellEditSourceImpl();
138*cdf0e10cSrcweir 
139*cdf0e10cSrcweir 	void SAL_CALL acquire();
140*cdf0e10cSrcweir 	void SAL_CALL release();
141*cdf0e10cSrcweir 
142*cdf0e10cSrcweir 	virtual void			Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
143*cdf0e10cSrcweir 
144*cdf0e10cSrcweir 	SvxEditSource*			Clone() const;
145*cdf0e10cSrcweir 	SvxTextForwarder*		GetTextForwarder();
146*cdf0e10cSrcweir     SvxEditViewForwarder* 	GetEditViewForwarder( sal_Bool );
147*cdf0e10cSrcweir 	void					UpdateData();
148*cdf0e10cSrcweir 
149*cdf0e10cSrcweir 	void addRange( SvxUnoTextRangeBase* pNewRange );
150*cdf0e10cSrcweir 	void removeRange( SvxUnoTextRangeBase* pOldRange );
151*cdf0e10cSrcweir 	const SvxUnoTextRangeBaseList& getRanges() const;
152*cdf0e10cSrcweir 
153*cdf0e10cSrcweir 	void 					lock();
154*cdf0e10cSrcweir 	void 					unlock();
155*cdf0e10cSrcweir 
156*cdf0e10cSrcweir 	sal_Bool					IsValid() const;
157*cdf0e10cSrcweir 
158*cdf0e10cSrcweir     Rectangle				GetVisArea();
159*cdf0e10cSrcweir     Point					LogicToPixel( const Point&, const MapMode& rMapMode );
160*cdf0e10cSrcweir     Point 					PixelToLogic( const Point&, const MapMode& rMapMode );
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir     DECL_LINK( NotifyHdl, EENotify* );
163*cdf0e10cSrcweir 
164*cdf0e10cSrcweir 	void ChangeModel( SdrModel* pNewModel );
165*cdf0e10cSrcweir };
166*cdf0e10cSrcweir 
167*cdf0e10cSrcweir //------------------------------------------------------------------------
168*cdf0e10cSrcweir 
169*cdf0e10cSrcweir CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell )
170*cdf0e10cSrcweir   :	maRefCount		( 0 ),
171*cdf0e10cSrcweir 	mpView			( NULL ),
172*cdf0e10cSrcweir 	mpWindow		( NULL ),
173*cdf0e10cSrcweir 	mpModel			( NULL ),
174*cdf0e10cSrcweir 	mpOutliner		( NULL ),
175*cdf0e10cSrcweir 	mpTextForwarder	( NULL ),
176*cdf0e10cSrcweir 	mpViewForwarder	( NULL ),
177*cdf0e10cSrcweir 	mbDataValid		( false ),
178*cdf0e10cSrcweir 	mbDisposed		( false ),
179*cdf0e10cSrcweir 	mbIsLocked		( false ),
180*cdf0e10cSrcweir 	mbNeedsUpdate	( false ),
181*cdf0e10cSrcweir 	mbOldUndoMode	( false ),
182*cdf0e10cSrcweir 	mbForwarderIsEditMode ( false ),
183*cdf0e10cSrcweir 	mbShapeIsEditMode	  ( false ),
184*cdf0e10cSrcweir 	mbNotificationsDisabled ( false ),
185*cdf0e10cSrcweir 	mxCell( xCell )
186*cdf0e10cSrcweir {
187*cdf0e10cSrcweir }
188*cdf0e10cSrcweir 
189*cdf0e10cSrcweir //------------------------------------------------------------------------
190*cdf0e10cSrcweir 
191*cdf0e10cSrcweir CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow )
192*cdf0e10cSrcweir   :	maRefCount		( 0 ),
193*cdf0e10cSrcweir     mpView			( &rView ),
194*cdf0e10cSrcweir     mpWindow		( &rWindow ),
195*cdf0e10cSrcweir 	mpModel			( NULL ),
196*cdf0e10cSrcweir 	mpOutliner		( NULL ),
197*cdf0e10cSrcweir 	mpTextForwarder	( NULL ),
198*cdf0e10cSrcweir 	mpViewForwarder	( NULL ),
199*cdf0e10cSrcweir 	mbDataValid		( false ),
200*cdf0e10cSrcweir 	mbDisposed		( false ),
201*cdf0e10cSrcweir 	mbIsLocked		( false ),
202*cdf0e10cSrcweir 	mbNeedsUpdate	( false ),
203*cdf0e10cSrcweir 	mbOldUndoMode	( false ),
204*cdf0e10cSrcweir 	mbForwarderIsEditMode ( false ),
205*cdf0e10cSrcweir     mbShapeIsEditMode	  ( true ),
206*cdf0e10cSrcweir 	mbNotificationsDisabled ( false ),
207*cdf0e10cSrcweir 	mxCell( xCell )
208*cdf0e10cSrcweir {
209*cdf0e10cSrcweir 	if( mpView )
210*cdf0e10cSrcweir 		StartListening( *mpView );
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir     // #104157# Init edit mode state from shape info (IsTextEditActive())
213*cdf0e10cSrcweir     mbShapeIsEditMode = IsEditMode();
214*cdf0e10cSrcweir }
215*cdf0e10cSrcweir 
216*cdf0e10cSrcweir //------------------------------------------------------------------------
217*cdf0e10cSrcweir 
218*cdf0e10cSrcweir CellEditSourceImpl::~CellEditSourceImpl()
219*cdf0e10cSrcweir {
220*cdf0e10cSrcweir 	DBG_ASSERT( mbIsLocked == sal_False, "CellEditSourceImpl::~CellEditSourceImpl(), was not unlocked before dispose!" );
221*cdf0e10cSrcweir 	dispose();
222*cdf0e10cSrcweir }
223*cdf0e10cSrcweir 
224*cdf0e10cSrcweir //------------------------------------------------------------------------
225*cdf0e10cSrcweir 
226*cdf0e10cSrcweir void CellEditSourceImpl::addRange( SvxUnoTextRangeBase* pNewRange )
227*cdf0e10cSrcweir {
228*cdf0e10cSrcweir 	if( pNewRange )
229*cdf0e10cSrcweir 		if( std::find( maTextRanges.begin(), maTextRanges.end(), pNewRange ) == maTextRanges.end() )
230*cdf0e10cSrcweir 			maTextRanges.push_back( pNewRange );
231*cdf0e10cSrcweir }
232*cdf0e10cSrcweir 
233*cdf0e10cSrcweir //------------------------------------------------------------------------
234*cdf0e10cSrcweir 
235*cdf0e10cSrcweir void CellEditSourceImpl::removeRange( SvxUnoTextRangeBase* pOldRange )
236*cdf0e10cSrcweir {
237*cdf0e10cSrcweir 	if( pOldRange )
238*cdf0e10cSrcweir 		maTextRanges.remove( pOldRange );
239*cdf0e10cSrcweir }
240*cdf0e10cSrcweir 
241*cdf0e10cSrcweir //------------------------------------------------------------------------
242*cdf0e10cSrcweir 
243*cdf0e10cSrcweir const SvxUnoTextRangeBaseList& CellEditSourceImpl::getRanges() const
244*cdf0e10cSrcweir {
245*cdf0e10cSrcweir 	return maTextRanges;
246*cdf0e10cSrcweir }
247*cdf0e10cSrcweir 
248*cdf0e10cSrcweir //------------------------------------------------------------------------
249*cdf0e10cSrcweir 
250*cdf0e10cSrcweir void SAL_CALL CellEditSourceImpl::acquire()
251*cdf0e10cSrcweir {
252*cdf0e10cSrcweir 	osl_incrementInterlockedCount( &maRefCount );
253*cdf0e10cSrcweir }
254*cdf0e10cSrcweir 
255*cdf0e10cSrcweir //------------------------------------------------------------------------
256*cdf0e10cSrcweir 
257*cdf0e10cSrcweir void SAL_CALL CellEditSourceImpl::release()
258*cdf0e10cSrcweir {
259*cdf0e10cSrcweir 	if( ! osl_decrementInterlockedCount( &maRefCount ) )
260*cdf0e10cSrcweir 		delete this;
261*cdf0e10cSrcweir }
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir void CellEditSourceImpl::ChangeModel( SdrModel* pNewModel )
264*cdf0e10cSrcweir {
265*cdf0e10cSrcweir 	if( mpModel != pNewModel )
266*cdf0e10cSrcweir 	{
267*cdf0e10cSrcweir 		if( mpOutliner )
268*cdf0e10cSrcweir 		{
269*cdf0e10cSrcweir 			if( mpModel )
270*cdf0e10cSrcweir 				mpModel->disposeOutliner( mpOutliner );
271*cdf0e10cSrcweir 			else
272*cdf0e10cSrcweir 				delete mpOutliner;
273*cdf0e10cSrcweir 			mpOutliner = 0;
274*cdf0e10cSrcweir 		}
275*cdf0e10cSrcweir 
276*cdf0e10cSrcweir 		if( mpView )
277*cdf0e10cSrcweir 		{
278*cdf0e10cSrcweir 			EndListening( *mpView );
279*cdf0e10cSrcweir 			mpView = 0;
280*cdf0e10cSrcweir 		}
281*cdf0e10cSrcweir 
282*cdf0e10cSrcweir 		mpWindow = 0;
283*cdf0e10cSrcweir 		mxLinguServiceManager.clear();
284*cdf0e10cSrcweir 
285*cdf0e10cSrcweir 		mpModel = pNewModel;
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir 		if( mpTextForwarder )
288*cdf0e10cSrcweir 		{
289*cdf0e10cSrcweir 	        delete mpTextForwarder;
290*cdf0e10cSrcweir 		    mpTextForwarder = 0;
291*cdf0e10cSrcweir 		}
292*cdf0e10cSrcweir 
293*cdf0e10cSrcweir 		if( mpViewForwarder )
294*cdf0e10cSrcweir 		{
295*cdf0e10cSrcweir 			delete mpViewForwarder;
296*cdf0e10cSrcweir 			mpViewForwarder = 0;
297*cdf0e10cSrcweir 		}
298*cdf0e10cSrcweir 	}
299*cdf0e10cSrcweir }
300*cdf0e10cSrcweir 
301*cdf0e10cSrcweir //------------------------------------------------------------------------
302*cdf0e10cSrcweir 
303*cdf0e10cSrcweir void CellEditSourceImpl::Notify( SfxBroadcaster&, const SfxHint& rHint )
304*cdf0e10cSrcweir {
305*cdf0e10cSrcweir 	const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
306*cdf0e10cSrcweir 	const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
307*cdf0e10cSrcweir 
308*cdf0e10cSrcweir     if( pViewHint )
309*cdf0e10cSrcweir     {
310*cdf0e10cSrcweir         switch( pViewHint->GetHintType() )
311*cdf0e10cSrcweir         {
312*cdf0e10cSrcweir             case SvxViewHint::SVX_HINT_VIEWCHANGED:
313*cdf0e10cSrcweir                 Broadcast( *pViewHint );
314*cdf0e10cSrcweir                 break;
315*cdf0e10cSrcweir         }
316*cdf0e10cSrcweir     }
317*cdf0e10cSrcweir 	else if( pSdrHint )
318*cdf0e10cSrcweir 	{
319*cdf0e10cSrcweir         switch( pSdrHint->GetKind() )
320*cdf0e10cSrcweir         {
321*cdf0e10cSrcweir             case HINT_OBJCHG:
322*cdf0e10cSrcweir             {
323*cdf0e10cSrcweir                 mbDataValid = sal_False;						// Text muss neu geholt werden
324*cdf0e10cSrcweir 
325*cdf0e10cSrcweir                 if( HasView() )
326*cdf0e10cSrcweir                 {
327*cdf0e10cSrcweir                     // #104157# Update maTextOffset, object has changed
328*cdf0e10cSrcweir 					// #105196#, #105203#: Cannot call that // here,
329*cdf0e10cSrcweir 					// since TakeTextRect() (called from there) //
330*cdf0e10cSrcweir 					// changes outliner content.
331*cdf0e10cSrcweir 					// UpdateOutliner();
332*cdf0e10cSrcweir 
333*cdf0e10cSrcweir                     // #101029# Broadcast object changes, as they might change visible attributes
334*cdf0e10cSrcweir                     SvxViewHint aHint(SvxViewHint::SVX_HINT_VIEWCHANGED);
335*cdf0e10cSrcweir                     Broadcast( aHint );
336*cdf0e10cSrcweir                 }
337*cdf0e10cSrcweir                 break;
338*cdf0e10cSrcweir             }
339*cdf0e10cSrcweir 
340*cdf0e10cSrcweir             case HINT_BEGEDIT:
341*cdf0e10cSrcweir /* todo
342*cdf0e10cSrcweir                 if( mpObject == pSdrHint->GetObject() )
343*cdf0e10cSrcweir                 {
344*cdf0e10cSrcweir                     // invalidate old forwarder
345*cdf0e10cSrcweir                     if( !mbForwarderIsEditMode )
346*cdf0e10cSrcweir                     {
347*cdf0e10cSrcweir                         delete mpTextForwarder;
348*cdf0e10cSrcweir                         mpTextForwarder = NULL;
349*cdf0e10cSrcweir                     }
350*cdf0e10cSrcweir 
351*cdf0e10cSrcweir                     // register as listener - need to broadcast state change messages
352*cdf0e10cSrcweir                     if( mpView && mpView->GetTextEditOutliner() )
353*cdf0e10cSrcweir                         mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
354*cdf0e10cSrcweir 
355*cdf0e10cSrcweir                     // #104157# Only now we're really in edit mode
356*cdf0e10cSrcweir                     mbShapeIsEditMode = sal_True;
357*cdf0e10cSrcweir 
358*cdf0e10cSrcweir                     Broadcast( *pSdrHint );
359*cdf0e10cSrcweir                 }
360*cdf0e10cSrcweir */
361*cdf0e10cSrcweir                 break;
362*cdf0e10cSrcweir 
363*cdf0e10cSrcweir             case HINT_ENDEDIT:
364*cdf0e10cSrcweir /* todo
365*cdf0e10cSrcweir                 if( mpObject == pSdrHint->GetObject() )
366*cdf0e10cSrcweir                 {
367*cdf0e10cSrcweir                     Broadcast( *pSdrHint );
368*cdf0e10cSrcweir 
369*cdf0e10cSrcweir                     // #104157# We're no longer in edit mode
370*cdf0e10cSrcweir                     mbShapeIsEditMode = sal_False;
371*cdf0e10cSrcweir 
372*cdf0e10cSrcweir                     // remove as listener - outliner might outlive ourselves
373*cdf0e10cSrcweir                     if( mpView && mpView->GetTextEditOutliner() )
374*cdf0e10cSrcweir                         mpView->GetTextEditOutliner()->SetNotifyHdl( Link() );
375*cdf0e10cSrcweir 
376*cdf0e10cSrcweir                     // destroy view forwarder, OutlinerView no longer
377*cdf0e10cSrcweir                     // valid (no need for UpdateData(), it's been
378*cdf0e10cSrcweir                     // synched on SdrEndTextEdit)
379*cdf0e10cSrcweir                     delete mpViewForwarder;
380*cdf0e10cSrcweir                     mpViewForwarder = NULL;
381*cdf0e10cSrcweir 
382*cdf0e10cSrcweir                     // #100424# Invalidate text forwarder, we might
383*cdf0e10cSrcweir                     // not be called again before entering edit mode a
384*cdf0e10cSrcweir                     // second time! Then, the old outliner might be
385*cdf0e10cSrcweir                     // invalid.
386*cdf0e10cSrcweir                     if( mbForwarderIsEditMode )
387*cdf0e10cSrcweir                     {
388*cdf0e10cSrcweir                         mbForwarderIsEditMode = sal_False;
389*cdf0e10cSrcweir                         delete mpTextForwarder;
390*cdf0e10cSrcweir                         mpTextForwarder = NULL;
391*cdf0e10cSrcweir                     }
392*cdf0e10cSrcweir                 }
393*cdf0e10cSrcweir */
394*cdf0e10cSrcweir                 break;
395*cdf0e10cSrcweir 
396*cdf0e10cSrcweir 			case HINT_MODELCLEARED:
397*cdf0e10cSrcweir 				dispose();
398*cdf0e10cSrcweir 				break;
399*cdf0e10cSrcweir 			default:
400*cdf0e10cSrcweir 				break;
401*cdf0e10cSrcweir         }
402*cdf0e10cSrcweir     }
403*cdf0e10cSrcweir }
404*cdf0e10cSrcweir 
405*cdf0e10cSrcweir /* unregister at all objects and set all references to 0 */
406*cdf0e10cSrcweir void CellEditSourceImpl::dispose()
407*cdf0e10cSrcweir {
408*cdf0e10cSrcweir 	if( mpTextForwarder )
409*cdf0e10cSrcweir 	{
410*cdf0e10cSrcweir 	    delete mpTextForwarder;
411*cdf0e10cSrcweir 		mpTextForwarder = 0;
412*cdf0e10cSrcweir 	}
413*cdf0e10cSrcweir 
414*cdf0e10cSrcweir 	if( mpViewForwarder )
415*cdf0e10cSrcweir 	{
416*cdf0e10cSrcweir 	    delete mpViewForwarder;
417*cdf0e10cSrcweir 		mpViewForwarder = 0;
418*cdf0e10cSrcweir 	}
419*cdf0e10cSrcweir 
420*cdf0e10cSrcweir 	if( mpOutliner )
421*cdf0e10cSrcweir 	{
422*cdf0e10cSrcweir 		if( mpModel )
423*cdf0e10cSrcweir 		{
424*cdf0e10cSrcweir 			mpModel->disposeOutliner( mpOutliner );
425*cdf0e10cSrcweir 		}
426*cdf0e10cSrcweir 		else
427*cdf0e10cSrcweir 		{
428*cdf0e10cSrcweir 			delete mpOutliner;
429*cdf0e10cSrcweir 		}
430*cdf0e10cSrcweir 		mpOutliner = 0;
431*cdf0e10cSrcweir 	}
432*cdf0e10cSrcweir 
433*cdf0e10cSrcweir 	if( mpView )
434*cdf0e10cSrcweir 	{
435*cdf0e10cSrcweir 		EndListening( *mpView );
436*cdf0e10cSrcweir         mpView = 0;
437*cdf0e10cSrcweir 	}
438*cdf0e10cSrcweir 
439*cdf0e10cSrcweir 	mpModel = 0;
440*cdf0e10cSrcweir 	mpWindow = 0;
441*cdf0e10cSrcweir }
442*cdf0e10cSrcweir 
443*cdf0e10cSrcweir //------------------------------------------------------------------------
444*cdf0e10cSrcweir 
445*cdf0e10cSrcweir void CellEditSourceImpl::SetupOutliner()
446*cdf0e10cSrcweir {
447*cdf0e10cSrcweir     // #101029#
448*cdf0e10cSrcweir     // only for UAA edit source: setup outliner equivalently as in
449*cdf0e10cSrcweir     // SdrTextObj::Paint(), such that formatting equals screen
450*cdf0e10cSrcweir     // layout
451*cdf0e10cSrcweir /* todo
452*cdf0e10cSrcweir     if( mpObject && mpOutliner )
453*cdf0e10cSrcweir     {
454*cdf0e10cSrcweir         SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
455*cdf0e10cSrcweir         Rectangle aPaintRect;
456*cdf0e10cSrcweir         if( pTextObj )
457*cdf0e10cSrcweir         {
458*cdf0e10cSrcweir             Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
459*cdf0e10cSrcweir             pTextObj->SetupOutlinerFormatting( *mpOutliner, aPaintRect );
460*cdf0e10cSrcweir 
461*cdf0e10cSrcweir             // #101029# calc text offset from shape anchor
462*cdf0e10cSrcweir             maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
463*cdf0e10cSrcweir         }
464*cdf0e10cSrcweir     }
465*cdf0e10cSrcweir */
466*cdf0e10cSrcweir }
467*cdf0e10cSrcweir 
468*cdf0e10cSrcweir //------------------------------------------------------------------------
469*cdf0e10cSrcweir 
470*cdf0e10cSrcweir void CellEditSourceImpl::UpdateOutliner()
471*cdf0e10cSrcweir {
472*cdf0e10cSrcweir     // #104157#
473*cdf0e10cSrcweir     // only for UAA edit source: update outliner equivalently as in
474*cdf0e10cSrcweir     // SdrTextObj::Paint(), such that formatting equals screen
475*cdf0e10cSrcweir     // layout
476*cdf0e10cSrcweir /* todo
477*cdf0e10cSrcweir     if( mpObject && mpOutliner )
478*cdf0e10cSrcweir     {
479*cdf0e10cSrcweir         SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
480*cdf0e10cSrcweir         Rectangle aPaintRect;
481*cdf0e10cSrcweir         if( pTextObj )
482*cdf0e10cSrcweir         {
483*cdf0e10cSrcweir             Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
484*cdf0e10cSrcweir             pTextObj->UpdateOutlinerFormatting( *mpOutliner, aPaintRect );
485*cdf0e10cSrcweir 
486*cdf0e10cSrcweir             // #101029# calc text offset from shape anchor
487*cdf0e10cSrcweir             maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
488*cdf0e10cSrcweir         }
489*cdf0e10cSrcweir     }
490*cdf0e10cSrcweir */
491*cdf0e10cSrcweir }
492*cdf0e10cSrcweir 
493*cdf0e10cSrcweir //------------------------------------------------------------------------
494*cdf0e10cSrcweir 
495*cdf0e10cSrcweir 
496*cdf0e10cSrcweir SvxTextForwarder* CellEditSourceImpl::GetBackgroundTextForwarder()
497*cdf0e10cSrcweir {
498*cdf0e10cSrcweir     sal_Bool bCreated = sal_False;
499*cdf0e10cSrcweir 
500*cdf0e10cSrcweir     // #99840#: prevent EE/Outliner notifications during setup
501*cdf0e10cSrcweir     mbNotificationsDisabled = true;
502*cdf0e10cSrcweir 
503*cdf0e10cSrcweir 	if (!mpTextForwarder)
504*cdf0e10cSrcweir 	{
505*cdf0e10cSrcweir 		if( mpOutliner == NULL )
506*cdf0e10cSrcweir 		{
507*cdf0e10cSrcweir 			mpOutliner = mpModel->createOutliner( OUTLINERMODE_TEXTOBJECT );
508*cdf0e10cSrcweir 
509*cdf0e10cSrcweir             // #109151# Do the setup after outliner creation, would be useless otherwise
510*cdf0e10cSrcweir             if( HasView() )
511*cdf0e10cSrcweir             {
512*cdf0e10cSrcweir                 // #101029#, #104157# Setup outliner _before_ filling it
513*cdf0e10cSrcweir                 SetupOutliner();
514*cdf0e10cSrcweir             }
515*cdf0e10cSrcweir 
516*cdf0e10cSrcweir // todo?			mpOutliner->SetTextObjNoInit( pTextObj );
517*cdf0e10cSrcweir 
518*cdf0e10cSrcweir 			if( mbIsLocked )
519*cdf0e10cSrcweir 			{
520*cdf0e10cSrcweir 				((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
521*cdf0e10cSrcweir 				mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
522*cdf0e10cSrcweir 				((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
523*cdf0e10cSrcweir 			}
524*cdf0e10cSrcweir 
525*cdf0e10cSrcweir 			if ( !mxLinguServiceManager.is() )
526*cdf0e10cSrcweir 			{
527*cdf0e10cSrcweir 				Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
528*cdf0e10cSrcweir 				mxLinguServiceManager = Reference< XLinguServiceManager >(
529*cdf0e10cSrcweir 					xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.linguistic2.LinguServiceManager" ))), UNO_QUERY );
530*cdf0e10cSrcweir 			}
531*cdf0e10cSrcweir 
532*cdf0e10cSrcweir 			if ( mxLinguServiceManager.is() )
533*cdf0e10cSrcweir 			{
534*cdf0e10cSrcweir 				Reference< XHyphenator > xHyphenator( mxLinguServiceManager->getHyphenator(), UNO_QUERY );
535*cdf0e10cSrcweir 				if( xHyphenator.is() )
536*cdf0e10cSrcweir 					mpOutliner->SetHyphenator( xHyphenator );
537*cdf0e10cSrcweir 			}
538*cdf0e10cSrcweir 		}
539*cdf0e10cSrcweir 
540*cdf0e10cSrcweir 		mpTextForwarder = new SvxOutlinerForwarder( *mpOutliner );
541*cdf0e10cSrcweir 
542*cdf0e10cSrcweir         // delay listener subscription and UAA initialization until Outliner is fully setup
543*cdf0e10cSrcweir         bCreated = true;
544*cdf0e10cSrcweir         mbForwarderIsEditMode = false;
545*cdf0e10cSrcweir 	}
546*cdf0e10cSrcweir 
547*cdf0e10cSrcweir 	if( !mbDataValid )
548*cdf0e10cSrcweir 	{
549*cdf0e10cSrcweir 		mpTextForwarder->flushCache();
550*cdf0e10cSrcweir 
551*cdf0e10cSrcweir 		OutlinerParaObject* pOutlinerParaObject = NULL;
552*cdf0e10cSrcweir 		bool bTextEditActive = false;
553*cdf0e10cSrcweir 
554*cdf0e10cSrcweir 		pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
555*cdf0e10cSrcweir 
556*cdf0e10cSrcweir 		if( pOutlinerParaObject )
557*cdf0e10cSrcweir 			bTextEditActive = true;	// text edit active
558*cdf0e10cSrcweir 		else
559*cdf0e10cSrcweir 			pOutlinerParaObject = mxCell->GetOutlinerParaObject();
560*cdf0e10cSrcweir 
561*cdf0e10cSrcweir 		if( pOutlinerParaObject )
562*cdf0e10cSrcweir 		{
563*cdf0e10cSrcweir 			mpOutliner->SetText( *pOutlinerParaObject );
564*cdf0e10cSrcweir 		}
565*cdf0e10cSrcweir 		else
566*cdf0e10cSrcweir 		{
567*cdf0e10cSrcweir 			bool bVertical = false; // todo?
568*cdf0e10cSrcweir 
569*cdf0e10cSrcweir 			// set objects style sheet on empty outliner
570*cdf0e10cSrcweir 			SfxStyleSheetPool* pPool = mxCell->GetStyleSheetPool();
571*cdf0e10cSrcweir 			if( pPool )
572*cdf0e10cSrcweir 				mpOutliner->SetStyleSheetPool( pPool );
573*cdf0e10cSrcweir 
574*cdf0e10cSrcweir 			SfxStyleSheet* pStyleSheet = mxCell->GetStyleSheet();
575*cdf0e10cSrcweir 			if( pStyleSheet )
576*cdf0e10cSrcweir 				mpOutliner->SetStyleSheet( 0, pStyleSheet );
577*cdf0e10cSrcweir 
578*cdf0e10cSrcweir 			if( bVertical )
579*cdf0e10cSrcweir 				mpOutliner->SetVertical( sal_True );
580*cdf0e10cSrcweir 		}
581*cdf0e10cSrcweir 
582*cdf0e10cSrcweir 		// evtually we have to set the border attributes
583*cdf0e10cSrcweir 		if (mpOutliner->GetParagraphCount()==1)
584*cdf0e10cSrcweir 		{
585*cdf0e10cSrcweir 			// if we only have one paragraph we check if it is empty
586*cdf0e10cSrcweir 			XubString aStr( mpOutliner->GetText( mpOutliner->GetParagraph( 0 ) ) );
587*cdf0e10cSrcweir 
588*cdf0e10cSrcweir 			if(!aStr.Len())
589*cdf0e10cSrcweir 			{
590*cdf0e10cSrcweir 				// its empty, so we have to force the outliner to initialise itself
591*cdf0e10cSrcweir 				mpOutliner->SetText( String(), mpOutliner->GetParagraph( 0 ) );
592*cdf0e10cSrcweir 
593*cdf0e10cSrcweir 				if(mxCell->GetStyleSheet())
594*cdf0e10cSrcweir 					mpOutliner->SetStyleSheet( 0, mxCell->GetStyleSheet());
595*cdf0e10cSrcweir 			}
596*cdf0e10cSrcweir 		}
597*cdf0e10cSrcweir 
598*cdf0e10cSrcweir         if( bTextEditActive )
599*cdf0e10cSrcweir             delete pOutlinerParaObject;
600*cdf0e10cSrcweir 
601*cdf0e10cSrcweir 		mbDataValid = true;
602*cdf0e10cSrcweir 	}
603*cdf0e10cSrcweir 
604*cdf0e10cSrcweir     if( bCreated && mpOutliner && HasView() )
605*cdf0e10cSrcweir     {
606*cdf0e10cSrcweir         // register as listener - need to broadcast state change messages
607*cdf0e10cSrcweir         // registration delayed until outliner is completely set up
608*cdf0e10cSrcweir         mpOutliner->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
609*cdf0e10cSrcweir     }
610*cdf0e10cSrcweir 
611*cdf0e10cSrcweir     // #99840#: prevent EE/Outliner notifications during setup
612*cdf0e10cSrcweir     mbNotificationsDisabled = false;
613*cdf0e10cSrcweir 
614*cdf0e10cSrcweir 	return mpTextForwarder;
615*cdf0e10cSrcweir }
616*cdf0e10cSrcweir 
617*cdf0e10cSrcweir //------------------------------------------------------------------------
618*cdf0e10cSrcweir 
619*cdf0e10cSrcweir SvxTextForwarder* CellEditSourceImpl::GetEditModeTextForwarder()
620*cdf0e10cSrcweir {
621*cdf0e10cSrcweir     if( !mpTextForwarder && HasView() )
622*cdf0e10cSrcweir     {
623*cdf0e10cSrcweir         SdrOutliner* pEditOutliner = mpView->GetTextEditOutliner();
624*cdf0e10cSrcweir 
625*cdf0e10cSrcweir         if( pEditOutliner )
626*cdf0e10cSrcweir         {
627*cdf0e10cSrcweir             mpTextForwarder = new SvxOutlinerForwarder( *pEditOutliner );
628*cdf0e10cSrcweir             mbForwarderIsEditMode = true;
629*cdf0e10cSrcweir         }
630*cdf0e10cSrcweir     }
631*cdf0e10cSrcweir 
632*cdf0e10cSrcweir     return mpTextForwarder;
633*cdf0e10cSrcweir }
634*cdf0e10cSrcweir 
635*cdf0e10cSrcweir //------------------------------------------------------------------------
636*cdf0e10cSrcweir 
637*cdf0e10cSrcweir SvxTextForwarder* CellEditSourceImpl::GetTextForwarder()
638*cdf0e10cSrcweir {
639*cdf0e10cSrcweir 	if( mbDisposed )
640*cdf0e10cSrcweir 		return NULL;
641*cdf0e10cSrcweir 
642*cdf0e10cSrcweir 	if( mpModel == NULL )
643*cdf0e10cSrcweir 		return NULL;
644*cdf0e10cSrcweir 
645*cdf0e10cSrcweir     // distinguish the cases
646*cdf0e10cSrcweir     // a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
647*cdf0e10cSrcweir     // b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
648*cdf0e10cSrcweir     if( HasView() )
649*cdf0e10cSrcweir     {
650*cdf0e10cSrcweir         if( IsEditMode() != mbForwarderIsEditMode )
651*cdf0e10cSrcweir         {
652*cdf0e10cSrcweir             // forwarder mismatch - create new
653*cdf0e10cSrcweir             delete mpTextForwarder;
654*cdf0e10cSrcweir             mpTextForwarder = NULL;
655*cdf0e10cSrcweir         }
656*cdf0e10cSrcweir 
657*cdf0e10cSrcweir         if( IsEditMode() )
658*cdf0e10cSrcweir             return GetEditModeTextForwarder();
659*cdf0e10cSrcweir         else
660*cdf0e10cSrcweir             return GetBackgroundTextForwarder();
661*cdf0e10cSrcweir     }
662*cdf0e10cSrcweir     else
663*cdf0e10cSrcweir         return GetBackgroundTextForwarder();
664*cdf0e10cSrcweir }
665*cdf0e10cSrcweir 
666*cdf0e10cSrcweir //------------------------------------------------------------------------
667*cdf0e10cSrcweir 
668*cdf0e10cSrcweir SvxDrawOutlinerViewForwarder* CellEditSourceImpl::CreateViewForwarder()
669*cdf0e10cSrcweir {
670*cdf0e10cSrcweir     if( mpView->GetTextEditOutlinerView() )
671*cdf0e10cSrcweir     {
672*cdf0e10cSrcweir         // register as listener - need to broadcast state change messages
673*cdf0e10cSrcweir         mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
674*cdf0e10cSrcweir 
675*cdf0e10cSrcweir 		Rectangle aBoundRect( mxCell->GetCurrentBoundRect() );
676*cdf0e10cSrcweir 		OutlinerView& rOutlView = *mpView->GetTextEditOutlinerView();
677*cdf0e10cSrcweir 
678*cdf0e10cSrcweir 		return new SvxDrawOutlinerViewForwarder( rOutlView, aBoundRect.TopLeft() );
679*cdf0e10cSrcweir     }
680*cdf0e10cSrcweir 
681*cdf0e10cSrcweir     return NULL;
682*cdf0e10cSrcweir }
683*cdf0e10cSrcweir 
684*cdf0e10cSrcweir SvxEditViewForwarder* CellEditSourceImpl::GetEditViewForwarder( sal_Bool bCreate )
685*cdf0e10cSrcweir {
686*cdf0e10cSrcweir 	if( mbDisposed )
687*cdf0e10cSrcweir 		return NULL;
688*cdf0e10cSrcweir 
689*cdf0e10cSrcweir 	if( mpModel == NULL )
690*cdf0e10cSrcweir 		return NULL;
691*cdf0e10cSrcweir 
692*cdf0e10cSrcweir     // shall we delete?
693*cdf0e10cSrcweir     if( mpViewForwarder )
694*cdf0e10cSrcweir     {
695*cdf0e10cSrcweir         if( !IsEditMode() )
696*cdf0e10cSrcweir         {
697*cdf0e10cSrcweir             // destroy all forwarders (no need for UpdateData(),
698*cdf0e10cSrcweir             // it's been synched on SdrEndTextEdit)
699*cdf0e10cSrcweir 			delete mpViewForwarder;
700*cdf0e10cSrcweir 			mpViewForwarder = NULL;
701*cdf0e10cSrcweir         }
702*cdf0e10cSrcweir     }
703*cdf0e10cSrcweir     // which to create? Directly in edit mode, create new, or none?
704*cdf0e10cSrcweir     else if( mpView )
705*cdf0e10cSrcweir     {
706*cdf0e10cSrcweir         if( IsEditMode() )
707*cdf0e10cSrcweir         {
708*cdf0e10cSrcweir             // create new view forwarder
709*cdf0e10cSrcweir             mpViewForwarder = CreateViewForwarder();
710*cdf0e10cSrcweir         }
711*cdf0e10cSrcweir         else if( bCreate )
712*cdf0e10cSrcweir         {
713*cdf0e10cSrcweir             // dispose old text forwarder
714*cdf0e10cSrcweir             UpdateData();
715*cdf0e10cSrcweir 
716*cdf0e10cSrcweir             delete mpTextForwarder;
717*cdf0e10cSrcweir             mpTextForwarder = NULL;
718*cdf0e10cSrcweir 
719*cdf0e10cSrcweir             // enter edit mode
720*cdf0e10cSrcweir             mpView->SdrEndTextEdit();
721*cdf0e10cSrcweir 
722*cdf0e10cSrcweir /* todo
723*cdf0e10cSrcweir 			if(mpView->SdrBeginTextEdit(mpObject, 0L, 0L, sal_False, (SdrOutliner*)0L, 0L, sal_False, sal_False))
724*cdf0e10cSrcweir             {
725*cdf0e10cSrcweir                 if( mxCell->IsTextEditActive() )
726*cdf0e10cSrcweir                 {
727*cdf0e10cSrcweir 					// create new view forwarder
728*cdf0e10cSrcweir 					mpViewForwarder = CreateViewForwarder();
729*cdf0e10cSrcweir                 }
730*cdf0e10cSrcweir                 else
731*cdf0e10cSrcweir                 {
732*cdf0e10cSrcweir 					// failure. Somehow, SdrBeginTextEdit did not set
733*cdf0e10cSrcweir                     // our SdrTextObj into edit mode
734*cdf0e10cSrcweir                     mpView->SdrEndTextEdit();
735*cdf0e10cSrcweir                 }
736*cdf0e10cSrcweir             }
737*cdf0e10cSrcweir */
738*cdf0e10cSrcweir         }
739*cdf0e10cSrcweir     }
740*cdf0e10cSrcweir 
741*cdf0e10cSrcweir 	return mpViewForwarder;
742*cdf0e10cSrcweir }
743*cdf0e10cSrcweir 
744*cdf0e10cSrcweir //------------------------------------------------------------------------
745*cdf0e10cSrcweir 
746*cdf0e10cSrcweir void CellEditSourceImpl::UpdateData()
747*cdf0e10cSrcweir {
748*cdf0e10cSrcweir     // if we have a view and in edit mode, we're working with the
749*cdf0e10cSrcweir     // DrawOutliner. Thus, all changes made on the text forwarder are
750*cdf0e10cSrcweir     // reflected on the view and committed to the model on
751*cdf0e10cSrcweir     // SdrEndTextEdit(). Thus, no need for explicit updates here.
752*cdf0e10cSrcweir     if( !HasView() || !IsEditMode() )
753*cdf0e10cSrcweir     {
754*cdf0e10cSrcweir         if( mbIsLocked  )
755*cdf0e10cSrcweir         {
756*cdf0e10cSrcweir             mbNeedsUpdate = true;
757*cdf0e10cSrcweir         }
758*cdf0e10cSrcweir         else
759*cdf0e10cSrcweir         {
760*cdf0e10cSrcweir             if( mpOutliner && !mbDisposed )
761*cdf0e10cSrcweir             {
762*cdf0e10cSrcweir                 if( mpOutliner->GetParagraphCount() != 1 || mpOutliner->GetEditEngine().GetTextLen( 0 ) )
763*cdf0e10cSrcweir 				{
764*cdf0e10cSrcweir                     mxCell->SetOutlinerParaObject( mpOutliner->CreateParaObject() );
765*cdf0e10cSrcweir 				}
766*cdf0e10cSrcweir                 else
767*cdf0e10cSrcweir 				{
768*cdf0e10cSrcweir                     mxCell->SetOutlinerParaObject( NULL );
769*cdf0e10cSrcweir 				}
770*cdf0e10cSrcweir 			}
771*cdf0e10cSrcweir         }
772*cdf0e10cSrcweir     }
773*cdf0e10cSrcweir }
774*cdf0e10cSrcweir 
775*cdf0e10cSrcweir void CellEditSourceImpl::lock()
776*cdf0e10cSrcweir {
777*cdf0e10cSrcweir 	mbIsLocked = true;
778*cdf0e10cSrcweir 	if( mpOutliner )
779*cdf0e10cSrcweir 	{
780*cdf0e10cSrcweir 		((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
781*cdf0e10cSrcweir 		mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
782*cdf0e10cSrcweir 		((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
783*cdf0e10cSrcweir 	}
784*cdf0e10cSrcweir }
785*cdf0e10cSrcweir 
786*cdf0e10cSrcweir void CellEditSourceImpl::unlock()
787*cdf0e10cSrcweir {
788*cdf0e10cSrcweir 	mbIsLocked = false;
789*cdf0e10cSrcweir 
790*cdf0e10cSrcweir 	if( mbNeedsUpdate )
791*cdf0e10cSrcweir 	{
792*cdf0e10cSrcweir 		UpdateData();
793*cdf0e10cSrcweir 		mbNeedsUpdate = false;
794*cdf0e10cSrcweir 	}
795*cdf0e10cSrcweir 
796*cdf0e10cSrcweir 	if( mpOutliner )
797*cdf0e10cSrcweir 	{
798*cdf0e10cSrcweir 		((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_True );
799*cdf0e10cSrcweir 		((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( mbOldUndoMode );
800*cdf0e10cSrcweir 	}
801*cdf0e10cSrcweir }
802*cdf0e10cSrcweir 
803*cdf0e10cSrcweir sal_Bool CellEditSourceImpl::IsValid() const
804*cdf0e10cSrcweir {
805*cdf0e10cSrcweir     return mpView && mpWindow ? sal_True : sal_False;
806*cdf0e10cSrcweir }
807*cdf0e10cSrcweir 
808*cdf0e10cSrcweir Rectangle CellEditSourceImpl::GetVisArea()
809*cdf0e10cSrcweir {
810*cdf0e10cSrcweir     if( IsValid() )
811*cdf0e10cSrcweir     {
812*cdf0e10cSrcweir 		SdrPaintWindow* pPaintWindow = mpView->FindPaintWindow(*mpWindow);
813*cdf0e10cSrcweir 		Rectangle aVisArea;
814*cdf0e10cSrcweir 
815*cdf0e10cSrcweir 		if(pPaintWindow)
816*cdf0e10cSrcweir 		{
817*cdf0e10cSrcweir 			aVisArea = pPaintWindow->GetVisibleArea();
818*cdf0e10cSrcweir 		}
819*cdf0e10cSrcweir 
820*cdf0e10cSrcweir         // offset vis area by edit engine left-top position
821*cdf0e10cSrcweir         Rectangle aAnchorRect;
822*cdf0e10cSrcweir         mxCell->TakeTextAnchorRect( aAnchorRect );
823*cdf0e10cSrcweir         aVisArea.Move( -aAnchorRect.Left(), -aAnchorRect.Top() );
824*cdf0e10cSrcweir 
825*cdf0e10cSrcweir         MapMode aMapMode(mpWindow->GetMapMode());
826*cdf0e10cSrcweir         aMapMode.SetOrigin(Point());
827*cdf0e10cSrcweir         return mpWindow->LogicToPixel( aVisArea, aMapMode );
828*cdf0e10cSrcweir     }
829*cdf0e10cSrcweir 
830*cdf0e10cSrcweir     return Rectangle();
831*cdf0e10cSrcweir }
832*cdf0e10cSrcweir 
833*cdf0e10cSrcweir Point CellEditSourceImpl::LogicToPixel( const Point& rPoint, const MapMode& rMapMode )
834*cdf0e10cSrcweir {
835*cdf0e10cSrcweir     // #101029#: The responsibilities of ViewForwarder happen to be
836*cdf0e10cSrcweir     // somewhat mixed in this case. On the one hand, we need the
837*cdf0e10cSrcweir     // different interface queries on the SvxEditSource interface,
838*cdf0e10cSrcweir     // since we need both VisAreas. On the other hand, if an
839*cdf0e10cSrcweir     // EditViewForwarder exists, maTextOffset does not remain static,
840*cdf0e10cSrcweir     // but may change with every key press.
841*cdf0e10cSrcweir     if( IsEditMode() )
842*cdf0e10cSrcweir     {
843*cdf0e10cSrcweir         SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
844*cdf0e10cSrcweir 
845*cdf0e10cSrcweir         if( pForwarder )
846*cdf0e10cSrcweir             return pForwarder->LogicToPixel( rPoint, rMapMode );
847*cdf0e10cSrcweir     }
848*cdf0e10cSrcweir     else if( IsValid() && mpModel )
849*cdf0e10cSrcweir     {
850*cdf0e10cSrcweir         // #101029#
851*cdf0e10cSrcweir         Point aPoint1( rPoint );
852*cdf0e10cSrcweir         aPoint1.X() += maTextOffset.X();
853*cdf0e10cSrcweir         aPoint1.Y() += maTextOffset.Y();
854*cdf0e10cSrcweir 
855*cdf0e10cSrcweir         Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
856*cdf0e10cSrcweir                                                    MapMode(mpModel->GetScaleUnit()) ) );
857*cdf0e10cSrcweir         MapMode aMapMode(mpWindow->GetMapMode());
858*cdf0e10cSrcweir         aMapMode.SetOrigin(Point());
859*cdf0e10cSrcweir         return mpWindow->LogicToPixel( aPoint2, aMapMode );
860*cdf0e10cSrcweir     }
861*cdf0e10cSrcweir 
862*cdf0e10cSrcweir     return Point();
863*cdf0e10cSrcweir }
864*cdf0e10cSrcweir 
865*cdf0e10cSrcweir Point CellEditSourceImpl::PixelToLogic( const Point& rPoint, const MapMode& rMapMode )
866*cdf0e10cSrcweir {
867*cdf0e10cSrcweir     // #101029#: The responsibilities of ViewForwarder happen to be
868*cdf0e10cSrcweir     // somewhat mixed in this case. On the one hand, we need the
869*cdf0e10cSrcweir     // different interface queries on the SvxEditSource interface,
870*cdf0e10cSrcweir     // since we need both VisAreas. On the other hand, if an
871*cdf0e10cSrcweir     // EditViewForwarder exists, maTextOffset does not remain static,
872*cdf0e10cSrcweir     // but may change with every key press.
873*cdf0e10cSrcweir     if( IsEditMode() )
874*cdf0e10cSrcweir     {
875*cdf0e10cSrcweir         SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
876*cdf0e10cSrcweir 
877*cdf0e10cSrcweir         if( pForwarder )
878*cdf0e10cSrcweir             return pForwarder->PixelToLogic( rPoint, rMapMode );
879*cdf0e10cSrcweir     }
880*cdf0e10cSrcweir     else if( IsValid() && mpModel )
881*cdf0e10cSrcweir     {
882*cdf0e10cSrcweir         MapMode aMapMode(mpWindow->GetMapMode());
883*cdf0e10cSrcweir         aMapMode.SetOrigin(Point());
884*cdf0e10cSrcweir         Point aPoint1( mpWindow->PixelToLogic( rPoint, aMapMode ) );
885*cdf0e10cSrcweir         Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
886*cdf0e10cSrcweir                                                    MapMode(mpModel->GetScaleUnit()),
887*cdf0e10cSrcweir                                                    rMapMode ) );
888*cdf0e10cSrcweir         // #101029#
889*cdf0e10cSrcweir         aPoint2.X() -= maTextOffset.X();
890*cdf0e10cSrcweir         aPoint2.Y() -= maTextOffset.Y();
891*cdf0e10cSrcweir 
892*cdf0e10cSrcweir         return aPoint2;
893*cdf0e10cSrcweir     }
894*cdf0e10cSrcweir 
895*cdf0e10cSrcweir     return Point();
896*cdf0e10cSrcweir }
897*cdf0e10cSrcweir 
898*cdf0e10cSrcweir IMPL_LINK(CellEditSourceImpl, NotifyHdl, EENotify*, aNotify)
899*cdf0e10cSrcweir {
900*cdf0e10cSrcweir     if( aNotify && !mbNotificationsDisabled )
901*cdf0e10cSrcweir     {
902*cdf0e10cSrcweir         ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( aNotify) );
903*cdf0e10cSrcweir 
904*cdf0e10cSrcweir         if( aHint.get() )
905*cdf0e10cSrcweir             Broadcast( *aHint.get() );
906*cdf0e10cSrcweir     }
907*cdf0e10cSrcweir 
908*cdf0e10cSrcweir     return 0;
909*cdf0e10cSrcweir }
910*cdf0e10cSrcweir 
911*cdf0e10cSrcweir //------------------------------------------------------------------------
912*cdf0e10cSrcweir 
913*cdf0e10cSrcweir // --------------------------------------------------------------------
914*cdf0e10cSrcweir // CellEditSource
915*cdf0e10cSrcweir // --------------------------------------------------------------------
916*cdf0e10cSrcweir 
917*cdf0e10cSrcweir CellEditSource::CellEditSource( const CellRef& xCell )
918*cdf0e10cSrcweir {
919*cdf0e10cSrcweir 	mpImpl = new CellEditSourceImpl( xCell );
920*cdf0e10cSrcweir 	mpImpl->acquire();
921*cdf0e10cSrcweir }
922*cdf0e10cSrcweir 
923*cdf0e10cSrcweir // --------------------------------------------------------------------
924*cdf0e10cSrcweir CellEditSource::CellEditSource( const CellRef& xCell, SdrView& rView, const Window& rWindow )
925*cdf0e10cSrcweir {
926*cdf0e10cSrcweir 	mpImpl = new CellEditSourceImpl( xCell, rView, rWindow );
927*cdf0e10cSrcweir 	mpImpl->acquire();
928*cdf0e10cSrcweir }
929*cdf0e10cSrcweir 
930*cdf0e10cSrcweir // --------------------------------------------------------------------
931*cdf0e10cSrcweir 
932*cdf0e10cSrcweir CellEditSource::CellEditSource( CellEditSourceImpl* pImpl )
933*cdf0e10cSrcweir {
934*cdf0e10cSrcweir 	mpImpl = pImpl;
935*cdf0e10cSrcweir 	mpImpl->acquire();
936*cdf0e10cSrcweir }
937*cdf0e10cSrcweir 
938*cdf0e10cSrcweir //------------------------------------------------------------------------
939*cdf0e10cSrcweir CellEditSource::~CellEditSource()
940*cdf0e10cSrcweir {
941*cdf0e10cSrcweir 	OGuard aGuard( Application::GetSolarMutex() );
942*cdf0e10cSrcweir 	mpImpl->release();
943*cdf0e10cSrcweir }
944*cdf0e10cSrcweir 
945*cdf0e10cSrcweir //------------------------------------------------------------------------
946*cdf0e10cSrcweir SvxEditSource* CellEditSource::Clone() const
947*cdf0e10cSrcweir {
948*cdf0e10cSrcweir 	return new CellEditSource( mpImpl );
949*cdf0e10cSrcweir }
950*cdf0e10cSrcweir 
951*cdf0e10cSrcweir //------------------------------------------------------------------------
952*cdf0e10cSrcweir SvxTextForwarder* CellEditSource::GetTextForwarder()
953*cdf0e10cSrcweir {
954*cdf0e10cSrcweir     return mpImpl->GetTextForwarder();
955*cdf0e10cSrcweir }
956*cdf0e10cSrcweir 
957*cdf0e10cSrcweir //------------------------------------------------------------------------
958*cdf0e10cSrcweir SvxEditViewForwarder* CellEditSource::GetEditViewForwarder( sal_Bool bCreate )
959*cdf0e10cSrcweir {
960*cdf0e10cSrcweir     return mpImpl->GetEditViewForwarder( bCreate );
961*cdf0e10cSrcweir }
962*cdf0e10cSrcweir 
963*cdf0e10cSrcweir //------------------------------------------------------------------------
964*cdf0e10cSrcweir 
965*cdf0e10cSrcweir SvxViewForwarder* CellEditSource::GetViewForwarder()
966*cdf0e10cSrcweir {
967*cdf0e10cSrcweir     return this;
968*cdf0e10cSrcweir }
969*cdf0e10cSrcweir 
970*cdf0e10cSrcweir //------------------------------------------------------------------------
971*cdf0e10cSrcweir 
972*cdf0e10cSrcweir void CellEditSource::UpdateData()
973*cdf0e10cSrcweir {
974*cdf0e10cSrcweir     mpImpl->UpdateData();
975*cdf0e10cSrcweir }
976*cdf0e10cSrcweir 
977*cdf0e10cSrcweir //------------------------------------------------------------------------
978*cdf0e10cSrcweir 
979*cdf0e10cSrcweir SfxBroadcaster& CellEditSource::GetBroadcaster() const
980*cdf0e10cSrcweir {
981*cdf0e10cSrcweir     return *mpImpl;
982*cdf0e10cSrcweir }
983*cdf0e10cSrcweir 
984*cdf0e10cSrcweir //------------------------------------------------------------------------
985*cdf0e10cSrcweir 
986*cdf0e10cSrcweir void CellEditSource::lock()
987*cdf0e10cSrcweir {
988*cdf0e10cSrcweir     mpImpl->lock();
989*cdf0e10cSrcweir }
990*cdf0e10cSrcweir 
991*cdf0e10cSrcweir //------------------------------------------------------------------------
992*cdf0e10cSrcweir 
993*cdf0e10cSrcweir void CellEditSource::unlock()
994*cdf0e10cSrcweir {
995*cdf0e10cSrcweir     mpImpl->unlock();
996*cdf0e10cSrcweir }
997*cdf0e10cSrcweir 
998*cdf0e10cSrcweir //------------------------------------------------------------------------
999*cdf0e10cSrcweir 
1000*cdf0e10cSrcweir sal_Bool CellEditSource::IsValid() const
1001*cdf0e10cSrcweir {
1002*cdf0e10cSrcweir     return mpImpl->IsValid();
1003*cdf0e10cSrcweir }
1004*cdf0e10cSrcweir 
1005*cdf0e10cSrcweir //------------------------------------------------------------------------
1006*cdf0e10cSrcweir 
1007*cdf0e10cSrcweir Rectangle CellEditSource::GetVisArea() const
1008*cdf0e10cSrcweir {
1009*cdf0e10cSrcweir     return mpImpl->GetVisArea();
1010*cdf0e10cSrcweir }
1011*cdf0e10cSrcweir 
1012*cdf0e10cSrcweir //------------------------------------------------------------------------
1013*cdf0e10cSrcweir 
1014*cdf0e10cSrcweir Point CellEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1015*cdf0e10cSrcweir {
1016*cdf0e10cSrcweir     return mpImpl->LogicToPixel( rPoint, rMapMode );
1017*cdf0e10cSrcweir }
1018*cdf0e10cSrcweir 
1019*cdf0e10cSrcweir //------------------------------------------------------------------------
1020*cdf0e10cSrcweir 
1021*cdf0e10cSrcweir Point CellEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1022*cdf0e10cSrcweir {
1023*cdf0e10cSrcweir     return mpImpl->PixelToLogic( rPoint, rMapMode );
1024*cdf0e10cSrcweir }
1025*cdf0e10cSrcweir 
1026*cdf0e10cSrcweir //------------------------------------------------------------------------
1027*cdf0e10cSrcweir 
1028*cdf0e10cSrcweir void CellEditSource::addRange( SvxUnoTextRangeBase* pNewRange )
1029*cdf0e10cSrcweir {
1030*cdf0e10cSrcweir 	mpImpl->addRange( pNewRange );
1031*cdf0e10cSrcweir }
1032*cdf0e10cSrcweir 
1033*cdf0e10cSrcweir //------------------------------------------------------------------------
1034*cdf0e10cSrcweir 
1035*cdf0e10cSrcweir void CellEditSource::removeRange( SvxUnoTextRangeBase* pOldRange )
1036*cdf0e10cSrcweir {
1037*cdf0e10cSrcweir 	mpImpl->removeRange( pOldRange );
1038*cdf0e10cSrcweir }
1039*cdf0e10cSrcweir 
1040*cdf0e10cSrcweir //------------------------------------------------------------------------
1041*cdf0e10cSrcweir 
1042*cdf0e10cSrcweir const SvxUnoTextRangeBaseList& CellEditSource::getRanges() const
1043*cdf0e10cSrcweir {
1044*cdf0e10cSrcweir 	return mpImpl->getRanges();
1045*cdf0e10cSrcweir }
1046*cdf0e10cSrcweir 
1047*cdf0e10cSrcweir //------------------------------------------------------------------------
1048*cdf0e10cSrcweir 
1049*cdf0e10cSrcweir void CellEditSource::ChangeModel( SdrModel* pNewModel )
1050*cdf0e10cSrcweir {
1051*cdf0e10cSrcweir 	mpImpl->ChangeModel( pNewModel );
1052*cdf0e10cSrcweir }
1053*cdf0e10cSrcweir 
1054*cdf0e10cSrcweir //------------------------------------------------------------------------
1055*cdf0e10cSrcweir 
1056*cdf0e10cSrcweir } }
1057