LCOV - code coverage report
Current view: top level - sw/source/core/edit - autofmt.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1421 0.0 %
Date: 2014-04-14 Functions: 0 50 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <ctype.h>
      21             : #include <hintids.hxx>
      22             : 
      23             : #include <unotools/charclass.hxx>
      24             : 
      25             : #include <vcl/msgbox.hxx>
      26             : 
      27             : #include <editeng/boxitem.hxx>
      28             : #include <editeng/lrspitem.hxx>
      29             : #include <editeng/formatbreakitem.hxx>
      30             : #include <editeng/adjustitem.hxx>
      31             : #include <editeng/tstpitem.hxx>
      32             : #include <editeng/fontitem.hxx>
      33             : #include <editeng/langitem.hxx>
      34             : #include <editeng/charsetcoloritem.hxx>
      35             : #include <editeng/unolingu.hxx>
      36             : #include <editeng/acorrcfg.hxx>
      37             : 
      38             : #include <swwait.hxx>
      39             : #include <fmtpdsc.hxx>
      40             : #include <fmtanchr.hxx>
      41             : #include <doc.hxx>
      42             : #include <IDocumentUndoRedo.hxx>
      43             : #include <docary.hxx>
      44             : #include <editsh.hxx>
      45             : #include <index.hxx>
      46             : #include <pam.hxx>
      47             : #include <edimp.hxx>
      48             : #include <fesh.hxx>
      49             : #include <swundo.hxx>
      50             : #include <poolfmt.hxx>
      51             : #include <ndtxt.hxx>
      52             : #include <txtfrm.hxx>
      53             : #include <frminf.hxx>
      54             : #include <pagedesc.hxx>
      55             : #include <paratr.hxx>
      56             : #include <swtable.hxx>
      57             : #include <acorrect.hxx>
      58             : #include <shellres.hxx>
      59             : #include <section.hxx>
      60             : #include <frmatr.hxx>
      61             : #include <charatr.hxx>
      62             : #include <mdiexp.hxx>
      63             : #include <statstr.hrc>
      64             : #include <comcore.hrc>
      65             : #include <numrule.hxx>
      66             : 
      67             : #include <boost/scoped_ptr.hpp>
      68             : 
      69             : using namespace ::com::sun::star;
      70             : 
      71             : //JP 16.12.99: definition:
      72             : //      from pos cPosEnDash to cPosEmDash all chars changed to endashes,
      73             : //      from pos cPosEmDash to cPosEnd    all chars changed to emdashes
      74             : //      all other chars are changed to the user configuration
      75             : 
      76             : const sal_Unicode pBulletChar[6] = { '+', '*', '-', 0x2013, 0x2014, 0 };
      77             : const int cnPosEnDash = 2, cnPosEmDash = 4;
      78             : 
      79             : const sal_Unicode cStarSymbolEnDash = 0x2013;
      80             : const sal_Unicode cStarSymbolEmDash = 0x2014;
      81             : 
      82             : SvxSwAutoFmtFlags* SwEditShell::pAutoFmtFlags = 0;
      83             : 
      84             : // Number of num-/bullet-paragraph templates. MAXLEVEL will soon be raised
      85             : // to x, but not the number of templates. (Artifact from <= 4.0)
      86             : const sal_uInt16 cnNumBullColls = 4;
      87             : 
      88           0 : class SwAutoFormat
      89             : {
      90             :     SvxSwAutoFmtFlags m_aFlags;
      91             :     SwPaM m_aDelPam;            // a Pam that can be used
      92             :     SwNodeIndex m_aNdIdx;       // the index on the current TextNode
      93             :     SwNodeIndex m_aEndNdIdx;    // index on the end of the area
      94             : 
      95             :     SwEditShell* m_pEditShell;
      96             :     SwDoc* m_pDoc;
      97             :     SwTxtNode* m_pCurTxtNd;     // the current TextNode
      98             :     SwTxtFrm* m_pCurTxtFrm;     // frame of the current TextNode
      99             :     sal_uLong m_nEndNdIdx;      // for the percentage-display
     100             :     mutable boost::scoped_ptr<CharClass> m_pCharClass; // Character classification
     101             :     mutable LanguageType m_eCharClassLang;
     102             : 
     103             :     sal_uInt16 m_nLastHeadLvl, m_nLastCalcHeadLvl;
     104             :     sal_uInt16 m_nRedlAutoFmtSeqId;
     105             : 
     106             :     enum
     107             :     {
     108             :         NONE = 0,
     109             :         DELIM = 1,
     110             :         DIGIT = 2,
     111             :         CHG = 4,
     112             :         LOWER_ALPHA = 8,
     113             :         UPPER_ALPHA = 16,
     114             :         LOWER_ROMAN = 32,
     115             :         UPPER_ROMAN = 64,
     116             :         NO_DELIM = (DIGIT|LOWER_ALPHA|UPPER_ALPHA|LOWER_ROMAN|UPPER_ROMAN)
     117             :     };
     118             : 
     119             :     enum Format_Status
     120             :     {
     121             :         READ_NEXT_PARA,
     122             :         TST_EMPTY_LINE,
     123             :         TST_ALPHA_LINE,
     124             :         GET_ALL_INFO,
     125             :         IS_ONE_LINE,
     126             :         TST_ENUMERIC,
     127             :         TST_IDENT,
     128             :         TST_NEG_IDENT,
     129             :         TST_TXT_BODY,
     130             :         HAS_FMTCOLL,
     131             :         IS_END
     132             :     } m_eStat;
     133             : 
     134             :     bool m_bEnd : 1;
     135             :     bool m_bEmptyLine : 1;
     136             :     bool m_bMoreLines : 1;
     137             : 
     138             :     // ------------- private methods -----------------------------
     139           0 :     CharClass& GetCharClass( LanguageType eLang ) const
     140             :     {
     141           0 :         if( !m_pCharClass || eLang != m_eCharClassLang )
     142             :         {
     143           0 :             m_pCharClass.reset( new CharClass( LanguageTag( eLang ) ) );
     144           0 :             m_eCharClassLang = eLang;
     145             :         }
     146           0 :         return *m_pCharClass;
     147             :     }
     148             : 
     149           0 :     bool IsSpace( const sal_Unicode c ) const
     150           0 :         { return (' ' == c || '\t' == c || 0x0a == c|| 0x3000 == c /* Jap. space */); }
     151             : 
     152             :     void SetColl( sal_uInt16 nId, bool bHdLineOrText = false );
     153             :     OUString GoNextPara();
     154             :     bool HasObjects( const SwNode& rNd );
     155             : 
     156             :     // TxtNode methods
     157             :     const SwTxtNode* GetNextNode() const;
     158           0 :     bool IsEmptyLine( const SwTxtNode& rNd ) const
     159           0 :         {   return rNd.GetTxt().isEmpty() ||
     160           0 :                 rNd.GetTxt().getLength() == GetLeadingBlanks( rNd.GetTxt() ); }
     161             : 
     162             :     sal_Bool IsOneLine( const SwTxtNode& ) const;
     163             :     sal_Bool IsFastFullLine( const SwTxtNode& ) const;
     164             :     sal_Bool IsNoAlphaLine( const SwTxtNode&) const;
     165             :     sal_Bool IsEnumericChar( const SwTxtNode&) const;
     166             :     sal_Bool IsBlanksInString( const SwTxtNode&) const;
     167             :     sal_uInt16 CalcLevel( const SwTxtNode&, sal_uInt16 *pDigitLvl = 0 ) const;
     168             :     sal_Int32 GetBigIndent( sal_Int32& rAktSpacePos ) const;
     169             : 
     170             :     OUString DelLeadingBlanks(const OUString& rStr) const;
     171             :     OUString& DelTrailingBlanks( OUString& rStr ) const;
     172             :     sal_Int32 GetLeadingBlanks( const OUString& rStr ) const;
     173             :     sal_Int32 GetTrailingBlanks( const OUString& rStr ) const;
     174             : 
     175             :     bool IsFirstCharCapital( const SwTxtNode& rNd ) const;
     176             :     sal_uInt16 GetDigitLevel( const SwTxtNode& rTxtNd, sal_Int32& rPos,
     177             :                             OUString* pPrefix = 0, OUString* pPostfix = 0,
     178             :                             OUString* pNumTypes = 0 ) const;
     179             :     /// get the FORMATED TextFrame
     180             :     SwTxtFrm* GetFrm( const SwTxtNode& rTxtNd ) const;
     181             : 
     182             :     void BuildIndent();
     183             :     void BuildText();
     184             :     void BuildTextIndent();
     185             :     void BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel );
     186             :     void BuildNegIndent( SwTwips nSpaces );
     187             :     void BuildHeadLine( sal_uInt16 nLvl );
     188             : 
     189             :     bool HasSelBlanks( SwPaM& rPam ) const;
     190             :     bool HasBreakAttr( const SwTxtNode& ) const;
     191             :     void DeleteSel( SwPaM& rPam );
     192             :     bool DeleteCurNxtPara( const OUString& rNxtPara );
     193             :     /// delete in the node start and/or end
     194             :     void DeleteCurrentParagraph( bool bStart = true, bool nEnd = true );
     195             :     void DelEmptyLine( bool bTstNextPara = true );
     196             :     /// when using multiline paragraphs delete the "left" and/or
     197             :     /// "right" margins
     198             :     void DelMoreLinesBlanks( bool bWithLineBreaks = false );
     199             :     /// delete the previous paragraph
     200             :     void DelPrevPara();
     201             :     /// execute AutoCorrect on current TextNode
     202             :     void AutoCorrect( sal_Int32 nSttPos = 0 );
     203             : 
     204           0 :     bool CanJoin( const SwTxtNode* pTxtNd ) const
     205             :     {
     206           0 :         return !m_bEnd && pTxtNd &&
     207           0 :              !IsEmptyLine( *pTxtNd ) &&
     208           0 :              !IsNoAlphaLine( *pTxtNd) &&
     209           0 :              !IsEnumericChar( *pTxtNd ) &&
     210           0 :              ((COMPLETE_STRING - 50 - pTxtNd->GetTxt().getLength()) >
     211           0 :                     m_pCurTxtNd->GetTxt().getLength()) &&
     212           0 :              !HasBreakAttr( *pTxtNd );
     213             :     }
     214             : 
     215             :     /// is a dot at the end ??
     216             :     bool IsSentenceAtEnd( const SwTxtNode& rTxtNd ) const;
     217             : 
     218             :     bool DoUnderline();
     219             :     bool DoTable();
     220             : 
     221             :     void _SetRedlineTxt( sal_uInt16 nId );
     222           0 :     bool SetRedlineTxt( sal_uInt16 nId )
     223           0 :         { if( m_aFlags.bWithRedlining )   _SetRedlineTxt( nId );  return true; }
     224           0 :     bool ClearRedlineTxt()
     225           0 :         { if( m_aFlags.bWithRedlining )   m_pDoc->SetAutoFmtRedlineComment(0);  return true; }
     226             : 
     227             : public:
     228             :     SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFmtFlags& rFlags,
     229             :                 SwNodeIndex* pSttNd = 0, SwNodeIndex* pEndNd = 0 );
     230             : };
     231             : 
     232           0 : const sal_Unicode* StrChr( const sal_Unicode* pSrc, sal_Unicode c )
     233             : {
     234           0 :     while( *pSrc && *pSrc != c )
     235           0 :         ++pSrc;
     236           0 :     return *pSrc ? pSrc : 0;
     237             : }
     238             : 
     239           0 : SwTxtFrm* SwAutoFormat::GetFrm( const SwTxtNode& rTxtNd ) const
     240             : {
     241             :     // get the Frame
     242           0 :     const SwCntntFrm *pFrm = rTxtNd.getLayoutFrm( m_pEditShell->GetLayout() );
     243             :     OSL_ENSURE( pFrm, "For Autoformat a Layout is needed" );
     244           0 :     if( m_aFlags.bAFmtByInput && !pFrm->IsValid() )
     245             :     {
     246           0 :         SwRect aTmpFrm( pFrm->Frm() );
     247           0 :         SwRect aTmpPrt( pFrm->Prt() );
     248           0 :         pFrm->Calc();
     249           0 :         if( pFrm->Frm() != aTmpFrm || pFrm->Prt() != aTmpPrt ||
     250           0 :             ( pFrm->IsTxtFrm() && !((SwTxtFrm*)pFrm)->Paint().IsEmpty() ) )
     251           0 :             pFrm->SetCompletePaint();
     252             :     }
     253           0 :     return ((SwTxtFrm*)pFrm)->GetFormatted();
     254             : }
     255             : 
     256           0 : void SwAutoFormat::_SetRedlineTxt( sal_uInt16 nActionId )
     257             : {
     258           0 :     OUString sTxt;
     259           0 :     sal_uInt16 nSeqNo = 0;
     260           0 :     if( STR_AUTOFMTREDL_END > nActionId )
     261             :     {
     262           0 :         sTxt = SwViewShell::GetShellRes()->GetAutoFmtNameLst()[ nActionId ];
     263           0 :         switch( nActionId )
     264             :         {
     265             :         case STR_AUTOFMTREDL_SET_NUMBULET:
     266             :         case STR_AUTOFMTREDL_DEL_MORELINES:
     267             : 
     268             :         // AutoCorrect actions
     269             :         case STR_AUTOFMTREDL_USE_REPLACE:
     270             :         case STR_AUTOFMTREDL_CPTL_STT_WORD:
     271             :         case STR_AUTOFMTREDL_CPTL_STT_SENT:
     272             :         case STR_AUTOFMTREDL_TYPO:
     273             :         case STR_AUTOFMTREDL_UNDER:
     274             :         case STR_AUTOFMTREDL_BOLD:
     275             :         case STR_AUTOFMTREDL_FRACTION:
     276             :         case STR_AUTOFMTREDL_DASH:
     277             :         case STR_AUTOFMTREDL_ORDINAL:
     278             :         case STR_AUTOFMTREDL_NON_BREAK_SPACE:
     279           0 :             nSeqNo = ++m_nRedlAutoFmtSeqId;
     280           0 :             break;
     281             :         }
     282             :     }
     283             : #if OSL_DEBUG_LEVEL > 0
     284             :     else
     285             :         sTxt = "Action text is missing";
     286             : #endif
     287             : 
     288           0 :     m_pDoc->SetAutoFmtRedlineComment( &sTxt, nSeqNo );
     289           0 : }
     290             : 
     291           0 : OUString SwAutoFormat::GoNextPara()
     292             : {
     293           0 :     SwNode* pNewNd = 0;
     294           0 :     do {
     295             :         // has to be checked twice before and after incrementation
     296           0 :         if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
     297             :         {
     298           0 :             m_bEnd = true;
     299           0 :             return OUString();
     300             :         }
     301             : 
     302           0 :         m_aNdIdx++;
     303           0 :         if( m_aNdIdx.GetIndex() >= m_aEndNdIdx.GetIndex() )
     304             :         {
     305           0 :             m_bEnd = true;
     306           0 :             return OUString();
     307             :         }
     308             :         else
     309           0 :             pNewNd = &m_aNdIdx.GetNode();
     310             : 
     311             :         // not a TextNode ->
     312             :         //      TableNode   : skip table
     313             :         //      NoTxtNode   : skip nodes
     314             :         //      EndNode     : at the end, terminate
     315           0 :         if( pNewNd->IsEndNode() )
     316             :         {
     317           0 :             m_bEnd = true;
     318           0 :             return OUString();
     319             :         }
     320           0 :         else if( pNewNd->IsTableNode() )
     321           0 :             m_aNdIdx = *pNewNd->EndOfSectionNode();
     322           0 :         else if( pNewNd->IsSectionNode() )
     323             :         {
     324           0 :             const SwSection& rSect = pNewNd->GetSectionNode()->GetSection();
     325           0 :             if( rSect.IsHiddenFlag() || rSect.IsProtectFlag() )
     326           0 :                 m_aNdIdx = *pNewNd->EndOfSectionNode();
     327             :         }
     328           0 :     } while( !pNewNd->IsTxtNode() );
     329             : 
     330           0 :     if( !m_aFlags.bAFmtByInput )
     331           0 :         ::SetProgressState( m_aNdIdx.GetIndex() + m_nEndNdIdx - m_aEndNdIdx.GetIndex(),
     332           0 :                             m_pDoc->GetDocShell() );
     333             : 
     334           0 :     m_pCurTxtNd = (SwTxtNode*)pNewNd;
     335           0 :     m_pCurTxtFrm = GetFrm( *m_pCurTxtNd );
     336           0 :     return m_pCurTxtNd->GetTxt();
     337             : }
     338             : 
     339           0 : bool SwAutoFormat::HasObjects( const SwNode& rNd )
     340             : {
     341             :     // Is there something bound to the paragraph in the paragraph
     342             :     // like borders, DrawObjects, ...
     343           0 :     bool bRet = false;
     344           0 :     const SwFrmFmts& rFmts = *m_pDoc->GetSpzFrmFmts();
     345           0 :     for( sal_uInt16 n = 0; n < rFmts.size(); ++n )
     346             :     {
     347           0 :         const SwFmtAnchor& rAnchor = rFmts[ n ]->GetAnchor();
     348           0 :         if ((FLY_AT_PAGE != rAnchor.GetAnchorId()) &&
     349           0 :             rAnchor.GetCntntAnchor() &&
     350           0 :             &rAnchor.GetCntntAnchor()->nNode.GetNode() == &rNd )
     351             :         {
     352           0 :             bRet = true;
     353           0 :             break;
     354             :         }
     355             :     }
     356           0 :     return bRet;
     357             : }
     358             : 
     359           0 : const SwTxtNode* SwAutoFormat::GetNextNode() const
     360             : {
     361           0 :     if( m_aNdIdx.GetIndex()+1 >= m_aEndNdIdx.GetIndex() )
     362           0 :         return 0;
     363           0 :     return m_pDoc->GetNodes()[ m_aNdIdx.GetIndex() + 1 ]->GetTxtNode();
     364             : }
     365             : 
     366           0 : sal_Bool SwAutoFormat::IsOneLine( const SwTxtNode& rNd ) const
     367             : {
     368           0 :     SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
     369           0 :     return aFInfo.IsOneLine();
     370             : }
     371             : 
     372           0 : sal_Bool SwAutoFormat::IsFastFullLine( const SwTxtNode& rNd ) const
     373             : {
     374           0 :     sal_Bool bRet = m_aFlags.bRightMargin;
     375           0 :     if( bRet )
     376             :     {
     377           0 :         SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
     378           0 :         bRet = aFInfo.IsFilled( m_aFlags.nRightMargin );
     379             :     }
     380           0 :     return bRet;
     381             : }
     382             : 
     383           0 : sal_Bool SwAutoFormat::IsEnumericChar( const SwTxtNode& rNd ) const
     384             : {
     385           0 :     const OUString& rTxt = rNd.GetTxt();
     386           0 :     sal_Int32 nBlnks = GetLeadingBlanks( rTxt );
     387           0 :     const sal_Int32 nLen = rTxt.getLength() - nBlnks;
     388           0 :     if( !nLen )
     389           0 :         return sal_False;
     390             : 
     391             :     // -, +, * separated by blank ??
     392           0 :     if (2 < nLen && IsSpace(rTxt[nBlnks + 1]))
     393             :     {
     394           0 :         if (StrChr(pBulletChar, rTxt[nBlnks]))
     395           0 :             return sal_True;
     396             :         // Should there be a symbol font at the position?
     397           0 :         SwTxtFrmInfo aFInfo( GetFrm( rNd ) );
     398           0 :         if( aFInfo.IsBullet( nBlnks ))
     399           0 :             return sal_True;
     400             :     }
     401             : 
     402             :     // 1.) / 1. / 1.1.1 / (1). / (1) / ....
     403           0 :     return USHRT_MAX != GetDigitLevel( rNd, nBlnks );
     404             : }
     405             : 
     406           0 : sal_Bool SwAutoFormat::IsBlanksInString( const SwTxtNode& rNd ) const
     407             : {
     408             :     // Search more than 5 consecutive blanks/tabs in the string.
     409           0 :     OUString sTmp( DelLeadingBlanks(rNd.GetTxt()) );
     410           0 :     const sal_Int32 nLen = sTmp.getLength();
     411           0 :     sal_Int32 nIdx = 0;
     412           0 :     while (nIdx < nLen)
     413             :     {
     414             :         // Skip non-blanks
     415           0 :         while (nIdx < nLen && !IsSpace(sTmp[nIdx])) ++nIdx;
     416           0 :         if (nIdx == nLen)
     417           0 :             return sal_False;
     418             :         // Then count consecutive blanks
     419           0 :         const sal_Int32 nFirst = nIdx;
     420           0 :         while (nIdx < nLen && IsSpace(sTmp[nIdx])) ++nIdx;
     421             :         // And exit if enough consecutive blanks were found
     422           0 :         if (nIdx-nFirst > 5)
     423           0 :             return sal_True;
     424             :     }
     425           0 :     return sal_False;
     426             : }
     427             : 
     428           0 : sal_uInt16 SwAutoFormat::CalcLevel( const SwTxtNode& rNd, sal_uInt16 *pDigitLvl ) const
     429             : {
     430           0 :     sal_uInt16 nLvl = 0, nBlnk = 0;
     431           0 :     const OUString& rTxt = rNd.GetTxt();
     432           0 :     if( pDigitLvl )
     433           0 :         *pDigitLvl = USHRT_MAX;
     434             : 
     435           0 :     if( RES_POOLCOLL_TEXT_MOVE == rNd.GetTxtColl()->GetPoolFmtId() )
     436             :     {
     437           0 :         if( m_aFlags.bAFmtByInput )
     438             :         {
     439           0 :             nLvl = rNd.GetAutoFmtLvl();
     440           0 :             ((SwTxtNode&)rNd).SetAutoFmtLvl( 0 );
     441           0 :             if( nLvl )
     442           0 :                 return nLvl;
     443             :         }
     444           0 :         ++nLvl;
     445             :     }
     446             : 
     447           0 :     for (sal_Int32 n = 0, nEnd = rTxt.getLength(); n < nEnd; ++n)
     448             :     {
     449           0 :         switch (rTxt[n])
     450             :         {
     451           0 :         case ' ':   if( 3 == ++nBlnk )
     452           0 :                         ++nLvl, nBlnk = 0;
     453           0 :                     break;
     454           0 :         case '\t':  ++nLvl, nBlnk = 0;
     455           0 :                     break;
     456             :         default:
     457           0 :             if( pDigitLvl )
     458             :                 // test 1.) / 1. / 1.1.1 / (1). / (1) / ....
     459           0 :                 *pDigitLvl = GetDigitLevel( rNd, n );
     460           0 :             return nLvl;
     461             :         }
     462             :     }
     463           0 :     return nLvl;
     464             : }
     465             : 
     466           0 : sal_Int32 SwAutoFormat::GetBigIndent( sal_Int32& rAktSpacePos ) const
     467             : {
     468           0 :     SwTxtFrmInfo aFInfo( GetFrm( *m_pCurTxtNd ) );
     469           0 :     const SwTxtFrm* pNxtFrm = 0;
     470             : 
     471           0 :     if( !m_bMoreLines )
     472             :     {
     473           0 :         const SwTxtNode* pNxtNd = GetNextNode();
     474           0 :         if( !CanJoin( pNxtNd ) || !IsOneLine( *pNxtNd ) )
     475           0 :             return 0;
     476             : 
     477           0 :         pNxtFrm = GetFrm( *pNxtNd );
     478             :     }
     479             : 
     480           0 :     return aFInfo.GetBigIndent( rAktSpacePos, pNxtFrm );
     481             : }
     482             : 
     483           0 : sal_Bool SwAutoFormat::IsNoAlphaLine( const SwTxtNode& rNd ) const
     484             : {
     485           0 :     const OUString& rStr = rNd.GetTxt();
     486           0 :     if( rStr.isEmpty() )
     487           0 :         return sal_False;
     488             :     // or better: determine via number of AlphaNum and !AlphaNum characters
     489           0 :     sal_Int32 nANChar = 0, nBlnk = 0;
     490             : 
     491           0 :     CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().GetLanguage().GetLanguage() );
     492           0 :     for( sal_Int32 n = 0, nEnd = rStr.getLength(); n < nEnd; ++n )
     493           0 :         if( IsSpace( rStr[ n ] ) )
     494           0 :             ++nBlnk;
     495           0 :         else if( rCC.isLetterNumeric( rStr, n ))
     496           0 :             ++nANChar;
     497             : 
     498             :     // If there are 75% of non-alphanumeric characters, then sal_True
     499           0 :     sal_uLong nLen = rStr.getLength() - nBlnk;
     500           0 :     nLen = ( nLen * 3 ) / 4;            // long overflow, if the strlen > sal_uInt16
     501           0 :     return sal_Int32(nLen) < (rStr.getLength() - nANChar - nBlnk);
     502             : }
     503             : 
     504           0 : bool SwAutoFormat::DoUnderline()
     505             : {
     506           0 :     if( !m_aFlags.bSetBorder )
     507           0 :         return false;
     508             : 
     509           0 :     OUString const& rTxt(m_pCurTxtNd->GetTxt());
     510           0 :     int eState = 0;
     511           0 :     sal_Int32 nCnt = 0;
     512           0 :     while (nCnt < rTxt.getLength())
     513             :     {
     514           0 :         int eTmp = 0;
     515           0 :         switch (rTxt[nCnt])
     516             :         {
     517           0 :             case '-': eTmp = 1; break;
     518           0 :             case '_': eTmp = 2; break;
     519           0 :             case '=': eTmp = 3; break;
     520           0 :             case '*': eTmp = 4; break;
     521           0 :             case '~': eTmp = 5; break;
     522           0 :             case '#': eTmp = 6; break;
     523             :             default:
     524           0 :                 return false;
     525             :         }
     526           0 :         if( 0 == eState )
     527           0 :             eState = eTmp;
     528           0 :         else if( eState != eTmp )
     529           0 :             return false;
     530           0 :         ++nCnt;
     531             :     }
     532             : 
     533           0 :     if( 2 < nCnt )
     534             :     {
     535             :         // then underline the previous paragraph if one exists
     536           0 :         DelEmptyLine( false );
     537           0 :         m_aDelPam.SetMark();
     538           0 :         m_aDelPam.GetMark()->nContent = 0;
     539             : 
     540           0 :         editeng::SvxBorderLine aLine;
     541           0 :         switch( eState )
     542             :         {
     543             :         case 1:         // single, 0.05 pt
     544           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::SOLID);
     545           0 :             aLine.SetWidth( DEF_LINE_WIDTH_0 );
     546           0 :             break;
     547             :         case 2:         // single, 1.0 pt
     548           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::SOLID);
     549           0 :             aLine.SetWidth( DEF_LINE_WIDTH_1 );
     550           0 :             break;
     551             :         case 3:         // double, 1.0 pt
     552           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
     553           0 :             aLine.SetWidth( DEF_LINE_WIDTH_1 );
     554           0 :             break;
     555             :         case 4:         // double (thick/thin), 4.0 pt
     556           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::THICKTHIN_SMALLGAP);
     557           0 :             aLine.SetWidth( DEF_LINE_WIDTH_3  );
     558           0 :             break;
     559             :         case 5:         // double (thin/thick), 4.0 pt
     560           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::THINTHICK_SMALLGAP);
     561           0 :             aLine.SetWidth( DEF_LINE_WIDTH_3 );
     562           0 :             break;
     563             :         case 6:         // double, 2.5 pt
     564           0 :             aLine.SetBorderLineStyle(table::BorderLineStyle::DOUBLE);
     565           0 :             aLine.SetWidth( DEF_LINE_WIDTH_2 );
     566           0 :             break;
     567             :         }
     568           0 :         SfxItemSet aSet(m_pDoc->GetAttrPool(),
     569             :                     RES_PARATR_CONNECT_BORDER, RES_PARATR_CONNECT_BORDER,
     570             :                     RES_BOX, RES_BOX,
     571           0 :                     0);
     572           0 :         aSet.Put( SwParaConnectBorderItem( sal_False ) );
     573           0 :         SvxBoxItem aBox( RES_BOX );
     574           0 :         aBox.SetLine( &aLine, BOX_LINE_BOTTOM );
     575           0 :         aBox.SetDistance( 42 );     // ~0,75 mm
     576           0 :         aSet.Put(aBox);
     577           0 :         m_pDoc->InsertItemSet( m_aDelPam, aSet, 0 );
     578             : 
     579           0 :         m_aDelPam.DeleteMark();
     580             :     }
     581           0 :     return 2 < nCnt;
     582             : }
     583             : 
     584           0 : bool SwAutoFormat::DoTable()
     585             : {
     586           0 :     if( !m_aFlags.bCreateTable || !m_aFlags.bAFmtByInput ||
     587           0 :         m_pCurTxtNd->FindTableNode() )
     588           0 :         return false;
     589             : 
     590           0 :     const OUString& rTmp = m_pCurTxtNd->GetTxt();
     591           0 :     sal_Int32 nSttPlus = GetLeadingBlanks( rTmp );
     592           0 :     sal_Int32 nEndPlus = GetTrailingBlanks( rTmp );
     593             :     sal_Unicode cChar;
     594             : 
     595           0 :     if( 2 > nEndPlus - nSttPlus ||
     596           0 :         ( '+' != ( cChar = rTmp[nSttPlus]) && '|' != cChar ) ||
     597           0 :         ( '+' != ( cChar = rTmp[nEndPlus - 1]) && '|' != cChar ))
     598           0 :         return false;
     599             : 
     600           0 :     SwTxtFrmInfo aInfo( m_pCurTxtFrm );
     601             : 
     602           0 :     sal_Int32 n = nSttPlus;
     603           0 :     std::vector<sal_uInt16> aPosArr;
     604             : 
     605           0 :     while (n < rTmp.getLength())
     606             :     {
     607           0 :         switch (rTmp[n])
     608             :         {
     609             :         case '-':
     610             :         case '_':
     611             :         case '=':
     612             :         case ' ':
     613             :         case '\t':
     614           0 :             break;
     615             : 
     616             :         case '+':
     617             :         case '|':
     618           0 :             aPosArr.push_back( static_cast<sal_uInt16>(aInfo.GetCharPos(n)) );
     619           0 :             break;
     620             : 
     621             :         default:
     622           0 :             return false;
     623             :         }
     624           0 :         if( ++n == nEndPlus )
     625           0 :             break;
     626             :     }
     627             : 
     628           0 :     if( 1 < aPosArr.size() )
     629             :     {
     630             :         // get the text node's alignment
     631           0 :         sal_uInt16 nColCnt = aPosArr.size() - 1;
     632           0 :         SwTwips nSttPos = aPosArr[ 0 ];
     633             :         sal_Int16 eHori;
     634           0 :         switch( m_pCurTxtNd->GetSwAttrSet().GetAdjust().GetAdjust() )
     635             :         {
     636           0 :         case SVX_ADJUST_CENTER:     eHori = text::HoriOrientation::CENTER;    break;
     637           0 :         case SVX_ADJUST_RIGHT:      eHori = text::HoriOrientation::RIGHT;     break;
     638             : 
     639             :         default:
     640           0 :             if( nSttPos )
     641             :             {
     642           0 :                 eHori = text::HoriOrientation::NONE;
     643             :                 // then - as last - we need to add the current frame width into the array
     644           0 :                 aPosArr.push_back( static_cast<sal_uInt16>(m_pCurTxtFrm->Frm().Width()) );
     645             :             }
     646             :             else
     647           0 :                 eHori = text::HoriOrientation::LEFT;
     648           0 :             break;
     649             :         }
     650             : 
     651             :         // then create a table that matches the character
     652           0 :         DelEmptyLine();
     653           0 :         SwNodeIndex aIdx( m_aDelPam.GetPoint()->nNode );
     654           0 :         m_aDelPam.Move( fnMoveForward );
     655             :         m_pDoc->InsertTable( SwInsertTableOptions( tabopts::ALL_TBL_INS_ATTR , 1 ),
     656           0 :                            *m_aDelPam.GetPoint(), 1, nColCnt, eHori,
     657           0 :                            0, &aPosArr );
     658           0 :         m_aDelPam.GetPoint()->nNode = aIdx;
     659             :     }
     660           0 :     return 1 < aPosArr.size();
     661             : }
     662             : 
     663           0 : OUString SwAutoFormat::DelLeadingBlanks( const OUString& rStr ) const
     664             : {
     665             :     sal_Int32 nL, n;
     666           0 :     for( nL = rStr.getLength(), n = 0; n < nL && IsSpace( rStr[n] ); ++n )
     667             :         ;
     668           0 :     if( n ) // no Spaces
     669           0 :         return rStr.copy(n);
     670           0 :     return rStr;
     671             : }
     672             : 
     673           0 : OUString& SwAutoFormat::DelTrailingBlanks( OUString& rStr ) const
     674             : {
     675           0 :     sal_Int32 nL = rStr.getLength(), n = nL;
     676           0 :     if( !nL )
     677           0 :         return rStr;
     678             : 
     679           0 :     while( --n && IsSpace( rStr[ n ] )  )
     680             :         ;
     681           0 :     if( n+1 != nL ) // no Spaces
     682           0 :         rStr = rStr.copy( 0, n+1 );
     683           0 :     return rStr;
     684             : }
     685             : 
     686           0 : sal_Int32 SwAutoFormat::GetLeadingBlanks( const OUString& rStr ) const
     687             : {
     688             :     sal_Int32 nL;
     689             :     sal_Int32 n;
     690             : 
     691           0 :     for( nL = rStr.getLength(), n = 0; n < nL && IsSpace( rStr[ n ] ); ++n )
     692             :         ;
     693           0 :     return n;
     694             : }
     695             : 
     696           0 : sal_Int32 SwAutoFormat::GetTrailingBlanks( const OUString& rStr ) const
     697             : {
     698           0 :     sal_Int32 nL = rStr.getLength(), n = nL;
     699           0 :     if( !nL )
     700           0 :         return 0;
     701             : 
     702           0 :     while( --n && IsSpace( rStr[ n ] )  )
     703             :         ;
     704           0 :     return ++n;
     705             : }
     706             : 
     707           0 : bool SwAutoFormat::IsFirstCharCapital( const SwTxtNode& rNd ) const
     708             : {
     709           0 :     const OUString& rTxt = rNd.GetTxt();
     710           0 :     for( sal_Int32 n = 0, nEnd = rTxt.getLength(); n < nEnd; ++n )
     711           0 :         if (!IsSpace(rTxt[n]))
     712             :         {
     713           0 :             CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().
     714           0 :                                         GetLanguage().GetLanguage() );
     715           0 :             sal_Int32 nCharType = rCC.getCharacterType( rTxt, n );
     716           0 :             return CharClass::isLetterType( nCharType ) &&
     717           0 :                    0 != ( i18n::KCharacterType::UPPER &
     718           0 :                                                     nCharType );
     719             :         }
     720           0 :     return false;
     721             : }
     722             : 
     723           0 : sal_uInt16 SwAutoFormat::GetDigitLevel( const SwTxtNode& rNd, sal_Int32& rPos,
     724             :         OUString* pPrefix, OUString* pPostfix, OUString* pNumTypes ) const
     725             : {
     726             :     // check for 1.) / 1. / 1.1.1 / (1). / (1) / ....
     727           0 :     const OUString& rTxt = rNd.GetTxt();
     728           0 :     sal_Int32 nPos = rPos;
     729           0 :     int eScan = NONE;
     730             : 
     731           0 :     sal_uInt16 nStart = 0;
     732           0 :     sal_uInt8 nDigitLvl = 0, nDigitCnt = 0;
     733             :     // count number of parenthesis to assure a sensible order is found
     734           0 :     sal_uInt16 nOpeningParentheses = 0;
     735           0 :     sal_uInt16 nClosingParentheses = 0;
     736             : 
     737           0 :     CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().GetLanguage().GetLanguage() );
     738             : 
     739           0 :     while (nPos < rTxt.getLength() && nDigitLvl < MAXLEVEL - 1)
     740             :     {
     741           0 :         const sal_Unicode cCurrentChar = rTxt[nPos];
     742           0 :         if( ('0' <= cCurrentChar &&  '9' >= cCurrentChar) ||
     743           0 :             (0xff10 <= cCurrentChar &&  0xff19 >= cCurrentChar) )
     744             :         {
     745           0 :             if( eScan & DELIM )
     746             :             {
     747           0 :                 if( eScan & CHG )   // not if it starts with a number
     748             :                 {
     749           0 :                     ++nDigitLvl;
     750           0 :                     if( pPostfix )
     751           0 :                         *pPostfix += OUString((sal_Unicode)1);
     752             :                 }
     753             : 
     754           0 :                 if( pNumTypes )
     755           0 :                     *pNumTypes += OUString((sal_Unicode)('0' + SVX_NUM_ARABIC));
     756             : 
     757           0 :                 eScan = eScan | CHG;
     758             :             }
     759           0 :             else if( pNumTypes && !(eScan & DIGIT) )
     760           0 :                 *pNumTypes += OUString((sal_Unicode)('0' + SVX_NUM_ARABIC));
     761             : 
     762           0 :             eScan &= ~DELIM;        // remvoe Delim
     763           0 :             if( 0 != (eScan & ~CHG) && DIGIT != (eScan & ~CHG))
     764           0 :                 return USHRT_MAX;
     765             : 
     766           0 :             eScan |= DIGIT;         // add Digit
     767           0 :             if( 3 == ++nDigitCnt )  // more than 2 numbers are not an enum anymore
     768           0 :                 return USHRT_MAX;
     769             : 
     770           0 :             nStart *= 10;
     771           0 :             nStart += cCurrentChar <= '9' ? cCurrentChar - '0' : cCurrentChar - 0xff10;
     772             :         }
     773           0 :         else if( rCC.isAlpha( rTxt, nPos ) )
     774             :         {
     775             :             bool bIsUpper =
     776           0 :                 0 != ( i18n::KCharacterType::UPPER &
     777           0 :                                         rCC.getCharacterType( rTxt, nPos ));
     778           0 :             sal_Unicode cLow = rCC.lowercase(rTxt, nPos, 1)[0], cNumTyp;
     779             :             int eTmpScan;
     780             : 
     781             :             // Roman numbers are "mdclxvi". Since we want to start numbering with c or d more often,
     782             :             // convert first to characters and later to roman numbers if needed.
     783             : #ifdef WITH_ALPHANUM_AS_NUMFMT
     784             :             // detection of 'c' and 'd' a ROMAN numbering should not be done here
     785             :             if( 256 > cLow  &&( (eScan & (LOWER_ROMAN|UPPER_ROMAN))
     786             :                                     ? strchr( "mdclxvi", cLow )
     787             :                                     : strchr( "mlxvi", cLow ) ))
     788             : #else
     789           0 :             if( 256 > cLow  && ( strchr( "mdclxvi", cLow ) ))
     790             : #endif
     791             :             {
     792           0 :                 if( bIsUpper )
     793           0 :                     cNumTyp = '0' + SVX_NUM_ROMAN_UPPER, eTmpScan = UPPER_ROMAN;
     794             :                 else
     795           0 :                     cNumTyp = '0' + SVX_NUM_ROMAN_LOWER, eTmpScan = LOWER_ROMAN;
     796             :             }
     797           0 :             else if( bIsUpper )
     798           0 :                 cNumTyp = '0' + SVX_NUM_CHARS_UPPER_LETTER, eTmpScan = UPPER_ALPHA;
     799             :             else
     800           0 :                 cNumTyp = '0' + SVX_NUM_CHARS_LOWER_LETTER, eTmpScan = LOWER_ALPHA;
     801             : 
     802             :             // Switch to roman numbers (only for c/d!)
     803           0 :             if( 1 == nDigitCnt && ( eScan & (UPPER_ALPHA|LOWER_ALPHA) ) &&
     804           0 :                 ( 3 == nStart || 4 == nStart) && 256 > cLow &&
     805           0 :                 strchr( "mdclxvi", cLow ) &&
     806           0 :                 (( eScan & UPPER_ALPHA ) ? (eTmpScan & (UPPER_ALPHA|UPPER_ROMAN))
     807           0 :                                          : (eTmpScan & (LOWER_ALPHA|LOWER_ROMAN))) )
     808             :             {
     809           0 :                 sal_Unicode c = '0';
     810           0 :                 nStart = 3 == nStart ? 100 : 500;
     811           0 :                 if( UPPER_ALPHA == eTmpScan )
     812           0 :                     eTmpScan = UPPER_ROMAN, c += SVX_NUM_ROMAN_UPPER;
     813             :                 else
     814           0 :                     eTmpScan = LOWER_ROMAN, c += SVX_NUM_ROMAN_LOWER;
     815             : 
     816           0 :                 ( eScan &= ~(UPPER_ALPHA|LOWER_ALPHA)) |= eTmpScan;
     817           0 :                 if( pNumTypes )
     818           0 :                     (*pNumTypes) = pNumTypes->replaceAt( pNumTypes->getLength() - 1, 1, OUString(c) );
     819             :             }
     820             : 
     821           0 :             if( eScan & DELIM )
     822             :             {
     823           0 :                 if( eScan & CHG )   // not if it starts with a number
     824             :                 {
     825           0 :                     ++nDigitLvl;
     826           0 :                     if( pPostfix )
     827           0 :                         *pPostfix += OUString((sal_Unicode)1);
     828             :                 }
     829             : 
     830           0 :                 if( pNumTypes )
     831           0 :                     *pNumTypes += OUString(cNumTyp);
     832           0 :                 eScan = eScan | CHG;
     833             :             }
     834           0 :             else if( pNumTypes && !(eScan & eTmpScan) )
     835           0 :                 *pNumTypes += OUString(cNumTyp);
     836             : 
     837           0 :             eScan &= ~DELIM;        // remove Delim
     838             : 
     839             :             // if another type is set, stop here
     840           0 :             if( 0 != ( eScan & ~CHG ) && eTmpScan != ( eScan & ~CHG ))
     841           0 :                 return USHRT_MAX;
     842             : 
     843           0 :             if( eTmpScan & (UPPER_ALPHA | LOWER_ALPHA) )
     844             :             {
     845             :                 // allow characters only if they appear once
     846           0 :                 return USHRT_MAX;
     847             :             }
     848             :             else
     849             :             {
     850             :                 // roman numbers, check if valid characters
     851             :                 sal_uInt16 nVal;
     852           0 :                 bool bError = false;
     853           0 :                 switch( cLow )
     854             :                 {
     855           0 :                 case 'm':   nVal = 1000; goto CHECK_ROMAN_1;
     856           0 :                 case 'd':   nVal =  500; goto CHECK_ROMAN_5;
     857           0 :                 case 'c':   nVal =  100; goto CHECK_ROMAN_1;
     858           0 :                 case 'l':   nVal =   50; goto CHECK_ROMAN_5;
     859           0 :                 case 'x':   nVal =   10; goto CHECK_ROMAN_1;
     860           0 :                 case 'v':   nVal =    5; goto CHECK_ROMAN_5;
     861             : 
     862             : CHECK_ROMAN_1:
     863             :                     {
     864           0 :                         int nMod5 = nStart % (nVal * 5);
     865           0 :                         int nLast = nStart % nVal;
     866           0 :                         int n10 = nVal / 10;
     867             : 
     868           0 :                         if( nMod5 == ((3 * nVal) + n10 ) ||
     869           0 :                             nMod5 == ((4 * nVal) + n10 ) ||
     870             :                             nLast == n10 )
     871           0 :                             nStart = static_cast<sal_uInt16>(nStart + (n10 * 8));
     872           0 :                         else if( nMod5 == 0 ||
     873           0 :                                  nMod5 == (1 * nVal) ||
     874           0 :                                  nMod5 == (2 * nVal) )
     875           0 :                             nStart = nStart + nVal;
     876             :                         else
     877           0 :                             bError = true;
     878             :                     }
     879           0 :                     break;
     880             : 
     881             : CHECK_ROMAN_5:
     882             :                     {
     883           0 :                         if( ( nStart / nVal ) & 1 )
     884           0 :                             bError = true;
     885             :                         else
     886             :                         {
     887           0 :                             int nMod = nStart % nVal;
     888           0 :                             int n10 = nVal / 5;
     889           0 :                             if( n10 == nMod )
     890           0 :                                 nStart = static_cast<sal_uInt16>(nStart + (3 * n10));
     891           0 :                             else if( 0 == nMod )
     892           0 :                                 nStart = nStart + nVal;
     893             :                             else
     894           0 :                                 bError = true;
     895             :                         }
     896             :                     }
     897           0 :                     break;
     898             : 
     899             :                 case 'i':
     900           0 :                         if( nStart % 5 >= 3 )
     901           0 :                             bError = true;
     902             :                         else
     903           0 :                             nStart += 1;
     904           0 :                         break;
     905             : 
     906             :                 default:
     907           0 :                     bError = true;
     908             :                 }
     909             : 
     910           0 :                 if( bError )
     911           0 :                     return USHRT_MAX;
     912             :             }
     913           0 :             eScan |= eTmpScan;          // add Digit
     914           0 :             ++nDigitCnt;
     915             :         }
     916           0 :         else if( (256 > cCurrentChar &&
     917           0 :                  strchr( ".)(", cCurrentChar )) ||
     918           0 :                  0x3002 == cCurrentChar /* Chinese trad. dot */||
     919           0 :                  0xff0e == cCurrentChar /* Japanese dot */||
     920           0 :                  0xFF08 == cCurrentChar /* opening bracket Chin./Jap.*/||
     921             :                  0xFF09 == cCurrentChar )/* closing bracket Chin./Jap. */
     922             :         {
     923           0 :             if(cCurrentChar == '(' || cCurrentChar == 0xFF09)
     924           0 :                 nOpeningParentheses++;
     925           0 :             else if(cCurrentChar == ')'|| cCurrentChar == 0xFF08)
     926           0 :                 nClosingParentheses++;
     927             :             // only if no numbers were read until here
     928           0 :             if( pPrefix && !( eScan & ( NO_DELIM | CHG )) )
     929           0 :                 *pPrefix += OUString(rTxt[nPos]);
     930           0 :             else if( pPostfix )
     931           0 :                 *pPostfix += OUString(rTxt[nPos]);
     932             : 
     933           0 :             if( NO_DELIM & eScan )
     934             :             {
     935           0 :                 eScan |= CHG;
     936           0 :                 if( pPrefix )
     937             :                     *pPrefix += OUString((sal_Unicode)1)
     938           0 :                               + OUString::number( nStart );
     939             :             }
     940           0 :             eScan &= ~NO_DELIM;     // remove Delim
     941           0 :             eScan |= DELIM;         // add Digit
     942           0 :             nDigitCnt = 0;
     943           0 :             nStart = 0;
     944             :         }
     945             :         else
     946             :             break;
     947           0 :         ++nPos;
     948             :     }
     949           0 :     if( !( CHG & eScan ) || rPos == nPos ||
     950           0 :         nPos == rTxt.getLength() || !IsSpace(rTxt[nPos]) ||
     951             :         (nOpeningParentheses > nClosingParentheses))
     952           0 :         return USHRT_MAX;
     953             : 
     954           0 :     if( (NO_DELIM & eScan) && pPrefix )     // do not forget the last one
     955           0 :         *pPrefix += OUString((sal_Unicode)1) + OUString::number( nStart );
     956             : 
     957           0 :     rPos = nPos;
     958           0 :     return nDigitLvl;       // 0 .. 9 (MAXLEVEL - 1)
     959             : }
     960             : 
     961           0 : void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
     962             : {
     963           0 :     m_aDelPam.DeleteMark();
     964           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
     965           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
     966             : 
     967             :     // keep hard tabs, alignment, language, hyphenation, DropCaps and nearly all frame attributes
     968           0 :     SfxItemSet aSet( m_pDoc->GetAttrPool(),
     969             :                         RES_PARATR_ADJUST, RES_PARATR_ADJUST,
     970             :                         RES_PARATR_TABSTOP, RES_PARATR_DROP,
     971             :                         RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
     972             :                         RES_BACKGROUND, RES_SHADOW,
     973           0 :                         0 );
     974             : 
     975           0 :     if( m_pCurTxtNd->HasSwAttrSet() )
     976             :     {
     977           0 :         aSet.Put( *m_pCurTxtNd->GetpSwAttrSet() );
     978             :         // take HeaderLine/TextBody only if centered or right aligned, otherwise only justification
     979             :         SvxAdjustItem* pAdj;
     980           0 :         if( SFX_ITEM_SET == aSet.GetItemState( RES_PARATR_ADJUST,
     981           0 :                         false, (const SfxPoolItem**)&pAdj ))
     982             :         {
     983           0 :             SvxAdjust eAdj = pAdj->GetAdjust();
     984           0 :             if( bHdLineOrText ? (SVX_ADJUST_RIGHT != eAdj &&
     985             :                                  SVX_ADJUST_CENTER != eAdj)
     986             :                               : SVX_ADJUST_BLOCK != eAdj )
     987           0 :                 aSet.ClearItem( RES_PARATR_ADJUST );
     988             :         }
     989             :     }
     990             : 
     991           0 :     m_pDoc->SetTxtFmtCollByAutoFmt( *m_aDelPam.GetPoint(), nId, &aSet );
     992           0 : }
     993             : 
     994           0 : bool SwAutoFormat::HasSelBlanks( SwPaM& rPam ) const
     995             : {
     996             :     // Is there a Blank at the beginning or end?
     997             :     // Do not delete it, it will be inserted again.
     998           0 :     SwPosition * pPos = rPam.End();
     999           0 :     sal_Int32 nBlnkPos = pPos->nContent.GetIndex();
    1000           0 :     SwTxtNode* pTxtNd = pPos->nNode.GetNode().GetTxtNode();
    1001           0 :     if (nBlnkPos && nBlnkPos-- < pTxtNd->GetTxt().getLength() &&
    1002           0 :         (' ' == pTxtNd->GetTxt()[nBlnkPos]))
    1003           0 :         pPos->nContent--;
    1004             :     else
    1005             :     {
    1006           0 :         pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint();
    1007           0 :         nBlnkPos = pPos->nContent.GetIndex();
    1008           0 :         pTxtNd = pPos->nNode.GetNode().GetTxtNode();
    1009           0 :         if (nBlnkPos < pTxtNd->GetTxt().getLength() &&
    1010           0 :             (' ' == pTxtNd->GetTxt()[nBlnkPos]))
    1011           0 :             pPos->nContent++;
    1012             :         else
    1013           0 :             return false;
    1014             :     }
    1015           0 :     return true;
    1016             : }
    1017             : 
    1018           0 : bool SwAutoFormat::HasBreakAttr( const SwTxtNode& rTxtNd ) const
    1019             : {
    1020           0 :     const SfxItemSet* pSet = rTxtNd.GetpSwAttrSet();
    1021           0 :     if( !pSet )
    1022           0 :         return false;
    1023             : 
    1024             :     const SfxPoolItem* pItem;
    1025           0 :     if( SFX_ITEM_SET == pSet->GetItemState( RES_BREAK, false, &pItem )
    1026           0 :         && SVX_BREAK_NONE != ((SvxFmtBreakItem*)pItem)->GetBreak() )
    1027           0 :         return true;
    1028             : 
    1029           0 :     if( SFX_ITEM_SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem )
    1030           0 :         && ((SwFmtPageDesc*)pItem)->GetPageDesc()
    1031           0 :         && nsUseOnPage::PD_NONE != ((SwFmtPageDesc*)pItem)->GetPageDesc()->GetUseOn() )
    1032           0 :         return true;
    1033           0 :     return false;
    1034             : }
    1035             : 
    1036             : /// Is there a dot at the end?
    1037           0 : bool SwAutoFormat::IsSentenceAtEnd( const SwTxtNode& rTxtNd ) const
    1038             : {
    1039           0 :     const OUString& rStr = rTxtNd.GetTxt();
    1040           0 :     sal_Int32 n = rStr.getLength();
    1041           0 :     if( !n )
    1042           0 :         return true;
    1043             : 
    1044           0 :     while( --n && IsSpace( rStr[ n ] ) )
    1045             :         ;
    1046           0 :     return '.' == rStr[ n ];
    1047             : }
    1048             : 
    1049             : /// Delete beginning and/or end in a node
    1050           0 : void SwAutoFormat::DeleteCurrentParagraph( bool bStart, bool bEnd )
    1051             : {
    1052           0 :     if( m_aFlags.bAFmtByInput
    1053             :         ? m_aFlags.bAFmtByInpDelSpacesAtSttEnd
    1054             :         : m_aFlags.bAFmtDelSpacesAtSttEnd )
    1055             :     {
    1056             :         // delete blanks at the end of the current and at the beginning of the next one
    1057           0 :         m_aDelPam.DeleteMark();
    1058           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1059           0 :         sal_Int32 nPos(0);
    1060           0 :         if( bStart && 0 != ( nPos = GetLeadingBlanks( m_pCurTxtNd->GetTxt() )))
    1061             :         {
    1062           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
    1063           0 :             m_aDelPam.SetMark();
    1064           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    1065           0 :             DeleteSel( m_aDelPam );
    1066           0 :             m_aDelPam.DeleteMark();
    1067             :         }
    1068           0 :         if (bEnd && m_pCurTxtNd->GetTxt().getLength() !=
    1069           0 :                     ( nPos = GetTrailingBlanks( m_pCurTxtNd->GetTxt() )) )
    1070             :         {
    1071           0 :             m_aDelPam.GetPoint()->nContent.Assign(
    1072           0 :                     m_pCurTxtNd, m_pCurTxtNd->GetTxt().getLength());
    1073           0 :             m_aDelPam.SetMark();
    1074           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    1075           0 :             DeleteSel( m_aDelPam );
    1076           0 :             m_aDelPam.DeleteMark();
    1077             :         }
    1078             :     }
    1079           0 : }
    1080             : 
    1081           0 : void SwAutoFormat::DeleteSel( SwPaM& rDelPam )
    1082             : {
    1083           0 :     if( m_aFlags.bWithRedlining )
    1084             :     {
    1085             :         // Add to Shell-Cursor-Ring so that DelPam will be moved as well!
    1086           0 :         SwPaM* pShCrsr = m_pEditShell->_GetCrsr();
    1087           0 :         SwPaM aTmp( *m_pCurTxtNd, 0, pShCrsr );
    1088             : 
    1089           0 :         Ring *pPrev = rDelPam.GetPrev();
    1090           0 :         rDelPam.MoveRingTo( pShCrsr );
    1091             : 
    1092           0 :         m_pEditShell->DeleteSel( rDelPam );
    1093             : 
    1094             :         // and remove Pam again:
    1095           0 :         Ring *p, *pNext = (Ring*)&rDelPam;
    1096           0 :         do {
    1097           0 :             p = pNext;
    1098           0 :             pNext = p->GetNext();
    1099           0 :             p->MoveTo( &rDelPam );
    1100             :         } while( p != pPrev );
    1101             : 
    1102           0 :         m_aNdIdx = aTmp.GetPoint()->nNode;
    1103           0 :         m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    1104             :     }
    1105             :     else
    1106           0 :         m_pEditShell->DeleteSel( rDelPam );
    1107           0 : }
    1108             : 
    1109           0 : bool SwAutoFormat::DeleteCurNxtPara( const OUString& rNxtPara )
    1110             : {
    1111             :     // delete blanks at the end of the current and at the beginning of the next one
    1112           0 :     m_aDelPam.DeleteMark();
    1113           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1114           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd,
    1115           0 :                     GetTrailingBlanks( m_pCurTxtNd->GetTxt() ) );
    1116           0 :     m_aDelPam.SetMark();
    1117             : 
    1118           0 :     m_aDelPam.GetPoint()->nNode++;
    1119           0 :     SwTxtNode* pTNd = m_aDelPam.GetNode()->GetTxtNode();
    1120           0 :     if( !pTNd )
    1121             :     {
    1122             :         // then delete only up to end of the paragraph
    1123           0 :         m_aDelPam.GetPoint()->nNode--;
    1124           0 :         m_aDelPam.GetPoint()->nContent = m_pCurTxtNd->GetTxt().getLength();
    1125             :     }
    1126             :     else
    1127           0 :         m_aDelPam.GetPoint()->nContent.Assign( pTNd,
    1128           0 :                             GetLeadingBlanks( rNxtPara ));
    1129             : 
    1130             :     // Is there a Blank at the beginning or end?
    1131             :     // Do not delete it, it will be inserted again.
    1132           0 :     bool bHasBlnks = HasSelBlanks( m_aDelPam );
    1133             : 
    1134           0 :     if( *m_aDelPam.GetPoint() != *m_aDelPam.GetMark() )
    1135           0 :         DeleteSel( m_aDelPam );
    1136           0 :     m_aDelPam.DeleteMark();
    1137             : 
    1138           0 :     return !bHasBlnks;
    1139             : }
    1140             : 
    1141           0 : void SwAutoFormat::DelEmptyLine( bool bTstNextPara )
    1142             : {
    1143           0 :     SetRedlineTxt( STR_AUTOFMTREDL_DEL_EMPTY_PARA );
    1144             :     // delete blanks in empty paragraph
    1145           0 :     m_aDelPam.DeleteMark();
    1146           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1147           0 :     m_aDelPam.GetPoint()->nContent.Assign(
    1148           0 :             m_pCurTxtNd, m_pCurTxtNd->GetTxt().getLength() );
    1149           0 :     m_aDelPam.SetMark();
    1150             : 
    1151           0 :     m_aDelPam.GetMark()->nNode--;
    1152           0 :     SwTxtNode* pTNd = m_aDelPam.GetNode( false )->GetTxtNode();
    1153           0 :     if( pTNd )
    1154             :         // first use the previous text node
    1155           0 :         m_aDelPam.GetMark()->nContent.Assign(pTNd, pTNd->GetTxt().getLength());
    1156           0 :     else if( bTstNextPara )
    1157             :     {
    1158             :         // then try the next (at the beginning of a Doc, table cells, borders, ...)
    1159           0 :         m_aDelPam.GetMark()->nNode += 2;
    1160           0 :         pTNd = m_aDelPam.GetNode( false )->GetTxtNode();
    1161           0 :         if( pTNd )
    1162             :         {
    1163           0 :             m_aDelPam.GetMark()->nContent.Assign( pTNd, 0 );
    1164           0 :             m_aDelPam.GetPoint()->nContent = 0;
    1165             :         }
    1166             :     }
    1167             :     else
    1168             :     {
    1169           0 :         m_aDelPam.GetMark()->nNode = m_aNdIdx;
    1170           0 :         m_aDelPam.GetMark()->nContent = 0;
    1171           0 :         pTNd = m_pCurTxtNd;
    1172             :     }
    1173           0 :     if( pTNd )
    1174           0 :         DeleteSel( m_aDelPam );
    1175             : 
    1176           0 :     m_aDelPam.DeleteMark();
    1177           0 :     ClearRedlineTxt();
    1178           0 : }
    1179             : 
    1180           0 : void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
    1181             : {
    1182           0 :     if( m_aFlags.bAFmtByInput
    1183             :         ? m_aFlags.bAFmtByInpDelSpacesBetweenLines
    1184             :         : m_aFlags.bAFmtDelSpacesBetweenLines )
    1185             :     {
    1186             :         // delete all blanks on the left and right of the indentation
    1187           0 :         m_aDelPam.DeleteMark();
    1188           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1189           0 :         m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
    1190             : 
    1191           0 :         SwTxtFrmInfo aFInfo( m_pCurTxtFrm );
    1192           0 :         aFInfo.GetSpaces( m_aDelPam, !m_aFlags.bAFmtByInput || bWithLineBreaks );
    1193             : 
    1194             :         SwPaM* pNxt;
    1195             :         do {
    1196           0 :             pNxt = (SwPaM*)m_aDelPam.GetNext();
    1197           0 :             if( pNxt->HasMark() && *pNxt->GetPoint() != *pNxt->GetMark() )
    1198             :             {
    1199           0 :                 bool bHasBlnks = HasSelBlanks( *pNxt );
    1200           0 :                 DeleteSel( *pNxt );
    1201           0 :                 if( !bHasBlnks )
    1202             :                 {
    1203           0 :                     m_pDoc->InsertString( *pNxt, OUString(' ') );
    1204             :                 }
    1205             :             }
    1206             : 
    1207           0 :             if( pNxt == &m_aDelPam )
    1208           0 :                 break;
    1209           0 :             delete pNxt;
    1210             :         } while( true );
    1211             : 
    1212           0 :         m_aDelPam.DeleteMark();
    1213             :     }
    1214           0 : }
    1215             : 
    1216             : // delete the previous paragraph
    1217           0 : void SwAutoFormat::DelPrevPara()
    1218             : {
    1219           0 :     m_aDelPam.DeleteMark();
    1220           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1221           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
    1222           0 :     m_aDelPam.SetMark();
    1223             : 
    1224           0 :     m_aDelPam.GetPoint()->nNode--;
    1225           0 :     SwTxtNode* pTNd = m_aDelPam.GetNode()->GetTxtNode();
    1226           0 :     if( pTNd )
    1227             :     {
    1228             :         // use the previous text node first
    1229           0 :         m_aDelPam.GetPoint()->nContent.Assign(pTNd, pTNd->GetTxt().getLength());
    1230           0 :         DeleteSel( m_aDelPam );
    1231             :     }
    1232           0 :     m_aDelPam.DeleteMark();
    1233           0 : }
    1234             : 
    1235           0 : void SwAutoFormat::BuildIndent()
    1236             : {
    1237           0 :     SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_INDENT );
    1238             : 
    1239             :     // read all succeeding paragraphs that belong to this indentation
    1240           0 :     bool bBreak = true;
    1241           0 :     if( m_bMoreLines )
    1242           0 :         DelMoreLinesBlanks( true );
    1243             :     else
    1244           0 :         bBreak = !IsFastFullLine( *m_pCurTxtNd ) ||
    1245           0 :                 IsBlanksInString( *m_pCurTxtNd ) ||
    1246           0 :                 IsSentenceAtEnd( *m_pCurTxtNd );
    1247           0 :     SetColl( RES_POOLCOLL_TEXT_IDENT );
    1248           0 :     if( !bBreak )
    1249             :     {
    1250           0 :         SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
    1251           0 :         const SwTxtNode* pNxtNd = GetNextNode();
    1252           0 :         if( pNxtNd && !m_bEnd )
    1253             :         {
    1254           0 :             do {
    1255           0 :                 bBreak = !IsFastFullLine( *pNxtNd ) ||
    1256           0 :                         IsBlanksInString( *pNxtNd ) ||
    1257           0 :                         IsSentenceAtEnd( *pNxtNd );
    1258           0 :                 if( DeleteCurNxtPara( pNxtNd->GetTxt() ))
    1259             :                 {
    1260           0 :                     m_pDoc->InsertString( m_aDelPam, OUString(' ') );
    1261             :                 }
    1262           0 :                 if( bBreak )
    1263           0 :                     break;
    1264           0 :                 pNxtNd = GetNextNode();
    1265           0 :             } while( CanJoin( pNxtNd ) &&
    1266           0 :                     !CalcLevel( *pNxtNd ) );
    1267             :         }
    1268             :     }
    1269           0 :     DeleteCurrentParagraph( true, true );
    1270           0 :     AutoCorrect();
    1271           0 : }
    1272             : 
    1273           0 : void SwAutoFormat::BuildTextIndent()
    1274             : {
    1275           0 :     SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT_INDENT);
    1276             :     // read all succeeding paragraphs that belong to this indentation
    1277           0 :     bool bBreak = true;
    1278           0 :     if( m_bMoreLines )
    1279           0 :         DelMoreLinesBlanks( true );
    1280             :     else
    1281           0 :         bBreak = !IsFastFullLine( *m_pCurTxtNd ) ||
    1282           0 :                     IsBlanksInString( *m_pCurTxtNd ) ||
    1283           0 :                     IsSentenceAtEnd( *m_pCurTxtNd );
    1284             : 
    1285           0 :     if( m_aFlags.bAFmtByInput )
    1286           0 :         m_pCurTxtNd->SetAutoFmtLvl( (sal_uInt8)CalcLevel( *m_pCurTxtNd ) );
    1287             : 
    1288           0 :     SetColl( RES_POOLCOLL_TEXT_MOVE );
    1289           0 :     if( !bBreak )
    1290             :     {
    1291           0 :         SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
    1292           0 :         const SwTxtNode* pNxtNd = GetNextNode();
    1293           0 :         while(  CanJoin( pNxtNd ) &&
    1294           0 :                 CalcLevel( *pNxtNd ) )
    1295             :         {
    1296           0 :             bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1297           0 :                     IsSentenceAtEnd( *pNxtNd );
    1298           0 :             if( DeleteCurNxtPara( pNxtNd->GetTxt() ) )
    1299             :             {
    1300           0 :                 m_pDoc->InsertString( m_aDelPam, OUString(' ') );
    1301             :             }
    1302           0 :             if( bBreak )
    1303           0 :                 break;
    1304           0 :             pNxtNd = GetNextNode();
    1305             :         }
    1306             :     }
    1307           0 :     DeleteCurrentParagraph( true, true );
    1308           0 :     AutoCorrect();
    1309           0 : }
    1310             : 
    1311           0 : void SwAutoFormat::BuildText()
    1312             : {
    1313           0 :     SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT );
    1314             :     // read all succeeding paragraphs that belong to this text without indentation
    1315           0 :     bool bBreak = true;
    1316           0 :     if( m_bMoreLines )
    1317           0 :         DelMoreLinesBlanks();
    1318             :     else
    1319           0 :         bBreak = !IsFastFullLine( *m_pCurTxtNd ) ||
    1320           0 :                     IsBlanksInString( *m_pCurTxtNd ) ||
    1321           0 :                     IsSentenceAtEnd( *m_pCurTxtNd );
    1322           0 :     SetColl( RES_POOLCOLL_TEXT, true );
    1323           0 :     if( !bBreak )
    1324             :     {
    1325           0 :         SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
    1326           0 :         const SwTxtNode* pNxtNd = GetNextNode();
    1327           0 :         while(  CanJoin( pNxtNd ) &&
    1328           0 :                 !CalcLevel( *pNxtNd ) )
    1329             :         {
    1330           0 :             bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1331           0 :                     IsSentenceAtEnd( *pNxtNd );
    1332           0 :             if( DeleteCurNxtPara( pNxtNd->GetTxt() ) )
    1333             :             {
    1334           0 :                 m_pDoc->InsertString( m_aDelPam, OUString(' ') );
    1335             :             }
    1336           0 :             if( bBreak )
    1337           0 :                 break;
    1338           0 :             const SwTxtNode* pCurrNode = pNxtNd;
    1339           0 :             pNxtNd = GetNextNode();
    1340           0 :             if(!pNxtNd || pCurrNode == pNxtNd)
    1341             :                 break;
    1342             :         }
    1343             :     }
    1344           0 :     DeleteCurrentParagraph( true, true );
    1345           0 :     AutoCorrect();
    1346           0 : }
    1347             : 
    1348           0 : void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
    1349             : {
    1350           0 :     SetRedlineTxt( STR_AUTOFMTREDL_SET_NUMBULET );
    1351             : 
    1352           0 :     bool bBreak = true;
    1353             : 
    1354             :     // first, determine current indentation and frame width
    1355           0 :     SwTwips nFrmWidth = m_pCurTxtFrm->Prt().Width();;
    1356             :     SwTwips nLeftTxtPos;
    1357             :     {
    1358           0 :         sal_Int32 nPos(0);
    1359           0 :         while (nPos < m_pCurTxtNd->GetTxt().getLength() &&
    1360           0 :                IsSpace(m_pCurTxtNd->GetTxt()[nPos]))
    1361             :         {
    1362           0 :             ++nPos;
    1363             :         }
    1364             : 
    1365           0 :         SwTxtFrmInfo aInfo( m_pCurTxtFrm );
    1366           0 :         nLeftTxtPos = aInfo.GetCharPos(nPos);
    1367           0 :         nLeftTxtPos -= m_pCurTxtNd->GetSwAttrSet().GetLRSpace().GetLeft();
    1368             :     }
    1369             : 
    1370           0 :     if( m_bMoreLines )
    1371           0 :         DelMoreLinesBlanks();
    1372             :     else
    1373           0 :         bBreak = !IsFastFullLine( *m_pCurTxtNd ) ||
    1374           0 :                     IsBlanksInString( *m_pCurTxtNd ) ||
    1375           0 :                     IsSentenceAtEnd( *m_pCurTxtNd );
    1376           0 :     sal_Bool bRTL = m_pEditShell->IsInRightToLeftText();
    1377           0 :     DeleteCurrentParagraph( true, true );
    1378             : 
    1379           0 :     bool bChgBullet = false, bChgEnum = false;
    1380           0 :     sal_Int32 nAutoCorrPos = 0;
    1381             : 
    1382             :     // if numbering is set, get the current one
    1383             :     SwNumRule aRule( m_pDoc->GetUniqueNumRuleName(),
    1384             :                      // #i89178#
    1385           0 :                      numfunc::GetDefaultPositionAndSpaceMode() );
    1386             : 
    1387           0 :     const SwNumRule* pCur = 0;
    1388           0 :     if( m_aFlags.bSetNumRule && 0 != (pCur = m_pCurTxtNd->GetNumRule()) )
    1389           0 :         aRule = *pCur;
    1390             : 
    1391             :     // replace bullet character with defined one
    1392           0 :     const OUString& rStr = m_pCurTxtNd->GetTxt();
    1393           0 :     sal_Int32 nTxtStt = 0;
    1394             :     const sal_Unicode* pFndBulletChr;
    1395           0 :     if( m_aFlags.bChgEnumNum &&
    1396           0 :         2 < rStr.getLength() &&
    1397           0 :         0 != ( pFndBulletChr = StrChr( pBulletChar, rStr[ nTxtStt ] ))
    1398           0 :         && IsSpace( rStr[ nTxtStt + 1 ] ) )
    1399             :     {
    1400           0 :         if( m_aFlags.bAFmtByInput )
    1401             :         {
    1402           0 :             if( m_aFlags.bSetNumRule )
    1403             :             {
    1404             :                 SwCharFmt* pCFmt = m_pDoc->GetCharFmtFromPool(
    1405           0 :                                             RES_POOLCHR_BUL_LEVEL );
    1406           0 :                 bChgBullet = true;
    1407             :                 // Was the format already somewhere adjusted?
    1408           0 :                 if( !aRule.GetNumFmt( nLvl ) )
    1409             :                 {
    1410           0 :                     int nBulletPos = pFndBulletChr - pBulletChar;
    1411             :                     sal_Unicode cBullChar;
    1412           0 :                     const Font* pBullFnt( 0 );
    1413           0 :                     if( nBulletPos < cnPosEnDash )
    1414             :                     {
    1415           0 :                         cBullChar = m_aFlags.cBullet;
    1416           0 :                         pBullFnt = &m_aFlags.aBulletFont;
    1417             :                     }
    1418             :                     else
    1419             :                     {
    1420             :                         cBullChar = nBulletPos < cnPosEmDash
    1421             :                                         ? cStarSymbolEnDash
    1422           0 :                                         : cStarSymbolEmDash;
    1423             :                         // #i63395#
    1424             :                         // Only apply user defined default bullet font
    1425           0 :                         if ( numfunc::IsDefBulletFontUserDefined() )
    1426             :                         {
    1427           0 :                             pBullFnt = &numfunc::GetDefBulletFont();
    1428             :                         }
    1429             :                     }
    1430             : 
    1431           0 :                     sal_uInt16 nAbsPos = lBullIndent;
    1432             :                     sal_uInt16 nSpaceSteps = nLvl
    1433           0 :                                             ? sal_uInt16(nLeftTxtPos / nLvl)
    1434           0 :                                             : lBullIndent;
    1435           0 :                     for( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nAbsPos = nAbsPos + nSpaceSteps )
    1436             :                     {
    1437           0 :                         SwNumFmt aFmt( aRule.Get( n ) );
    1438           0 :                         aFmt.SetBulletFont( pBullFnt );
    1439           0 :                         aFmt.SetBulletChar( cBullChar );
    1440           0 :                         aFmt.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
    1441             :                         // #i93908# clear suffix for bullet lists
    1442           0 :                         aFmt.SetPrefix(OUString());
    1443           0 :                         aFmt.SetSuffix(OUString());
    1444           0 :                         aFmt.SetFirstLineOffset( lBullFirstLineOffset );
    1445           0 :                         aFmt.SetAbsLSpace( nAbsPos );
    1446           0 :                         if( !aFmt.GetCharFmt() )
    1447           0 :                             aFmt.SetCharFmt( pCFmt );
    1448           0 :                         if( bRTL )
    1449           0 :                             aFmt.SetNumAdjust( SVX_ADJUST_RIGHT );
    1450             : 
    1451           0 :                         aRule.Set( n, aFmt );
    1452             : 
    1453           0 :                         if( n == nLvl &&
    1454           0 :                             nFrmWidth < ( nSpaceSteps * MAXLEVEL ) )
    1455           0 :                             nSpaceSteps = static_cast<sal_uInt16>(( nFrmWidth - nLeftTxtPos ) /
    1456           0 :                                                 ( MAXLEVEL - nLvl ));
    1457           0 :                     }
    1458             :                 }
    1459             :             }
    1460             :         }
    1461             :         else
    1462             :         {
    1463           0 :             bChgBullet = true;
    1464           0 :             SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_BUL_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 )) );
    1465             :         }
    1466             :     }
    1467             :     else
    1468             :     {
    1469             :         // Then it is a numbering
    1470             : 
    1471             :         //JP 21.11.97: The NumLevel is either the DigitLevel or, if the latter is not existent or 0,
    1472             :         //             it is determined by the indentation level.
    1473             : 
    1474           0 :         OUString aPostfix, aPrefix, aNumTypes;
    1475           0 :         if( USHRT_MAX != ( nDigitLevel = GetDigitLevel( *m_pCurTxtNd, nTxtStt,
    1476           0 :                                         &aPrefix, &aPostfix, &aNumTypes )) )
    1477             :         {
    1478           0 :             bChgEnum = true;
    1479             : 
    1480             :             // Level 0 and Indentation, determine level by left indentation and default NumIndent
    1481           0 :             if( !nDigitLevel && nLeftTxtPos )
    1482           0 :                 nLvl = std::min( sal_uInt16( nLeftTxtPos / lNumIndent ),
    1483           0 :                             sal_uInt16( MAXLEVEL - 1 ) );
    1484             :             else
    1485           0 :                 nLvl = nDigitLevel;
    1486             :         }
    1487             : 
    1488           0 :         if( bChgEnum && m_aFlags.bSetNumRule )
    1489             :         {
    1490           0 :             if( !pCur )         // adjust NumRule if it is new
    1491             :             {
    1492             :                 SwCharFmt* pCFmt = m_pDoc->GetCharFmtFromPool(
    1493           0 :                                             RES_POOLCHR_NUM_LEVEL );
    1494           0 :                 if( !nDigitLevel )
    1495             :                 {
    1496           0 :                     SwNumFmt aFmt( aRule.Get( nLvl ) );
    1497             :                     aFmt.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( 1,
    1498           0 :                                             (sal_Unicode)1 ).toInt32()));
    1499           0 :                     aFmt.SetPrefix( aPrefix.getToken( 0, (sal_Unicode)1 ));
    1500           0 :                     aFmt.SetSuffix( aPostfix.getToken( 0, (sal_Unicode)1 ));
    1501           0 :                     aFmt.SetIncludeUpperLevels( 0 );
    1502             : 
    1503           0 :                     if( !aFmt.GetCharFmt() )
    1504           0 :                         aFmt.SetCharFmt( pCFmt );
    1505             : 
    1506           0 :                     if( !aNumTypes.isEmpty() )
    1507           0 :                         aFmt.SetNumberingType(aNumTypes[ 0 ] - '0');
    1508             : 
    1509           0 :                     if( bRTL )
    1510           0 :                         aFmt.SetNumAdjust( SVX_ADJUST_RIGHT );
    1511           0 :                     aRule.Set( nLvl, aFmt );
    1512             :                 }
    1513             :                 else
    1514             :                 {
    1515           0 :                     sal_uInt16 nSpaceSteps = nLvl ? sal_uInt16(nLeftTxtPos / nLvl) : 0;
    1516             :                     sal_uInt8 n;
    1517           0 :                     for( n = 0; n <= nLvl; ++n )
    1518             :                     {
    1519           0 :                         SwNumFmt aFmt( aRule.Get( n ) );
    1520             : 
    1521           0 :                         aFmt.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( n+1,
    1522           0 :                                                     (sal_Unicode)1 ).toInt32() ));
    1523           0 :                         if( !n )
    1524           0 :                             aFmt.SetPrefix( aPrefix.getToken( n, (sal_Unicode)1 ));
    1525           0 :                         aFmt.SetSuffix( aPostfix.getToken( n, (sal_Unicode)1 ));
    1526           0 :                         aFmt.SetIncludeUpperLevels( MAXLEVEL );
    1527           0 :                         if( n < aNumTypes.getLength() )
    1528           0 :                             aFmt.SetNumberingType((aNumTypes[ n ] - '0'));
    1529             : 
    1530             :                         aFmt.SetAbsLSpace( sal_uInt16( nSpaceSteps * n )
    1531           0 :                                             + lNumIndent );
    1532             : 
    1533           0 :                         if( !aFmt.GetCharFmt() )
    1534           0 :                             aFmt.SetCharFmt( pCFmt );
    1535           0 :                         if( bRTL )
    1536           0 :                             aFmt.SetNumAdjust( SVX_ADJUST_RIGHT );
    1537             : 
    1538           0 :                         aRule.Set( n, aFmt );
    1539           0 :                     }
    1540             : 
    1541             :                     // Does it fit completely into the frame?
    1542           0 :                     bool bDefStep = nFrmWidth < (nSpaceSteps * MAXLEVEL);
    1543           0 :                     for( ; n < MAXLEVEL; ++n )
    1544             :                     {
    1545           0 :                         SwNumFmt aFmt( aRule.Get( n ) );
    1546           0 :                         aFmt.SetIncludeUpperLevels( MAXLEVEL );
    1547           0 :                         if( bDefStep )
    1548             :                             aFmt.SetAbsLSpace( sal_uInt16( (nLeftTxtPos +
    1549           0 :                                 SwNumRule::GetNumIndent(static_cast<sal_uInt8>(n-nLvl)))));
    1550             :                         else
    1551             :                             aFmt.SetAbsLSpace( sal_uInt16( nSpaceSteps * n )
    1552           0 :                                                 + lNumIndent );
    1553           0 :                         aRule.Set( n, aFmt );
    1554           0 :                     }
    1555             :                 }
    1556           0 :             }
    1557             :         }
    1558           0 :         else if( !m_aFlags.bAFmtByInput )
    1559           0 :             SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_NUM_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 ) ));
    1560             :         else
    1561           0 :             bChgEnum = false;
    1562             :     }
    1563             : 
    1564           0 :     if ( bChgEnum || bChgBullet )
    1565             :     {
    1566           0 :         m_aDelPam.DeleteMark();
    1567           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1568             : 
    1569           0 :         if( m_aFlags.bSetNumRule )
    1570             :         {
    1571           0 :             if( m_aFlags.bAFmtByInput )
    1572             :             {
    1573           0 :                 m_aDelPam.SetMark();
    1574           0 :                 m_aDelPam.GetMark()->nNode++;
    1575           0 :                 m_aDelPam.GetNode(false)->GetTxtNode()->SetAttrListLevel( nLvl );
    1576             :             }
    1577             : 
    1578           0 :             m_pCurTxtNd->SetAttrListLevel(nLvl);
    1579           0 :             m_pCurTxtNd->SetNumLSpace( true );
    1580             : 
    1581             :             // start new list
    1582           0 :             m_pDoc->SetNumRule( m_aDelPam, aRule, true );
    1583           0 :             m_aDelPam.DeleteMark();
    1584             : 
    1585           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
    1586             :         }
    1587             :         else
    1588           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd,
    1589           0 :                         bChgEnum ? nTxtStt : 0 );
    1590           0 :         m_aDelPam.SetMark();
    1591             : 
    1592           0 :         if ( bChgBullet )
    1593           0 :             nTxtStt += 2;
    1594             : 
    1595           0 :         while( nTxtStt < rStr.getLength() && IsSpace( rStr[ nTxtStt ] ))
    1596           0 :             nTxtStt++;
    1597             : 
    1598           0 :         m_aDelPam.GetPoint()->nContent = nTxtStt;
    1599           0 :         DeleteSel( m_aDelPam );
    1600             : 
    1601           0 :         if( !m_aFlags.bSetNumRule )
    1602             :         {
    1603           0 :             OUString sChgStr('\t');
    1604           0 :             if( bChgBullet )
    1605           0 :                 sChgStr = OUString( m_aFlags.cBullet ) + sChgStr;
    1606           0 :             m_pDoc->InsertString( m_aDelPam, sChgStr );
    1607             : 
    1608           0 :             SfxItemSet aSet( m_pDoc->GetAttrPool(), aTxtNodeSetRange );
    1609           0 :             if( bChgBullet )
    1610             :             {
    1611           0 :                 m_aDelPam.GetPoint()->nContent = 0;
    1612           0 :                 m_aDelPam.SetMark();
    1613           0 :                 m_aDelPam.GetMark()->nContent = 1;
    1614             :                 SetAllScriptItem( aSet,
    1615             :                      SvxFontItem( m_aFlags.aBulletFont.GetFamily(),
    1616           0 :                                   m_aFlags.aBulletFont.GetName(),
    1617           0 :                                   m_aFlags.aBulletFont.GetStyleName(),
    1618             :                                   m_aFlags.aBulletFont.GetPitch(),
    1619           0 :                                   m_aFlags.aBulletFont.GetCharSet(),
    1620           0 :                                   RES_CHRATR_FONT ) );
    1621           0 :                 m_pDoc->SetFmtItemByAutoFmt( m_aDelPam, aSet );
    1622           0 :                 m_aDelPam.DeleteMark();
    1623           0 :                 nAutoCorrPos = 2;
    1624           0 :                 aSet.ClearItem();
    1625             :             }
    1626           0 :             SvxTabStopItem aTStops( RES_PARATR_TABSTOP );
    1627           0 :             aTStops.Insert( SvxTabStop( 0 ) );
    1628           0 :             aSet.Put( aTStops );
    1629           0 :             m_pDoc->SetFmtItemByAutoFmt( m_aDelPam, aSet );
    1630             :         }
    1631             :     }
    1632             : 
    1633           0 :     if( bBreak )
    1634             :     {
    1635           0 :         AutoCorrect( nAutoCorrPos );       /* Offset due to Bullet + Tab */
    1636           0 :         return;
    1637             :     }
    1638             : 
    1639           0 :     const SwTxtNode* pNxtNd = GetNextNode();
    1640           0 :     while( CanJoin( pNxtNd ) &&
    1641           0 :             nLvl == CalcLevel( *pNxtNd ) )
    1642             :     {
    1643           0 :         SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
    1644           0 :         bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1645           0 :                 IsSentenceAtEnd( *pNxtNd );
    1646           0 :         if( DeleteCurNxtPara( pNxtNd->GetTxt() ) )
    1647             :         {
    1648           0 :             m_pDoc->InsertString( m_aDelPam, OUString(' ') );
    1649             :         }
    1650           0 :         if( bBreak )
    1651           0 :             break;
    1652           0 :         const SwTxtNode* pCurrNode = pNxtNd;
    1653           0 :         pNxtNd = GetNextNode();
    1654           0 :         if(!pNxtNd || pCurrNode == pNxtNd)
    1655             :             break;
    1656             :     }
    1657           0 :     DeleteCurrentParagraph( false, true );
    1658           0 :     AutoCorrect( nAutoCorrPos );
    1659             : }
    1660             : 
    1661           0 : void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
    1662             : {
    1663           0 :     SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_NEG_INDENT );
    1664             :     // Test of contraposition (n words, divided by spaces/tabs, with same indentation in 2nd line)
    1665             : 
    1666             :     // read all succeeding paragraphs that belong to this enumeration
    1667           0 :     bool bBreak = true;
    1668           0 :     sal_Int32 nSpacePos = 0;
    1669           0 :     const sal_Int32 nTxtPos = GetBigIndent( nSpacePos );
    1670           0 :     if( m_bMoreLines )
    1671           0 :         DelMoreLinesBlanks( true );
    1672             :     else
    1673           0 :         bBreak = !IsFastFullLine( *m_pCurTxtNd ) ||
    1674           0 :                     ( !nTxtPos && IsBlanksInString( *m_pCurTxtNd )) ||
    1675           0 :                     IsSentenceAtEnd( *m_pCurTxtNd );
    1676             : 
    1677             :     SetColl( static_cast<sal_uInt16>( nTxtPos
    1678             :                 ? RES_POOLCOLL_CONFRONTATION
    1679           0 :                 : RES_POOLCOLL_TEXT_NEGIDENT ) );
    1680             : 
    1681           0 :     if( nTxtPos )
    1682             :     {
    1683           0 :         const OUString& rStr = m_pCurTxtNd->GetTxt();
    1684           0 :         bool bInsTab = true;
    1685             : 
    1686           0 :         if ('\t' == rStr[nSpacePos+1]) // leave tab alone
    1687             :         {
    1688           0 :             --nSpacePos;
    1689           0 :             bInsTab = false;
    1690             :         }
    1691             : 
    1692           0 :         sal_Int32 nSpaceStt = nSpacePos;
    1693           0 :         while (nSpaceStt && IsSpace(rStr[--nSpaceStt]))
    1694             :             ;
    1695           0 :         ++nSpaceStt;
    1696             : 
    1697           0 :         if (bInsTab && '\t' == rStr[nSpaceStt]) // leave tab alone
    1698             :         {
    1699           0 :             ++nSpaceStt;
    1700           0 :             bInsTab = false;
    1701             :         }
    1702             : 
    1703           0 :         m_aDelPam.DeleteMark();
    1704           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1705           0 :         m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, nSpacePos );
    1706             : 
    1707             :         // delete old Spaces, etc.
    1708           0 :         if( nSpaceStt < nSpacePos )
    1709             :         {
    1710           0 :             m_aDelPam.SetMark();
    1711           0 :             m_aDelPam.GetMark()->nContent = nSpaceStt;
    1712           0 :             DeleteSel( m_aDelPam );
    1713           0 :             if( bInsTab )
    1714             :             {
    1715           0 :                 m_pDoc->InsertString( m_aDelPam, OUString('\t') );
    1716             :             }
    1717             :         }
    1718             :     }
    1719             : 
    1720           0 :     if( !bBreak )
    1721             :     {
    1722           0 :         SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES );
    1723           0 :         SwTxtFrmInfo aFInfo( m_pCurTxtFrm );
    1724           0 :         const SwTxtNode* pNxtNd = GetNextNode();
    1725           0 :         while(  CanJoin( pNxtNd ) &&
    1726             :                 20 < std::abs( (long)(nSpaces - aFInfo.SetFrm(
    1727           0 :                                 GetFrm( *pNxtNd ) ).GetLineStart() ))
    1728             :             )
    1729             :         {
    1730           0 :             bBreak = !IsFastFullLine( *pNxtNd ) ||
    1731           0 :                     IsBlanksInString( *pNxtNd ) ||
    1732           0 :                     IsSentenceAtEnd( *pNxtNd );
    1733           0 :             if( DeleteCurNxtPara( pNxtNd->GetTxt() ) )
    1734             :             {
    1735           0 :                 m_pDoc->InsertString( m_aDelPam, OUString(' ') );
    1736             :             }
    1737           0 :             if( bBreak )
    1738           0 :                 break;
    1739           0 :             pNxtNd = GetNextNode();
    1740             :         }
    1741             :     }
    1742           0 :     DeleteCurrentParagraph( true, true );
    1743           0 :     AutoCorrect();
    1744           0 : }
    1745             : 
    1746           0 : void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl )
    1747             : {
    1748           0 :     if( m_aFlags.bWithRedlining )
    1749             :     {
    1750           0 :         OUString sTxt(SwViewShell::GetShellRes()->GetAutoFmtNameLst()[
    1751           0 :                                     STR_AUTOFMTREDL_SET_TMPL_HEADLINE ] );
    1752           0 :         sTxt = sTxt.replaceAll( "$(ARG1)", OUString::number( nLvl + 1 ) );
    1753           0 :         m_pDoc->SetAutoFmtRedlineComment( &sTxt );
    1754             :     }
    1755             : 
    1756           0 :     SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true );
    1757           0 :     if( m_aFlags.bAFmtByInput )
    1758             :     {
    1759           0 :         SwTxtFmtColl& rNxtColl = m_pCurTxtNd->GetTxtColl()->GetNextTxtFmtColl();
    1760             : 
    1761           0 :         DelPrevPara();
    1762             : 
    1763           0 :         DeleteCurrentParagraph( true, false );
    1764           0 :         (void)DeleteCurNxtPara( OUString() );
    1765             : 
    1766           0 :         m_aDelPam.DeleteMark();
    1767           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx.GetIndex() + 1;
    1768           0 :         m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetCntntNode(), 0 );
    1769           0 :         m_pDoc->SetTxtFmtColl( m_aDelPam, &rNxtColl );
    1770             :     }
    1771             :     else
    1772             :     {
    1773           0 :         DeleteCurrentParagraph( true, true );
    1774           0 :         AutoCorrect();
    1775             :     }
    1776           0 : }
    1777             : 
    1778             : /// Start autocorrection for the current TextNode
    1779           0 : void SwAutoFormat::AutoCorrect( sal_Int32 nPos )
    1780             : {
    1781           0 :     SvxAutoCorrect* pATst = SvxAutoCorrCfg::Get().GetAutoCorrect();
    1782           0 :     long aSvxFlags = pATst->GetFlags( );
    1783           0 :     bool bReplaceQuote = ( aSvxFlags & ChgQuotes ) > 0;
    1784           0 :     bool bReplaceSglQuote = ( aSvxFlags & ChgSglQuotes ) > 0;
    1785             : 
    1786           0 :     if( m_aFlags.bAFmtByInput ||
    1787           0 :         (!m_aFlags.bAutoCorrect && !bReplaceQuote && !bReplaceSglQuote &&
    1788           0 :         !m_aFlags.bCptlSttSntnc && !m_aFlags.bCptlSttWrd &&
    1789           0 :         !m_aFlags.bChgOrdinalNumber &&
    1790           0 :         !m_aFlags.bChgToEnEmDash && !m_aFlags.bSetINetAttr &&
    1791           0 :         !m_aFlags.bChgWeightUnderl && !m_aFlags.bAddNonBrkSpace) )
    1792           0 :         return;
    1793             : 
    1794           0 :     const OUString* pTxt = &m_pCurTxtNd->GetTxt();
    1795           0 :     if (nPos >= pTxt->getLength())
    1796           0 :         return;
    1797             : 
    1798           0 :     bool bGetLanguage = m_aFlags.bChgOrdinalNumber ||
    1799           0 :                         m_aFlags.bChgToEnEmDash || m_aFlags.bSetINetAttr ||
    1800           0 :                         m_aFlags.bCptlSttWrd || m_aFlags.bCptlSttSntnc ||
    1801           0 :                         m_aFlags.bAddNonBrkSpace;
    1802             : 
    1803           0 :     m_aDelPam.DeleteMark();
    1804           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1805           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTxtNd, 0 );
    1806             : 
    1807           0 :     SwAutoCorrDoc aACorrDoc( *m_pEditShell, m_aDelPam );
    1808             : 
    1809           0 :     SwTxtFrmInfo aFInfo( 0 );
    1810             : 
    1811           0 :     sal_Int32 nSttPos, nLastBlank = nPos;
    1812           0 :     sal_Bool bFirst = m_aFlags.bCptlSttSntnc, bFirstSent = bFirst;
    1813           0 :     sal_Unicode cChar = 0;
    1814             : 
    1815           0 :     CharClass& rAppCC = GetAppCharClass();
    1816             : 
    1817           0 :     do {
    1818           0 :         while (nPos < pTxt->getLength() && IsSpace(cChar = (*pTxt)[nPos]))
    1819           0 :             ++nPos;
    1820           0 :         if (nPos == pTxt->getLength())
    1821           0 :             break;      // das wars
    1822             : 
    1823           0 :         if( ( ( bReplaceQuote && '\"' == cChar ) ||
    1824           0 :               ( bReplaceSglQuote && '\'' == cChar ) ) &&
    1825           0 :             (!nPos || ' ' == (*pTxt)[nPos-1]))
    1826             :         {
    1827             : 
    1828             :             // beachte: Sonderfall Symbolfonts !!!
    1829           0 :             if( !aFInfo.GetFrm() )
    1830           0 :                 aFInfo.SetFrm( GetFrm( *m_pCurTxtNd ) );
    1831           0 :             if( !aFInfo.IsBullet( nPos ))
    1832             :             {
    1833           0 :                 SetRedlineTxt( STR_AUTOFMTREDL_TYPO );
    1834           0 :                 m_aDelPam.GetPoint()->nContent = nPos;
    1835           0 :                 bool bSetHardBlank = false;
    1836             : 
    1837             :                 OUString sReplace( pATst->GetQuote( aACorrDoc,
    1838           0 :                                     nPos, cChar, true ));
    1839             : 
    1840           0 :                 m_aDelPam.SetMark();
    1841           0 :                 m_aDelPam.GetPoint()->nContent = nPos+1;
    1842           0 :                 if( 2 == sReplace.getLength() && ' ' == sReplace[ 1 ])
    1843             :                 {
    1844           0 :                     sReplace = sReplace.copy( 0, 1 );
    1845           0 :                     bSetHardBlank = true;
    1846             :                 }
    1847           0 :                 m_pDoc->ReplaceRange( m_aDelPam, sReplace, false );
    1848             : 
    1849           0 :                 if( m_aFlags.bWithRedlining )
    1850             :                 {
    1851           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1852           0 :                     m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    1853           0 :                     pTxt = &m_pCurTxtNd->GetTxt();
    1854           0 :                     m_aDelPam.SetMark();
    1855           0 :                     aFInfo.SetFrm( 0 );
    1856             :                 }
    1857             : 
    1858           0 :                 nPos += sReplace.getLength() - 1;
    1859           0 :                 m_aDelPam.DeleteMark();
    1860           0 :                 if( bSetHardBlank )
    1861             :                 {
    1862           0 :                     m_pDoc->InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
    1863           0 :                     ++nPos;
    1864           0 :                 }
    1865             :             }
    1866             :         }
    1867             : 
    1868           0 :         bool bCallACorr = false;
    1869           0 :         int bBreak = 0;
    1870           0 :         if (nPos && IsSpace((*pTxt)[nPos-1]))
    1871           0 :             nLastBlank = nPos;
    1872           0 :         for (nSttPos = nPos; !bBreak && nPos < pTxt->getLength(); ++nPos)
    1873           0 :             switch (cChar = (*pTxt)[nPos])
    1874             :             {
    1875             :             case '\"':
    1876             :             case '\'':
    1877           0 :                 if( ( cChar == '\"' && bReplaceQuote ) || ( cChar == '\'' && bReplaceSglQuote ) )
    1878             :                 {
    1879             :                     // consider Symbolfonts!
    1880           0 :                     if( !aFInfo.GetFrm() )
    1881           0 :                         aFInfo.SetFrm( GetFrm( *m_pCurTxtNd ) );
    1882           0 :                     if( !aFInfo.IsBullet( nPos ))
    1883             :                     {
    1884           0 :                         SetRedlineTxt( STR_AUTOFMTREDL_TYPO );
    1885           0 :                         bool bSetHardBlank = false;
    1886           0 :                         m_aDelPam.GetPoint()->nContent = nPos;
    1887             :                         OUString sReplace( pATst->GetQuote( aACorrDoc,
    1888           0 :                                                     nPos, cChar, false ));
    1889             : 
    1890           0 :                         if( 2 == sReplace.getLength() && ' ' == sReplace[ 0 ])
    1891             :                         {
    1892           0 :                             sReplace = sReplace.copy( 1 );
    1893           0 :                             bSetHardBlank = true;
    1894             :                         }
    1895             : 
    1896           0 :                         m_aDelPam.SetMark();
    1897           0 :                         m_aDelPam.GetPoint()->nContent = nPos+1;
    1898           0 :                         m_pDoc->ReplaceRange( m_aDelPam, sReplace, false );
    1899             : 
    1900           0 :                         if( m_aFlags.bWithRedlining )
    1901             :                         {
    1902           0 :                             m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1903           0 :                             m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    1904           0 :                             pTxt = &m_pCurTxtNd->GetTxt();
    1905           0 :                             m_aDelPam.SetMark();
    1906           0 :                             m_aDelPam.DeleteMark();
    1907           0 :                             aFInfo.SetFrm( 0 );
    1908             :                         }
    1909             : 
    1910           0 :                         nPos += sReplace.getLength() - 1;
    1911           0 :                         m_aDelPam.DeleteMark();
    1912             : 
    1913           0 :                         if( bSetHardBlank )
    1914             :                         {
    1915           0 :                             m_aDelPam.GetPoint()->nContent = nPos;
    1916           0 :                             m_pDoc->InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
    1917           0 :                             m_aDelPam.GetPoint()->nContent = ++nPos;
    1918           0 :                         }
    1919             :                     }
    1920             :                 }
    1921           0 :                 break;
    1922             :             case '*':
    1923             :             case '_':
    1924           0 :                 if( m_aFlags.bChgWeightUnderl )
    1925             :                 {
    1926             :                     // consider Symbolfonts!
    1927           0 :                     if( !aFInfo.GetFrm() )
    1928           0 :                         aFInfo.SetFrm( GetFrm( *m_pCurTxtNd ) );
    1929           0 :                     if( !aFInfo.IsBullet( nPos ))
    1930             :                     {
    1931             :                         SetRedlineTxt( '*' == cChar
    1932             :                                             ? STR_AUTOFMTREDL_BOLD
    1933           0 :                                             : STR_AUTOFMTREDL_UNDER );
    1934             : 
    1935           0 :                         sal_Unicode cBlank = nSttPos ? (*pTxt)[nSttPos - 1] : 0;
    1936           0 :                         m_aDelPam.GetPoint()->nContent = nPos;
    1937             : 
    1938           0 :                         if( pATst->FnChgWeightUnderl( aACorrDoc, *pTxt,
    1939           0 :                                                             nSttPos, nPos ))
    1940             :                         {
    1941           0 :                             if( m_aFlags.bWithRedlining )
    1942             :                             {
    1943           0 :                                 m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1944           0 :                                 m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    1945           0 :                                 pTxt = &m_pCurTxtNd->GetTxt();
    1946           0 :                                 m_aDelPam.SetMark();
    1947           0 :                                 m_aDelPam.DeleteMark();
    1948           0 :                                 aFInfo.SetFrm( 0 );
    1949             :                             }
    1950             :                             //#125102# in case of the mode REDLINE_SHOW_DELETE the ** are still contained in pTxt
    1951           0 :                             if(0 == (m_pDoc->GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_DELETE))
    1952           0 :                                 nPos = m_aDelPam.GetPoint()->nContent.GetIndex() - 1;
    1953             :                             // Was a character deleted before starting?
    1954           0 :                             if (cBlank && cBlank != (*pTxt)[nSttPos - 1])
    1955           0 :                                 --nSttPos;
    1956             :                         }
    1957             :                     }
    1958             :                 }
    1959           0 :                 break;
    1960             :             case '/':
    1961           0 :                 if ( m_aFlags.bAddNonBrkSpace )
    1962             :                 {
    1963             :                     LanguageType eLang = bGetLanguage
    1964           0 :                                            ? m_pCurTxtNd->GetLang( nSttPos )
    1965           0 :                                            : LANGUAGE_SYSTEM;
    1966             : 
    1967           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_NON_BREAK_SPACE );
    1968           0 :                     if ( pATst->FnAddNonBrkSpace( aACorrDoc, *pTxt, nSttPos, nPos, eLang ) )
    1969           0 :                         --nPos;
    1970             :                 }
    1971           0 :                 break;
    1972             : 
    1973             :             case '.':
    1974             :             case '!':
    1975             :             case '?':
    1976           0 :                 if( m_aFlags.bCptlSttSntnc )
    1977           0 :                     bFirstSent = sal_True;
    1978             :                 /* fallthrough */
    1979             :             default:
    1980           0 :                 if( !( rAppCC.isLetterNumeric( *pTxt, nPos )
    1981           0 :                         || '/' == cChar )) //  '/' should not be a word separator (e.g. '1/2' needs to be handled as one word for replacement)
    1982             :                 {
    1983           0 :                     --nPos;     // revert ++nPos which was decremented in for loop
    1984           0 :                     ++bBreak;
    1985             :                 }
    1986           0 :                 break;
    1987             :             }
    1988             : 
    1989           0 :         if( nPos == nSttPos )
    1990             :         {
    1991           0 :             if (++nPos == pTxt->getLength())
    1992           0 :                 bCallACorr = true;
    1993             :         }
    1994             :         else
    1995           0 :             bCallACorr = true;
    1996             : 
    1997           0 :         if( bCallACorr )
    1998             :         {
    1999           0 :             bCallACorr = false;
    2000           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    2001           0 :             SetRedlineTxt( STR_AUTOFMTREDL_USE_REPLACE );
    2002           0 :             if( m_aFlags.bAutoCorrect &&
    2003           0 :                 aACorrDoc.ChgAutoCorrWord( nSttPos, nPos, *pATst, 0 ) )
    2004             :             {
    2005           0 :                 nPos = m_aDelPam.GetPoint()->nContent.GetIndex();
    2006             : 
    2007           0 :                 if( m_aFlags.bWithRedlining )
    2008             :                 {
    2009           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    2010           0 :                     m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    2011           0 :                     pTxt = &m_pCurTxtNd->GetTxt();
    2012           0 :                     m_aDelPam.SetMark();
    2013           0 :                     m_aDelPam.DeleteMark();
    2014             :                 }
    2015             : 
    2016           0 :                 continue;       // do not check further
    2017             :             }
    2018             : 
    2019             :             LanguageType eLang = bGetLanguage
    2020           0 :                                            ? m_pCurTxtNd->GetLang( nSttPos )
    2021           0 :                                            : LANGUAGE_SYSTEM;
    2022             : 
    2023           0 :             if ( m_aFlags.bAddNonBrkSpace )
    2024             :             {
    2025           0 :                 SetRedlineTxt( STR_AUTOFMTREDL_NON_BREAK_SPACE );
    2026           0 :                 pATst->FnAddNonBrkSpace( aACorrDoc, *pTxt, nSttPos, nPos, eLang );
    2027             :             }
    2028             : 
    2029           0 :             if( ( m_aFlags.bChgOrdinalNumber &&
    2030           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_ORDINAL ) &&
    2031           0 :                     pATst->FnChgOrdinalNumber( aACorrDoc, *pTxt, nSttPos, nPos, eLang ) ) ||
    2032           0 :                 ( m_aFlags.bChgToEnEmDash &&
    2033           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_DASH ) &&
    2034           0 :                     pATst->FnChgToEnEmDash( aACorrDoc, *pTxt, nSttPos, nPos, eLang ) ) ||
    2035           0 :                 ( m_aFlags.bSetINetAttr &&
    2036           0 :                     (nPos == pTxt->getLength() || IsSpace((*pTxt)[nPos])) &&
    2037           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_DETECT_URL ) &&
    2038           0 :                     pATst->FnSetINetAttr( aACorrDoc, *pTxt, nLastBlank, nPos, eLang ) ) )
    2039           0 :                     nPos = m_aDelPam.GetPoint()->nContent.GetIndex();
    2040             :             else
    2041             :             {
    2042             :                 // two capital letters at the beginning of a word?
    2043           0 :                 if( m_aFlags.bCptlSttWrd )
    2044             :                 {
    2045           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_WORD );
    2046           0 :                     pATst->FnCptlSttWrd( aACorrDoc, *pTxt, nSttPos, nPos, eLang );
    2047             :                 }
    2048             :                 // capital letter at the beginning of a sentence?
    2049           0 :                 if( m_aFlags.bCptlSttSntnc && bFirst )
    2050             :                 {
    2051           0 :                     SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_SENT );
    2052           0 :                     pATst->FnCptlSttSntnc( aACorrDoc, *pTxt, true, nSttPos, nPos, eLang);
    2053           0 :                     bFirst = sal_False;
    2054             :                 }
    2055             : 
    2056           0 :                 bFirst = bFirstSent;
    2057           0 :                 bFirstSent = sal_False;
    2058             : 
    2059           0 :                 if( m_aFlags.bWithRedlining )
    2060             :                 {
    2061           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    2062           0 :                     m_pCurTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    2063           0 :                     pTxt = &m_pCurTxtNd->GetTxt();
    2064           0 :                     m_aDelPam.SetMark();
    2065           0 :                     m_aDelPam.DeleteMark();
    2066             :                 }
    2067             :             }
    2068             :         }
    2069           0 :     } while (nPos < pTxt->getLength());
    2070           0 :     ClearRedlineTxt();
    2071             : }
    2072             : 
    2073           0 : SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFmtFlags& rFlags,
    2074             :                             SwNodeIndex* pSttNd, SwNodeIndex* pEndNd )
    2075             :     : m_aFlags( rFlags ),
    2076           0 :     m_aDelPam( pEdShell->GetDoc()->GetNodes().GetEndOfExtras() ),
    2077           0 :     m_aNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfExtras(), +1 ),
    2078           0 :     m_aEndNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfContent() ),
    2079             :     m_pEditShell( pEdShell ),
    2080           0 :     m_pDoc( pEdShell->GetDoc() ),
    2081             :     m_pCurTxtNd( 0 ), m_pCurTxtFrm( 0 ),
    2082           0 :     m_nRedlAutoFmtSeqId( 0 )
    2083             : {
    2084             :     OSL_ENSURE( (pSttNd && pEndNd) || (!pSttNd && !pEndNd),
    2085             :             "Got no area" );
    2086             : 
    2087           0 :     if( m_aFlags.bSetNumRule && !m_aFlags.bAFmtByInput )
    2088           0 :         m_aFlags.bSetNumRule = false;
    2089             : 
    2090           0 :     bool bReplaceStyles = !m_aFlags.bAFmtByInput || m_aFlags.bReplaceStyles;
    2091             : 
    2092           0 :     const SwTxtNode* pNxtNd = 0;
    2093           0 :     bool bNxtEmpty = false;
    2094           0 :     sal_Bool bNxtAlpha = sal_False;
    2095           0 :     sal_uInt16 nNxtLevel = 0;
    2096             : 
    2097             :     // set area for autoformatting
    2098           0 :     if( pSttNd )
    2099             :     {
    2100           0 :         m_aNdIdx = *pSttNd;
    2101           0 :         m_aNdIdx--;           // for GoNextPara, one paragraph prior to that
    2102           0 :         m_aEndNdIdx = *pEndNd;
    2103           0 :         m_aEndNdIdx++;
    2104             : 
    2105             :         // check the previous TextNode
    2106           0 :         pNxtNd = m_aNdIdx.GetNode().GetTxtNode();
    2107           0 :         m_bEmptyLine = !pNxtNd ||
    2108           0 :                     IsEmptyLine( *pNxtNd ) ||
    2109           0 :                     IsNoAlphaLine( *pNxtNd );
    2110             :     }
    2111             :     else
    2112           0 :         m_bEmptyLine = true;      // at document beginning
    2113             : 
    2114           0 :     m_bEnd = false;
    2115             : 
    2116             :     // set value for percentage display
    2117           0 :     m_nEndNdIdx = m_aEndNdIdx.GetIndex();
    2118             : 
    2119           0 :     if( !m_aFlags.bAFmtByInput )
    2120           0 :         ::StartProgress( STR_STATSTR_AUTOFORMAT, m_aNdIdx.GetIndex(),
    2121           0 :                          m_nEndNdIdx = m_aEndNdIdx.GetIndex(),
    2122           0 :                          m_pDoc->GetDocShell() );
    2123             : 
    2124           0 :     RedlineMode_t eRedlMode = m_pDoc->GetRedlineMode(), eOldMode = eRedlMode;
    2125           0 :     if( m_aFlags.bWithRedlining )
    2126             :     {
    2127           0 :         m_pDoc->SetAutoFmtRedline( true );
    2128           0 :         eRedlMode = (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT);
    2129             :     }
    2130             :     else
    2131           0 :       eRedlMode = (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_IGNORE);
    2132           0 :     m_pDoc->SetRedlineMode( eRedlMode );
    2133             : 
    2134             :     // save undo state (might be turned off)
    2135           0 :     bool const bUndoState = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
    2136             : 
    2137             :     // If multiple lines, then do not merge with next paragraph
    2138           0 :     m_bMoreLines = false;
    2139             : 
    2140           0 :     m_nLastCalcHeadLvl = 0;
    2141           0 :     m_nLastHeadLvl = USHRT_MAX;
    2142           0 :     sal_uInt16 nLevel = 0;
    2143           0 :     sal_uInt16 nDigitLvl = 0;
    2144             : 
    2145             :     // set defaults
    2146           0 :     SwTxtFrmInfo aFInfo( 0 );
    2147             : 
    2148             :     // This is the automat for autoformatting
    2149           0 :     m_eStat = READ_NEXT_PARA;
    2150           0 :     while( !m_bEnd )
    2151             :     {
    2152           0 :         switch( m_eStat )
    2153             :         {
    2154             :         case READ_NEXT_PARA:
    2155             :             {
    2156           0 :                 GoNextPara();
    2157           0 :                 m_eStat = m_bEnd ? IS_END : TST_EMPTY_LINE;
    2158             :             }
    2159           0 :             break;
    2160             : 
    2161             :         case TST_EMPTY_LINE:
    2162           0 :             if( IsEmptyLine( *m_pCurTxtNd ) )
    2163             :             {
    2164           0 :                 if( m_aFlags.bDelEmptyNode && !HasObjects( *m_pCurTxtNd ) )
    2165             :                 {
    2166           0 :                     m_bEmptyLine = true;
    2167           0 :                     sal_uLong nOldCnt = m_pDoc->GetNodes().Count();
    2168           0 :                     DelEmptyLine();
    2169             :                     // Was there really a deletion of a node?
    2170           0 :                     if( nOldCnt != m_pDoc->GetNodes().Count() )
    2171           0 :                         m_aNdIdx--;       // do not skip the next paragraph
    2172             :                 }
    2173           0 :                 m_eStat = READ_NEXT_PARA;
    2174             :             }
    2175             :             else
    2176           0 :                 m_eStat = TST_ALPHA_LINE;
    2177           0 :             break;
    2178             : 
    2179             :         case TST_ALPHA_LINE:
    2180           0 :             if( IsNoAlphaLine( *m_pCurTxtNd ))
    2181             :             {
    2182             :                 // recognize a table definition +---+---+
    2183           0 :                 if( m_aFlags.bAFmtByInput && m_aFlags.bCreateTable && DoTable() )
    2184             :                 {
    2185             :                     //JP 30.09.96: DoTable() builds on PopCrsr and MoveCrsr after AutoFormat!
    2186           0 :                     pEdShell->Pop( sal_False );
    2187           0 :                     *pEdShell->GetCrsr() = m_aDelPam;
    2188           0 :                     pEdShell->Push();
    2189             : 
    2190           0 :                     m_eStat = IS_END;
    2191           0 :                     break;
    2192             :                 }
    2193             : 
    2194             :                 // Check for 3 "---" or "===". In this case, the previous paragraph should be
    2195             :                 // underlined and the current be deleted!
    2196           0 :                 if( !DoUnderline() && bReplaceStyles )
    2197             :                 {
    2198           0 :                     SetColl( RES_POOLCOLL_STANDARD, true );
    2199           0 :                     m_bEmptyLine = true;
    2200             :                 }
    2201           0 :                 m_eStat = READ_NEXT_PARA;
    2202             :             }
    2203             :             else
    2204           0 :                 m_eStat = GET_ALL_INFO;
    2205           0 :             break;
    2206             : 
    2207             :         case GET_ALL_INFO:
    2208             :             {
    2209           0 :                 if( m_pCurTxtNd->GetNumRule() )
    2210             :                 {
    2211             :                     // do nothing in numbering, go to next
    2212           0 :                     m_bEmptyLine = false;
    2213           0 :                     m_eStat = READ_NEXT_PARA;
    2214             :                     // delete all blanks at beginning/end and in between
    2215             :                     //JP 29.04.98: first only "all in between"
    2216           0 :                     DelMoreLinesBlanks( false );
    2217           0 :                     break;
    2218             :                 }
    2219             : 
    2220           0 :                 aFInfo.SetFrm( m_pCurTxtFrm );
    2221             : 
    2222             :                 // so far: if there were templates assigned, keep these and go to next node
    2223           0 :                 sal_uInt16 nPoolId = m_pCurTxtNd->GetTxtColl()->GetPoolFmtId();
    2224           0 :                 if( IsPoolUserFmt( nPoolId )
    2225           0 :                         ? !m_aFlags.bChgUserColl
    2226           0 :                         : ( RES_POOLCOLL_STANDARD != nPoolId &&
    2227           0 :                            ( !m_aFlags.bAFmtByInput ||
    2228           0 :                             (RES_POOLCOLL_TEXT_MOVE != nPoolId &&
    2229             :                              RES_POOLCOLL_TEXT != nPoolId )) ))
    2230             :                 {
    2231           0 :                     m_eStat = HAS_FMTCOLL;
    2232           0 :                     break;
    2233             :                 }
    2234             : 
    2235             :                 // check for hard spaces or LRSpaces set by the template
    2236           0 :                 if( IsPoolUserFmt( nPoolId ) ||
    2237             :                     RES_POOLCOLL_STANDARD == nPoolId )
    2238             :                 {
    2239             :                     short nSz;
    2240             :                     SvxLRSpaceItem* pLRSpace;
    2241           0 :                     if( SFX_ITEM_SET == m_pCurTxtNd->GetSwAttrSet().
    2242             :                         GetItemState( RES_LR_SPACE, true,
    2243           0 :                                         (const SfxPoolItem**)&pLRSpace ) &&
    2244           0 :                         ( 0 != (nSz = pLRSpace->GetTxtFirstLineOfst()) ||
    2245           0 :                             0 != pLRSpace->GetTxtLeft() ) )
    2246             :                     {
    2247             :                         // exception: numbering/enumation can have an indentation
    2248           0 :                         if( IsEnumericChar( *m_pCurTxtNd ))
    2249             :                         {
    2250           0 :                             nLevel = CalcLevel( *m_pCurTxtNd, &nDigitLvl );
    2251           0 :                             if( nLevel >= MAXLEVEL )
    2252           0 :                                 nLevel = MAXLEVEL-1;
    2253           0 :                             BuildEnum( nLevel, nDigitLvl );
    2254           0 :                             m_eStat = READ_NEXT_PARA;
    2255           0 :                             break;
    2256             :                         }
    2257             : 
    2258             :                         // never merge (maybe only indent as exception)
    2259           0 :                         m_bMoreLines = true;
    2260             : 
    2261           0 :                         if( bReplaceStyles )
    2262             :                         {
    2263             :                             // then use one of our templates
    2264           0 :                             if( 0 < nSz )           // positive 1st line indentation
    2265           0 :                                 BuildIndent();
    2266           0 :                             else if( 0 > nSz )      // negative 1st line indentation
    2267           0 :                                 BuildNegIndent( aFInfo.GetLineStart() );
    2268           0 :                             else if( pLRSpace->GetTxtLeft() )   // is indentation
    2269           0 :                                 BuildTextIndent();
    2270             :                         }
    2271           0 :                         m_eStat = READ_NEXT_PARA;
    2272           0 :                         break;
    2273             :                     }
    2274             :                 }
    2275             : 
    2276           0 :                 nLevel = CalcLevel( *m_pCurTxtNd, &nDigitLvl );
    2277           0 :                 m_bMoreLines = !IsOneLine( *m_pCurTxtNd );
    2278           0 :                 pNxtNd = GetNextNode();
    2279           0 :                 if( pNxtNd )
    2280             :                 {
    2281           0 :                     bNxtEmpty = IsEmptyLine( *pNxtNd );
    2282           0 :                     bNxtAlpha = IsNoAlphaLine( *pNxtNd );
    2283           0 :                     nNxtLevel = CalcLevel( *pNxtNd );
    2284             : 
    2285           0 :                     if( !m_bEmptyLine && HasBreakAttr( *m_pCurTxtNd ) )
    2286           0 :                         m_bEmptyLine = true;
    2287           0 :                     if( !bNxtEmpty && HasBreakAttr( *pNxtNd ) )
    2288           0 :                         bNxtEmpty = true;
    2289             : 
    2290             :                 }
    2291             :                 else
    2292             :                 {
    2293           0 :                     bNxtEmpty = false;
    2294           0 :                     bNxtAlpha = sal_False;
    2295           0 :                     nNxtLevel = 0;
    2296             :                 }
    2297           0 :                 m_eStat = !m_bMoreLines ? IS_ONE_LINE : TST_ENUMERIC;
    2298             :             }
    2299           0 :             break;
    2300             : 
    2301             :         case IS_ONE_LINE:
    2302             :             {
    2303           0 :                 m_eStat = TST_ENUMERIC;
    2304           0 :                 if( !bReplaceStyles )
    2305           0 :                     break;
    2306             : 
    2307           0 :                 OUString sClrStr( DelLeadingBlanks(m_pCurTxtNd->GetTxt()) );
    2308             : 
    2309           0 :                 if( sClrStr.isEmpty() )
    2310             :                 {
    2311           0 :                     m_bEmptyLine = true;
    2312           0 :                     m_eStat = READ_NEXT_PARA;
    2313           0 :                     break;      // read next paragraph
    2314             :                 }
    2315             : 
    2316             :                 // check if headline
    2317           0 :                 if( !m_bEmptyLine || !IsFirstCharCapital( *m_pCurTxtNd ) ||
    2318           0 :                     IsBlanksInString( *m_pCurTxtNd ) )
    2319           0 :                     break;
    2320             : 
    2321           0 :                 m_bEmptyLine = false;
    2322           0 :                 OUString sEndClrStr( sClrStr );
    2323           0 :                 sal_Int32 nLen = DelTrailingBlanks( sEndClrStr ).getLength();
    2324             : 
    2325             :                 // not, then check if headline
    2326           0 :                 if( ':' == sEndClrStr[ nLen - 1 ] )
    2327             :                 {
    2328             :                     {
    2329           0 :                         BuildHeadLine( 2 );
    2330           0 :                         m_eStat = READ_NEXT_PARA;
    2331           0 :                         break;
    2332             :                     }
    2333             :                 }
    2334           0 :                 else if( 256 <= sEndClrStr[ nLen-1 ] ||
    2335           0 :                          !strchr( ",.;", sEndClrStr[ nLen-1 ]) )
    2336             :                 {
    2337           0 :                     if( bNxtEmpty || bNxtAlpha
    2338           0 :                         || ( pNxtNd && IsEnumericChar( *pNxtNd ))
    2339             : 
    2340             :                         )
    2341             :                     {
    2342             : 
    2343             :                         // one level below?
    2344           0 :                         if( nLevel >= MAXLEVEL )
    2345           0 :                             nLevel = MAXLEVEL-1;
    2346             : 
    2347           0 :                         if( USHRT_MAX == m_nLastHeadLvl )
    2348           0 :                             m_nLastHeadLvl = 0;
    2349           0 :                         else if( m_nLastCalcHeadLvl < nLevel )
    2350             :                         {
    2351           0 :                             if( m_nLastHeadLvl+1 < MAXLEVEL )
    2352           0 :                                 ++m_nLastHeadLvl;
    2353             :                         }
    2354             :                         // one level above?
    2355           0 :                         else if( m_nLastCalcHeadLvl > nLevel )
    2356             :                         {
    2357           0 :                             if( m_nLastHeadLvl )
    2358           0 :                                 --m_nLastHeadLvl;
    2359             :                         }
    2360           0 :                         m_nLastCalcHeadLvl = nLevel;
    2361             : 
    2362           0 :                         if( m_aFlags.bAFmtByInput )
    2363           0 :                             BuildHeadLine( nLevel );
    2364             :                         else
    2365           0 :                             BuildHeadLine( m_nLastHeadLvl );
    2366           0 :                         m_eStat = READ_NEXT_PARA;
    2367           0 :                         break;
    2368             :                     }
    2369           0 :                 }
    2370             :             }
    2371           0 :             break;
    2372             : 
    2373             :         case TST_ENUMERIC:
    2374             :             {
    2375           0 :                 m_bEmptyLine = false;
    2376           0 :                 if( IsEnumericChar( *m_pCurTxtNd ))
    2377             :                 {
    2378           0 :                     if( nLevel >= MAXLEVEL )
    2379           0 :                         nLevel = MAXLEVEL-1;
    2380           0 :                     BuildEnum( nLevel, nDigitLvl );
    2381           0 :                     m_eStat = READ_NEXT_PARA;
    2382             :                 }
    2383           0 :                 else if( bReplaceStyles )
    2384           0 :                     m_eStat = nLevel ? TST_IDENT : TST_NEG_IDENT;
    2385             :                 else
    2386           0 :                     m_eStat = READ_NEXT_PARA;
    2387             :             }
    2388           0 :             break;
    2389             : 
    2390             :         case TST_IDENT:
    2391             :             // Spaces at the beginning, check again for indentation
    2392           0 :             if( m_bMoreLines && nLevel )
    2393             :             {
    2394           0 :                 SwTwips nSz = aFInfo.GetFirstIndent();
    2395           0 :                 if( 0 < nSz )           // positive 1st line indentation
    2396           0 :                     BuildIndent();
    2397           0 :                 else if( 0 > nSz )      // negative 1st line indentation
    2398           0 :                     BuildNegIndent( aFInfo.GetLineStart() );
    2399             :                 else                    // is indentation
    2400           0 :                     BuildTextIndent();
    2401           0 :                 m_eStat = READ_NEXT_PARA;
    2402             :             }
    2403           0 :             else if( nLevel && pNxtNd && !m_bEnd &&
    2404           0 :                      !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
    2405           0 :                      !IsEnumericChar( *pNxtNd ) )
    2406             :             {
    2407             :                 // is an indentation
    2408           0 :                 BuildIndent();
    2409           0 :                 m_eStat = READ_NEXT_PARA;
    2410             :             }
    2411             :             else
    2412           0 :                 m_eStat = TST_TXT_BODY;
    2413           0 :             break;
    2414             : 
    2415             :         case TST_NEG_IDENT:
    2416             :             // no spaces at the beginning, check again for negative indentation
    2417             :             {
    2418           0 :                 if( m_bMoreLines && !nLevel )
    2419             :                 {
    2420           0 :                     SwTwips nSz = aFInfo.GetFirstIndent();
    2421           0 :                     if( 0 < nSz )           // positive 1st line indentation
    2422           0 :                         BuildIndent();
    2423           0 :                     else if( 0 > nSz )      // negative 1st line indentation
    2424           0 :                         BuildNegIndent( aFInfo.GetLineStart() );
    2425             :                     else                    // is _no_ indentation
    2426           0 :                         BuildText();
    2427           0 :                     m_eStat = READ_NEXT_PARA;
    2428             :                 }
    2429           0 :                 else if( !nLevel && pNxtNd && !m_bEnd &&
    2430           0 :                          !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
    2431           0 :                          !IsEnumericChar( *pNxtNd ) )
    2432             :                 {
    2433             :                     // is a negative indentation
    2434           0 :                     BuildNegIndent( aFInfo.GetLineStart() );
    2435           0 :                     m_eStat = READ_NEXT_PARA;
    2436             :                 }
    2437             :                 else
    2438           0 :                     m_eStat = TST_TXT_BODY;
    2439             :             }
    2440           0 :             break;
    2441             : 
    2442             :         case TST_TXT_BODY:
    2443             :             {
    2444           0 :                 if( m_bMoreLines )
    2445             :                 {
    2446           0 :                     SwTwips nSz = aFInfo.GetFirstIndent();
    2447           0 :                     if( 0 < nSz )           // positive 1st line indentation
    2448           0 :                         BuildIndent();
    2449           0 :                     else if( 0 > nSz )      // negative 1st line indentation
    2450           0 :                         BuildNegIndent( aFInfo.GetLineStart() );
    2451           0 :                     else if( nLevel )       // is indentation
    2452           0 :                         BuildTextIndent();
    2453             :                     else
    2454           0 :                         BuildText();
    2455             :                 }
    2456           0 :                 else if( nLevel )
    2457           0 :                     BuildTextIndent();
    2458             :                 else
    2459           0 :                     BuildText();
    2460           0 :                 m_eStat = READ_NEXT_PARA;
    2461             :             }
    2462           0 :             break;
    2463             : 
    2464             :         case HAS_FMTCOLL:
    2465             :             {
    2466             :                 // so far: if there were templates assigned, keep these and go to next node
    2467           0 :                 m_bEmptyLine = false;
    2468           0 :                 m_eStat = READ_NEXT_PARA;
    2469             :                 // delete all blanks at beginning/end and in between
    2470             :                 //JP 29.04.98: first only "all in between"
    2471           0 :                 DelMoreLinesBlanks( false );
    2472             : 
    2473             :                 // handle hard attributes
    2474           0 :                 if( m_pCurTxtNd->HasSwAttrSet() )
    2475             :                 {
    2476             :                     short nSz;
    2477             :                     SvxLRSpaceItem* pLRSpace;
    2478           0 :                     if( bReplaceStyles &&
    2479           0 :                         SFX_ITEM_SET == m_pCurTxtNd->GetSwAttrSet().
    2480             :                         GetItemState( RES_LR_SPACE, false,
    2481           0 :                                         (const SfxPoolItem**)&pLRSpace ) &&
    2482           0 :                         ( 0 != (nSz = pLRSpace->GetTxtFirstLineOfst()) ||
    2483           0 :                             0 != pLRSpace->GetTxtLeft() ) )
    2484             :                     {
    2485             :                         // then use one of our templates
    2486           0 :                         if( 0 < nSz )           // positive 1st line indentation
    2487           0 :                             BuildIndent();
    2488           0 :                         else if( 0 > nSz )      // negative 1st line indentation
    2489             :                         {
    2490           0 :                             BuildNegIndent( aFInfo.GetLineStart() );
    2491             :                         }
    2492           0 :                         else if( pLRSpace->GetTxtLeft() )   // is indentation
    2493           0 :                             BuildTextIndent();
    2494             :                         else
    2495           0 :                             BuildText();
    2496             :                     }
    2497             :                 }
    2498             :             }
    2499           0 :             break;
    2500             : 
    2501             :         case IS_END:
    2502           0 :             m_bEnd = true;
    2503           0 :             break;
    2504             :         }
    2505             :     }
    2506             : 
    2507           0 :     if( m_aFlags.bWithRedlining )
    2508           0 :         m_pDoc->SetAutoFmtRedline( false );
    2509           0 :     m_pDoc->SetRedlineMode( eOldMode );
    2510             : 
    2511             :     // restore undo (in case it has been changed)
    2512           0 :     m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoState);
    2513             : 
    2514             :     // disable display of percentage again
    2515           0 :     if( !m_aFlags.bAFmtByInput )
    2516           0 :         ::EndProgress( m_pDoc->GetDocShell() );
    2517           0 : }
    2518             : 
    2519           0 : void SwEditShell::AutoFormat( const SvxSwAutoFmtFlags* pAFlags )
    2520             : {
    2521           0 :     boost::scoped_ptr<SwWait> pWait;
    2522             : 
    2523           0 :     SET_CURR_SHELL( this );
    2524           0 :     StartAllAction();
    2525           0 :     StartUndo( UNDO_AUTOFORMAT );
    2526             : 
    2527           0 :     SvxSwAutoFmtFlags aAFFlags;     // use default values or add params?
    2528           0 :     if( pAFlags )
    2529             :     {
    2530           0 :         aAFFlags = *pAFlags;
    2531           0 :         if( !aAFFlags.bAFmtByInput )
    2532           0 :             pWait.reset(new SwWait( *GetDoc()->GetDocShell(), true ));
    2533             :     }
    2534             : 
    2535           0 :     SwPaM* pCrsr = GetCrsr();
    2536             :     // There are more than one or a selection is open
    2537           0 :     if( pCrsr->GetNext() != pCrsr || pCrsr->HasMark() )
    2538             :     {
    2539           0 :         FOREACHPAM_START(GetCrsr())
    2540           0 :             if( PCURCRSR->HasMark() )
    2541             :             {
    2542           0 :                 SwAutoFormat aFmt( this, aAFFlags, &PCURCRSR->Start()->nNode,
    2543           0 :                                      &PCURCRSR->End()->nNode );
    2544             :             }
    2545           0 :         FOREACHPAM_END()
    2546             :     }
    2547             :     else
    2548             :     {
    2549           0 :         SwAutoFormat aFmt( this, aAFFlags );
    2550             :     }
    2551             : 
    2552           0 :     EndUndo( UNDO_AUTOFORMAT );
    2553           0 :     EndAllAction();
    2554           0 : }
    2555             : 
    2556           0 : void SwEditShell::AutoFmtBySplitNode()
    2557             : {
    2558           0 :     SET_CURR_SHELL( this );
    2559           0 :     SwPaM* pCrsr = GetCrsr();
    2560           0 :     if( pCrsr->GetNext() == pCrsr && pCrsr->Move( fnMoveBackward, fnGoNode ) )
    2561             :     {
    2562           0 :         StartAllAction();
    2563           0 :         StartUndo( UNDO_AUTOFORMAT );
    2564             : 
    2565           0 :         bool bRange = false;
    2566           0 :         pCrsr->SetMark();
    2567           0 :         SwIndex* pCntnt = &pCrsr->GetMark()->nContent;
    2568           0 :         if( pCntnt->GetIndex() )
    2569             :         {
    2570           0 :             *pCntnt = 0;
    2571           0 :             bRange = true;
    2572             :         }
    2573             :         else
    2574             :         {
    2575             :             // then go one node backwards
    2576           0 :             SwNodeIndex m_aNdIdx( pCrsr->GetMark()->nNode, -1 );
    2577           0 :             SwTxtNode* pTxtNd = m_aNdIdx.GetNode().GetTxtNode();
    2578           0 :             if (pTxtNd && !pTxtNd->GetTxt().isEmpty())
    2579             :             {
    2580           0 :                 pCntnt->Assign( pTxtNd, 0 );
    2581           0 :                 pCrsr->GetMark()->nNode = m_aNdIdx;
    2582           0 :                 bRange = true;
    2583           0 :             }
    2584             :         }
    2585             : 
    2586           0 :         if( bRange )
    2587             :         {
    2588           0 :             Push();     // save cursor
    2589             : 
    2590           0 :             SvxSwAutoFmtFlags aAFFlags = *GetAutoFmtFlags(); // use default values so far
    2591             : 
    2592           0 :             SwAutoFormat aFmt( this, aAFFlags, &pCrsr->GetMark()->nNode,
    2593           0 :                                     &pCrsr->GetPoint()->nNode );
    2594             : 
    2595             :             //JP 30.09.96: DoTable() builds on PopCrsr and MoveCrsr!
    2596           0 :             Pop( sal_False );
    2597           0 :             pCrsr = GetCrsr();
    2598             :         }
    2599           0 :         pCrsr->DeleteMark();
    2600           0 :         pCrsr->Move( fnMoveForward, fnGoNode );
    2601             : 
    2602           0 :         EndUndo( UNDO_AUTOFORMAT );
    2603           0 :         EndAllAction();
    2604           0 :     }
    2605           0 : }
    2606             : 
    2607           0 : SvxSwAutoFmtFlags* SwEditShell::GetAutoFmtFlags()
    2608             : {
    2609           0 :     if (!pAutoFmtFlags)
    2610           0 :         pAutoFmtFlags = new SvxSwAutoFmtFlags;
    2611             : 
    2612           0 :     return pAutoFmtFlags;
    2613             : }
    2614             : 
    2615           0 : void SwEditShell::SetAutoFmtFlags(SvxSwAutoFmtFlags * pFlags)
    2616             : {
    2617           0 :     SvxSwAutoFmtFlags* pEditFlags = GetAutoFmtFlags();
    2618             : 
    2619           0 :     pEditFlags->bSetNumRule     = pFlags->bSetNumRule;
    2620           0 :     pEditFlags->bChgEnumNum     = pFlags->bChgEnumNum;
    2621           0 :     pEditFlags->bSetBorder      = pFlags->bSetBorder;
    2622           0 :     pEditFlags->bCreateTable    = pFlags->bCreateTable;
    2623           0 :     pEditFlags->bReplaceStyles  = pFlags->bReplaceStyles;
    2624             :     pEditFlags->bAFmtByInpDelSpacesAtSttEnd =
    2625           0 :                                     pFlags->bAFmtByInpDelSpacesAtSttEnd;
    2626             :     pEditFlags->bAFmtByInpDelSpacesBetweenLines =
    2627           0 :                                     pFlags->bAFmtByInpDelSpacesBetweenLines;
    2628             : 
    2629             :     //JP 15.12.98: copy BulletChar and Font into "normal" ones
    2630             :     //             because AutoFormat can only work with the latter!
    2631           0 :     pEditFlags->cBullet             = pFlags->cByInputBullet;
    2632           0 :     pEditFlags->aBulletFont         = pFlags->aByInputBulletFont;
    2633           0 :     pEditFlags->cByInputBullet      = pFlags->cByInputBullet;
    2634           0 :     pEditFlags->aByInputBulletFont  = pFlags->aByInputBulletFont;
    2635           0 : }
    2636             : 
    2637             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10