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: SwGrammarContact.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_sw.hxx"
34 #include <vcl/timer.hxx>
36 #include <IGrammarContact.hxx>
39 #include <SwGrammarMarkUp.hxx>
41 #include <rootfrm.hxx>
44 extern void repaintTextFrames( SwModify
& rModify
);
48 This class is responsible for the delayed display of grammar checks when a paragraph is edited
49 It's a client of the paragraph the cursor points to.
50 If the cursor position changes, updateCursorPosition has to be called
51 If the grammar checker wants to set a grammar marker at a paragraph, he has to request
52 the grammar list from this class. If the requested paragraph is not edited, it returns
53 the normal grammar list. But if the paragraph is the active one, a proxy list will be returned and
54 all changes are set in this proxy list. If the cursor leaves the paragraph the proxy list
55 will replace the old list. If the grammar checker has completed the paragraph ('setChecked')
56 then a timer is setup which replaces the old list as well.
59 class SwGrammarContact
: public IGrammarContact
, public SwClient
62 SwGrammarMarkUp
*mpProxyList
;
64 SwTxtNode
* getMyTxtNode() { return (SwTxtNode
*)pRegisteredIn
; }
65 DECL_LINK( TimerRepaint
, Timer
* );
69 ~SwGrammarContact() { aTimer
.Stop(); delete mpProxyList
; }
71 // (pure) virtual functions of IGrammarContact
72 virtual void updateCursorPosition( const SwPosition
& rNewPos
);
73 virtual SwGrammarMarkUp
* getGrammarCheck( SwTxtNode
& rTxtNode
, bool bCreate
);
74 virtual void finishGrammarCheck( SwTxtNode
& rTxtNode
);
76 // virtual function of SwClient
77 virtual void Modify( SfxPoolItem
*pOld
, SfxPoolItem
*pNew
);
80 SwGrammarContact::SwGrammarContact() : mpProxyList(0), mbFinished( false )
82 aTimer
.SetTimeout( 2000 ); // Repaint of grammar check after 'setChecked'
83 aTimer
.SetTimeoutHdl( LINK(this, SwGrammarContact
, TimerRepaint
) );
86 IMPL_LINK( SwGrammarContact
, TimerRepaint
, Timer
*, pTimer
)
92 { //Replace the old wrong list by the proxy list and repaint all frames
93 getMyTxtNode()->SetGrammarCheck( mpProxyList
, true );
95 repaintTextFrames( *pRegisteredIn
);
101 /* I'm always a client of the current paragraph */
102 void SwGrammarContact::updateCursorPosition( const SwPosition
& rNewPos
)
104 SwTxtNode
* pTxtNode
= rNewPos
.nNode
.GetNode().GetTxtNode();
105 if( pTxtNode
!= GetRegisteredIn() ) // paragraph has been changed
108 if( GetRegisteredIn() ) // My last paragraph has been left
111 { // replace old list by the proxy list and repaint
112 getMyTxtNode()->SetGrammarCheck( mpProxyList
, true );
113 repaintTextFrames( *pRegisteredIn
);
115 pRegisteredIn
->Remove( this ); // good bye old paragraph
119 pTxtNode
->Add( this ); // welcome new paragraph
123 /* deliver a grammar check list for the given text node */
124 SwGrammarMarkUp
* SwGrammarContact::getGrammarCheck( SwTxtNode
& rTxtNode
, bool bCreate
)
126 SwGrammarMarkUp
*pRet
= 0;
127 if( GetRegisteredIn() == &rTxtNode
) // hey, that's my current paragraph!
128 { // so you will get a proxy list...
138 if( rTxtNode
.GetGrammarCheck() )
139 mpProxyList
= (SwGrammarMarkUp
*)rTxtNode
.GetGrammarCheck()->Clone();
142 mpProxyList
= new SwGrammarMarkUp();
143 mpProxyList
->SetInvalid( 0, STRING_LEN
);
152 pRet
= rTxtNode
.GetGrammarCheck(); // do you have already a list?
153 if( bCreate
&& !pRet
) // do you want to create a list?
155 pRet
= new SwGrammarMarkUp();
156 pRet
->SetInvalid( 0, STRING_LEN
);
157 rTxtNode
.SetGrammarCheck( pRet
);
158 rTxtNode
.SetGrammarCheckDirty( true );
164 void SwGrammarContact::Modify( SfxPoolItem
*pOld
, SfxPoolItem
* )
166 if( !pOld
|| pOld
->Which() != RES_OBJECTDYING
)
169 SwPtrMsgPoolItem
*pDead
= (SwPtrMsgPoolItem
*)pOld
;
170 if( pDead
->pObject
== pRegisteredIn
)
171 { // if my current paragraph dies, I throw the proxy list away
173 pRegisteredIn
->Remove( this );
179 void SwGrammarContact::finishGrammarCheck( SwTxtNode
& rTxtNode
)
181 if( &rTxtNode
!= pRegisteredIn
) // not my paragraph
182 repaintTextFrames( rTxtNode
); // can be repainted directly
188 aTimer
.Start(); // will replace old list and repaint with delay
190 else if( getMyTxtNode()->GetGrammarCheck() )
191 { // all grammar problems seems to be gone, no delay needed
192 getMyTxtNode()->SetGrammarCheck( 0, true );
193 repaintTextFrames( *pRegisteredIn
);
198 IGrammarContact
* createGrammarContact()
200 return new SwGrammarContact();
203 /* repaint all text frames of the given text node */
204 void repaintTextFrames( SwModify
& rModify
)
206 SwClientIter
aIter( rModify
);
207 for( const SwTxtFrm
*pFrm
= (const SwTxtFrm
*)aIter
.First( TYPE(SwTxtFrm
) );
208 pFrm
; pFrm
= (const SwTxtFrm
*)aIter
.Next() )
210 SwRect
aRec( pFrm
->PaintArea() );
211 const SwRootFrm
*pRootFrm
= pFrm
->FindRootFrm();
212 ViewShell
*pCurShell
= pRootFrm
? pRootFrm
->GetCurrShell() : NULL
;
214 pCurShell
->InvalidateWindows( aRec
);
218 void finishGrammarCheck( SwTxtNode
& rTxtNode
)
220 IGrammarContact
* pGrammarContact
= getGrammarContact( rTxtNode
);
221 if( pGrammarContact
)
222 pGrammarContact
->finishGrammarCheck( rTxtNode
);