xref: /AOO41X/main/sw/source/core/edit/acorrect.cxx (revision 69a743679e823ad8f875be547552acb607b8ada5)
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 }
543cdf0e10cSrcweir 
544cdf0e10cSrcweir 
545