xref: /trunk/main/sw/source/core/edit/acorrect.cxx (revision cf6516809c57e1bb0a940545cca99cdad54d4ce2)
1efeef26fSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3efeef26fSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4efeef26fSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5efeef26fSAndrew Rist  * distributed with this work for additional information
6efeef26fSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7efeef26fSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8efeef26fSAndrew Rist  * "License"); you may not use this file except in compliance
9efeef26fSAndrew Rist  * with the License.  You may obtain a copy of the License at
10cdf0e10cSrcweir  *
11efeef26fSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12cdf0e10cSrcweir  *
13efeef26fSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14efeef26fSAndrew Rist  * software distributed under the License is distributed on an
15efeef26fSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16efeef26fSAndrew Rist  * KIND, either express or implied.  See the License for the
17efeef26fSAndrew Rist  * specific language governing permissions and limitations
18efeef26fSAndrew Rist  * under the License.
19cdf0e10cSrcweir  *
20efeef26fSAndrew Rist  *************************************************************/
21efeef26fSAndrew Rist 
22efeef26fSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_sw.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir 
28cdf0e10cSrcweir #define _STD_VAR_ARRAYS
29cdf0e10cSrcweir #include <hintids.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir #include <svx/svxids.hrc>
32cdf0e10cSrcweir #include <editeng/langitem.hxx>
33cdf0e10cSrcweir #include <fmtinfmt.hxx>
34cdf0e10cSrcweir #include <txtatr.hxx>
35cdf0e10cSrcweir #include <txtinet.hxx>
36cdf0e10cSrcweir #include <editsh.hxx>
37cdf0e10cSrcweir #include <doc.hxx>
38cdf0e10cSrcweir #include <pam.hxx>
39cdf0e10cSrcweir #include <ndtxt.hxx>
40cdf0e10cSrcweir #include <acorrect.hxx>
41cdf0e10cSrcweir #include <shellio.hxx>
42cdf0e10cSrcweir #include <swundo.hxx>
43cdf0e10cSrcweir #include <viscrs.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir #include <editeng/acorrcfg.hxx>
46cdf0e10cSrcweir 
47cdf0e10cSrcweir using namespace ::com::sun::star;
48cdf0e10cSrcweir 
49cdf0e10cSrcweir 
50cdf0e10cSrcweir class _PaMIntoCrsrShellRing
51cdf0e10cSrcweir {
52cdf0e10cSrcweir     SwCrsrShell& rSh;
53cdf0e10cSrcweir     SwPaM &rDelPam, &rCrsr;
54cdf0e10cSrcweir     Ring *pPrevDelPam, *pPrevCrsr;
55cdf0e10cSrcweir 
56cdf0e10cSrcweir     void RemoveFromRing( SwPaM& rPam, Ring* pPrev );
57cdf0e10cSrcweir public:
58cdf0e10cSrcweir     _PaMIntoCrsrShellRing( SwCrsrShell& rSh, SwPaM& rCrsr, SwPaM& rPam );
59cdf0e10cSrcweir     ~_PaMIntoCrsrShellRing();
60cdf0e10cSrcweir };
61cdf0e10cSrcweir 
_PaMIntoCrsrShellRing(SwCrsrShell & rCSh,SwPaM & rShCrsr,SwPaM & rPam)62cdf0e10cSrcweir _PaMIntoCrsrShellRing::_PaMIntoCrsrShellRing( SwCrsrShell& rCSh,
63cdf0e10cSrcweir                                             SwPaM& rShCrsr, SwPaM& rPam )
64cdf0e10cSrcweir     : rSh( rCSh ), rDelPam( rPam ), rCrsr( rShCrsr )
65cdf0e10cSrcweir {
66cdf0e10cSrcweir     SwPaM* pShCrsr = rSh._GetCrsr();
67cdf0e10cSrcweir 
68cdf0e10cSrcweir     pPrevDelPam = rDelPam.GetPrev();
69cdf0e10cSrcweir     pPrevCrsr = rCrsr.GetPrev();
70cdf0e10cSrcweir 
71cdf0e10cSrcweir     rDelPam.MoveRingTo( pShCrsr );
72cdf0e10cSrcweir     rCrsr.MoveRingTo( pShCrsr );
73cdf0e10cSrcweir }
~_PaMIntoCrsrShellRing()74cdf0e10cSrcweir _PaMIntoCrsrShellRing::~_PaMIntoCrsrShellRing()
75cdf0e10cSrcweir {
76cdf0e10cSrcweir     // und den Pam wieder herausnehmen:
77cdf0e10cSrcweir     RemoveFromRing( rDelPam, pPrevDelPam );
78cdf0e10cSrcweir     RemoveFromRing( rCrsr, pPrevCrsr );
79cdf0e10cSrcweir }
RemoveFromRing(SwPaM & rPam,Ring * pPrev)80cdf0e10cSrcweir void _PaMIntoCrsrShellRing::RemoveFromRing( SwPaM& rPam, Ring* pPrev )
81cdf0e10cSrcweir {
82cdf0e10cSrcweir     Ring *p, *pNext = (Ring*)&rPam;
83cdf0e10cSrcweir     do {
84cdf0e10cSrcweir         p = pNext;
85cdf0e10cSrcweir         pNext = p->GetNext();
86cdf0e10cSrcweir         p->MoveTo( &rPam );
87cdf0e10cSrcweir     } while( p != pPrev );
88cdf0e10cSrcweir }
89cdf0e10cSrcweir 
90cdf0e10cSrcweir 
SwAutoCorrDoc(SwEditShell & rEditShell,SwPaM & rPam,sal_Unicode cIns)91cdf0e10cSrcweir SwAutoCorrDoc::SwAutoCorrDoc( SwEditShell& rEditShell, SwPaM& rPam,
92cdf0e10cSrcweir                                 sal_Unicode cIns )
93cdf0e10cSrcweir     : rEditSh( rEditShell ), rCrsr( rPam ), pIdx( 0 )
94cdf0e10cSrcweir     , m_nEndUndoCounter(0)
95cdf0e10cSrcweir     , bUndoIdInitialized( cIns ? false : true )
96cdf0e10cSrcweir {
97cdf0e10cSrcweir }
98cdf0e10cSrcweir 
99cdf0e10cSrcweir 
~SwAutoCorrDoc()100cdf0e10cSrcweir SwAutoCorrDoc::~SwAutoCorrDoc()
101cdf0e10cSrcweir {
102cdf0e10cSrcweir     for (int i = 0; i < m_nEndUndoCounter; ++i)
103cdf0e10cSrcweir     {
104cdf0e10cSrcweir         rEditSh.EndUndo();
105cdf0e10cSrcweir     }
106cdf0e10cSrcweir     delete pIdx;
107cdf0e10cSrcweir }
108cdf0e10cSrcweir 
DeleteSel(SwPaM & rDelPam)109cdf0e10cSrcweir void SwAutoCorrDoc::DeleteSel( SwPaM& rDelPam )
110cdf0e10cSrcweir {
111cdf0e10cSrcweir     SwDoc* pDoc = rEditSh.GetDoc();
112cdf0e10cSrcweir     if( pDoc->IsAutoFmtRedline() )
113cdf0e10cSrcweir     {
114cdf0e10cSrcweir         // damit der DelPam auch verschoben wird, in den Shell-Cursr-Ring
115cdf0e10cSrcweir         // mit aufnehmen !!
116cdf0e10cSrcweir         _PaMIntoCrsrShellRing aTmp( rEditSh, rCrsr, rDelPam );
117cdf0e10cSrcweir         pDoc->DeleteAndJoin( rDelPam );
118cdf0e10cSrcweir     }
119cdf0e10cSrcweir     else
120cdf0e10cSrcweir     {
121cdf0e10cSrcweir         pDoc->DeleteRange( rDelPam );
122cdf0e10cSrcweir     }
123cdf0e10cSrcweir }
124cdf0e10cSrcweir 
Delete(xub_StrLen nStt,xub_StrLen nEnd)125cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::Delete( xub_StrLen nStt, xub_StrLen nEnd )
126cdf0e10cSrcweir {
127cdf0e10cSrcweir     const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
128cdf0e10cSrcweir     SwPaM aSel( rNd, nStt, rNd, nEnd );
129cdf0e10cSrcweir     DeleteSel( aSel );
130cdf0e10cSrcweir 
131cdf0e10cSrcweir     if( bUndoIdInitialized )
132cdf0e10cSrcweir         bUndoIdInitialized = true;
133cdf0e10cSrcweir     return sal_True;
134cdf0e10cSrcweir }
135cdf0e10cSrcweir 
136cdf0e10cSrcweir 
Insert(xub_StrLen nPos,const String & rTxt)137cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::Insert( xub_StrLen nPos, const String& rTxt )
138cdf0e10cSrcweir {
139cdf0e10cSrcweir     SwPaM aPam( rCrsr.GetPoint()->nNode.GetNode(), nPos );
140cdf0e10cSrcweir     rEditSh.GetDoc()->InsertString( aPam, rTxt );
141cdf0e10cSrcweir     if( !bUndoIdInitialized )
142cdf0e10cSrcweir     {
143cdf0e10cSrcweir         bUndoIdInitialized = true;
144cdf0e10cSrcweir         if( 1 == rTxt.Len() )
145cdf0e10cSrcweir         {
146cdf0e10cSrcweir             rEditSh.StartUndo( UNDO_AUTOCORRECT );
147cdf0e10cSrcweir             ++m_nEndUndoCounter;
148cdf0e10cSrcweir         }
149cdf0e10cSrcweir     }
150cdf0e10cSrcweir     return sal_True;
151cdf0e10cSrcweir }
152cdf0e10cSrcweir 
153cdf0e10cSrcweir 
Replace(xub_StrLen nPos,const String & rTxt)154cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::Replace( xub_StrLen nPos, const String& rTxt )
155cdf0e10cSrcweir {
156cdf0e10cSrcweir     return ReplaceRange( nPos, rTxt.Len(), rTxt );
157cdf0e10cSrcweir }
ReplaceRange(xub_StrLen nPos,xub_StrLen nSourceLength,const String & rTxt)158cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::ReplaceRange( xub_StrLen nPos, xub_StrLen nSourceLength, const String& rTxt )
159cdf0e10cSrcweir {
160cdf0e10cSrcweir     SwPaM* pPam = &rCrsr;
161cdf0e10cSrcweir     if( pPam->GetPoint()->nContent.GetIndex() != nPos )
162cdf0e10cSrcweir     {
163cdf0e10cSrcweir         pPam = new SwPaM( *rCrsr.GetPoint() );
164cdf0e10cSrcweir         pPam->GetPoint()->nContent = nPos;
165cdf0e10cSrcweir     }
166cdf0e10cSrcweir 
167cdf0e10cSrcweir     SwTxtNode * const pNd = pPam->GetNode()->GetTxtNode();
168cdf0e10cSrcweir     if ( !pNd )
169cdf0e10cSrcweir     {
170cdf0e10cSrcweir         return sal_False;
171cdf0e10cSrcweir     }
172cdf0e10cSrcweir 
173cdf0e10cSrcweir     // text attributes with dummy characters must not be replaced!
174cdf0e10cSrcweir     bool bDoReplace = true;
175cdf0e10cSrcweir     xub_StrLen const nLen = rTxt.Len();
176cdf0e10cSrcweir     for ( xub_StrLen n = 0; n < nLen; ++n )
177cdf0e10cSrcweir     {
178cdf0e10cSrcweir         sal_Unicode const Char = pNd->GetTxt().GetChar( n + nPos );
179cdf0e10cSrcweir         if ( ( CH_TXTATR_BREAKWORD == Char || CH_TXTATR_INWORD == Char )
180cdf0e10cSrcweir              && pNd->GetTxtAttrForCharAt( n + nPos ) )
181cdf0e10cSrcweir         {
182cdf0e10cSrcweir             bDoReplace = false;
183cdf0e10cSrcweir             break;
184cdf0e10cSrcweir         }
185cdf0e10cSrcweir     }
186cdf0e10cSrcweir 
187cdf0e10cSrcweir     if ( bDoReplace )
188cdf0e10cSrcweir     {
189cdf0e10cSrcweir         SwDoc* pDoc = rEditSh.GetDoc();
190cdf0e10cSrcweir 
191cdf0e10cSrcweir //      if( !pDoc->IsAutoFmtRedline() &&
192cdf0e10cSrcweir //          pPam != &rCrsr )    // nur an akt. Position das Redline sichern
193cdf0e10cSrcweir //          pDoc->SetRedlineMode_intern( eOld | REDLINE_IGNORE );
194cdf0e10cSrcweir 
195cdf0e10cSrcweir         if( pDoc->IsAutoFmtRedline() )
196cdf0e10cSrcweir         {
197cdf0e10cSrcweir             if( nPos == pNd->GetTxt().Len() )       // am Ende erfolgt ein Insert
198cdf0e10cSrcweir             {
199cdf0e10cSrcweir                 pDoc->InsertString( *pPam, rTxt );
200cdf0e10cSrcweir             }
201cdf0e10cSrcweir             else
202cdf0e10cSrcweir             {
203cdf0e10cSrcweir                 _PaMIntoCrsrShellRing aTmp( rEditSh, rCrsr, *pPam );
204cdf0e10cSrcweir 
205cdf0e10cSrcweir                 pPam->SetMark();
206cdf0e10cSrcweir                 pPam->GetPoint()->nContent = Min( pNd->GetTxt().Len(),
207cdf0e10cSrcweir                                               xub_StrLen( nPos + nSourceLength ));
208cdf0e10cSrcweir                 pDoc->ReplaceRange( *pPam, rTxt, false );
209cdf0e10cSrcweir                 pPam->Exchange();
210cdf0e10cSrcweir                 pPam->DeleteMark();
211cdf0e10cSrcweir             }
212cdf0e10cSrcweir         }
213cdf0e10cSrcweir         else
214cdf0e10cSrcweir         {
215cdf0e10cSrcweir             if( nSourceLength != rTxt.Len() )
216cdf0e10cSrcweir             {
217cdf0e10cSrcweir                 pPam->SetMark();
218cdf0e10cSrcweir                 pPam->GetPoint()->nContent = Min( pNd->GetTxt().Len(),
219cdf0e10cSrcweir                                               xub_StrLen( nPos + nSourceLength ));
220cdf0e10cSrcweir                 pDoc->ReplaceRange( *pPam, rTxt, false );
221cdf0e10cSrcweir                 pPam->Exchange();
222cdf0e10cSrcweir                 pPam->DeleteMark();
223cdf0e10cSrcweir             }
224cdf0e10cSrcweir             else
225cdf0e10cSrcweir                 pDoc->Overwrite( *pPam, rTxt );
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir 
228cdf0e10cSrcweir //      pDoc->SetRedlineMode_intern( eOld );
229cdf0e10cSrcweir         if( bUndoIdInitialized )
230cdf0e10cSrcweir         {
231cdf0e10cSrcweir             bUndoIdInitialized = true;
232cdf0e10cSrcweir             if( 1 == rTxt.Len() )
233cdf0e10cSrcweir             {
234cdf0e10cSrcweir                 rEditSh.StartUndo( UNDO_AUTOCORRECT );
235cdf0e10cSrcweir                 ++m_nEndUndoCounter;
236cdf0e10cSrcweir             }
237cdf0e10cSrcweir         }
238cdf0e10cSrcweir     }
239cdf0e10cSrcweir 
240cdf0e10cSrcweir     if( pPam != &rCrsr )
241cdf0e10cSrcweir         delete pPam;
242cdf0e10cSrcweir 
243cdf0e10cSrcweir     return sal_True;
244cdf0e10cSrcweir }
245cdf0e10cSrcweir 
246cdf0e10cSrcweir 
247cdf0e10cSrcweir 
SetAttr(xub_StrLen nStt,xub_StrLen nEnd,sal_uInt16 nSlotId,SfxPoolItem & rItem)248cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::SetAttr( xub_StrLen nStt, xub_StrLen nEnd, sal_uInt16 nSlotId,
249cdf0e10cSrcweir                                         SfxPoolItem& rItem )
250cdf0e10cSrcweir {
251cdf0e10cSrcweir     const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
252cdf0e10cSrcweir     SwPaM aPam( rNd, nStt, rNd, nEnd );
253cdf0e10cSrcweir 
254cdf0e10cSrcweir     SfxItemPool& rPool = rEditSh.GetDoc()->GetAttrPool();
255cdf0e10cSrcweir     sal_uInt16 nWhich = rPool.GetWhich( nSlotId, sal_False );
256cdf0e10cSrcweir     if( nWhich )
257cdf0e10cSrcweir     {
258cdf0e10cSrcweir         rItem.SetWhich( nWhich );
259cdf0e10cSrcweir 
260cdf0e10cSrcweir         SfxItemSet aSet( rPool, aCharFmtSetRange );
261cdf0e10cSrcweir         SetAllScriptItem( aSet, rItem );
262cdf0e10cSrcweir 
263cdf0e10cSrcweir         rEditSh.GetDoc()->SetFmtItemByAutoFmt( aPam, aSet );
264cdf0e10cSrcweir 
265cdf0e10cSrcweir         if( bUndoIdInitialized )
266cdf0e10cSrcweir             bUndoIdInitialized = true;
267cdf0e10cSrcweir     }
268cdf0e10cSrcweir     return 0 != nWhich;
269cdf0e10cSrcweir }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir 
272cdf0e10cSrcweir 
SetINetAttr(xub_StrLen nStt,xub_StrLen nEnd,const String & rURL)273cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::SetINetAttr( xub_StrLen nStt, xub_StrLen nEnd, const String& rURL )
274cdf0e10cSrcweir {
275cdf0e10cSrcweir     const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
276cdf0e10cSrcweir     SwPaM aPam( rNd, nStt, rNd, nEnd );
277cdf0e10cSrcweir 
278cdf0e10cSrcweir     SfxItemSet aSet( rEditSh.GetDoc()->GetAttrPool(),
279cdf0e10cSrcweir                         RES_TXTATR_INETFMT, RES_TXTATR_INETFMT );
280cdf0e10cSrcweir     aSet.Put( SwFmtINetFmt( rURL, aEmptyStr ));
281cdf0e10cSrcweir     rEditSh.GetDoc()->SetFmtItemByAutoFmt( aPam, aSet );
282cdf0e10cSrcweir     if( bUndoIdInitialized )
283cdf0e10cSrcweir         bUndoIdInitialized = true;
284cdf0e10cSrcweir     return sal_True;
285cdf0e10cSrcweir }
286cdf0e10cSrcweir 
287cdf0e10cSrcweir     // returne den Text eines vorherigen Absatzes.
288cdf0e10cSrcweir     // Dieser darf nicht leer sein!
289cdf0e10cSrcweir     // Gibt es diesen nicht oder gibt es davor nur Leere, dann returne 0
290cdf0e10cSrcweir     // Das Flag gibt an:
291cdf0e10cSrcweir     //      sal_True: den, vor der normalen Einfuegeposition (sal_True)
292cdf0e10cSrcweir     //      sal_False: den, in den das korrigierte Wort eingfuegt wurde.
293cdf0e10cSrcweir     //              (Muss nicht der gleiche Absatz sein!!!!)
GetPrevPara(sal_Bool bAtNormalPos)294cdf0e10cSrcweir const String* SwAutoCorrDoc::GetPrevPara( sal_Bool bAtNormalPos )
295cdf0e10cSrcweir {
296cdf0e10cSrcweir     const String* pStr = 0;
297cdf0e10cSrcweir 
298cdf0e10cSrcweir     if( bAtNormalPos || !pIdx )
299cdf0e10cSrcweir         pIdx = new SwNodeIndex( rCrsr.GetPoint()->nNode, -1 );
300cdf0e10cSrcweir     else
301cdf0e10cSrcweir         (*pIdx)--;
302cdf0e10cSrcweir 
303cdf0e10cSrcweir     SwTxtNode* pTNd = pIdx->GetNode().GetTxtNode();
304cdf0e10cSrcweir     while( pTNd && !pTNd->GetTxt().Len() )
305cdf0e10cSrcweir     {
306cdf0e10cSrcweir         (*pIdx)--;
307cdf0e10cSrcweir         pTNd = pIdx->GetNode().GetTxtNode();
308cdf0e10cSrcweir     }
309cdf0e10cSrcweir     //if( pTNd && NO_NUMBERING == pTNd->GetTxtColl()->GetOutlineLevel() )
310cdf0e10cSrcweir     if( pTNd && 0 == pTNd->GetAttrOutlineLevel() )//#outline level,zhaojianwei
311cdf0e10cSrcweir         pStr = &pTNd->GetTxt();
312cdf0e10cSrcweir 
313cdf0e10cSrcweir     if( bUndoIdInitialized )
314cdf0e10cSrcweir         bUndoIdInitialized = true;
315cdf0e10cSrcweir     return pStr;
316cdf0e10cSrcweir }
317cdf0e10cSrcweir 
318cdf0e10cSrcweir 
ChgAutoCorrWord(xub_StrLen & rSttPos,xub_StrLen nEndPos,SvxAutoCorrect & rACorrect,const String ** ppPara)319cdf0e10cSrcweir sal_Bool SwAutoCorrDoc::ChgAutoCorrWord( xub_StrLen & rSttPos, xub_StrLen nEndPos,
320cdf0e10cSrcweir                                             SvxAutoCorrect& rACorrect,
321cdf0e10cSrcweir                                             const String** ppPara )
322cdf0e10cSrcweir {
323cdf0e10cSrcweir     if( bUndoIdInitialized )
324cdf0e10cSrcweir         bUndoIdInitialized = true;
325cdf0e10cSrcweir 
326cdf0e10cSrcweir     // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
327cdf0e10cSrcweir     // Kuerzel im Auto
328cdf0e10cSrcweir     SwTxtNode* pTxtNd = rCrsr.GetNode()->GetTxtNode();
329cdf0e10cSrcweir     ASSERT( pTxtNd, "wo ist denn der TextNode?" );
330cdf0e10cSrcweir 
331cdf0e10cSrcweir     sal_Bool bRet = sal_False;
332cdf0e10cSrcweir     if( nEndPos == rSttPos )
333cdf0e10cSrcweir         return bRet;
334cdf0e10cSrcweir 
335cdf0e10cSrcweir     LanguageType eLang = GetLanguage(nEndPos, sal_False);
336cdf0e10cSrcweir     if(LANGUAGE_SYSTEM == eLang)
337cdf0e10cSrcweir         eLang = (LanguageType)GetAppLanguage();
338cdf0e10cSrcweir 
339cdf0e10cSrcweir     //JP 22.04.99: Bug 63883 - Sonderbehandlung fuer Punkte.
340cdf0e10cSrcweir     sal_Bool bLastCharIsPoint = nEndPos < pTxtNd->GetTxt().Len() &&
341cdf0e10cSrcweir                             '.' == pTxtNd->GetTxt().GetChar( nEndPos );
342cdf0e10cSrcweir 
343cdf0e10cSrcweir     const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList(
344cdf0e10cSrcweir                                 pTxtNd->GetTxt(), rSttPos, nEndPos, *this, eLang );
345cdf0e10cSrcweir     SwDoc* pDoc = rEditSh.GetDoc();
346cdf0e10cSrcweir     if( pFnd )
347cdf0e10cSrcweir     {
348cdf0e10cSrcweir         const SwNodeIndex& rNd = rCrsr.GetPoint()->nNode;
349cdf0e10cSrcweir         SwPaM aPam( rNd, rSttPos, rNd, nEndPos );
350cdf0e10cSrcweir 
351cdf0e10cSrcweir         if( pFnd->IsTextOnly() )
352cdf0e10cSrcweir         {
353cdf0e10cSrcweir             //JP 22.04.99: Bug 63883 - Sonderbehandlung fuer Punkte.
354cdf0e10cSrcweir             if( !bLastCharIsPoint || !pFnd->GetLong().Len() ||
355cdf0e10cSrcweir                 '.' != pFnd->GetLong().GetChar( pFnd->GetLong().Len() - 1 ) )
356cdf0e10cSrcweir             {
357cdf0e10cSrcweir                 // replace the selection
358cdf0e10cSrcweir                 pDoc->ReplaceRange( aPam, pFnd->GetLong(), false);
359cdf0e10cSrcweir                 bRet = sal_True;
360cdf0e10cSrcweir             }
361cdf0e10cSrcweir         }
362cdf0e10cSrcweir         else
363cdf0e10cSrcweir         {
364cdf0e10cSrcweir             SwTextBlocks aTBlks( rACorrect.GetAutoCorrFileName( eLang, sal_False, sal_True ));
365cdf0e10cSrcweir             sal_uInt16 nPos = aTBlks.GetIndex( pFnd->GetShort() );
366cdf0e10cSrcweir             if( USHRT_MAX != nPos && aTBlks.BeginGetDoc( nPos ) )
367cdf0e10cSrcweir             {
368cdf0e10cSrcweir                 DeleteSel( aPam );
369cdf0e10cSrcweir                 pDoc->DontExpandFmt( *aPam.GetPoint() );
370cdf0e10cSrcweir 
371cdf0e10cSrcweir                 if( ppPara )
372cdf0e10cSrcweir                 {
373cdf0e10cSrcweir                     ASSERT( !pIdx, "wer hat seinen Index nicht geloescht?" );
374cdf0e10cSrcweir                     pIdx = new SwNodeIndex( rCrsr.GetPoint()->nNode, -1 );
375cdf0e10cSrcweir                 }
376cdf0e10cSrcweir 
377cdf0e10cSrcweir                 //
378cdf0e10cSrcweir                 SwDoc* pAutoDoc = aTBlks.GetDoc();
379cdf0e10cSrcweir                 SwNodeIndex aSttIdx( pAutoDoc->GetNodes().GetEndOfExtras(), 1 );
380cdf0e10cSrcweir                 SwCntntNode* pCntntNd = pAutoDoc->GetNodes().GoNext( &aSttIdx );
381cdf0e10cSrcweir                 SwPaM aCpyPam( aSttIdx );
382cdf0e10cSrcweir 
383cdf0e10cSrcweir                 const SwTableNode* pTblNd = pCntntNd->FindTableNode();
384cdf0e10cSrcweir                 if( pTblNd )
385cdf0e10cSrcweir                 {
386cdf0e10cSrcweir                     aCpyPam.GetPoint()->nContent.Assign( 0, 0 );
387cdf0e10cSrcweir                     aCpyPam.GetPoint()->nNode = *pTblNd;
388cdf0e10cSrcweir                 }
389cdf0e10cSrcweir                 aCpyPam.SetMark();
390cdf0e10cSrcweir 
391cdf0e10cSrcweir                 // dann bis zum Ende vom Nodes Array
392cdf0e10cSrcweir                 aCpyPam.GetPoint()->nNode.Assign( pAutoDoc->GetNodes().GetEndOfContent(), -1 );
393cdf0e10cSrcweir                 pCntntNd = aCpyPam.GetCntntNode();
394cdf0e10cSrcweir                 aCpyPam.GetPoint()->nContent.Assign( pCntntNd, pCntntNd->Len() );
395cdf0e10cSrcweir 
396cdf0e10cSrcweir                 SwDontExpandItem aExpItem;
397cdf0e10cSrcweir                 aExpItem.SaveDontExpandItems( *aPam.GetPoint() );
398cdf0e10cSrcweir 
399cdf0e10cSrcweir                 pAutoDoc->CopyRange( aCpyPam, *aPam.GetPoint(), false );
400cdf0e10cSrcweir 
401cdf0e10cSrcweir                 aExpItem.RestoreDontExpandItems( *aPam.GetPoint() );
402cdf0e10cSrcweir 
403cdf0e10cSrcweir                 if( ppPara )
404cdf0e10cSrcweir                 {
405cdf0e10cSrcweir                     (*pIdx)++;
406cdf0e10cSrcweir                     pTxtNd = pIdx->GetNode().GetTxtNode();
407cdf0e10cSrcweir                 }
408cdf0e10cSrcweir                 bRet = sal_True;
409cdf0e10cSrcweir             }
410cdf0e10cSrcweir             aTBlks.EndGetDoc();
411cdf0e10cSrcweir         }
412cdf0e10cSrcweir     }
413cdf0e10cSrcweir 
414cdf0e10cSrcweir     if( bRet && ppPara && pTxtNd )
415cdf0e10cSrcweir         *ppPara = &pTxtNd->GetTxt();
416cdf0e10cSrcweir 
417cdf0e10cSrcweir     return bRet;
418cdf0e10cSrcweir }
419cdf0e10cSrcweir 
420cdf0e10cSrcweir 
421cdf0e10cSrcweir     // wird nach dem austauschen der Zeichen von den Funktionen
422cdf0e10cSrcweir     //  - FnCptlSttWrd
423cdf0e10cSrcweir     //  - FnCptlSttSntnc
424cdf0e10cSrcweir     // gerufen. Dann koennen die Worte ggfs. in die Ausnahmelisten
425cdf0e10cSrcweir     // aufgenommen werden.
SaveCpltSttWord(sal_uLong nFlag,xub_StrLen nPos,const String & rExceptWord,sal_Unicode cChar)426cdf0e10cSrcweir void SwAutoCorrDoc::SaveCpltSttWord( sal_uLong nFlag, xub_StrLen nPos,
427cdf0e10cSrcweir                                             const String& rExceptWord,
428cdf0e10cSrcweir                                             sal_Unicode cChar )
429cdf0e10cSrcweir {
430cdf0e10cSrcweir     sal_uLong nNode = pIdx ? pIdx->GetIndex() : rCrsr.GetPoint()->nNode.GetIndex();
431cdf0e10cSrcweir     LanguageType eLang = GetLanguage(nPos, sal_False);
432cdf0e10cSrcweir     rEditSh.GetDoc()->SetAutoCorrExceptWord( new SwAutoCorrExceptWord( nFlag,
433cdf0e10cSrcweir                                         nNode, nPos, rExceptWord, cChar, eLang ));
434cdf0e10cSrcweir }
435cdf0e10cSrcweir 
GetLanguage(xub_StrLen nPos,sal_Bool bPrevPara) const436cdf0e10cSrcweir LanguageType SwAutoCorrDoc::GetLanguage( xub_StrLen nPos, sal_Bool bPrevPara ) const
437cdf0e10cSrcweir {
438cdf0e10cSrcweir     LanguageType eRet = LANGUAGE_SYSTEM;
439cdf0e10cSrcweir 
440cdf0e10cSrcweir     SwTxtNode* pNd = (( bPrevPara && pIdx )
441cdf0e10cSrcweir                             ? *pIdx
442cdf0e10cSrcweir                             : rCrsr.GetPoint()->nNode ).GetNode().GetTxtNode();
443cdf0e10cSrcweir 
444cdf0e10cSrcweir     if( pNd )
445cdf0e10cSrcweir         eRet = pNd->GetLang( nPos, 0 );
446cdf0e10cSrcweir     if(LANGUAGE_SYSTEM == eRet)
447cdf0e10cSrcweir         eRet = (LanguageType)GetAppLanguage();
448cdf0e10cSrcweir     return eRet;
449cdf0e10cSrcweir }
450cdf0e10cSrcweir 
CheckChar(const SwPosition & rPos,sal_Unicode cChr)451cdf0e10cSrcweir void SwAutoCorrExceptWord::CheckChar( const SwPosition& rPos, sal_Unicode cChr )
452cdf0e10cSrcweir {
453cdf0e10cSrcweir     // nur testen ob es eine Verbesserung ist. Wenn ja, dann das Wort
454cdf0e10cSrcweir     // in die Ausnahmeliste aufnehmen.
455cdf0e10cSrcweir     if( cChar == cChr && rPos.nNode.GetIndex() == nNode &&
456cdf0e10cSrcweir         rPos.nContent.GetIndex() == nCntnt )
457cdf0e10cSrcweir     {
458cdf0e10cSrcweir         // die akt. Autokorrektur besorgen:
459cdf0e10cSrcweir         SvxAutoCorrect* pACorr = SvxAutoCorrCfg::Get()->GetAutoCorrect();
460cdf0e10cSrcweir 
461cdf0e10cSrcweir         // dann in die Liste aufnehmen:
462cdf0e10cSrcweir         if( CptlSttWrd & nFlags )
463cdf0e10cSrcweir             pACorr->AddWrtSttException( sWord, eLanguage );
464cdf0e10cSrcweir         else if( CptlSttSntnc & nFlags )
465cdf0e10cSrcweir             pACorr->AddCplSttException( sWord, eLanguage );
466cdf0e10cSrcweir     }
467cdf0e10cSrcweir }
468cdf0e10cSrcweir 
469cdf0e10cSrcweir 
CheckDelChar(const SwPosition & rPos)470cdf0e10cSrcweir sal_Bool SwAutoCorrExceptWord::CheckDelChar( const SwPosition& rPos )
471cdf0e10cSrcweir {
472cdf0e10cSrcweir     sal_Bool bRet = sal_False;
473cdf0e10cSrcweir     if( !bDeleted && rPos.nNode.GetIndex() == nNode &&
474cdf0e10cSrcweir         rPos.nContent.GetIndex() == nCntnt )
475cdf0e10cSrcweir         bDeleted = bRet = sal_True;
476cdf0e10cSrcweir     return bRet;
477cdf0e10cSrcweir }
478cdf0e10cSrcweir 
~SwDontExpandItem()479cdf0e10cSrcweir SwDontExpandItem::~SwDontExpandItem()
480cdf0e10cSrcweir {
481cdf0e10cSrcweir     delete pDontExpItems;
482cdf0e10cSrcweir }
483cdf0e10cSrcweir 
SaveDontExpandItems(const SwPosition & rPos)484cdf0e10cSrcweir void SwDontExpandItem::SaveDontExpandItems( const SwPosition& rPos )
485cdf0e10cSrcweir {
486cdf0e10cSrcweir     const SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
487cdf0e10cSrcweir     if( pTxtNd )
488cdf0e10cSrcweir     {
489cdf0e10cSrcweir         pDontExpItems = new SfxItemSet( ((SwDoc*)pTxtNd->GetDoc())->GetAttrPool(),
490cdf0e10cSrcweir                                             aCharFmtSetRange );
491cdf0e10cSrcweir         xub_StrLen n = rPos.nContent.GetIndex();
492cdf0e10cSrcweir         if( !pTxtNd->GetAttr( *pDontExpItems, n, n,
493cdf0e10cSrcweir                                 n != pTxtNd->GetTxt().Len() ))
494cdf0e10cSrcweir             delete pDontExpItems, pDontExpItems = 0;
495cdf0e10cSrcweir     }
496cdf0e10cSrcweir }
497cdf0e10cSrcweir 
RestoreDontExpandItems(const SwPosition & rPos)498cdf0e10cSrcweir void SwDontExpandItem::RestoreDontExpandItems( const SwPosition& rPos )
499cdf0e10cSrcweir {
500cdf0e10cSrcweir     SwTxtNode* pTxtNd = rPos.nNode.GetNode().GetTxtNode();
501cdf0e10cSrcweir     if( pTxtNd )
502cdf0e10cSrcweir     {
503cdf0e10cSrcweir         xub_StrLen nStart = rPos.nContent.GetIndex();
504cdf0e10cSrcweir         if( nStart == pTxtNd->GetTxt().Len() )
505cdf0e10cSrcweir             pTxtNd->FmtToTxtAttr( pTxtNd );
506cdf0e10cSrcweir 
507cdf0e10cSrcweir         if( pTxtNd->GetpSwpHints() && pTxtNd->GetpSwpHints()->Count() )
508cdf0e10cSrcweir         {
509cdf0e10cSrcweir             const sal_uInt16 nSize = pTxtNd->GetpSwpHints()->Count();
510cdf0e10cSrcweir             sal_uInt16 n;
511cdf0e10cSrcweir             xub_StrLen nAttrStart;
512cdf0e10cSrcweir             const xub_StrLen* pAttrEnd;
513cdf0e10cSrcweir 
514cdf0e10cSrcweir             for( n = 0; n < nSize; ++n )
515cdf0e10cSrcweir             {
516cdf0e10cSrcweir                 SwTxtAttr* pHt = pTxtNd->GetpSwpHints()->GetTextHint( n );
517cdf0e10cSrcweir                 nAttrStart = *pHt->GetStart();
518cdf0e10cSrcweir                 if( nAttrStart > nStart )       // ueber den Bereich hinaus
519cdf0e10cSrcweir                     break;
520cdf0e10cSrcweir 
521*69a74367SOliver-Rainer Wittmann                 if( 0 != ( pAttrEnd = pHt->End() ) &&
522cdf0e10cSrcweir                     ( ( nAttrStart < nStart &&
523cdf0e10cSrcweir                         ( pHt->DontExpand() ? nStart < *pAttrEnd
524cdf0e10cSrcweir                                             : nStart <= *pAttrEnd )) ||
525cdf0e10cSrcweir                       ( nStart == nAttrStart &&
526cdf0e10cSrcweir                         ( nAttrStart == *pAttrEnd || !nStart ))) )
527cdf0e10cSrcweir                 {
528cdf0e10cSrcweir                     const SfxPoolItem* pItem;
529cdf0e10cSrcweir                     if( !pDontExpItems || SFX_ITEM_SET != pDontExpItems->
530cdf0e10cSrcweir                         GetItemState( pHt->Which(), sal_False, &pItem ) ||
531cdf0e10cSrcweir                         *pItem != pHt->GetAttr() )
532cdf0e10cSrcweir                     {
533cdf0e10cSrcweir                         // das Attribut war vorher nicht in dieser Form im Absatz
534cdf0e10cSrcweir                         // gesetzt, also kann es nur durchs einfuegen/kopieren erzeugt
535cdf0e10cSrcweir                         // worden sein. Damit ist es ein Kandiadat fuers DontExpand
536cdf0e10cSrcweir                         pHt->SetDontExpand( sal_True );
537cdf0e10cSrcweir                     }
538cdf0e10cSrcweir                 }
539cdf0e10cSrcweir             }
540cdf0e10cSrcweir         }
541cdf0e10cSrcweir     }
542cdf0e10cSrcweir }
543