Update ooo320-m1
[ooovba.git] / svx / source / table / celleditsource.cxx
blob3be461adceb04a1998202a52c5bd59150a6a1387
1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: celleditsource.cxx,v $
10 * $Revision: 1.3 $
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 #include <com/sun/star/linguistic2/XLinguServiceManager.hpp>
36 #include <rtl/ref.hxx>
37 #include <osl/mutex.hxx>
38 #include <vos/mutex.hxx>
39 #include <vcl/svapp.hxx>
40 #include <comphelper/processfactory.hxx>
41 #include <svtools/lstner.hxx>
42 #include <svtools/hint.hxx>
43 #include <svtools/style.hxx>
45 #include "celleditsource.hxx"
46 #include "cell.hxx"
47 #include "svx/svdmodel.hxx"
48 #include "svx/svdoutl.hxx"
49 #include "svx/svdobj.hxx"
50 #include "unoedhlp.hxx"
51 #include "svx/svdview.hxx"
52 #include "svx/svdetc.hxx"
53 #include "svx/outliner.hxx"
54 #include "svx/unoforou.hxx"
55 #include "svx/unoviwou.hxx"
56 #include "svx/outlobj.hxx"
57 #include "svx/svdotext.hxx"
58 #include "svx/svdpage.hxx"
59 #include "svx/editeng.hxx"
60 #include "svx/unotext.hxx"
61 #include "sdrpaintwindow.hxx"
63 //------------------------------------------------------------------------
65 using ::rtl::OUString;
66 using namespace ::osl;
67 using namespace ::vos;
69 using namespace ::com::sun::star::uno;
70 using namespace ::com::sun::star::linguistic2;
71 using namespace ::com::sun::star::lang;
73 //------------------------------------------------------------------------
75 namespace sdr { namespace table {
77 //------------------------------------------------------------------------
78 // CellEditSourceImpl
79 //------------------------------------------------------------------------
81 /** @descr
82 <p>This class essentially provides the text and view forwarders. If
83 no SdrView is given, this class handles the UNO objects, which are
84 currently not concerned with view issues. In this case,
85 GetViewForwarder() always returns NULL and the underlying
86 EditEngine of the SvxTextForwarder is a background one (i.e. not
87 the official DrawOutliner, but one created exclusively for this
88 object, with no relation to a view).
89 </p>
91 <p>If a SdrView is given at construction time, the caller is
92 responsible for destroying this object when the view becomes
93 invalid (the views cannot notify). If GetViewForwarder(sal_True)
94 is called, the underlying shape is put into edit mode, the view
95 forwarder returned encapsulates the OutlinerView and the next call
96 to GetTextForwarder() yields a forwarder encapsulating the actual
97 DrawOutliner. Thus, changes on that Outliner are immediately
98 reflected on the screen. If the object leaves edit mode, the old
99 behaviour is restored.</p>
101 class CellEditSourceImpl : public SfxListener, public SfxBroadcaster
103 private:
104 oslInterlockedCount maRefCount;
106 SdrView* mpView;
107 const Window* mpWindow;
108 SdrModel* mpModel;
109 SdrOutliner* mpOutliner;
110 SvxOutlinerForwarder* mpTextForwarder;
111 SvxDrawOutlinerViewForwarder* mpViewForwarder;
112 Reference< ::com::sun::star::linguistic2::XLinguServiceManager > mxLinguServiceManager;
113 Point maTextOffset;
114 bool mbDataValid;
115 bool mbDisposed;
116 bool mbIsLocked;
117 bool mbNeedsUpdate;
118 bool mbOldUndoMode;
119 bool mbForwarderIsEditMode; // have to reflect that, since ENDEDIT can happen more often
120 bool mbShapeIsEditMode; // #104157# only true, if HINT_BEGEDIT was received
121 bool mbNotificationsDisabled; // prevent EditEngine/Outliner notifications (e.g. when setting up forwarder)
123 CellRef mxCell;
124 SvxUnoTextRangeBaseList maTextRanges;
126 SvxTextForwarder* GetBackgroundTextForwarder();
127 SvxTextForwarder* GetEditModeTextForwarder();
128 SvxDrawOutlinerViewForwarder* CreateViewForwarder();
130 void SetupOutliner();
131 void UpdateOutliner();
133 bool HasView() const { return mpView != 0; }
134 bool IsEditMode() const { return mxCell->IsTextEditActive(); };
135 void dispose();
137 public:
138 CellEditSourceImpl( const CellRef& xCell );
139 CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow );
140 ~CellEditSourceImpl();
142 void SAL_CALL acquire();
143 void SAL_CALL release();
145 virtual void Notify( SfxBroadcaster& rBC, const SfxHint& rHint );
147 SvxEditSource* Clone() const;
148 SvxTextForwarder* GetTextForwarder();
149 SvxEditViewForwarder* GetEditViewForwarder( sal_Bool );
150 void UpdateData();
152 void addRange( SvxUnoTextRangeBase* pNewRange );
153 void removeRange( SvxUnoTextRangeBase* pOldRange );
154 const SvxUnoTextRangeBaseList& getRanges() const;
156 void lock();
157 void unlock();
159 BOOL IsValid() const;
161 Rectangle GetVisArea();
162 Point LogicToPixel( const Point&, const MapMode& rMapMode );
163 Point PixelToLogic( const Point&, const MapMode& rMapMode );
165 DECL_LINK( NotifyHdl, EENotify* );
167 void ChangeModel( SdrModel* pNewModel );
170 //------------------------------------------------------------------------
172 CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell )
173 : maRefCount ( 0 ),
174 mpView ( NULL ),
175 mpWindow ( NULL ),
176 mpModel ( NULL ),
177 mpOutliner ( NULL ),
178 mpTextForwarder ( NULL ),
179 mpViewForwarder ( NULL ),
180 mbDataValid ( false ),
181 mbDisposed ( false ),
182 mbIsLocked ( false ),
183 mbNeedsUpdate ( false ),
184 mbOldUndoMode ( false ),
185 mbForwarderIsEditMode ( false ),
186 mbShapeIsEditMode ( false ),
187 mbNotificationsDisabled ( false ),
188 mxCell( xCell )
192 //------------------------------------------------------------------------
194 CellEditSourceImpl::CellEditSourceImpl( const CellRef& xCell, SdrView& rView, const Window& rWindow )
195 : maRefCount ( 0 ),
196 mpView ( &rView ),
197 mpWindow ( &rWindow ),
198 mpModel ( NULL ),
199 mpOutliner ( NULL ),
200 mpTextForwarder ( NULL ),
201 mpViewForwarder ( NULL ),
202 mbDataValid ( false ),
203 mbDisposed ( false ),
204 mbIsLocked ( false ),
205 mbNeedsUpdate ( false ),
206 mbOldUndoMode ( false ),
207 mbForwarderIsEditMode ( false ),
208 mbShapeIsEditMode ( true ),
209 mbNotificationsDisabled ( false ),
210 mxCell( xCell )
212 if( mpView )
213 StartListening( *mpView );
215 // #104157# Init edit mode state from shape info (IsTextEditActive())
216 mbShapeIsEditMode = IsEditMode();
219 //------------------------------------------------------------------------
221 CellEditSourceImpl::~CellEditSourceImpl()
223 DBG_ASSERT( mbIsLocked == sal_False, "CellEditSourceImpl::~CellEditSourceImpl(), was not unlocked before dispose!" );
224 dispose();
227 //------------------------------------------------------------------------
229 void CellEditSourceImpl::addRange( SvxUnoTextRangeBase* pNewRange )
231 if( pNewRange )
232 if( std::find( maTextRanges.begin(), maTextRanges.end(), pNewRange ) == maTextRanges.end() )
233 maTextRanges.push_back( pNewRange );
236 //------------------------------------------------------------------------
238 void CellEditSourceImpl::removeRange( SvxUnoTextRangeBase* pOldRange )
240 if( pOldRange )
241 maTextRanges.remove( pOldRange );
244 //------------------------------------------------------------------------
246 const SvxUnoTextRangeBaseList& CellEditSourceImpl::getRanges() const
248 return maTextRanges;
251 //------------------------------------------------------------------------
253 void SAL_CALL CellEditSourceImpl::acquire()
255 osl_incrementInterlockedCount( &maRefCount );
258 //------------------------------------------------------------------------
260 void SAL_CALL CellEditSourceImpl::release()
262 if( ! osl_decrementInterlockedCount( &maRefCount ) )
263 delete this;
266 void CellEditSourceImpl::ChangeModel( SdrModel* pNewModel )
268 if( mpModel != pNewModel )
270 if( mpOutliner )
272 if( mpModel )
273 mpModel->disposeOutliner( mpOutliner );
274 else
275 delete mpOutliner;
276 mpOutliner = 0;
279 if( mpView )
281 EndListening( *mpView );
282 mpView = 0;
285 mpWindow = 0;
286 mxLinguServiceManager.clear();
288 mpModel = pNewModel;
290 if( mpTextForwarder )
292 delete mpTextForwarder;
293 mpTextForwarder = 0;
296 if( mpViewForwarder )
298 delete mpViewForwarder;
299 mpViewForwarder = 0;
304 //------------------------------------------------------------------------
306 void CellEditSourceImpl::Notify( SfxBroadcaster&, const SfxHint& rHint )
308 const SdrHint* pSdrHint = PTR_CAST( SdrHint, &rHint );
309 const SvxViewHint* pViewHint = PTR_CAST( SvxViewHint, &rHint );
311 if( pViewHint )
313 switch( pViewHint->GetHintType() )
315 case SvxViewHint::SVX_HINT_VIEWCHANGED:
316 Broadcast( *pViewHint );
317 break;
320 else if( pSdrHint )
322 switch( pSdrHint->GetKind() )
324 case HINT_OBJCHG:
326 mbDataValid = FALSE; // Text muss neu geholt werden
328 if( HasView() )
330 // #104157# Update maTextOffset, object has changed
331 // #105196#, #105203#: Cannot call that // here,
332 // since TakeTextRect() (called from there) //
333 // changes outliner content.
334 // UpdateOutliner();
336 // #101029# Broadcast object changes, as they might change visible attributes
337 SvxViewHint aHint(SvxViewHint::SVX_HINT_VIEWCHANGED);
338 Broadcast( aHint );
340 break;
343 case HINT_BEGEDIT:
344 /* todo
345 if( mpObject == pSdrHint->GetObject() )
347 // invalidate old forwarder
348 if( !mbForwarderIsEditMode )
350 delete mpTextForwarder;
351 mpTextForwarder = NULL;
354 // register as listener - need to broadcast state change messages
355 if( mpView && mpView->GetTextEditOutliner() )
356 mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
358 // #104157# Only now we're really in edit mode
359 mbShapeIsEditMode = TRUE;
361 Broadcast( *pSdrHint );
364 break;
366 case HINT_ENDEDIT:
367 /* todo
368 if( mpObject == pSdrHint->GetObject() )
370 Broadcast( *pSdrHint );
372 // #104157# We're no longer in edit mode
373 mbShapeIsEditMode = FALSE;
375 // remove as listener - outliner might outlive ourselves
376 if( mpView && mpView->GetTextEditOutliner() )
377 mpView->GetTextEditOutliner()->SetNotifyHdl( Link() );
379 // destroy view forwarder, OutlinerView no longer
380 // valid (no need for UpdateData(), it's been
381 // synched on SdrEndTextEdit)
382 delete mpViewForwarder;
383 mpViewForwarder = NULL;
385 // #100424# Invalidate text forwarder, we might
386 // not be called again before entering edit mode a
387 // second time! Then, the old outliner might be
388 // invalid.
389 if( mbForwarderIsEditMode )
391 mbForwarderIsEditMode = sal_False;
392 delete mpTextForwarder;
393 mpTextForwarder = NULL;
397 break;
399 case HINT_MODELCLEARED:
400 dispose();
401 break;
402 default:
403 break;
408 /* unregister at all objects and set all references to 0 */
409 void CellEditSourceImpl::dispose()
411 if( mpTextForwarder )
413 delete mpTextForwarder;
414 mpTextForwarder = 0;
417 if( mpViewForwarder )
419 delete mpViewForwarder;
420 mpViewForwarder = 0;
423 if( mpOutliner )
425 if( mpModel )
427 mpModel->disposeOutliner( mpOutliner );
429 else
431 delete mpOutliner;
433 mpOutliner = 0;
436 if( mpView )
438 EndListening( *mpView );
439 mpView = 0;
442 mpModel = 0;
443 mpWindow = 0;
446 //------------------------------------------------------------------------
448 void CellEditSourceImpl::SetupOutliner()
450 // #101029#
451 // only for UAA edit source: setup outliner equivalently as in
452 // SdrTextObj::Paint(), such that formatting equals screen
453 // layout
454 /* todo
455 if( mpObject && mpOutliner )
457 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
458 Rectangle aPaintRect;
459 if( pTextObj )
461 Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
462 pTextObj->SetupOutlinerFormatting( *mpOutliner, aPaintRect );
464 // #101029# calc text offset from shape anchor
465 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
471 //------------------------------------------------------------------------
473 void CellEditSourceImpl::UpdateOutliner()
475 // #104157#
476 // only for UAA edit source: update outliner equivalently as in
477 // SdrTextObj::Paint(), such that formatting equals screen
478 // layout
479 /* todo
480 if( mpObject && mpOutliner )
482 SdrTextObj* pTextObj = PTR_CAST( SdrTextObj, mpObject );
483 Rectangle aPaintRect;
484 if( pTextObj )
486 Rectangle aBoundRect( pTextObj->GetCurrentBoundRect() );
487 pTextObj->UpdateOutlinerFormatting( *mpOutliner, aPaintRect );
489 // #101029# calc text offset from shape anchor
490 maTextOffset = aPaintRect.TopLeft() - aBoundRect.TopLeft();
496 //------------------------------------------------------------------------
499 SvxTextForwarder* CellEditSourceImpl::GetBackgroundTextForwarder()
501 sal_Bool bCreated = sal_False;
503 // #99840#: prevent EE/Outliner notifications during setup
504 mbNotificationsDisabled = true;
506 if (!mpTextForwarder)
508 if( mpOutliner == NULL )
510 mpOutliner = mpModel->createOutliner( OUTLINERMODE_TEXTOBJECT );
512 // #109151# Do the setup after outliner creation, would be useless otherwise
513 if( HasView() )
515 // #101029#, #104157# Setup outliner _before_ filling it
516 SetupOutliner();
519 // todo? mpOutliner->SetTextObjNoInit( pTextObj );
521 if( mbIsLocked )
523 ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
524 mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
525 ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
528 if ( !mxLinguServiceManager.is() )
530 Reference< XMultiServiceFactory > xMgr( ::comphelper::getProcessServiceFactory() );
531 mxLinguServiceManager = Reference< XLinguServiceManager >(
532 xMgr->createInstance( OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.linguistic2.LinguServiceManager" ))), UNO_QUERY );
535 if ( mxLinguServiceManager.is() )
537 Reference< XHyphenator > xHyphenator( mxLinguServiceManager->getHyphenator(), UNO_QUERY );
538 if( xHyphenator.is() )
539 mpOutliner->SetHyphenator( xHyphenator );
543 mpTextForwarder = new SvxOutlinerForwarder( *mpOutliner );
545 // delay listener subscription and UAA initialization until Outliner is fully setup
546 bCreated = true;
547 mbForwarderIsEditMode = false;
550 if( !mbDataValid )
552 mpTextForwarder->flushCache();
554 OutlinerParaObject* pOutlinerParaObject = NULL;
555 bool bTextEditActive = false;
557 pOutlinerParaObject = mxCell->GetEditOutlinerParaObject(); // Get the OutlinerParaObject if text edit is active
559 if( pOutlinerParaObject )
560 bTextEditActive = true; // text edit active
561 else
562 pOutlinerParaObject = mxCell->GetOutlinerParaObject();
564 if( pOutlinerParaObject )
566 mpOutliner->SetText( *pOutlinerParaObject );
568 else
570 bool bVertical = false; // todo?
572 // set objects style sheet on empty outliner
573 SfxStyleSheetPool* pPool = mxCell->GetStyleSheetPool();
574 if( pPool )
575 mpOutliner->SetStyleSheetPool( pPool );
577 SfxStyleSheet* pStyleSheet = mxCell->GetStyleSheet();
578 if( pStyleSheet )
579 mpOutliner->SetStyleSheet( 0, pStyleSheet );
581 if( bVertical )
582 mpOutliner->SetVertical( sal_True );
585 // evtually we have to set the border attributes
586 if (mpOutliner->GetParagraphCount()==1)
588 // if we only have one paragraph we check if it is empty
589 XubString aStr( mpOutliner->GetText( mpOutliner->GetParagraph( 0 ) ) );
591 if(!aStr.Len())
593 // its empty, so we have to force the outliner to initialise itself
594 mpOutliner->SetText( String(), mpOutliner->GetParagraph( 0 ) );
596 if(mxCell->GetStyleSheet())
597 mpOutliner->SetStyleSheet( 0, mxCell->GetStyleSheet());
601 if( bTextEditActive )
602 delete pOutlinerParaObject;
604 mbDataValid = true;
607 if( bCreated && mpOutliner && HasView() )
609 // register as listener - need to broadcast state change messages
610 // registration delayed until outliner is completely set up
611 mpOutliner->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
614 // #99840#: prevent EE/Outliner notifications during setup
615 mbNotificationsDisabled = false;
617 return mpTextForwarder;
620 //------------------------------------------------------------------------
622 SvxTextForwarder* CellEditSourceImpl::GetEditModeTextForwarder()
624 if( !mpTextForwarder && HasView() )
626 SdrOutliner* pEditOutliner = mpView->GetTextEditOutliner();
628 if( pEditOutliner )
630 mpTextForwarder = new SvxOutlinerForwarder( *pEditOutliner );
631 mbForwarderIsEditMode = true;
635 return mpTextForwarder;
638 //------------------------------------------------------------------------
640 SvxTextForwarder* CellEditSourceImpl::GetTextForwarder()
642 if( mbDisposed )
643 return NULL;
645 if( mpModel == NULL )
646 return NULL;
648 // distinguish the cases
649 // a) connected to view, maybe edit mode is active, can work directly on the EditOutliner
650 // b) background Outliner, reflect changes into ParaOutlinerObject (this is exactly the old UNO code)
651 if( HasView() )
653 if( IsEditMode() != mbForwarderIsEditMode )
655 // forwarder mismatch - create new
656 delete mpTextForwarder;
657 mpTextForwarder = NULL;
660 if( IsEditMode() )
661 return GetEditModeTextForwarder();
662 else
663 return GetBackgroundTextForwarder();
665 else
666 return GetBackgroundTextForwarder();
669 //------------------------------------------------------------------------
671 SvxDrawOutlinerViewForwarder* CellEditSourceImpl::CreateViewForwarder()
673 if( mpView->GetTextEditOutlinerView() )
675 // register as listener - need to broadcast state change messages
676 mpView->GetTextEditOutliner()->SetNotifyHdl( LINK(this, CellEditSourceImpl, NotifyHdl) );
678 Rectangle aBoundRect( mxCell->GetCurrentBoundRect() );
679 OutlinerView& rOutlView = *mpView->GetTextEditOutlinerView();
681 return new SvxDrawOutlinerViewForwarder( rOutlView, aBoundRect.TopLeft() );
684 return NULL;
687 SvxEditViewForwarder* CellEditSourceImpl::GetEditViewForwarder( sal_Bool bCreate )
689 if( mbDisposed )
690 return NULL;
692 if( mpModel == NULL )
693 return NULL;
695 // shall we delete?
696 if( mpViewForwarder )
698 if( !IsEditMode() )
700 // destroy all forwarders (no need for UpdateData(),
701 // it's been synched on SdrEndTextEdit)
702 delete mpViewForwarder;
703 mpViewForwarder = NULL;
706 // which to create? Directly in edit mode, create new, or none?
707 else if( mpView )
709 if( IsEditMode() )
711 // create new view forwarder
712 mpViewForwarder = CreateViewForwarder();
714 else if( bCreate )
716 // dispose old text forwarder
717 UpdateData();
719 delete mpTextForwarder;
720 mpTextForwarder = NULL;
722 // enter edit mode
723 mpView->SdrEndTextEdit();
725 /* todo
726 if(mpView->SdrBeginTextEdit(mpObject, 0L, 0L, sal_False, (SdrOutliner*)0L, 0L, sal_False, sal_False))
728 if( mxCell->IsTextEditActive() )
730 // create new view forwarder
731 mpViewForwarder = CreateViewForwarder();
733 else
735 // failure. Somehow, SdrBeginTextEdit did not set
736 // our SdrTextObj into edit mode
737 mpView->SdrEndTextEdit();
744 return mpViewForwarder;
747 //------------------------------------------------------------------------
749 void CellEditSourceImpl::UpdateData()
751 // if we have a view and in edit mode, we're working with the
752 // DrawOutliner. Thus, all changes made on the text forwarder are
753 // reflected on the view and committed to the model on
754 // SdrEndTextEdit(). Thus, no need for explicit updates here.
755 if( !HasView() || !IsEditMode() )
757 if( mbIsLocked )
759 mbNeedsUpdate = true;
761 else
763 if( mpOutliner && !mbDisposed )
765 if( mpOutliner->GetParagraphCount() != 1 || mpOutliner->GetEditEngine().GetTextLen( 0 ) )
767 mxCell->SetOutlinerParaObject( mpOutliner->CreateParaObject() );
769 else
771 mxCell->SetOutlinerParaObject( NULL );
778 void CellEditSourceImpl::lock()
780 mbIsLocked = true;
781 if( mpOutliner )
783 ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_False );
784 mbOldUndoMode = ((EditEngine*)&(mpOutliner->GetEditEngine()))->IsUndoEnabled();
785 ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( sal_False );
789 void CellEditSourceImpl::unlock()
791 mbIsLocked = false;
793 if( mbNeedsUpdate )
795 UpdateData();
796 mbNeedsUpdate = false;
799 if( mpOutliner )
801 ((EditEngine*)&(mpOutliner->GetEditEngine()))->SetUpdateMode( sal_True );
802 ((EditEngine*)&(mpOutliner->GetEditEngine()))->EnableUndo( mbOldUndoMode );
806 BOOL CellEditSourceImpl::IsValid() const
808 return mpView && mpWindow ? TRUE : FALSE;
811 Rectangle CellEditSourceImpl::GetVisArea()
813 if( IsValid() )
815 SdrPaintWindow* pPaintWindow = mpView->FindPaintWindow(*mpWindow);
816 Rectangle aVisArea;
818 if(pPaintWindow)
820 aVisArea = pPaintWindow->GetVisibleArea();
823 // offset vis area by edit engine left-top position
824 Rectangle aAnchorRect;
825 mxCell->TakeTextAnchorRect( aAnchorRect );
826 aVisArea.Move( -aAnchorRect.Left(), -aAnchorRect.Top() );
828 MapMode aMapMode(mpWindow->GetMapMode());
829 aMapMode.SetOrigin(Point());
830 return mpWindow->LogicToPixel( aVisArea, aMapMode );
833 return Rectangle();
836 Point CellEditSourceImpl::LogicToPixel( const Point& rPoint, const MapMode& rMapMode )
838 // #101029#: The responsibilities of ViewForwarder happen to be
839 // somewhat mixed in this case. On the one hand, we need the
840 // different interface queries on the SvxEditSource interface,
841 // since we need both VisAreas. On the other hand, if an
842 // EditViewForwarder exists, maTextOffset does not remain static,
843 // but may change with every key press.
844 if( IsEditMode() )
846 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
848 if( pForwarder )
849 return pForwarder->LogicToPixel( rPoint, rMapMode );
851 else if( IsValid() && mpModel )
853 // #101029#
854 Point aPoint1( rPoint );
855 aPoint1.X() += maTextOffset.X();
856 aPoint1.Y() += maTextOffset.Y();
858 Point aPoint2( OutputDevice::LogicToLogic( aPoint1, rMapMode,
859 MapMode(mpModel->GetScaleUnit()) ) );
860 MapMode aMapMode(mpWindow->GetMapMode());
861 aMapMode.SetOrigin(Point());
862 return mpWindow->LogicToPixel( aPoint2, aMapMode );
865 return Point();
868 Point CellEditSourceImpl::PixelToLogic( const Point& rPoint, const MapMode& rMapMode )
870 // #101029#: The responsibilities of ViewForwarder happen to be
871 // somewhat mixed in this case. On the one hand, we need the
872 // different interface queries on the SvxEditSource interface,
873 // since we need both VisAreas. On the other hand, if an
874 // EditViewForwarder exists, maTextOffset does not remain static,
875 // but may change with every key press.
876 if( IsEditMode() )
878 SvxEditViewForwarder* pForwarder = GetEditViewForwarder(sal_False);
880 if( pForwarder )
881 return pForwarder->PixelToLogic( rPoint, rMapMode );
883 else if( IsValid() && mpModel )
885 MapMode aMapMode(mpWindow->GetMapMode());
886 aMapMode.SetOrigin(Point());
887 Point aPoint1( mpWindow->PixelToLogic( rPoint, aMapMode ) );
888 Point aPoint2( OutputDevice::LogicToLogic( aPoint1,
889 MapMode(mpModel->GetScaleUnit()),
890 rMapMode ) );
891 // #101029#
892 aPoint2.X() -= maTextOffset.X();
893 aPoint2.Y() -= maTextOffset.Y();
895 return aPoint2;
898 return Point();
901 IMPL_LINK(CellEditSourceImpl, NotifyHdl, EENotify*, aNotify)
903 if( aNotify && !mbNotificationsDisabled )
905 ::std::auto_ptr< SfxHint > aHint( SvxEditSourceHelper::EENotification2Hint( aNotify) );
907 if( aHint.get() )
908 Broadcast( *aHint.get() );
911 return 0;
914 //------------------------------------------------------------------------
916 // --------------------------------------------------------------------
917 // CellEditSource
918 // --------------------------------------------------------------------
920 CellEditSource::CellEditSource( const CellRef& xCell )
922 mpImpl = new CellEditSourceImpl( xCell );
923 mpImpl->acquire();
926 // --------------------------------------------------------------------
927 CellEditSource::CellEditSource( const CellRef& xCell, SdrView& rView, const Window& rWindow )
929 mpImpl = new CellEditSourceImpl( xCell, rView, rWindow );
930 mpImpl->acquire();
933 // --------------------------------------------------------------------
935 CellEditSource::CellEditSource( CellEditSourceImpl* pImpl )
937 mpImpl = pImpl;
938 mpImpl->acquire();
941 //------------------------------------------------------------------------
942 CellEditSource::~CellEditSource()
944 OGuard aGuard( Application::GetSolarMutex() );
945 mpImpl->release();
948 //------------------------------------------------------------------------
949 SvxEditSource* CellEditSource::Clone() const
951 return new CellEditSource( mpImpl );
954 //------------------------------------------------------------------------
955 SvxTextForwarder* CellEditSource::GetTextForwarder()
957 return mpImpl->GetTextForwarder();
960 //------------------------------------------------------------------------
961 SvxEditViewForwarder* CellEditSource::GetEditViewForwarder( sal_Bool bCreate )
963 return mpImpl->GetEditViewForwarder( bCreate );
966 //------------------------------------------------------------------------
968 SvxViewForwarder* CellEditSource::GetViewForwarder()
970 return this;
973 //------------------------------------------------------------------------
975 void CellEditSource::UpdateData()
977 mpImpl->UpdateData();
980 //------------------------------------------------------------------------
982 SfxBroadcaster& CellEditSource::GetBroadcaster() const
984 return *mpImpl;
987 //------------------------------------------------------------------------
989 void CellEditSource::lock()
991 mpImpl->lock();
994 //------------------------------------------------------------------------
996 void CellEditSource::unlock()
998 mpImpl->unlock();
1001 //------------------------------------------------------------------------
1003 BOOL CellEditSource::IsValid() const
1005 return mpImpl->IsValid();
1008 //------------------------------------------------------------------------
1010 Rectangle CellEditSource::GetVisArea() const
1012 return mpImpl->GetVisArea();
1015 //------------------------------------------------------------------------
1017 Point CellEditSource::LogicToPixel( const Point& rPoint, const MapMode& rMapMode ) const
1019 return mpImpl->LogicToPixel( rPoint, rMapMode );
1022 //------------------------------------------------------------------------
1024 Point CellEditSource::PixelToLogic( const Point& rPoint, const MapMode& rMapMode ) const
1026 return mpImpl->PixelToLogic( rPoint, rMapMode );
1029 //------------------------------------------------------------------------
1031 void CellEditSource::addRange( SvxUnoTextRangeBase* pNewRange )
1033 mpImpl->addRange( pNewRange );
1036 //------------------------------------------------------------------------
1038 void CellEditSource::removeRange( SvxUnoTextRangeBase* pOldRange )
1040 mpImpl->removeRange( pOldRange );
1043 //------------------------------------------------------------------------
1045 const SvxUnoTextRangeBaseList& CellEditSource::getRanges() const
1047 return mpImpl->getRanges();
1050 //------------------------------------------------------------------------
1052 void CellEditSource::ChangeModel( SdrModel* pNewModel )
1054 mpImpl->ChangeModel( pNewModel );
1057 //------------------------------------------------------------------------