diff options
Diffstat (limited to 'editeng/source/editeng/edtspell.cxx')
-rw-r--r-- | editeng/source/editeng/edtspell.cxx | 746 |
1 files changed, 746 insertions, 0 deletions
diff --git a/editeng/source/editeng/edtspell.cxx b/editeng/source/editeng/edtspell.cxx new file mode 100644 index 000000000000..fed1394e5fd0 --- /dev/null +++ b/editeng/source/editeng/edtspell.cxx @@ -0,0 +1,746 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_editeng.hxx" + +#include <vcl/wrkwin.hxx> +#include <vcl/dialog.hxx> +#include <vcl/msgbox.hxx> +#include <vcl/svapp.hxx> + +#include <impedit.hxx> +#include <editeng/editview.hxx> +#include <editeng/editeng.hxx> +#include <edtspell.hxx> +#include <editeng/flditem.hxx> +#include <editeng/fontitem.hxx> +#include <svl/intitem.hxx> +#include <svl/eitem.hxx> +#include <editeng/unolingu.hxx> +#include <linguistic/lngprops.hxx> +#include <com/sun/star/beans/XPropertySet.hpp> + +using ::rtl::OUString; +using namespace com::sun::star::uno; +using namespace com::sun::star::beans; +using namespace com::sun::star::linguistic2; + + +EditSpellWrapper::EditSpellWrapper( Window* _pWin, + Reference< XSpellChecker1 > &xChecker, + sal_Bool bIsStart, sal_Bool bIsAllRight, EditView* pView ) : + SvxSpellWrapper( _pWin, xChecker, bIsStart, bIsAllRight ) +{ + DBG_ASSERT( pView, "Es muss eine View uebergeben werden!" ); + // IgnoreList behalten, ReplaceList loeschen... + if (SvxGetChangeAllList().is()) + SvxGetChangeAllList()->clear(); + pEditView = pView; +} + +void __EXPORT EditSpellWrapper::SpellStart( SvxSpellArea eArea ) +{ + ImpEditEngine* pImpEE = pEditView->GetImpEditEngine(); + SpellInfo* pSpellInfo = pImpEE->GetSpellInfo(); + + if ( eArea == SVX_SPELL_BODY_START ) + { + // Wird gerufen, wenn + // a) Spell-Forwad ist am Ende angekomment und soll von vorne beginnen + // IsEndDone() liefert auch sal_True, wenn Rueckwaerts-Spelling am Ende gestartet wird! + if ( IsEndDone() ) + { + pSpellInfo->bSpellToEnd = sal_False; + pSpellInfo->aSpellTo = pSpellInfo->aSpellStart; + pEditView->GetImpEditView()->SetEditSelection( + pImpEE->GetEditDoc().GetStartPaM() ); + } + else + { + pSpellInfo->bSpellToEnd = sal_True; + pSpellInfo->aSpellTo = pImpEE->CreateEPaM( + pImpEE->GetEditDoc().GetStartPaM() ); + } + } + else if ( eArea == SVX_SPELL_BODY_END ) + { + // Wird gerufen, wenn + // a) Spell-Forwad wird gestartet + // IsStartDone() liefert auch sal_True, wenn Vorwaerts-Spelling am Anfang gestartet wird! + if ( !IsStartDone() ) + { + pSpellInfo->bSpellToEnd = sal_True; + pSpellInfo->aSpellTo = pImpEE->CreateEPaM( + pImpEE->GetEditDoc().GetEndPaM() ); + } + else + { + pSpellInfo->bSpellToEnd = sal_False; + pSpellInfo->aSpellTo = pSpellInfo->aSpellStart; + pEditView->GetImpEditView()->SetEditSelection( + pImpEE->GetEditDoc().GetEndPaM() ); + } + } + else if ( eArea == SVX_SPELL_BODY ) + { + ; // Wird ueber SpellNextDocument von App gehandelt + + // pSpellInfo->bSpellToEnd = sal_True; + // pSpellInfo->aSpellTo = pImpEE->CreateEPaM( pImpEE->GetEditDoc().GetEndPaM() ); + } + else + { + DBG_ERROR( "SpellStart: Unknown Area!" ); + } +} + +sal_Bool EditSpellWrapper::SpellContinue() +{ + SetLast( pEditView->GetImpEditEngine()->ImpSpell( pEditView ) ); + return GetLast().is(); +} + +void __EXPORT EditSpellWrapper::SpellEnd() +{ + // Base class will show language errors... + SvxSpellWrapper::SpellEnd(); +} + +sal_Bool __EXPORT EditSpellWrapper::HasOtherCnt() +{ + return sal_False; +} + +sal_Bool __EXPORT EditSpellWrapper::SpellMore() +{ + ImpEditEngine* pImpEE = pEditView->GetImpEditEngine(); + SpellInfo* pSpellInfo = pImpEE->GetSpellInfo(); + sal_Bool bMore = sal_False; + if ( pSpellInfo->bMultipleDoc ) + { + bMore = pImpEE->GetEditEnginePtr()->SpellNextDocument(); + if ( bMore ) + { + // Der Text wurde in diese Engine getreten, bei Rueckwaerts + // muss die Selektion hinten sein. + Reference< XPropertySet > xProp( SvxGetLinguPropertySet() ); + pEditView->GetImpEditView()->SetEditSelection( + pImpEE->GetEditDoc().GetStartPaM() ); + } + } + return bMore; +} + +void __EXPORT EditSpellWrapper::ScrollArea() +{ + // Keine weitere Aktion noetig... + // Es sei denn, der Bereich soll in die Mitte gescrollt werden, + // und nicht irgendwo stehen. +} + +void __EXPORT EditSpellWrapper::ReplaceAll( const String &rNewText, + sal_Int16 ) +{ + // Wird gerufen, wenn Wort in ReplaceList des SpellCheckers + pEditView->InsertText( rNewText ); + CheckSpellTo(); +} + +void __EXPORT EditSpellWrapper::ChangeWord( const String& rNewWord, + const sal_uInt16 ) +{ + // Wird gerufen, wenn Wort Button Change + // bzw. intern von mir bei ChangeAll + + // Wenn Punkt hinterm Wort, wird dieser nicht mitgegeben. + // Falls '"' => PreStripped. + String aNewWord( rNewWord ); + pEditView->InsertText( aNewWord ); + CheckSpellTo(); +} + +void __EXPORT EditSpellWrapper::ChangeThesWord( const String& rNewWord ) +{ + pEditView->InsertText( rNewWord ); + CheckSpellTo(); +} + +void __EXPORT EditSpellWrapper::AutoCorrect( const String&, const String& ) +{ +} + +void EditSpellWrapper::CheckSpellTo() +{ + ImpEditEngine* pImpEE = pEditView->GetImpEditEngine(); + SpellInfo* pSpellInfo = pImpEE->GetSpellInfo(); + EditPaM aPaM( pEditView->GetImpEditView()->GetEditSelection().Max() ); + EPaM aEPaM = pImpEE->CreateEPaM( aPaM ); + if ( aEPaM.nPara == pSpellInfo->aSpellTo.nPara ) + { + // prueffen, ob SpellToEnd noch gueltiger Index, falls in dem Absatz + // ersetzt wurde. + if ( pSpellInfo->aSpellTo.nIndex > aPaM.GetNode()->Len() ) + pSpellInfo->aSpellTo.nIndex = aPaM.GetNode()->Len(); + } +} +SV_IMPL_VARARR( WrongRanges, WrongRange ); + +WrongList::WrongList() +{ + nInvalidStart = 0; + nInvalidEnd = 0xFFFF; +} + +WrongList::~WrongList() +{ +} + +void WrongList::TextInserted( sal_uInt16 nPos, sal_uInt16 nNew, sal_Bool bPosIsSep ) +{ + if ( !IsInvalid() ) + { + nInvalidStart = nPos; + nInvalidEnd = nPos+nNew; + } + else + { + if ( nInvalidStart > nPos ) + nInvalidStart = nPos; + if ( nInvalidEnd >= nPos ) + nInvalidEnd = nInvalidEnd + nNew; + else + nInvalidEnd = nPos+nNew; + } + + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + sal_Bool bRefIsValid = sal_True; + if ( rWrong.nEnd >= nPos ) + { + // Alle Wrongs hinter der Einfuegeposition verschieben... + if ( rWrong.nStart > nPos ) + { + rWrong.nStart = rWrong.nStart + nNew; + rWrong.nEnd = rWrong.nEnd + nNew; + } + // 1: Startet davor, geht bis nPos... + else if ( rWrong.nEnd == nPos ) + { + // Sollte bei einem Blank unterbunden werden! + if ( !bPosIsSep ) + rWrong.nEnd = rWrong.nEnd + nNew; + } + // 2: Startet davor, geht hinter Pos... + else if ( ( rWrong.nStart < nPos ) && ( rWrong.nEnd > nPos ) ) + { + rWrong.nEnd = rWrong.nEnd + nNew; + // Bei einem Trenner das Wrong entfernen und neu pruefen + if ( bPosIsSep ) + { + // Wrong aufteilen... + WrongRange aNewWrong( rWrong.nStart, nPos ); + rWrong.nStart = nPos+1; + Insert( aNewWrong, n ); + bRefIsValid = sal_False; // Referenz nach Insert nicht mehr gueltig, der andere wurde davor an dessen Position eingefuegt + n++; // Diesen nicht nochmal... + } + } + // 3: Attribut startet auf Pos... + else if ( rWrong.nStart == nPos ) + { + rWrong.nEnd = rWrong.nEnd + nNew; + if ( bPosIsSep ) + rWrong.nStart++; + } + } + DBG_ASSERT( !bRefIsValid || ( rWrong.nStart < rWrong.nEnd ), + "TextInserted, WrongRange: Start >= End?!" ); + } + + DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" ); +} + +void WrongList::TextDeleted( sal_uInt16 nPos, sal_uInt16 nDeleted ) +{ + sal_uInt16 nEndChanges = nPos+nDeleted; + if ( !IsInvalid() ) + { + sal_uInt16 nNewInvalidStart = nPos ? nPos - 1 : 0; + nInvalidStart = nNewInvalidStart; + nInvalidEnd = nNewInvalidStart + 1; + } + else + { + if ( nInvalidStart > nPos ) + nInvalidStart = nPos; + if ( nInvalidEnd > nPos ) + { + if ( nInvalidEnd > nEndChanges ) + nInvalidEnd = nInvalidEnd - nDeleted; + else + nInvalidEnd = nPos+1; + } + } + + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + sal_Bool bDelWrong = sal_False; + if ( rWrong.nEnd >= nPos ) + { + // Alles Wrongs hinter der Einfuegeposition verschieben... + if ( rWrong.nStart >= nEndChanges ) + { + rWrong.nStart = rWrong.nStart - nDeleted; + rWrong.nEnd = rWrong.nEnd - nDeleted; + } + // 1. Innenliegende Wrongs loeschen... + else if ( ( rWrong.nStart >= nPos ) && ( rWrong.nEnd <= nEndChanges ) ) + { + bDelWrong = sal_True; + } + // 2. Wrong beginnt davor, endet drinnen oder dahinter... + else if ( ( rWrong.nStart <= nPos ) && ( rWrong.nEnd > nPos ) ) + { + if ( rWrong.nEnd <= nEndChanges ) // endet drinnen + rWrong.nEnd = nPos; + else + rWrong.nEnd = rWrong.nEnd - nDeleted; // endet dahinter + } + // 3. Wrong beginnt drinnen, endet dahinter... + else if ( ( rWrong.nStart >= nPos ) && ( rWrong.nEnd > nEndChanges ) ) + { + rWrong.nStart = nEndChanges; + rWrong.nStart = rWrong.nStart - nDeleted; + rWrong.nEnd = rWrong.nEnd - nDeleted; + } + } + DBG_ASSERT( rWrong.nStart < rWrong.nEnd, + "TextInserted, WrongRange: Start >= End?!" ); + if ( bDelWrong ) + { + Remove( n, 1 ); + n--; + } + } + + DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" ); +} + +sal_Bool WrongList::NextWrong( sal_uInt16& rnStart, sal_uInt16& rnEnd ) const +{ + /* + rnStart enthaelt die Startposition, wird ggf. auf Wrong-Start korrigiert + rnEnd braucht nicht inizialisiert sein. + */ + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + if ( rWrong.nEnd > rnStart ) + { + rnStart = rWrong.nStart; + rnEnd = rWrong.nEnd; + return sal_True; + } + } + return sal_False; +} + +sal_Bool WrongList::HasWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const +{ + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + if ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd == nEnd ) ) + return sal_True; + else if ( rWrong.nStart >= nStart ) + break; + } + return sal_False; +} + +sal_Bool WrongList::HasAnyWrong( sal_uInt16 nStart, sal_uInt16 nEnd ) const +{ + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + if ( ( rWrong.nEnd >= nStart ) && ( rWrong.nStart < nEnd ) ) + return sal_True; + else if ( rWrong.nStart >= nEnd ) + break; + } + return sal_False; +} + +void WrongList::ClearWrongs( sal_uInt16 nStart, sal_uInt16 nEnd, + const ContentNode* pNode ) +{ + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + if ( ( rWrong.nEnd > nStart ) && ( rWrong.nStart < nEnd ) ) + { + if ( rWrong.nEnd > nEnd ) // // Laeuft raus + { + rWrong.nStart = nEnd; + // Blanks? + while ( ( rWrong.nStart < pNode->Len() ) && + ( ( pNode->GetChar( rWrong.nStart ) == ' ' ) || + ( pNode->IsFeature( rWrong.nStart ) ) ) ) + { + rWrong.nStart++; + } + } + else + { + Remove( n, 1 ); + n--; + } + } + } + + DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" ); +} + +void WrongList::InsertWrong( sal_uInt16 nStart, sal_uInt16 nEnd, + sal_Bool bClearRange ) +{ + sal_uInt16 nPos = Count(); + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + if ( rWrong.nStart >= nStart ) + { + nPos = n; + if ( bClearRange ) + { + // Es kann eigentlich nur Passieren, dass der Wrong genau + // hier beginnt und weiter rauslauft, aber nicht, dass hier + // mehrere im Bereich liegen... + // Genau im Bereich darf keiner liegen, sonst darf diese Methode + // garnicht erst gerufen werden! + DBG_ASSERT( ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd > nEnd ) ) + || ( rWrong.nStart > nEnd ), "InsertWrong: RangeMismatch!" ); + if ( ( rWrong.nStart == nStart ) && ( rWrong.nEnd > nEnd ) ) + rWrong.nStart = nEnd+1; + } + break; + } + } + Insert( WrongRange( nStart, nEnd ), nPos ); + + DBG_ASSERT( !DbgIsBuggy(), "InsertWrong: WrongList kaputt!" ); +} + +void WrongList::MarkWrongsInvalid() +{ + if ( Count() ) + MarkInvalid( GetObject( 0 ).nStart, GetObject( Count()-1 ).nEnd ); +} + +WrongList* WrongList::Clone() const +{ + WrongList* pNew = new WrongList; + for ( sal_uInt16 n = 0; n < Count(); n++ ) + { + WrongRange& rWrong = GetObject( n ); + pNew->Insert( rWrong, pNew->Count() ); + } + + return pNew; +} + +// #i102062# +bool WrongList::operator==(const WrongList& rCompare) const +{ + // cleck direct members + if(GetInvalidStart() != rCompare.GetInvalidStart() + || GetInvalidEnd() != rCompare.GetInvalidEnd() + || Count() != rCompare.Count()) + { + return false; + } + + for(USHORT a(0); a < Count(); a++) + { + const WrongRange& rCandA(GetObject(a)); + const WrongRange& rCandB(rCompare.GetObject(a)); + + if(rCandA.nStart != rCandB.nStart + || rCandA.nEnd != rCandB.nEnd) + { + return false; + } + } + + return true; +} + +#ifdef DBG_UTIL +sal_Bool WrongList::DbgIsBuggy() const +{ + // Pruefen, ob sich Bereiche ueberlappen + sal_Bool bError = sal_False; + for ( sal_uInt16 _nA = 0; !bError && ( _nA < Count() ); _nA++ ) + { + WrongRange& rWrong = GetObject( _nA ); + for ( sal_uInt16 nB = _nA+1; !bError && ( nB < Count() ); nB++ ) + { + WrongRange& rNextWrong = GetObject( nB ); + // 1) Start davor, End hinterm anderen Start + if ( ( rWrong.nStart <= rNextWrong.nStart ) + && ( rWrong.nEnd >= rNextWrong.nStart ) ) + bError = sal_True; + // 2) Start hinter anderen Start, aber noch vorm anderen End + else if ( ( rWrong.nStart >= rNextWrong.nStart) + && ( rWrong.nStart <= rNextWrong.nEnd ) ) + bError = sal_True; + } + } + return bError; +} +#endif + + +EdtAutoCorrDoc::EdtAutoCorrDoc( ImpEditEngine* pE, ContentNode* pN, + sal_uInt16 nCrsr, xub_Unicode cIns ) +{ + pImpEE = pE; + pCurNode = pN; + nCursor = nCrsr; + + bUndoAction = sal_False; + bAllowUndoAction = cIns ? sal_True : sal_False; +} + +EdtAutoCorrDoc::~EdtAutoCorrDoc() +{ + if ( bUndoAction ) + pImpEE->UndoActionEnd( EDITUNDO_INSERT ); +} + +sal_Bool EdtAutoCorrDoc::Delete( sal_uInt16 nStt, sal_uInt16 nEnd ) +{ + EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) ); + pImpEE->ImpDeleteSelection( aSel ); + DBG_ASSERT( nCursor >= nEnd, "Cursor mitten im Geschehen ?!" ); + nCursor -= ( nEnd-nStt ); + bAllowUndoAction = sal_False; + return sal_True; +} + +sal_Bool EdtAutoCorrDoc::Insert( sal_uInt16 nPos, const String& rTxt ) +{ + EditSelection aSel = EditPaM( pCurNode, nPos ); + pImpEE->ImpInsertText( aSel, rTxt ); + DBG_ASSERT( nCursor >= nPos, "Cursor mitten im Geschehen ?!" ); + nCursor = nCursor + rTxt.Len(); + + if ( bAllowUndoAction && ( rTxt.Len() == 1 ) ) + ImplStartUndoAction(); + bAllowUndoAction = sal_False; + + return sal_True; +} + +sal_Bool EdtAutoCorrDoc::Replace( sal_uInt16 nPos, const String& rTxt ) +{ + // Eigentlich ein Replace einfuehren => Entspr. UNDO + sal_uInt16 nEnd = nPos+rTxt.Len(); + if ( nEnd > pCurNode->Len() ) + nEnd = pCurNode->Len(); + + // #i5925# First insert new text behind to be deleted text, for keeping attributes. + pImpEE->ImpInsertText( EditSelection( EditPaM( pCurNode, nEnd ) ), rTxt ); + pImpEE->ImpDeleteSelection( EditSelection( EditPaM( pCurNode, nPos ), EditPaM( pCurNode, nEnd ) ) ); + + if ( nPos == nCursor ) + nCursor = nCursor + rTxt.Len(); + + if ( bAllowUndoAction && ( rTxt.Len() == 1 ) ) + ImplStartUndoAction(); + + bAllowUndoAction = sal_False; + + return sal_True; +} + +sal_Bool EdtAutoCorrDoc::SetAttr( sal_uInt16 nStt, sal_uInt16 nEnd, + sal_uInt16 nSlotId, SfxPoolItem& rItem ) +{ + SfxItemPool* pPool = &pImpEE->GetEditDoc().GetItemPool(); + while ( pPool->GetSecondaryPool() && + !pPool->GetName().EqualsAscii( "EditEngineItemPool" ) ) + { + pPool = pPool->GetSecondaryPool(); + + } + sal_uInt16 nWhich = pPool->GetWhich( nSlotId ); + if ( nWhich ) + { + rItem.SetWhich( nWhich ); + + SfxItemSet aSet( pImpEE->GetEmptyItemSet() ); + aSet.Put( rItem ); + + EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) ); + aSel.Max().SetIndex( nEnd ); // ??? + pImpEE->SetAttribs( aSel, aSet, ATTRSPECIAL_EDGE ); + bAllowUndoAction = sal_False; + } + return sal_True; +} + +sal_Bool EdtAutoCorrDoc::SetINetAttr( sal_uInt16 nStt, sal_uInt16 nEnd, + const String& rURL ) +{ + // Aus dem Text ein Feldbefehl machen... + EditSelection aSel( EditPaM( pCurNode, nStt ), EditPaM( pCurNode, nEnd ) ); + String aText = pImpEE->GetSelected( aSel ); + aSel = pImpEE->ImpDeleteSelection( aSel ); + DBG_ASSERT( nCursor >= nEnd, "Cursor mitten im Geschehen ?!" ); + nCursor -= ( nEnd-nStt ); + SvxFieldItem aField( SvxURLField( rURL, aText, SVXURLFORMAT_REPR ), + EE_FEATURE_FIELD ); + pImpEE->InsertField( aSel, aField ); + nCursor++; + pImpEE->UpdateFields(); + bAllowUndoAction = sal_False; + return sal_True; +} + +sal_Bool EdtAutoCorrDoc::HasSymbolChars( sal_uInt16 nStt, sal_uInt16 nEnd ) +{ + USHORT nScriptType = pImpEE->GetScriptType( EditPaM( pCurNode, nStt ) ); + USHORT nScriptFontInfoItemId = GetScriptItemId( EE_CHAR_FONTINFO, nScriptType ); + + CharAttribArray& rAttribs = pCurNode->GetCharAttribs().GetAttribs(); + sal_uInt16 nAttrs = rAttribs.Count(); + for ( sal_uInt16 n = 0; n < nAttrs; n++ ) + { + EditCharAttrib* pAttr = rAttribs.GetObject( n ); + if ( pAttr->GetStart() >= nEnd ) + return sal_False; + + if ( ( pAttr->Which() == nScriptFontInfoItemId ) && + ( ((SvxFontItem*)pAttr->GetItem())->GetCharSet() == RTL_TEXTENCODING_SYMBOL ) ) + { + // Pruefen, ob das Attribt im Bereich liegt... + if ( pAttr->GetEnd() >= nStt ) + return sal_True; + } + } + return sal_False; +} + +const String* EdtAutoCorrDoc::GetPrevPara( sal_Bool ) +{ + // Vorherigen Absatz zurueck geben, damit ermittel werden kann, + // ob es sich beim aktuellen Wort um einen Satzanfang handelt. + + bAllowUndoAction = sal_False; // Jetzt nicht mehr... + + ContentList& rNodes = pImpEE->GetEditDoc(); + sal_uInt16 nPos = rNodes.GetPos( pCurNode ); + + // Sonderbehandlung: Bullet => Absatzanfang => einfach NULL returnen... + const SfxBoolItem& rBulletState = (const SfxBoolItem&) + pImpEE->GetParaAttrib( nPos, EE_PARA_BULLETSTATE ); + sal_Bool bBullet = rBulletState.GetValue() ? sal_True : sal_False; + if ( !bBullet && ( pImpEE->aStatus.GetControlWord() & EE_CNTRL_OUTLINER ) ) + { + // Der Outliner hat im Gliederungsmodus auf Ebene 0 immer ein Bullet. + const SfxInt16Item& rLevel = (const SfxInt16Item&) + pImpEE->GetParaAttrib( nPos, EE_PARA_OUTLLEVEL ); + if ( rLevel.GetValue() == 0 ) + bBullet = sal_True; + } + if ( bBullet ) + return NULL; + + for ( sal_uInt16 n = nPos; n; ) + { + n--; + ContentNode* pNode = rNodes[n]; + if ( pNode->Len() ) + return pNode; + } + return NULL; + +} + +sal_Bool EdtAutoCorrDoc::ChgAutoCorrWord( sal_uInt16& rSttPos, + sal_uInt16 nEndPos, SvxAutoCorrect& rACorrect, + const String** ppPara ) +{ + // Absatz-Anfang oder ein Blank gefunden, suche nach dem Wort + // Kuerzel im Auto + + bAllowUndoAction = sal_False; // Jetzt nicht mehr... + + String aShort( pCurNode->Copy( rSttPos, nEndPos - rSttPos ) ); + sal_Bool bRet = sal_False; + + if( !aShort.Len() ) + return bRet; + + LanguageType eLang = pImpEE->GetLanguage( EditPaM( pCurNode, rSttPos+1 ) ); + const SvxAutocorrWord* pFnd = rACorrect.SearchWordsInList( *pCurNode, rSttPos, nEndPos, *this, eLang ); + if( pFnd && pFnd->IsTextOnly() ) + { + // dann mal ersetzen + EditSelection aSel( EditPaM( pCurNode, rSttPos ), + EditPaM( pCurNode, nEndPos ) ); + aSel = pImpEE->ImpDeleteSelection( aSel ); + DBG_ASSERT( nCursor >= nEndPos, "Cursor mitten im Geschehen ?!" ); + nCursor -= ( nEndPos-rSttPos ); + pImpEE->ImpInsertText( aSel, pFnd->GetLong() ); + nCursor = nCursor + pFnd->GetLong().Len(); + if( ppPara ) + *ppPara = pCurNode; + bRet = sal_True; + } + + return bRet; +} + +LanguageType EdtAutoCorrDoc::GetLanguage( sal_uInt16 nPos, sal_Bool ) const +{ + return pImpEE->GetLanguage( EditPaM( pCurNode, nPos+1 ) ); +} + +void EdtAutoCorrDoc::ImplStartUndoAction() +{ + sal_uInt16 nPara = pImpEE->GetEditDoc().GetPos( pCurNode ); + ESelection aSel( nPara, nCursor, nPara, nCursor ); + pImpEE->UndoActionStart( EDITUNDO_INSERT, aSel ); + bUndoAction = sal_True; + bAllowUndoAction = sal_False; +} + |