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: edtspell.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_svx.hxx"
34 #include <eeng_pch.hxx>
36 #include <impedit.hxx>
37 #include <svx/editview.hxx>
38 #include <svx/editeng.hxx>
39 #include <edtspell.hxx>
40 #include <svx/flditem.hxx>
41 #include <fontitem.hxx>
42 #include <svtools/intitem.hxx>
43 #include <svtools/eitem.hxx>
44 #include <unolingu.hxx>
45 #include <linguistic/lngprops.hxx>
46 #include <com/sun/star/beans/XPropertySet.hpp>
48 using ::rtl::OUString
;
49 using namespace com::sun::star::uno
;
50 using namespace com::sun::star::beans
;
51 using namespace com::sun::star::linguistic2
;
54 EditSpellWrapper::EditSpellWrapper( Window
* _pWin
,
55 Reference
< XSpellChecker1
> &xChecker
,
56 sal_Bool bIsStart
, sal_Bool bIsAllRight
, EditView
* pView
) :
57 SvxSpellWrapper( _pWin
, xChecker
, bIsStart
, bIsAllRight
)
59 DBG_ASSERT( pView
, "Es muss eine View uebergeben werden!" );
60 // IgnoreList behalten, ReplaceList loeschen...
61 if (SvxGetChangeAllList().is())
62 SvxGetChangeAllList()->clear();
66 void __EXPORT
EditSpellWrapper::SpellStart( SvxSpellArea eArea
)
68 ImpEditEngine
* pImpEE
= pEditView
->GetImpEditEngine();
69 SpellInfo
* pSpellInfo
= pImpEE
->GetSpellInfo();
71 if ( eArea
== SVX_SPELL_BODY_START
)
74 // a) Spell-Forwad ist am Ende angekomment und soll von vorne beginnen
75 // IsEndDone() liefert auch sal_True, wenn Rueckwaerts-Spelling am Ende gestartet wird!
78 pSpellInfo
->bSpellToEnd
= sal_False
;
79 pSpellInfo
->aSpellTo
= pSpellInfo
->aSpellStart
;
80 pEditView
->GetImpEditView()->SetEditSelection(
81 pImpEE
->GetEditDoc().GetStartPaM() );
85 pSpellInfo
->bSpellToEnd
= sal_True
;
86 pSpellInfo
->aSpellTo
= pImpEE
->CreateEPaM(
87 pImpEE
->GetEditDoc().GetStartPaM() );
90 else if ( eArea
== SVX_SPELL_BODY_END
)
93 // a) Spell-Forwad wird gestartet
94 // IsStartDone() liefert auch sal_True, wenn Vorwaerts-Spelling am Anfang gestartet wird!
97 pSpellInfo
->bSpellToEnd
= sal_True
;
98 pSpellInfo
->aSpellTo
= pImpEE
->CreateEPaM(
99 pImpEE
->GetEditDoc().GetEndPaM() );
103 pSpellInfo
->bSpellToEnd
= sal_False
;
104 pSpellInfo
->aSpellTo
= pSpellInfo
->aSpellStart
;
105 pEditView
->GetImpEditView()->SetEditSelection(
106 pImpEE
->GetEditDoc().GetEndPaM() );
109 else if ( eArea
== SVX_SPELL_BODY
)
111 ; // Wird ueber SpellNextDocument von App gehandelt
113 // pSpellInfo->bSpellToEnd = sal_True;
114 // pSpellInfo->aSpellTo = pImpEE->CreateEPaM( pImpEE->GetEditDoc().GetEndPaM() );
118 DBG_ERROR( "SpellStart: Unknown Area!" );
122 sal_Bool
EditSpellWrapper::SpellContinue()
124 SetLast( pEditView
->GetImpEditEngine()->ImpSpell( pEditView
) );
125 return GetLast().is();
128 void __EXPORT
EditSpellWrapper::SpellEnd()
130 // Base class will show language errors...
131 SvxSpellWrapper::SpellEnd();
134 sal_Bool __EXPORT
EditSpellWrapper::HasOtherCnt()
139 sal_Bool __EXPORT
EditSpellWrapper::SpellMore()
141 ImpEditEngine
* pImpEE
= pEditView
->GetImpEditEngine();
142 SpellInfo
* pSpellInfo
= pImpEE
->GetSpellInfo();
143 sal_Bool bMore
= sal_False
;
144 if ( pSpellInfo
->bMultipleDoc
)
146 bMore
= pImpEE
->GetEditEnginePtr()->SpellNextDocument();
149 // Der Text wurde in diese Engine getreten, bei Rueckwaerts
150 // muss die Selektion hinten sein.
151 Reference
< XPropertySet
> xProp( SvxGetLinguPropertySet() );
152 pEditView
->GetImpEditView()->SetEditSelection(
153 pImpEE
->GetEditDoc().GetStartPaM() );
159 void __EXPORT
EditSpellWrapper::ScrollArea()
161 // Keine weitere Aktion noetig...
162 // Es sei denn, der Bereich soll in die Mitte gescrollt werden,
163 // und nicht irgendwo stehen.
166 void __EXPORT
EditSpellWrapper::ReplaceAll( const String
&rNewText
,
169 // Wird gerufen, wenn Wort in ReplaceList des SpellCheckers
170 pEditView
->InsertText( rNewText
);
174 void __EXPORT
EditSpellWrapper::ChangeWord( const String
& rNewWord
,
177 // Wird gerufen, wenn Wort Button Change
178 // bzw. intern von mir bei ChangeAll
180 // Wenn Punkt hinterm Wort, wird dieser nicht mitgegeben.
181 // Falls '"' => PreStripped.
182 String
aNewWord( rNewWord
);
183 pEditView
->InsertText( aNewWord
);
187 void __EXPORT
EditSpellWrapper::ChangeThesWord( const String
& rNewWord
)
189 pEditView
->InsertText( rNewWord
);
193 void __EXPORT
EditSpellWrapper::AutoCorrect( const String
&, const String
& )
197 void EditSpellWrapper::CheckSpellTo()
199 ImpEditEngine
* pImpEE
= pEditView
->GetImpEditEngine();
200 SpellInfo
* pSpellInfo
= pImpEE
->GetSpellInfo();
201 EditPaM
aPaM( pEditView
->GetImpEditView()->GetEditSelection().Max() );
202 EPaM aEPaM
= pImpEE
->CreateEPaM( aPaM
);
203 if ( aEPaM
.nPara
== pSpellInfo
->aSpellTo
.nPara
)
205 // prueffen, ob SpellToEnd noch gueltiger Index, falls in dem Absatz
207 if ( pSpellInfo
->aSpellTo
.nIndex
> aPaM
.GetNode()->Len() )
208 pSpellInfo
->aSpellTo
.nIndex
= aPaM
.GetNode()->Len();
211 SV_IMPL_VARARR( WrongRanges
, WrongRange
);
213 WrongList::WrongList()
216 nInvalidEnd
= 0xFFFF;
219 WrongList::~WrongList()
223 void WrongList::TextInserted( sal_uInt16 nPos
, sal_uInt16 nNew
, sal_Bool bPosIsSep
)
227 nInvalidStart
= nPos
;
228 nInvalidEnd
= nPos
+nNew
;
232 if ( nInvalidStart
> nPos
)
233 nInvalidStart
= nPos
;
234 if ( nInvalidEnd
>= nPos
)
235 nInvalidEnd
= nInvalidEnd
+ nNew
;
237 nInvalidEnd
= nPos
+nNew
;
240 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
242 WrongRange
& rWrong
= GetObject( n
);
243 sal_Bool bRefIsValid
= sal_True
;
244 if ( rWrong
.nEnd
>= nPos
)
246 // Alle Wrongs hinter der Einfuegeposition verschieben...
247 if ( rWrong
.nStart
> nPos
)
249 rWrong
.nStart
= rWrong
.nStart
+ nNew
;
250 rWrong
.nEnd
= rWrong
.nEnd
+ nNew
;
252 // 1: Startet davor, geht bis nPos...
253 else if ( rWrong
.nEnd
== nPos
)
255 // Sollte bei einem Blank unterbunden werden!
257 rWrong
.nEnd
= rWrong
.nEnd
+ nNew
;
259 // 2: Startet davor, geht hinter Pos...
260 else if ( ( rWrong
.nStart
< nPos
) && ( rWrong
.nEnd
> nPos
) )
262 rWrong
.nEnd
= rWrong
.nEnd
+ nNew
;
263 // Bei einem Trenner das Wrong entfernen und neu pruefen
266 // Wrong aufteilen...
267 WrongRange
aNewWrong( rWrong
.nStart
, nPos
);
268 rWrong
.nStart
= nPos
+1;
269 Insert( aNewWrong
, n
);
270 bRefIsValid
= sal_False
; // Referenz nach Insert nicht mehr gueltig, der andere wurde davor an dessen Position eingefuegt
271 n
++; // Diesen nicht nochmal...
274 // 3: Attribut startet auf Pos...
275 else if ( rWrong
.nStart
== nPos
)
277 rWrong
.nEnd
= rWrong
.nEnd
+ nNew
;
282 DBG_ASSERT( !bRefIsValid
|| ( rWrong
.nStart
< rWrong
.nEnd
),
283 "TextInserted, WrongRange: Start >= End?!" );
286 DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
289 void WrongList::TextDeleted( sal_uInt16 nPos
, sal_uInt16 nDeleted
)
291 sal_uInt16 nEndChanges
= nPos
+nDeleted
;
294 sal_uInt16 nNewInvalidStart
= nPos
? nPos
- 1 : 0;
295 nInvalidStart
= nNewInvalidStart
;
296 nInvalidEnd
= nNewInvalidStart
+ 1;
300 if ( nInvalidStart
> nPos
)
301 nInvalidStart
= nPos
;
302 if ( nInvalidEnd
> nPos
)
304 if ( nInvalidEnd
> nEndChanges
)
305 nInvalidEnd
= nInvalidEnd
- nDeleted
;
307 nInvalidEnd
= nPos
+1;
311 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
313 WrongRange
& rWrong
= GetObject( n
);
314 sal_Bool bDelWrong
= sal_False
;
315 if ( rWrong
.nEnd
>= nPos
)
317 // Alles Wrongs hinter der Einfuegeposition verschieben...
318 if ( rWrong
.nStart
>= nEndChanges
)
320 rWrong
.nStart
= rWrong
.nStart
- nDeleted
;
321 rWrong
.nEnd
= rWrong
.nEnd
- nDeleted
;
323 // 1. Innenliegende Wrongs loeschen...
324 else if ( ( rWrong
.nStart
>= nPos
) && ( rWrong
.nEnd
<= nEndChanges
) )
326 bDelWrong
= sal_True
;
328 // 2. Wrong beginnt davor, endet drinnen oder dahinter...
329 else if ( ( rWrong
.nStart
<= nPos
) && ( rWrong
.nEnd
> nPos
) )
331 if ( rWrong
.nEnd
<= nEndChanges
) // endet drinnen
334 rWrong
.nEnd
= rWrong
.nEnd
- nDeleted
; // endet dahinter
336 // 3. Wrong beginnt drinnen, endet dahinter...
337 else if ( ( rWrong
.nStart
>= nPos
) && ( rWrong
.nEnd
> nEndChanges
) )
339 rWrong
.nStart
= nEndChanges
;
340 rWrong
.nStart
= rWrong
.nStart
- nDeleted
;
341 rWrong
.nEnd
= rWrong
.nEnd
- nDeleted
;
344 DBG_ASSERT( rWrong
.nStart
< rWrong
.nEnd
,
345 "TextInserted, WrongRange: Start >= End?!" );
353 DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
356 sal_Bool
WrongList::NextWrong( sal_uInt16
& rnStart
, sal_uInt16
& rnEnd
) const
359 rnStart enthaelt die Startposition, wird ggf. auf Wrong-Start korrigiert
360 rnEnd braucht nicht inizialisiert sein.
362 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
364 WrongRange
& rWrong
= GetObject( n
);
365 if ( rWrong
.nEnd
> rnStart
)
367 rnStart
= rWrong
.nStart
;
375 sal_Bool
WrongList::HasWrong( sal_uInt16 nStart
, sal_uInt16 nEnd
) const
377 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
379 WrongRange
& rWrong
= GetObject( n
);
380 if ( ( rWrong
.nStart
== nStart
) && ( rWrong
.nEnd
== nEnd
) )
382 else if ( rWrong
.nStart
>= nStart
)
388 sal_Bool
WrongList::HasAnyWrong( sal_uInt16 nStart
, sal_uInt16 nEnd
) const
390 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
392 WrongRange
& rWrong
= GetObject( n
);
393 if ( ( rWrong
.nEnd
>= nStart
) && ( rWrong
.nStart
< nEnd
) )
395 else if ( rWrong
.nStart
>= nEnd
)
401 void WrongList::ClearWrongs( sal_uInt16 nStart
, sal_uInt16 nEnd
,
402 const ContentNode
* pNode
)
404 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
406 WrongRange
& rWrong
= GetObject( n
);
407 if ( ( rWrong
.nEnd
> nStart
) && ( rWrong
.nStart
< nEnd
) )
409 if ( rWrong
.nEnd
> nEnd
) // // Laeuft raus
411 rWrong
.nStart
= nEnd
;
413 while ( ( rWrong
.nStart
< pNode
->Len() ) &&
414 ( ( pNode
->GetChar( rWrong
.nStart
) == ' ' ) ||
415 ( pNode
->IsFeature( rWrong
.nStart
) ) ) )
428 DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
431 void WrongList::InsertWrong( sal_uInt16 nStart
, sal_uInt16 nEnd
,
432 sal_Bool bClearRange
)
434 sal_uInt16 nPos
= Count();
435 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
437 WrongRange
& rWrong
= GetObject( n
);
438 if ( rWrong
.nStart
>= nStart
)
443 // Es kann eigentlich nur Passieren, dass der Wrong genau
444 // hier beginnt und weiter rauslauft, aber nicht, dass hier
445 // mehrere im Bereich liegen...
446 // Genau im Bereich darf keiner liegen, sonst darf diese Methode
447 // garnicht erst gerufen werden!
448 DBG_ASSERT( ( ( rWrong
.nStart
== nStart
) && ( rWrong
.nEnd
> nEnd
) )
449 || ( rWrong
.nStart
> nEnd
), "InsertWrong: RangeMismatch!" );
450 if ( ( rWrong
.nStart
== nStart
) && ( rWrong
.nEnd
> nEnd
) )
451 rWrong
.nStart
= nEnd
+1;
456 Insert( WrongRange( nStart
, nEnd
), nPos
);
458 DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" );
461 void WrongList::MarkWrongsInvalid()
464 MarkInvalid( GetObject( 0 ).nStart
, GetObject( Count()-1 ).nEnd
);
467 WrongList
* WrongList::Clone() const
469 WrongList
* pNew
= new WrongList
;
470 for ( sal_uInt16 n
= 0; n
< Count(); n
++ )
472 WrongRange
& rWrong
= GetObject( n
);
473 pNew
->Insert( rWrong
, pNew
->Count() );
480 bool WrongList::operator==(const WrongList
& rCompare
) const
482 // cleck direct members
483 if(GetInvalidStart() != rCompare
.GetInvalidStart()
484 || GetInvalidEnd() != rCompare
.GetInvalidEnd()
485 || Count() != rCompare
.Count())
490 for(USHORT
a(0); a
< Count(); a
++)
492 const WrongRange
& rCandA(GetObject(a
));
493 const WrongRange
& rCandB(rCompare
.GetObject(a
));
495 if(rCandA
.nStart
!= rCandB
.nStart
496 || rCandA
.nEnd
!= rCandB
.nEnd
)
506 sal_Bool
WrongList::DbgIsBuggy() const
508 // Pruefen, ob sich Bereiche ueberlappen
509 sal_Bool bError
= sal_False
;
510 for ( sal_uInt16 _nA
= 0; !bError
&& ( _nA
< Count() ); _nA
++ )
512 WrongRange
& rWrong
= GetObject( _nA
);
513 for ( sal_uInt16 nB
= _nA
+1; !bError
&& ( nB
< Count() ); nB
++ )
515 WrongRange
& rNextWrong
= GetObject( nB
);
516 // 1) Start davor, End hinterm anderen Start
517 if ( ( rWrong
.nStart
<= rNextWrong
.nStart
)
518 && ( rWrong
.nEnd
>= rNextWrong
.nStart
) )
520 // 2) Start hinter anderen Start, aber noch vorm anderen End
521 else if ( ( rWrong
.nStart
>= rNextWrong
.nStart
)
522 && ( rWrong
.nStart
<= rNextWrong
.nEnd
) )
531 EdtAutoCorrDoc::EdtAutoCorrDoc( ImpEditEngine
* pE
, ContentNode
* pN
,
532 sal_uInt16 nCrsr
, xub_Unicode cIns
)
538 bUndoAction
= sal_False
;
539 bAllowUndoAction
= cIns
? sal_True
: sal_False
;
542 EdtAutoCorrDoc::~EdtAutoCorrDoc()
545 pImpEE
->UndoActionEnd( EDITUNDO_INSERT
);
548 sal_Bool
EdtAutoCorrDoc::Delete( sal_uInt16 nStt
, sal_uInt16 nEnd
)
550 EditSelection
aSel( EditPaM( pCurNode
, nStt
), EditPaM( pCurNode
, nEnd
) );
551 pImpEE
->ImpDeleteSelection( aSel
);
552 DBG_ASSERT( nCursor
>= nEnd
, "Cursor mitten im Geschehen ?!" );
553 nCursor
-= ( nEnd
-nStt
);
554 bAllowUndoAction
= sal_False
;
558 sal_Bool
EdtAutoCorrDoc::Insert( sal_uInt16 nPos
, const String
& rTxt
)
560 EditSelection aSel
= EditPaM( pCurNode
, nPos
);
561 pImpEE
->ImpInsertText( aSel
, rTxt
);
562 DBG_ASSERT( nCursor
>= nPos
, "Cursor mitten im Geschehen ?!" );
563 nCursor
= nCursor
+ rTxt
.Len();
565 if ( bAllowUndoAction
&& ( rTxt
.Len() == 1 ) )
566 ImplStartUndoAction();
567 bAllowUndoAction
= sal_False
;
572 sal_Bool
EdtAutoCorrDoc::Replace( sal_uInt16 nPos
, const String
& rTxt
)
574 // Eigentlich ein Replace einfuehren => Entspr. UNDO
575 sal_uInt16 nEnd
= nPos
+rTxt
.Len();
576 if ( nEnd
> pCurNode
->Len() )
577 nEnd
= pCurNode
->Len();
579 // #i5925# First insert new text behind to be deleted text, for keeping attributes.
580 pImpEE
->ImpInsertText( EditSelection( EditPaM( pCurNode
, nEnd
) ), rTxt
);
581 pImpEE
->ImpDeleteSelection( EditSelection( EditPaM( pCurNode
, nPos
), EditPaM( pCurNode
, nEnd
) ) );
583 if ( nPos
== nCursor
)
584 nCursor
= nCursor
+ rTxt
.Len();
586 if ( bAllowUndoAction
&& ( rTxt
.Len() == 1 ) )
587 ImplStartUndoAction();
589 bAllowUndoAction
= sal_False
;
594 sal_Bool
EdtAutoCorrDoc::SetAttr( sal_uInt16 nStt
, sal_uInt16 nEnd
,
595 sal_uInt16 nSlotId
, SfxPoolItem
& rItem
)
597 SfxItemPool
* pPool
= &pImpEE
->GetEditDoc().GetItemPool();
598 while ( pPool
->GetSecondaryPool() &&
599 !pPool
->GetName().EqualsAscii( "EditEngineItemPool" ) )
601 pPool
= pPool
->GetSecondaryPool();
604 sal_uInt16 nWhich
= pPool
->GetWhich( nSlotId
);
607 rItem
.SetWhich( nWhich
);
609 SfxItemSet
aSet( pImpEE
->GetEmptyItemSet() );
612 EditSelection
aSel( EditPaM( pCurNode
, nStt
), EditPaM( pCurNode
, nEnd
) );
613 aSel
.Max().SetIndex( nEnd
); // ???
614 pImpEE
->SetAttribs( aSel
, aSet
, ATTRSPECIAL_EDGE
);
615 bAllowUndoAction
= sal_False
;
620 sal_Bool
EdtAutoCorrDoc::SetINetAttr( sal_uInt16 nStt
, sal_uInt16 nEnd
,
623 // Aus dem Text ein Feldbefehl machen...
624 EditSelection
aSel( EditPaM( pCurNode
, nStt
), EditPaM( pCurNode
, nEnd
) );
625 String aText
= pImpEE
->GetSelected( aSel
);
626 aSel
= pImpEE
->ImpDeleteSelection( aSel
);
627 DBG_ASSERT( nCursor
>= nEnd
, "Cursor mitten im Geschehen ?!" );
628 nCursor
-= ( nEnd
-nStt
);
629 SvxFieldItem
aField( SvxURLField( rURL
, aText
, SVXURLFORMAT_REPR
),
631 pImpEE
->InsertField( aSel
, aField
);
633 pImpEE
->UpdateFields();
634 bAllowUndoAction
= sal_False
;
638 sal_Bool
EdtAutoCorrDoc::HasSymbolChars( sal_uInt16 nStt
, sal_uInt16 nEnd
)
640 USHORT nScriptType
= pImpEE
->GetScriptType( EditPaM( pCurNode
, nStt
) );
641 USHORT nScriptFontInfoItemId
= GetScriptItemId( EE_CHAR_FONTINFO
, nScriptType
);
643 CharAttribArray
& rAttribs
= pCurNode
->GetCharAttribs().GetAttribs();
644 sal_uInt16 nAttrs
= rAttribs
.Count();
645 for ( sal_uInt16 n
= 0; n
< nAttrs
; n
++ )
647 EditCharAttrib
* pAttr
= rAttribs
.GetObject( n
);
648 if ( pAttr
->GetStart() >= nEnd
)
651 if ( ( pAttr
->Which() == nScriptFontInfoItemId
) &&
652 ( ((SvxFontItem
*)pAttr
->GetItem())->GetCharSet() == RTL_TEXTENCODING_SYMBOL
) )
654 // Pruefen, ob das Attribt im Bereich liegt...
655 if ( pAttr
->GetEnd() >= nStt
)
662 const String
* EdtAutoCorrDoc::GetPrevPara( sal_Bool
)
664 // Vorherigen Absatz zurueck geben, damit ermittel werden kann,
665 // ob es sich beim aktuellen Wort um einen Satzanfang handelt.
667 bAllowUndoAction
= sal_False
; // Jetzt nicht mehr...
669 ContentList
& rNodes
= pImpEE
->GetEditDoc();
670 sal_uInt16 nPos
= rNodes
.GetPos( pCurNode
);
672 // Sonderbehandlung: Bullet => Absatzanfang => einfach NULL returnen...
673 const SfxBoolItem
& rBulletState
= (const SfxBoolItem
&)
674 pImpEE
->GetParaAttrib( nPos
, EE_PARA_BULLETSTATE
);
675 sal_Bool bBullet
= rBulletState
.GetValue() ? sal_True
: sal_False
;
676 if ( !bBullet
&& ( pImpEE
->aStatus
.GetControlWord() & EE_CNTRL_OUTLINER
) )
678 // Der Outliner hat im Gliederungsmodus auf Ebene 0 immer ein Bullet.
679 const SfxInt16Item
& rLevel
= (const SfxInt16Item
&)
680 pImpEE
->GetParaAttrib( nPos
, EE_PARA_OUTLLEVEL
);
681 if ( rLevel
.GetValue() == 0 )
687 for ( sal_uInt16 n
= nPos
; n
; )
690 ContentNode
* pNode
= rNodes
[n
];
698 sal_Bool
EdtAutoCorrDoc::ChgAutoCorrWord( sal_uInt16
& rSttPos
,
699 sal_uInt16 nEndPos
, SvxAutoCorrect
& rACorrect
,
700 const String
** ppPara
)
702 // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort
705 bAllowUndoAction
= sal_False
; // Jetzt nicht mehr...
707 String
aShort( pCurNode
->Copy( rSttPos
, nEndPos
- rSttPos
) );
708 sal_Bool bRet
= sal_False
;
713 LanguageType eLang
= pImpEE
->GetLanguage( EditPaM( pCurNode
, rSttPos
+1 ) );
714 const SvxAutocorrWord
* pFnd
= rACorrect
.SearchWordsInList( *pCurNode
, rSttPos
, nEndPos
, *this, eLang
);
715 if( pFnd
&& pFnd
->IsTextOnly() )
718 EditSelection
aSel( EditPaM( pCurNode
, rSttPos
),
719 EditPaM( pCurNode
, nEndPos
) );
720 aSel
= pImpEE
->ImpDeleteSelection( aSel
);
721 DBG_ASSERT( nCursor
>= nEndPos
, "Cursor mitten im Geschehen ?!" );
722 nCursor
-= ( nEndPos
-rSttPos
);
723 pImpEE
->ImpInsertText( aSel
, pFnd
->GetLong() );
724 nCursor
= nCursor
+ pFnd
->GetLong().Len();
733 LanguageType
EdtAutoCorrDoc::GetLanguage( sal_uInt16 nPos
, sal_Bool
) const
735 return pImpEE
->GetLanguage( EditPaM( pCurNode
, nPos
+1 ) );
738 void EdtAutoCorrDoc::ImplStartUndoAction()
740 sal_uInt16 nPara
= pImpEE
->GetEditDoc().GetPos( pCurNode
);
741 ESelection
aSel( nPara
, nCursor
, nPara
, nCursor
);
742 pImpEE
->UndoActionStart( EDITUNDO_INSERT
, aSel
);
743 bUndoAction
= sal_True
;
744 bAllowUndoAction
= sal_False
;