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

Generated by: LCOV version 1.10