merge the formfield patch from ooo-build
[ooovba.git] / sw / source / core / txtnode / SwGrammarContact.cxx
blob913fefcd6e1b10e60603fe209a94e71db00d6642
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: SwGrammarContact.cxx,v $
10 * $Revision: 1.2 $
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>
35 #include <hints.hxx>
36 #include <IGrammarContact.hxx>
37 #include <pam.hxx>
38 #include <ndtxt.hxx>
39 #include <SwGrammarMarkUp.hxx>
40 #include <txtfrm.hxx>
41 #include <rootfrm.hxx>
42 #include <viewsh.hxx>
44 extern void repaintTextFrames( SwModify& rModify );
47 /* SwGrammarContact
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
61 Timer aTimer;
62 SwGrammarMarkUp *mpProxyList;
63 bool mbFinished;
64 SwTxtNode* getMyTxtNode() { return (SwTxtNode*)pRegisteredIn; }
65 DECL_LINK( TimerRepaint, Timer * );
67 public:
68 SwGrammarContact();
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 )
88 if( pTimer )
90 pTimer->Stop();
91 if( pRegisteredIn )
92 { //Replace the old wrong list by the proxy list and repaint all frames
93 getMyTxtNode()->SetGrammarCheck( mpProxyList, true );
94 mpProxyList = 0;
95 repaintTextFrames( *pRegisteredIn );
98 return 0;
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
107 aTimer.Stop();
108 if( GetRegisteredIn() ) // My last paragraph has been left
110 if( mpProxyList )
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
116 mpProxyList = 0;
118 if( pTxtNode )
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...
129 if( bCreate )
131 if( mbFinished )
133 delete mpProxyList;
134 mpProxyList = 0;
136 if( !mpProxyList )
138 if( rTxtNode.GetGrammarCheck() )
139 mpProxyList = (SwGrammarMarkUp*)rTxtNode.GetGrammarCheck()->Clone();
140 else
142 mpProxyList = new SwGrammarMarkUp();
143 mpProxyList->SetInvalid( 0, STRING_LEN );
146 mbFinished = false;
148 pRet = mpProxyList;
150 else
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 );
161 return pRet;
164 void SwGrammarContact::Modify( SfxPoolItem *pOld, SfxPoolItem * )
166 if( !pOld || pOld->Which() != RES_OBJECTDYING )
167 return;
169 SwPtrMsgPoolItem *pDead = (SwPtrMsgPoolItem *)pOld;
170 if( pDead->pObject == pRegisteredIn )
171 { // if my current paragraph dies, I throw the proxy list away
172 aTimer.Stop();
173 pRegisteredIn->Remove( this );
174 delete mpProxyList;
175 mpProxyList = 0;
179 void SwGrammarContact::finishGrammarCheck( SwTxtNode& rTxtNode )
181 if( &rTxtNode != pRegisteredIn ) // not my paragraph
182 repaintTextFrames( rTxtNode ); // can be repainted directly
183 else
185 if( mpProxyList )
187 mbFinished = true;
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;
213 if( pCurShell )
214 pCurShell->InvalidateWindows( aRec );
218 void finishGrammarCheck( SwTxtNode& rTxtNode )
220 IGrammarContact* pGrammarContact = getGrammarContact( rTxtNode );
221 if( pGrammarContact )
222 pGrammarContact->finishGrammarCheck( rTxtNode );