LCOV - code coverage report
Current view: top level - sw/source/core/edit - autofmt.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 18 1419 1.3 %
Date: 2015-06-13 12:38:46 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             : SvxSwAutoFormatFlags* SwEditShell::s_pAutoFormatFlags = nullptr;
      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             :     SvxSwAutoFormatFlags 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             :     SwTextNode* m_pCurTextNd;     // the current TextNode
     100             :     SwTextFrm* m_pCurTextFrm;     // 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_nRedlAutoFormatSeqId;
     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 :     static bool IsSpace( const sal_Unicode c )
     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             :     // TextNode methods
     158             :     const SwTextNode* GetNextNode() const;
     159           0 :     static bool IsEmptyLine( const SwTextNode& rNd )
     160           0 :         {   return rNd.GetText().isEmpty() ||
     161           0 :                 rNd.GetText().getLength() == GetLeadingBlanks( rNd.GetText() ); }
     162             : 
     163             :     bool IsOneLine( const SwTextNode& ) const;
     164             :     bool IsFastFullLine( const SwTextNode& ) const;
     165             :     bool IsNoAlphaLine( const SwTextNode&) const;
     166             :     bool IsEnumericChar( const SwTextNode&) const;
     167             :     static bool IsBlanksInString( const SwTextNode&);
     168             :     sal_uInt16 CalcLevel( const SwTextNode&, sal_uInt16 *pDigitLvl = 0 ) const;
     169             :     sal_Int32 GetBigIndent( sal_Int32& rAktSpacePos ) const;
     170             : 
     171             :     static OUString DelLeadingBlanks(const OUString& rStr);
     172             :     static OUString DelTrailingBlanks( const OUString& rStr );
     173             :     static sal_Int32 GetLeadingBlanks( const OUString& rStr );
     174             :     static sal_Int32 GetTrailingBlanks( const OUString& rStr );
     175             : 
     176             :     bool IsFirstCharCapital( const SwTextNode& rNd ) const;
     177             :     sal_uInt16 GetDigitLevel( const SwTextNode& rTextNd, sal_Int32& rPos,
     178             :                             OUString* pPrefix = 0, OUString* pPostfix = 0,
     179             :                             OUString* pNumTypes = 0 ) const;
     180             :     /// get the FORMATED TextFrame
     181             :     SwTextFrm* GetFrm( const SwTextNode& rTextNd ) 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             :     static bool HasSelBlanks( SwPaM& rPam );
     191             :     static bool HasBreakAttr( const SwTextNode& );
     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 SwTextNode* pTextNd ) const
     206             :     {
     207           0 :         return !m_bEnd && pTextNd &&
     208           0 :              !IsEmptyLine( *pTextNd ) &&
     209           0 :              !IsNoAlphaLine( *pTextNd) &&
     210           0 :              !IsEnumericChar( *pTextNd ) &&
     211           0 :              ((COMPLETE_STRING - 50 - pTextNd->GetText().getLength()) >
     212           0 :                     m_pCurTextNd->GetText().getLength()) &&
     213           0 :              !HasBreakAttr( *pTextNd );
     214             :     }
     215             : 
     216             :     /// is a dot at the end ??
     217             :     static bool IsSentenceAtEnd( const SwTextNode& rTextNd );
     218             : 
     219             :     bool DoUnderline();
     220             :     bool DoTable();
     221             : 
     222             :     void _SetRedlineText( sal_uInt16 nId );
     223           0 :     bool SetRedlineText( sal_uInt16 nId )
     224           0 :         { if( m_aFlags.bWithRedlining )   _SetRedlineText( nId );  return true; }
     225           0 :     bool ClearRedlineText()
     226           0 :         { if( m_aFlags.bWithRedlining )   m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment(0);  return true; }
     227             : 
     228             : public:
     229             :     SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags& 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 : SwTextFrm* SwAutoFormat::GetFrm( const SwTextNode& rTextNd ) const
     241             : {
     242             :     // get the Frame
     243           0 :     const SwContentFrm *pFrm = rTextNd.getLayoutFrm( m_pEditShell->GetLayout() );
     244             :     OSL_ENSURE( pFrm, "For Autoformat a Layout is needed" );
     245           0 :     if( m_aFlags.bAFormatByInput && !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->IsTextFrm() && !const_cast<SwTextFrm*>(static_cast<const SwTextFrm*>(pFrm))->Paint().IsEmpty() ) )
     252           0 :             pFrm->SetCompletePaint();
     253             :     }
     254           0 :     return const_cast<SwTextFrm*>(static_cast<const SwTextFrm*>(pFrm))->GetFormatted();
     255             : }
     256             : 
     257           0 : void SwAutoFormat::_SetRedlineText( sal_uInt16 nActionId )
     258             : {
     259           0 :     OUString sText;
     260           0 :     sal_uInt16 nSeqNo = 0;
     261           0 :     if( STR_AUTOFMTREDL_END > nActionId )
     262             :     {
     263           0 :         sText = SwViewShell::GetShellRes()->GetAutoFormatNameLst()[ 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_nRedlAutoFormatSeqId;
     281           0 :             break;
     282             :         }
     283             :     }
     284             : #if OSL_DEBUG_LEVEL > 0
     285             :     else
     286             :         sText = "Action text is missing";
     287             : #endif
     288             : 
     289           0 :     m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText, 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             :         //      NoTextNode   : 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->IsTextNode() );
     330             : 
     331           0 :     if( !m_aFlags.bAFormatByInput )
     332           0 :         ::SetProgressState( m_aNdIdx.GetIndex() + m_nEndNdIdx - m_aEndNdIdx.GetIndex(),
     333           0 :                             m_pDoc->GetDocShell() );
     334             : 
     335           0 :     m_pCurTextNd = static_cast<SwTextNode*>(pNewNd);
     336           0 :     m_pCurTextFrm = GetFrm( *m_pCurTextNd );
     337           0 :     return m_pCurTextNd->GetText();
     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 SwFrameFormats& rFormats = *m_pDoc->GetSpzFrameFormats();
     346           0 :     for( auto pFrameFormat : rFormats )
     347             :     {
     348           0 :         const SwFormatAnchor& rAnchor = pFrameFormat->GetAnchor();
     349           0 :         if ((FLY_AT_PAGE != rAnchor.GetAnchorId()) &&
     350           0 :             rAnchor.GetContentAnchor() &&
     351           0 :             &rAnchor.GetContentAnchor()->nNode.GetNode() == &rNd )
     352             :         {
     353           0 :             bRet = true;
     354           0 :             break;
     355             :         }
     356             :     }
     357           0 :     return bRet;
     358             : }
     359             : 
     360           0 : const SwTextNode* 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 ]->GetTextNode();
     365             : }
     366             : 
     367           0 : bool SwAutoFormat::IsOneLine( const SwTextNode& rNd ) const
     368             : {
     369           0 :     SwTextFrmInfo aFInfo( GetFrm( rNd ) );
     370           0 :     return aFInfo.IsOneLine();
     371             : }
     372             : 
     373           0 : bool SwAutoFormat::IsFastFullLine( const SwTextNode& rNd ) const
     374             : {
     375           0 :     bool bRet = m_aFlags.bRightMargin;
     376           0 :     if( bRet )
     377             :     {
     378           0 :         SwTextFrmInfo aFInfo( GetFrm( rNd ) );
     379           0 :         bRet = aFInfo.IsFilled( m_aFlags.nRightMargin );
     380             :     }
     381           0 :     return bRet;
     382             : }
     383             : 
     384           0 : bool SwAutoFormat::IsEnumericChar( const SwTextNode& rNd ) const
     385             : {
     386           0 :     const OUString& rText = rNd.GetText();
     387           0 :     sal_Int32 nBlnks = GetLeadingBlanks( rText );
     388           0 :     const sal_Int32 nLen = rText.getLength() - nBlnks;
     389           0 :     if( !nLen )
     390           0 :         return false;
     391             : 
     392             :     // -, +, * separated by blank ??
     393           0 :     if (2 < nLen && IsSpace(rText[nBlnks + 1]))
     394             :     {
     395           0 :         if (StrChr(pBulletChar, rText[nBlnks]))
     396           0 :             return true;
     397             :         // Should there be a symbol font at the position?
     398           0 :         SwTextFrmInfo 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 SwTextNode& rNd )
     408             : {
     409             :     // Search more than 5 consecutive blanks/tabs in the string.
     410           0 :     OUString sTmp( DelLeadingBlanks(rNd.GetText()) );
     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 SwTextNode& rNd, sal_uInt16 *pDigitLvl ) const
     430             : {
     431           0 :     sal_uInt16 nLvl = 0, nBlnk = 0;
     432           0 :     const OUString& rText = rNd.GetText();
     433           0 :     if( pDigitLvl )
     434           0 :         *pDigitLvl = USHRT_MAX;
     435             : 
     436           0 :     if( RES_POOLCOLL_TEXT_MOVE == rNd.GetTextColl()->GetPoolFormatId() )
     437             :     {
     438           0 :         if( m_aFlags.bAFormatByInput )
     439             :         {
     440           0 :             nLvl = rNd.GetAutoFormatLvl();
     441           0 :             const_cast<SwTextNode&>(rNd).SetAutoFormatLvl( 0 );
     442           0 :             if( nLvl )
     443           0 :                 return nLvl;
     444             :         }
     445           0 :         ++nLvl;
     446             :     }
     447             : 
     448           0 :     for (sal_Int32 n = 0, nEnd = rText.getLength(); n < nEnd; ++n)
     449             :     {
     450           0 :         switch (rText[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 :     SwTextFrmInfo aFInfo( GetFrm( *m_pCurTextNd ) );
     470           0 :     const SwTextFrm* pNxtFrm = 0;
     471             : 
     472           0 :     if( !m_bMoreLines )
     473             :     {
     474           0 :         const SwTextNode* 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 SwTextNode& rNd ) const
     485             : {
     486           0 :     const OUString& rStr = rNd.GetText();
     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 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& rText(m_pCurTextNd->GetText());
     511           0 :     int eState = 0;
     512           0 :     sal_Int32 nCnt = 0;
     513           0 :     while (nCnt < rText.getLength())
     514             :     {
     515           0 :         int eTmp = 0;
     516           0 :         switch (rText[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, SvxBoxItemLine::BOTTOM );
     576           0 :         aBox.SetDistance( 42 );     // ~0,75 mm
     577           0 :         aSet.Put(aBox);
     578           0 :         m_pDoc->getIDocumentContentOperations().InsertItemSet( m_aDelPam, aSet );
     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.bAFormatByInput ||
     588           0 :         m_pCurTextNd->FindTableNode() )
     589           0 :         return false;
     590             : 
     591           0 :     const OUString& rTmp = m_pCurTextNd->GetText();
     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 :     SwTextFrmInfo aInfo( m_pCurTextFrm );
     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_pCurTextNd->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_pCurTextFrm->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 )
     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( const OUString& rStr )
     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 :         return rStr.copy( 0, n+1 );
     684           0 :     return rStr;
     685             : }
     686             : 
     687           0 : sal_Int32 SwAutoFormat::GetLeadingBlanks( const OUString& rStr )
     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 )
     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 SwTextNode& rNd ) const
     709             : {
     710           0 :     const OUString& rText = rNd.GetText();
     711           0 :     for( sal_Int32 n = 0, nEnd = rText.getLength(); n < nEnd; ++n )
     712           0 :         if (!IsSpace(rText[n]))
     713             :         {
     714           0 :             CharClass& rCC = GetCharClass( rNd.GetSwAttrSet().
     715           0 :                                         GetLanguage().GetLanguage() );
     716           0 :             sal_Int32 nCharType = rCC.getCharacterType( rText, 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 SwTextNode& 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& rText = rNd.GetText();
     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 < rText.getLength() && nDigitLvl < MAXLEVEL - 1)
     741             :     {
     742           0 :         const sal_Unicode cCurrentChar = rText[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( rText, nPos ) )
     775             :         {
     776             :             bool bIsUpper =
     777           0 :                 0 != ( i18n::KCharacterType::UPPER &
     778           0 :                                         rCC.getCharacterType( rText, nPos ));
     779           0 :             sal_Unicode cLow = rCC.lowercase(rText, 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(rText[nPos]);
     931           0 :             else if( pPostfix )
     932           0 :                 *pPostfix += OUString(rText[nPos]);
     933             : 
     934           0 :             if( NO_DELIM & eScan )
     935             :             {
     936           0 :                 eScan |= CHG;
     937           0 :                 if( pPrefix )
     938           0 :                     *pPrefix += "\x01" + OUString::number( nStart );
     939             :             }
     940           0 :             eScan &= ~NO_DELIM;     // remove Delim
     941           0 :             eScan |= DELIM;         // add Digit
     942           0 :             nDigitCnt = 0;
     943           0 :             nStart = 0;
     944             :         }
     945             :         else
     946             :             break;
     947           0 :         ++nPos;
     948             :     }
     949           0 :     if( !( CHG & eScan ) || rPos == nPos ||
     950           0 :         nPos == rText.getLength() || !IsSpace(rText[nPos]) ||
     951             :         (nOpeningParentheses > nClosingParentheses))
     952           0 :         return USHRT_MAX;
     953             : 
     954           0 :     if( (NO_DELIM & eScan) && pPrefix )     // do not forget the last one
     955           0 :         *pPrefix += "\x01" + OUString::number( nStart );
     956             : 
     957           0 :     rPos = nPos;
     958           0 :     return nDigitLvl;       // 0 .. 9 (MAXLEVEL - 1)
     959             : }
     960             : 
     961           0 : void SwAutoFormat::SetColl( sal_uInt16 nId, bool bHdLineOrText )
     962             : {
     963           0 :     m_aDelPam.DeleteMark();
     964           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
     965           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
     966             : 
     967             :     // keep hard tabs, alignment, language, hyphenation, DropCaps and nearly all frame attributes
     968           0 :     SfxItemSet aSet( m_pDoc->GetAttrPool(),
     969             :                         RES_PARATR_ADJUST, RES_PARATR_ADJUST,
     970             :                         RES_PARATR_TABSTOP, RES_PARATR_DROP,
     971             :                         RES_CHRATR_LANGUAGE, RES_CHRATR_LANGUAGE,
     972             :                         RES_BACKGROUND, RES_SHADOW,
     973           0 :                         0 );
     974             : 
     975           0 :     if( m_pCurTextNd->HasSwAttrSet() )
     976             :     {
     977           0 :         aSet.Put( *m_pCurTextNd->GetpSwAttrSet() );
     978             :         // take HeaderLine/TextBody only if centered or right aligned, otherwise only justification
     979             :         SvxAdjustItem const * pAdj;
     980           0 :         if( SfxItemState::SET == aSet.GetItemState( RES_PARATR_ADJUST,
     981           0 :                         false, reinterpret_cast<const SfxPoolItem**>(&pAdj) ))
     982             :         {
     983           0 :             SvxAdjust eAdj = pAdj->GetAdjust();
     984           0 :             if( bHdLineOrText ? (SVX_ADJUST_RIGHT != eAdj &&
     985             :                                  SVX_ADJUST_CENTER != eAdj)
     986             :                               : SVX_ADJUST_BLOCK != eAdj )
     987           0 :                 aSet.ClearItem( RES_PARATR_ADJUST );
     988             :         }
     989             :     }
     990             : 
     991           0 :     m_pDoc->SetTextFormatCollByAutoFormat( *m_aDelPam.GetPoint(), nId, &aSet );
     992           0 : }
     993             : 
     994           0 : bool SwAutoFormat::HasSelBlanks( SwPaM& rPam )
     995             : {
     996             :     // Is there a Blank at the beginning or end?
     997             :     // Do not delete it, it will be inserted again.
     998           0 :     SwPosition * pPos = rPam.End();
     999           0 :     sal_Int32 nBlnkPos = pPos->nContent.GetIndex();
    1000           0 :     SwTextNode* pTextNd = pPos->nNode.GetNode().GetTextNode();
    1001           0 :     if (nBlnkPos && nBlnkPos-- < pTextNd->GetText().getLength() &&
    1002           0 :         (' ' == pTextNd->GetText()[nBlnkPos]))
    1003           0 :         --pPos->nContent;
    1004             :     else
    1005             :     {
    1006           0 :         pPos = rPam.GetPoint() == pPos ? rPam.GetMark() : rPam.GetPoint();
    1007           0 :         nBlnkPos = pPos->nContent.GetIndex();
    1008           0 :         pTextNd = pPos->nNode.GetNode().GetTextNode();
    1009           0 :         if (nBlnkPos < pTextNd->GetText().getLength() &&
    1010           0 :             (' ' == pTextNd->GetText()[nBlnkPos]))
    1011           0 :             ++pPos->nContent;
    1012             :         else
    1013           0 :             return false;
    1014             :     }
    1015           0 :     return true;
    1016             : }
    1017             : 
    1018           0 : bool SwAutoFormat::HasBreakAttr( const SwTextNode& rTextNd )
    1019             : {
    1020           0 :     const SfxItemSet* pSet = rTextNd.GetpSwAttrSet();
    1021           0 :     if( !pSet )
    1022           0 :         return false;
    1023             : 
    1024             :     const SfxPoolItem* pItem;
    1025           0 :     if( SfxItemState::SET == pSet->GetItemState( RES_BREAK, false, &pItem )
    1026           0 :         && SVX_BREAK_NONE != static_cast<const SvxFormatBreakItem*>(pItem)->GetBreak() )
    1027           0 :         return true;
    1028             : 
    1029           0 :     if( SfxItemState::SET == pSet->GetItemState( RES_PAGEDESC, false, &pItem )
    1030           0 :         && static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc()
    1031           0 :         && nsUseOnPage::PD_NONE != static_cast<const SwFormatPageDesc*>(pItem)->GetPageDesc()->GetUseOn() )
    1032           0 :         return true;
    1033           0 :     return false;
    1034             : }
    1035             : 
    1036             : /// Is there a dot at the end?
    1037           0 : bool SwAutoFormat::IsSentenceAtEnd( const SwTextNode& rTextNd )
    1038             : {
    1039           0 :     const OUString& rStr = rTextNd.GetText();
    1040           0 :     sal_Int32 n = rStr.getLength();
    1041           0 :     if( !n )
    1042           0 :         return true;
    1043             : 
    1044           0 :     while( --n && IsSpace( rStr[ n ] ) )
    1045             :         ;
    1046           0 :     return '.' == rStr[ n ];
    1047             : }
    1048             : 
    1049             : /// Delete beginning and/or end in a node
    1050           0 : void SwAutoFormat::DeleteCurrentParagraph( bool bStart, bool bEnd )
    1051             : {
    1052           0 :     if( m_aFlags.bAFormatByInput
    1053             :         ? m_aFlags.bAFormatByInpDelSpacesAtSttEnd
    1054             :         : m_aFlags.bAFormatDelSpacesAtSttEnd )
    1055             :     {
    1056             :         // delete blanks at the end of the current and at the beginning of the next one
    1057           0 :         m_aDelPam.DeleteMark();
    1058           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1059           0 :         sal_Int32 nPos(0);
    1060           0 :         if( bStart && 0 != ( nPos = GetLeadingBlanks( m_pCurTextNd->GetText() )))
    1061             :         {
    1062           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
    1063           0 :             m_aDelPam.SetMark();
    1064           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    1065           0 :             DeleteSel( m_aDelPam );
    1066           0 :             m_aDelPam.DeleteMark();
    1067             :         }
    1068           0 :         if (bEnd && m_pCurTextNd->GetText().getLength() !=
    1069           0 :                     ( nPos = GetTrailingBlanks( m_pCurTextNd->GetText() )) )
    1070             :         {
    1071           0 :             m_aDelPam.GetPoint()->nContent.Assign(
    1072           0 :                     m_pCurTextNd, m_pCurTextNd->GetText().getLength());
    1073           0 :             m_aDelPam.SetMark();
    1074           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    1075           0 :             DeleteSel( m_aDelPam );
    1076           0 :             m_aDelPam.DeleteMark();
    1077             :         }
    1078             :     }
    1079           0 : }
    1080             : 
    1081           0 : void SwAutoFormat::DeleteSel( SwPaM& rDelPam )
    1082             : {
    1083           0 :     if( m_aFlags.bWithRedlining )
    1084             :     {
    1085             :         // Add to Shell-Cursor-Ring so that DelPam will be moved as well!
    1086           0 :         SwPaM* pShCrsr = m_pEditShell->_GetCrsr();
    1087           0 :         SwPaM aTmp( *m_pCurTextNd, 0, pShCrsr );
    1088             : 
    1089           0 :         SwPaM* pPrev = rDelPam.GetPrev();
    1090           0 :         rDelPam.GetRingContainer().merge( pShCrsr->GetRingContainer() );
    1091             : 
    1092           0 :         m_pEditShell->DeleteSel( rDelPam );
    1093             : 
    1094             :         // and remove Pam again:
    1095             :         SwPaM* p;
    1096           0 :         SwPaM* pNext = &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_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    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_pCurTextNd,
    1116           0 :                     GetTrailingBlanks( m_pCurTextNd->GetText() ) );
    1117           0 :     m_aDelPam.SetMark();
    1118             : 
    1119           0 :     ++m_aDelPam.GetPoint()->nNode;
    1120           0 :     SwTextNode* pTNd = m_aDelPam.GetNode().GetTextNode();
    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_pCurTextNd->GetText().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 :     SetRedlineText( 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_pCurTextNd, m_pCurTextNd->GetText().getLength() );
    1150           0 :     m_aDelPam.SetMark();
    1151             : 
    1152           0 :     --m_aDelPam.GetMark()->nNode;
    1153           0 :     SwTextNode* pTNd = m_aDelPam.GetNode( false ).GetTextNode();
    1154           0 :     if( pTNd )
    1155             :         // first use the previous text node
    1156           0 :         m_aDelPam.GetMark()->nContent.Assign(pTNd, pTNd->GetText().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 ).GetTextNode();
    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_pCurTextNd;
    1173             :     }
    1174           0 :     if( pTNd )
    1175           0 :         DeleteSel( m_aDelPam );
    1176             : 
    1177           0 :     m_aDelPam.DeleteMark();
    1178           0 :     ClearRedlineText();
    1179           0 : }
    1180             : 
    1181           0 : void SwAutoFormat::DelMoreLinesBlanks( bool bWithLineBreaks )
    1182             : {
    1183           0 :     if( m_aFlags.bAFormatByInput
    1184             :         ? m_aFlags.bAFormatByInpDelSpacesBetweenLines
    1185             :         : m_aFlags.bAFormatDelSpacesBetweenLines )
    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_pCurTextNd, 0 );
    1191             : 
    1192           0 :         SwTextFrmInfo aFInfo( m_pCurTextFrm );
    1193           0 :         aFInfo.GetSpaces( m_aDelPam, !m_aFlags.bAFormatByInput || bWithLineBreaks );
    1194             : 
    1195             :         do {
    1196           0 :             SwPaM* pNxt = m_aDelPam.GetNext();
    1197           0 :             if( pNxt->HasMark() && *pNxt->GetPoint() != *pNxt->GetMark() )
    1198             :             {
    1199           0 :                 bool bHasBlnks = HasSelBlanks( *pNxt );
    1200           0 :                 DeleteSel( *pNxt );
    1201           0 :                 if( !bHasBlnks )
    1202             :                 {
    1203           0 :                     m_pDoc->getIDocumentContentOperations().InsertString( *pNxt, OUString(' ') );
    1204             :                 }
    1205             :             }
    1206             : 
    1207           0 :             if( pNxt == &m_aDelPam )
    1208           0 :                 break;
    1209           0 :             delete pNxt;
    1210             :         } while( true );
    1211             : 
    1212           0 :         m_aDelPam.DeleteMark();
    1213             :     }
    1214           0 : }
    1215             : 
    1216             : // delete the previous paragraph
    1217           0 : void SwAutoFormat::DelPrevPara()
    1218             : {
    1219           0 :     m_aDelPam.DeleteMark();
    1220           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1221           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
    1222           0 :     m_aDelPam.SetMark();
    1223             : 
    1224           0 :     --m_aDelPam.GetPoint()->nNode;
    1225           0 :     SwTextNode* pTNd = m_aDelPam.GetNode().GetTextNode();
    1226           0 :     if( pTNd )
    1227             :     {
    1228             :         // use the previous text node first
    1229           0 :         m_aDelPam.GetPoint()->nContent.Assign(pTNd, pTNd->GetText().getLength());
    1230           0 :         DeleteSel( m_aDelPam );
    1231             :     }
    1232           0 :     m_aDelPam.DeleteMark();
    1233           0 : }
    1234             : 
    1235           0 : void SwAutoFormat::BuildIndent()
    1236             : {
    1237           0 :     SetRedlineText( STR_AUTOFMTREDL_SET_TMPL_INDENT );
    1238             : 
    1239             :     // read all succeeding paragraphs that belong to this indentation
    1240           0 :     bool bBreak = true;
    1241           0 :     if( m_bMoreLines )
    1242           0 :         DelMoreLinesBlanks( true );
    1243             :     else
    1244           0 :         bBreak = !IsFastFullLine( *m_pCurTextNd ) ||
    1245           0 :                 IsBlanksInString( *m_pCurTextNd ) ||
    1246           0 :                 IsSentenceAtEnd( *m_pCurTextNd );
    1247           0 :     SetColl( RES_POOLCOLL_TEXT_IDENT );
    1248           0 :     if( !bBreak )
    1249             :     {
    1250           0 :         SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
    1251           0 :         const SwTextNode* pNxtNd = GetNextNode();
    1252           0 :         if( pNxtNd && !m_bEnd )
    1253             :         {
    1254           0 :             do {
    1255           0 :                 bBreak = !IsFastFullLine( *pNxtNd ) ||
    1256           0 :                         IsBlanksInString( *pNxtNd ) ||
    1257           0 :                         IsSentenceAtEnd( *pNxtNd );
    1258           0 :                 if( DeleteCurNxtPara( pNxtNd->GetText() ))
    1259             :                 {
    1260           0 :                     m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
    1261             :                 }
    1262           0 :                 if( bBreak )
    1263           0 :                     break;
    1264           0 :                 pNxtNd = GetNextNode();
    1265           0 :             } while( CanJoin( pNxtNd ) &&
    1266           0 :                     !CalcLevel( *pNxtNd ) );
    1267             :         }
    1268             :     }
    1269           0 :     DeleteCurrentParagraph( true, true );
    1270           0 :     AutoCorrect();
    1271           0 : }
    1272             : 
    1273           0 : void SwAutoFormat::BuildTextIndent()
    1274             : {
    1275           0 :     SetRedlineText( STR_AUTOFMTREDL_SET_TMPL_TEXT_INDENT);
    1276             :     // read all succeeding paragraphs that belong to this indentation
    1277           0 :     bool bBreak = true;
    1278           0 :     if( m_bMoreLines )
    1279           0 :         DelMoreLinesBlanks( true );
    1280             :     else
    1281           0 :         bBreak = !IsFastFullLine( *m_pCurTextNd ) ||
    1282           0 :                     IsBlanksInString( *m_pCurTextNd ) ||
    1283           0 :                     IsSentenceAtEnd( *m_pCurTextNd );
    1284             : 
    1285           0 :     if( m_aFlags.bAFormatByInput )
    1286           0 :         m_pCurTextNd->SetAutoFormatLvl( (sal_uInt8)CalcLevel( *m_pCurTextNd ) );
    1287             : 
    1288           0 :     SetColl( RES_POOLCOLL_TEXT_MOVE );
    1289           0 :     if( !bBreak )
    1290             :     {
    1291           0 :         SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
    1292           0 :         const SwTextNode* pNxtNd = GetNextNode();
    1293           0 :         while(  CanJoin( pNxtNd ) &&
    1294           0 :                 CalcLevel( *pNxtNd ) )
    1295             :         {
    1296           0 :             bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1297           0 :                     IsSentenceAtEnd( *pNxtNd );
    1298           0 :             if( DeleteCurNxtPara( pNxtNd->GetText() ) )
    1299             :             {
    1300           0 :                 m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
    1301             :             }
    1302           0 :             if( bBreak )
    1303           0 :                 break;
    1304           0 :             pNxtNd = GetNextNode();
    1305             :         }
    1306             :     }
    1307           0 :     DeleteCurrentParagraph( true, true );
    1308           0 :     AutoCorrect();
    1309           0 : }
    1310             : 
    1311           0 : void SwAutoFormat::BuildText()
    1312             : {
    1313           0 :     SetRedlineText( STR_AUTOFMTREDL_SET_TMPL_TEXT );
    1314             :     // read all succeeding paragraphs that belong to this text without indentation
    1315           0 :     bool bBreak = true;
    1316           0 :     if( m_bMoreLines )
    1317           0 :         DelMoreLinesBlanks();
    1318             :     else
    1319           0 :         bBreak = !IsFastFullLine( *m_pCurTextNd ) ||
    1320           0 :                     IsBlanksInString( *m_pCurTextNd ) ||
    1321           0 :                     IsSentenceAtEnd( *m_pCurTextNd );
    1322           0 :     SetColl( RES_POOLCOLL_TEXT, true );
    1323           0 :     if( !bBreak )
    1324             :     {
    1325           0 :         SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
    1326           0 :         const SwTextNode* pNxtNd = GetNextNode();
    1327           0 :         while(  CanJoin( pNxtNd ) &&
    1328           0 :                 !CalcLevel( *pNxtNd ) )
    1329             :         {
    1330           0 :             bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1331           0 :                     IsSentenceAtEnd( *pNxtNd );
    1332           0 :             if( DeleteCurNxtPara( pNxtNd->GetText() ) )
    1333             :             {
    1334           0 :                 m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
    1335             :             }
    1336           0 :             if( bBreak )
    1337           0 :                 break;
    1338           0 :             const SwTextNode* pCurrNode = pNxtNd;
    1339           0 :             pNxtNd = GetNextNode();
    1340           0 :             if(!pNxtNd || pCurrNode == pNxtNd)
    1341             :                 break;
    1342             :         }
    1343             :     }
    1344           0 :     DeleteCurrentParagraph( true, true );
    1345           0 :     AutoCorrect();
    1346           0 : }
    1347             : 
    1348           0 : void SwAutoFormat::BuildEnum( sal_uInt16 nLvl, sal_uInt16 nDigitLevel )
    1349             : {
    1350           0 :     SetRedlineText( STR_AUTOFMTREDL_SET_NUMBULET );
    1351             : 
    1352           0 :     bool bBreak = true;
    1353             : 
    1354             :     // first, determine current indentation and frame width
    1355           0 :     SwTwips nFrmWidth = m_pCurTextFrm->Prt().Width();;
    1356             :     SwTwips nLeftTextPos;
    1357             :     {
    1358           0 :         sal_Int32 nPos(0);
    1359           0 :         while (nPos < m_pCurTextNd->GetText().getLength() &&
    1360           0 :                IsSpace(m_pCurTextNd->GetText()[nPos]))
    1361             :         {
    1362           0 :             ++nPos;
    1363             :         }
    1364             : 
    1365           0 :         SwTextFrmInfo aInfo( m_pCurTextFrm );
    1366           0 :         nLeftTextPos = aInfo.GetCharPos(nPos);
    1367           0 :         nLeftTextPos -= m_pCurTextNd->GetSwAttrSet().GetLRSpace().GetLeft();
    1368             :     }
    1369             : 
    1370           0 :     if( m_bMoreLines )
    1371           0 :         DelMoreLinesBlanks();
    1372             :     else
    1373           0 :         bBreak = !IsFastFullLine( *m_pCurTextNd ) ||
    1374           0 :                     IsBlanksInString( *m_pCurTextNd ) ||
    1375           0 :                     IsSentenceAtEnd( *m_pCurTextNd );
    1376           0 :     bool bRTL = m_pEditShell->IsInRightToLeftText();
    1377           0 :     DeleteCurrentParagraph( true, true );
    1378             : 
    1379           0 :     bool bChgBullet = false, bChgEnum = false;
    1380           0 :     sal_Int32 nAutoCorrPos = 0;
    1381             : 
    1382             :     // if numbering is set, get the current one
    1383             :     SwNumRule aRule( m_pDoc->GetUniqueNumRuleName(),
    1384             :                      // #i89178#
    1385           0 :                      numfunc::GetDefaultPositionAndSpaceMode() );
    1386             : 
    1387           0 :     const SwNumRule* pCur = 0;
    1388           0 :     if( m_aFlags.bSetNumRule && 0 != (pCur = m_pCurTextNd->GetNumRule()) )
    1389           0 :         aRule = *pCur;
    1390             : 
    1391             :     // replace bullet character with defined one
    1392           0 :     const OUString& rStr = m_pCurTextNd->GetText();
    1393           0 :     sal_Int32 nTextStt = 0;
    1394             :     const sal_Unicode* pFndBulletChr;
    1395           0 :     if( m_aFlags.bChgEnumNum &&
    1396           0 :         2 < rStr.getLength() &&
    1397           0 :         0 != ( pFndBulletChr = StrChr( pBulletChar, rStr[ nTextStt ] ))
    1398           0 :         && IsSpace( rStr[ nTextStt + 1 ] ) )
    1399             :     {
    1400           0 :         if( m_aFlags.bAFormatByInput )
    1401             :         {
    1402           0 :             if( m_aFlags.bSetNumRule )
    1403             :             {
    1404           0 :                 SwCharFormat* pCFormat = m_pDoc->getIDocumentStylePoolAccess().GetCharFormatFromPool(
    1405           0 :                                             RES_POOLCHR_BUL_LEVEL );
    1406           0 :                 bChgBullet = true;
    1407             :                 // Was the format already somewhere adjusted?
    1408           0 :                 if( !aRule.GetNumFormat( nLvl ) )
    1409             :                 {
    1410           0 :                     int nBulletPos = pFndBulletChr - pBulletChar;
    1411             :                     sal_Unicode cBullChar;
    1412           0 :                     const vcl::Font* pBullFnt( 0 );
    1413           0 :                     if( nBulletPos < cnPosEnDash )
    1414             :                     {
    1415           0 :                         cBullChar = m_aFlags.cBullet;
    1416           0 :                         pBullFnt = &m_aFlags.aBulletFont;
    1417             :                     }
    1418             :                     else
    1419             :                     {
    1420             :                         cBullChar = nBulletPos < cnPosEmDash
    1421             :                                         ? cStarSymbolEnDash
    1422           0 :                                         : cStarSymbolEmDash;
    1423             :                         // #i63395#
    1424             :                         // Only apply user defined default bullet font
    1425           0 :                         if ( numfunc::IsDefBulletFontUserDefined() )
    1426             :                         {
    1427           0 :                             pBullFnt = &numfunc::GetDefBulletFont();
    1428             :                         }
    1429             :                     }
    1430             : 
    1431           0 :                     sal_uInt16 nAbsPos = lBullIndent;
    1432             :                     sal_uInt16 nSpaceSteps = nLvl
    1433           0 :                                             ? sal_uInt16(nLeftTextPos / nLvl)
    1434           0 :                                             : lBullIndent;
    1435           0 :                     for( sal_uInt8 n = 0; n < MAXLEVEL; ++n, nAbsPos = nAbsPos + nSpaceSteps )
    1436             :                     {
    1437           0 :                         SwNumFormat aFormat( aRule.Get( n ) );
    1438           0 :                         aFormat.SetBulletFont( pBullFnt );
    1439           0 :                         aFormat.SetBulletChar( cBullChar );
    1440           0 :                         aFormat.SetNumberingType(SVX_NUM_CHAR_SPECIAL);
    1441             :                         // #i93908# clear suffix for bullet lists
    1442           0 :                         aFormat.SetPrefix(OUString());
    1443           0 :                         aFormat.SetSuffix(OUString());
    1444           0 :                         aFormat.SetFirstLineOffset( lBullFirstLineOffset );
    1445           0 :                         aFormat.SetAbsLSpace( nAbsPos );
    1446           0 :                         if( !aFormat.GetCharFormat() )
    1447           0 :                             aFormat.SetCharFormat( pCFormat );
    1448           0 :                         if( bRTL )
    1449           0 :                             aFormat.SetNumAdjust( SVX_ADJUST_RIGHT );
    1450             : 
    1451           0 :                         aRule.Set( n, aFormat );
    1452             : 
    1453           0 :                         if( n == nLvl &&
    1454           0 :                             nFrmWidth < ( nSpaceSteps * MAXLEVEL ) )
    1455           0 :                             nSpaceSteps = static_cast<sal_uInt16>(( nFrmWidth - nLeftTextPos ) /
    1456           0 :                                                 ( MAXLEVEL - nLvl ));
    1457           0 :                     }
    1458             :                 }
    1459             :             }
    1460             :         }
    1461             :         else
    1462             :         {
    1463           0 :             bChgBullet = true;
    1464           0 :             SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_BUL_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 )) );
    1465             :         }
    1466             :     }
    1467             :     else
    1468             :     {
    1469             :         // Then it is a numbering
    1470             : 
    1471             :         //JP 21.11.97: The NumLevel is either the DigitLevel or, if the latter is not existent or 0,
    1472             :         //             it is determined by the indentation level.
    1473             : 
    1474           0 :         OUString aPostfix, aPrefix, aNumTypes;
    1475           0 :         if( USHRT_MAX != ( nDigitLevel = GetDigitLevel( *m_pCurTextNd, nTextStt,
    1476           0 :                                         &aPrefix, &aPostfix, &aNumTypes )) )
    1477             :         {
    1478           0 :             bChgEnum = true;
    1479             : 
    1480             :             // Level 0 and Indentation, determine level by left indentation and default NumIndent
    1481           0 :             if( !nDigitLevel && nLeftTextPos )
    1482           0 :                 nLvl = std::min( sal_uInt16( nLeftTextPos / lNumIndent ),
    1483           0 :                             sal_uInt16( MAXLEVEL - 1 ) );
    1484             :             else
    1485           0 :                 nLvl = nDigitLevel;
    1486             :         }
    1487             : 
    1488           0 :         if( bChgEnum && m_aFlags.bSetNumRule )
    1489             :         {
    1490           0 :             if( !pCur )         // adjust NumRule if it is new
    1491             :             {
    1492           0 :                 SwCharFormat* pCFormat = m_pDoc->getIDocumentStylePoolAccess().GetCharFormatFromPool(
    1493           0 :                                             RES_POOLCHR_NUM_LEVEL );
    1494           0 :                 if( !nDigitLevel )
    1495             :                 {
    1496           0 :                     SwNumFormat aFormat( aRule.Get( nLvl ) );
    1497             :                     aFormat.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( 1,
    1498           0 :                                             (sal_Unicode)1 ).toInt32()));
    1499           0 :                     aFormat.SetPrefix( aPrefix.getToken( 0, (sal_Unicode)1 ));
    1500           0 :                     aFormat.SetSuffix( aPostfix.getToken( 0, (sal_Unicode)1 ));
    1501           0 :                     aFormat.SetIncludeUpperLevels( 0 );
    1502             : 
    1503           0 :                     if( !aFormat.GetCharFormat() )
    1504           0 :                         aFormat.SetCharFormat( pCFormat );
    1505             : 
    1506           0 :                     if( !aNumTypes.isEmpty() )
    1507           0 :                         aFormat.SetNumberingType(aNumTypes[ 0 ] - '0');
    1508             : 
    1509           0 :                     if( bRTL )
    1510           0 :                         aFormat.SetNumAdjust( SVX_ADJUST_RIGHT );
    1511           0 :                     aRule.Set( nLvl, aFormat );
    1512             :                 }
    1513             :                 else
    1514             :                 {
    1515           0 :                     sal_uInt16 nSpaceSteps = nLvl ? sal_uInt16(nLeftTextPos / nLvl) : 0;
    1516             :                     sal_uInt8 n;
    1517           0 :                     for( n = 0; n <= nLvl; ++n )
    1518             :                     {
    1519           0 :                         SwNumFormat aFormat( aRule.Get( n ) );
    1520             : 
    1521             :                         aFormat.SetStart( static_cast<sal_uInt16>(aPrefix.getToken( n+1,
    1522           0 :                                                     (sal_Unicode)1 ).toInt32() ));
    1523           0 :                         if( !n )
    1524           0 :                             aFormat.SetPrefix( aPrefix.getToken( n, (sal_Unicode)1 ));
    1525           0 :                         aFormat.SetSuffix( aPostfix.getToken( n, (sal_Unicode)1 ));
    1526           0 :                         aFormat.SetIncludeUpperLevels( MAXLEVEL );
    1527           0 :                         if( n < aNumTypes.getLength() )
    1528           0 :                             aFormat.SetNumberingType((aNumTypes[ n ] - '0'));
    1529             : 
    1530             :                         aFormat.SetAbsLSpace( sal_uInt16( nSpaceSteps * n )
    1531           0 :                                             + lNumIndent );
    1532             : 
    1533           0 :                         if( !aFormat.GetCharFormat() )
    1534           0 :                             aFormat.SetCharFormat( pCFormat );
    1535           0 :                         if( bRTL )
    1536           0 :                             aFormat.SetNumAdjust( SVX_ADJUST_RIGHT );
    1537             : 
    1538           0 :                         aRule.Set( n, aFormat );
    1539           0 :                     }
    1540             : 
    1541             :                     // Does it fit completely into the frame?
    1542           0 :                     bool bDefStep = nFrmWidth < (nSpaceSteps * MAXLEVEL);
    1543           0 :                     for( ; n < MAXLEVEL; ++n )
    1544             :                     {
    1545           0 :                         SwNumFormat aFormat( aRule.Get( n ) );
    1546           0 :                         aFormat.SetIncludeUpperLevels( MAXLEVEL );
    1547           0 :                         if( bDefStep )
    1548             :                             aFormat.SetAbsLSpace( sal_uInt16( (nLeftTextPos +
    1549           0 :                                 SwNumRule::GetNumIndent(static_cast<sal_uInt8>(n-nLvl)))));
    1550             :                         else
    1551             :                             aFormat.SetAbsLSpace( sal_uInt16( nSpaceSteps * n )
    1552           0 :                                                 + lNumIndent );
    1553           0 :                         aRule.Set( n, aFormat );
    1554           0 :                     }
    1555             :                 }
    1556           0 :             }
    1557             :         }
    1558           0 :         else if( !m_aFlags.bAFormatByInput )
    1559           0 :             SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_NUM_LEVEL1 + ( std::min( nLvl, cnNumBullColls ) * 4 ) ));
    1560             :         else
    1561           0 :             bChgEnum = false;
    1562             :     }
    1563             : 
    1564           0 :     if ( bChgEnum || bChgBullet )
    1565             :     {
    1566           0 :         m_aDelPam.DeleteMark();
    1567           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1568             : 
    1569           0 :         if( m_aFlags.bSetNumRule )
    1570             :         {
    1571           0 :             if( m_aFlags.bAFormatByInput )
    1572             :             {
    1573           0 :                 m_aDelPam.SetMark();
    1574           0 :                 ++m_aDelPam.GetMark()->nNode;
    1575           0 :                 m_aDelPam.GetNode(false).GetTextNode()->SetAttrListLevel( nLvl );
    1576             :             }
    1577             : 
    1578           0 :             m_pCurTextNd->SetAttrListLevel(nLvl);
    1579           0 :             m_pCurTextNd->SetNumLSpace( true );
    1580             : 
    1581             :             // start new list
    1582           0 :             m_pDoc->SetNumRule( m_aDelPam, aRule, true );
    1583           0 :             m_aDelPam.DeleteMark();
    1584             : 
    1585           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
    1586             :         }
    1587             :         else
    1588           0 :             m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd,
    1589           0 :                         bChgEnum ? nTextStt : 0 );
    1590           0 :         m_aDelPam.SetMark();
    1591             : 
    1592           0 :         if ( bChgBullet )
    1593           0 :             nTextStt += 2;
    1594             : 
    1595           0 :         while( nTextStt < rStr.getLength() && IsSpace( rStr[ nTextStt ] ))
    1596           0 :             nTextStt++;
    1597             : 
    1598           0 :         m_aDelPam.GetPoint()->nContent = nTextStt;
    1599           0 :         DeleteSel( m_aDelPam );
    1600             : 
    1601           0 :         if( !m_aFlags.bSetNumRule )
    1602             :         {
    1603           0 :             OUString sChgStr('\t');
    1604           0 :             if( bChgBullet )
    1605           0 :                 sChgStr = OUString( m_aFlags.cBullet ) + sChgStr;
    1606           0 :             m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, sChgStr );
    1607             : 
    1608           0 :             SfxItemSet aSet( m_pDoc->GetAttrPool(), aTextNodeSetRange );
    1609           0 :             if( bChgBullet )
    1610             :             {
    1611           0 :                 m_aDelPam.GetPoint()->nContent = 0;
    1612           0 :                 m_aDelPam.SetMark();
    1613           0 :                 m_aDelPam.GetMark()->nContent = 1;
    1614             :                 SetAllScriptItem( aSet,
    1615             :                      SvxFontItem( m_aFlags.aBulletFont.GetFamily(),
    1616           0 :                                   m_aFlags.aBulletFont.GetName(),
    1617           0 :                                   m_aFlags.aBulletFont.GetStyleName(),
    1618             :                                   m_aFlags.aBulletFont.GetPitch(),
    1619           0 :                                   m_aFlags.aBulletFont.GetCharSet(),
    1620           0 :                                   RES_CHRATR_FONT ) );
    1621           0 :                 m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
    1622           0 :                 m_aDelPam.DeleteMark();
    1623           0 :                 nAutoCorrPos = 2;
    1624           0 :                 aSet.ClearItem();
    1625             :             }
    1626           0 :             SvxTabStopItem aTStops( RES_PARATR_TABSTOP );
    1627           0 :             aTStops.Insert( SvxTabStop( 0 ) );
    1628           0 :             aSet.Put( aTStops );
    1629           0 :             m_pDoc->SetFormatItemByAutoFormat( m_aDelPam, aSet );
    1630             :         }
    1631             :     }
    1632             : 
    1633           0 :     if( bBreak )
    1634             :     {
    1635           0 :         AutoCorrect( nAutoCorrPos );       /* Offset due to Bullet + Tab */
    1636           0 :         return;
    1637             :     }
    1638             : 
    1639           0 :     const SwTextNode* pNxtNd = GetNextNode();
    1640           0 :     while( CanJoin( pNxtNd ) &&
    1641           0 :             nLvl == CalcLevel( *pNxtNd ) )
    1642             :     {
    1643           0 :         SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
    1644           0 :         bBreak = !IsFastFullLine( *pNxtNd ) || IsBlanksInString( *pNxtNd ) ||
    1645           0 :                 IsSentenceAtEnd( *pNxtNd );
    1646           0 :         if( DeleteCurNxtPara( pNxtNd->GetText() ) )
    1647             :         {
    1648           0 :             m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
    1649             :         }
    1650           0 :         if( bBreak )
    1651           0 :             break;
    1652           0 :         const SwTextNode* pCurrNode = pNxtNd;
    1653           0 :         pNxtNd = GetNextNode();
    1654           0 :         if(!pNxtNd || pCurrNode == pNxtNd)
    1655             :             break;
    1656             :     }
    1657           0 :     DeleteCurrentParagraph( false, true );
    1658           0 :     AutoCorrect( nAutoCorrPos );
    1659             : }
    1660             : 
    1661           0 : void SwAutoFormat::BuildNegIndent( SwTwips nSpaces )
    1662             : {
    1663           0 :     SetRedlineText( STR_AUTOFMTREDL_SET_TMPL_NEG_INDENT );
    1664             :     // Test of contraposition (n words, divided by spaces/tabs, with same indentation in 2nd line)
    1665             : 
    1666             :     // read all succeeding paragraphs that belong to this enumeration
    1667           0 :     bool bBreak = true;
    1668           0 :     sal_Int32 nSpacePos = 0;
    1669           0 :     const sal_Int32 nTextPos = GetBigIndent( nSpacePos );
    1670           0 :     if( m_bMoreLines )
    1671           0 :         DelMoreLinesBlanks( true );
    1672             :     else
    1673           0 :         bBreak = !IsFastFullLine( *m_pCurTextNd ) ||
    1674           0 :                     ( !nTextPos && IsBlanksInString( *m_pCurTextNd )) ||
    1675           0 :                     IsSentenceAtEnd( *m_pCurTextNd );
    1676             : 
    1677             :     SetColl( static_cast<sal_uInt16>( nTextPos
    1678             :                 ? RES_POOLCOLL_CONFRONTATION
    1679           0 :                 : RES_POOLCOLL_TEXT_NEGIDENT ) );
    1680             : 
    1681           0 :     if( nTextPos )
    1682             :     {
    1683           0 :         const OUString& rStr = m_pCurTextNd->GetText();
    1684           0 :         bool bInsTab = true;
    1685             : 
    1686           0 :         if ('\t' == rStr[nSpacePos+1]) // leave tab alone
    1687             :         {
    1688           0 :             --nSpacePos;
    1689           0 :             bInsTab = false;
    1690             :         }
    1691             : 
    1692           0 :         sal_Int32 nSpaceStt = nSpacePos;
    1693           0 :         while (nSpaceStt && IsSpace(rStr[--nSpaceStt]))
    1694             :             ;
    1695           0 :         ++nSpaceStt;
    1696             : 
    1697           0 :         if (bInsTab && '\t' == rStr[nSpaceStt]) // leave tab alone
    1698             :         {
    1699           0 :             ++nSpaceStt;
    1700           0 :             bInsTab = false;
    1701             :         }
    1702             : 
    1703           0 :         m_aDelPam.DeleteMark();
    1704           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1705           0 :         m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, nSpacePos );
    1706             : 
    1707             :         // delete old Spaces, etc.
    1708           0 :         if( nSpaceStt < nSpacePos )
    1709             :         {
    1710           0 :             m_aDelPam.SetMark();
    1711           0 :             m_aDelPam.GetMark()->nContent = nSpaceStt;
    1712           0 :             DeleteSel( m_aDelPam );
    1713           0 :             if( bInsTab )
    1714             :             {
    1715           0 :                 m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString('\t') );
    1716             :             }
    1717             :         }
    1718             :     }
    1719             : 
    1720           0 :     if( !bBreak )
    1721             :     {
    1722           0 :         SetRedlineText( STR_AUTOFMTREDL_DEL_MORELINES );
    1723           0 :         SwTextFrmInfo aFInfo( m_pCurTextFrm );
    1724           0 :         const SwTextNode* pNxtNd = GetNextNode();
    1725           0 :         while(  CanJoin( pNxtNd ) &&
    1726             :                 20 < std::abs( (long)(nSpaces - aFInfo.SetFrm(
    1727           0 :                                 GetFrm( *pNxtNd ) ).GetLineStart() ))
    1728             :             )
    1729             :         {
    1730           0 :             bBreak = !IsFastFullLine( *pNxtNd ) ||
    1731           0 :                     IsBlanksInString( *pNxtNd ) ||
    1732           0 :                     IsSentenceAtEnd( *pNxtNd );
    1733           0 :             if( DeleteCurNxtPara( pNxtNd->GetText() ) )
    1734             :             {
    1735           0 :                 m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(' ') );
    1736             :             }
    1737           0 :             if( bBreak )
    1738           0 :                 break;
    1739           0 :             pNxtNd = GetNextNode();
    1740             :         }
    1741             :     }
    1742           0 :     DeleteCurrentParagraph( true, true );
    1743           0 :     AutoCorrect();
    1744           0 : }
    1745             : 
    1746           0 : void SwAutoFormat::BuildHeadLine( sal_uInt16 nLvl )
    1747             : {
    1748           0 :     if( m_aFlags.bWithRedlining )
    1749             :     {
    1750           0 :         OUString sText(SwViewShell::GetShellRes()->GetAutoFormatNameLst()[
    1751           0 :                                     STR_AUTOFMTREDL_SET_TMPL_HEADLINE ] );
    1752           0 :         sText = sText.replaceAll( "$(ARG1)", OUString::number( nLvl + 1 ) );
    1753           0 :         m_pDoc->GetDocumentRedlineManager().SetAutoFormatRedlineComment( &sText );
    1754             :     }
    1755             : 
    1756           0 :     SetColl( static_cast<sal_uInt16>(RES_POOLCOLL_HEADLINE1 + nLvl ), true );
    1757           0 :     if( m_aFlags.bAFormatByInput )
    1758             :     {
    1759           0 :         SwTextFormatColl& rNxtColl = m_pCurTextNd->GetTextColl()->GetNextTextFormatColl();
    1760             : 
    1761           0 :         DelPrevPara();
    1762             : 
    1763           0 :         DeleteCurrentParagraph( true, false );
    1764           0 :         (void)DeleteCurNxtPara( OUString() );
    1765             : 
    1766           0 :         m_aDelPam.DeleteMark();
    1767           0 :         m_aDelPam.GetPoint()->nNode = m_aNdIdx.GetIndex() + 1;
    1768           0 :         m_aDelPam.GetPoint()->nContent.Assign( m_aDelPam.GetContentNode(), 0 );
    1769           0 :         m_pDoc->SetTextFormatColl( m_aDelPam, &rNxtColl );
    1770             :     }
    1771             :     else
    1772             :     {
    1773           0 :         DeleteCurrentParagraph( true, true );
    1774           0 :         AutoCorrect();
    1775             :     }
    1776           0 : }
    1777             : 
    1778             : /// Start autocorrection for the current TextNode
    1779           0 : void SwAutoFormat::AutoCorrect( sal_Int32 nPos )
    1780             : {
    1781           0 :     SvxAutoCorrect* pATst = SvxAutoCorrCfg::Get().GetAutoCorrect();
    1782           0 :     long aSvxFlags = pATst->GetFlags( );
    1783           0 :     bool bReplaceQuote = ( aSvxFlags & ChgQuotes ) > 0;
    1784           0 :     bool bReplaceSglQuote = ( aSvxFlags & ChgSglQuotes ) > 0;
    1785             : 
    1786           0 :     if( m_aFlags.bAFormatByInput ||
    1787           0 :         (!m_aFlags.bAutoCorrect && !bReplaceQuote && !bReplaceSglQuote &&
    1788           0 :         !m_aFlags.bCapitalStartSentence && !m_aFlags.bCapitalStartWord &&
    1789           0 :         !m_aFlags.bChgOrdinalNumber &&
    1790           0 :         !m_aFlags.bChgToEnEmDash && !m_aFlags.bSetINetAttr &&
    1791           0 :         !m_aFlags.bChgWeightUnderl && !m_aFlags.bAddNonBrkSpace) )
    1792           0 :         return;
    1793             : 
    1794           0 :     const OUString* pText = &m_pCurTextNd->GetText();
    1795           0 :     if (nPos >= pText->getLength())
    1796           0 :         return;
    1797             : 
    1798           0 :     bool bGetLanguage = m_aFlags.bChgOrdinalNumber ||
    1799           0 :                         m_aFlags.bChgToEnEmDash || m_aFlags.bSetINetAttr ||
    1800           0 :                         m_aFlags.bCapitalStartWord || m_aFlags.bCapitalStartSentence ||
    1801           0 :                         m_aFlags.bAddNonBrkSpace;
    1802             : 
    1803           0 :     m_aDelPam.DeleteMark();
    1804           0 :     m_aDelPam.GetPoint()->nNode = m_aNdIdx;
    1805           0 :     m_aDelPam.GetPoint()->nContent.Assign( m_pCurTextNd, 0 );
    1806             : 
    1807           0 :     SwAutoCorrDoc aACorrDoc( *m_pEditShell, m_aDelPam );
    1808             : 
    1809           0 :     SwTextFrmInfo aFInfo( 0 );
    1810             : 
    1811           0 :     sal_Int32 nSttPos, nLastBlank = nPos;
    1812           0 :     bool bFirst = m_aFlags.bCapitalStartSentence, bFirstSent = bFirst;
    1813           0 :     sal_Unicode cChar = 0;
    1814             : 
    1815           0 :     CharClass& rAppCC = GetAppCharClass();
    1816             : 
    1817           0 :     do {
    1818           0 :         while (nPos < pText->getLength() && IsSpace(cChar = (*pText)[nPos]))
    1819           0 :             ++nPos;
    1820           0 :         if (nPos == pText->getLength())
    1821           0 :             break;      // das wars
    1822             : 
    1823           0 :         if( ( ( bReplaceQuote && '\"' == cChar ) ||
    1824           0 :               ( bReplaceSglQuote && '\'' == cChar ) ) &&
    1825           0 :             (!nPos || ' ' == (*pText)[nPos-1]))
    1826             :         {
    1827             : 
    1828             :             // beachte: Sonderfall Symbolfonts !!!
    1829           0 :             if( !aFInfo.GetFrm() )
    1830           0 :                 aFInfo.SetFrm( GetFrm( *m_pCurTextNd ) );
    1831           0 :             if( !aFInfo.IsBullet( nPos ))
    1832             :             {
    1833           0 :                 SetRedlineText( STR_AUTOFMTREDL_TYPO );
    1834           0 :                 m_aDelPam.GetPoint()->nContent = nPos;
    1835           0 :                 bool bSetHardBlank = false;
    1836             : 
    1837             :                 OUString sReplace( pATst->GetQuote( aACorrDoc,
    1838           0 :                                     nPos, cChar, true ));
    1839             : 
    1840           0 :                 m_aDelPam.SetMark();
    1841           0 :                 m_aDelPam.GetPoint()->nContent = nPos+1;
    1842           0 :                 if( 2 == sReplace.getLength() && ' ' == sReplace[ 1 ])
    1843             :                 {
    1844           0 :                     sReplace = sReplace.copy( 0, 1 );
    1845           0 :                     bSetHardBlank = true;
    1846             :                 }
    1847           0 :                 m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
    1848             : 
    1849           0 :                 if( m_aFlags.bWithRedlining )
    1850             :                 {
    1851           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1852           0 :                     m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    1853           0 :                     pText = &m_pCurTextNd->GetText();
    1854           0 :                     m_aDelPam.SetMark();
    1855           0 :                     aFInfo.SetFrm( 0 );
    1856             :                 }
    1857             : 
    1858           0 :                 nPos += sReplace.getLength() - 1;
    1859           0 :                 m_aDelPam.DeleteMark();
    1860           0 :                 if( bSetHardBlank )
    1861             :                 {
    1862           0 :                     m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
    1863           0 :                     ++nPos;
    1864           0 :                 }
    1865             :             }
    1866             :         }
    1867             : 
    1868           0 :         bool bCallACorr = false;
    1869           0 :         int bBreak = 0;
    1870           0 :         if (nPos && IsSpace((*pText)[nPos-1]))
    1871           0 :             nLastBlank = nPos;
    1872           0 :         for (nSttPos = nPos; !bBreak && nPos < pText->getLength(); ++nPos)
    1873           0 :             switch (cChar = (*pText)[nPos])
    1874             :             {
    1875             :             case '\"':
    1876             :             case '\'':
    1877           0 :                 if( ( cChar == '\"' && bReplaceQuote ) || ( cChar == '\'' && bReplaceSglQuote ) )
    1878             :                 {
    1879             :                     // consider Symbolfonts!
    1880           0 :                     if( !aFInfo.GetFrm() )
    1881           0 :                         aFInfo.SetFrm( GetFrm( *m_pCurTextNd ) );
    1882           0 :                     if( !aFInfo.IsBullet( nPos ))
    1883             :                     {
    1884           0 :                         SetRedlineText( STR_AUTOFMTREDL_TYPO );
    1885           0 :                         bool bSetHardBlank = false;
    1886           0 :                         m_aDelPam.GetPoint()->nContent = nPos;
    1887             :                         OUString sReplace( pATst->GetQuote( aACorrDoc,
    1888           0 :                                                     nPos, cChar, false ));
    1889             : 
    1890           0 :                         if( 2 == sReplace.getLength() && ' ' == sReplace[ 0 ])
    1891             :                         {
    1892           0 :                             sReplace = sReplace.copy( 1 );
    1893           0 :                             bSetHardBlank = true;
    1894             :                         }
    1895             : 
    1896           0 :                         m_aDelPam.SetMark();
    1897           0 :                         m_aDelPam.GetPoint()->nContent = nPos+1;
    1898           0 :                         m_pDoc->getIDocumentContentOperations().ReplaceRange( m_aDelPam, sReplace, false );
    1899             : 
    1900           0 :                         if( m_aFlags.bWithRedlining )
    1901             :                         {
    1902           0 :                             m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1903           0 :                             m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    1904           0 :                             pText = &m_pCurTextNd->GetText();
    1905           0 :                             m_aDelPam.SetMark();
    1906           0 :                             m_aDelPam.DeleteMark();
    1907           0 :                             aFInfo.SetFrm( 0 );
    1908             :                         }
    1909             : 
    1910           0 :                         nPos += sReplace.getLength() - 1;
    1911           0 :                         m_aDelPam.DeleteMark();
    1912             : 
    1913           0 :                         if( bSetHardBlank )
    1914             :                         {
    1915           0 :                             m_aDelPam.GetPoint()->nContent = nPos;
    1916           0 :                             m_pDoc->getIDocumentContentOperations().InsertString( m_aDelPam, OUString(CHAR_HARDBLANK) );
    1917           0 :                             m_aDelPam.GetPoint()->nContent = ++nPos;
    1918           0 :                         }
    1919             :                     }
    1920             :                 }
    1921           0 :                 break;
    1922             :             case '*':
    1923             :             case '_':
    1924           0 :                 if( m_aFlags.bChgWeightUnderl )
    1925             :                 {
    1926             :                     // consider Symbolfonts!
    1927           0 :                     if( !aFInfo.GetFrm() )
    1928           0 :                         aFInfo.SetFrm( GetFrm( *m_pCurTextNd ) );
    1929           0 :                     if( !aFInfo.IsBullet( nPos ))
    1930             :                     {
    1931             :                         SetRedlineText( '*' == cChar
    1932             :                                             ? STR_AUTOFMTREDL_BOLD
    1933           0 :                                             : STR_AUTOFMTREDL_UNDER );
    1934             : 
    1935           0 :                         sal_Unicode cBlank = nSttPos ? (*pText)[nSttPos - 1] : 0;
    1936           0 :                         m_aDelPam.GetPoint()->nContent = nPos;
    1937             : 
    1938           0 :                         if( pATst->FnChgWeightUnderl( aACorrDoc, *pText,
    1939           0 :                                                             nSttPos, nPos ))
    1940             :                         {
    1941           0 :                             if( m_aFlags.bWithRedlining )
    1942             :                             {
    1943           0 :                                 m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    1944           0 :                                 m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    1945           0 :                                 pText = &m_pCurTextNd->GetText();
    1946           0 :                                 m_aDelPam.SetMark();
    1947           0 :                                 m_aDelPam.DeleteMark();
    1948           0 :                                 aFInfo.SetFrm( 0 );
    1949             :                             }
    1950             :                             //#125102# in case of the mode REDLINE_SHOW_DELETE the ** are still contained in pText
    1951           0 :                             if(0 == (m_pDoc->getIDocumentRedlineAccess().GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_DELETE))
    1952           0 :                                 nPos = m_aDelPam.GetPoint()->nContent.GetIndex() - 1;
    1953             :                             // Was a character deleted before starting?
    1954           0 :                             if (cBlank && cBlank != (*pText)[nSttPos - 1])
    1955           0 :                                 --nSttPos;
    1956             :                         }
    1957             :                     }
    1958             :                 }
    1959           0 :                 break;
    1960             :             case '/':
    1961           0 :                 if ( m_aFlags.bAddNonBrkSpace )
    1962             :                 {
    1963             :                     LanguageType eLang = bGetLanguage
    1964           0 :                                            ? m_pCurTextNd->GetLang( nSttPos )
    1965           0 :                                            : LANGUAGE_SYSTEM;
    1966             : 
    1967           0 :                     SetRedlineText( STR_AUTOFMTREDL_NON_BREAK_SPACE );
    1968           0 :                     if ( pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nSttPos, nPos, eLang ) )
    1969           0 :                         --nPos;
    1970             :                 }
    1971           0 :                 break;
    1972             : 
    1973             :             case '.':
    1974             :             case '!':
    1975             :             case '?':
    1976           0 :                 if( m_aFlags.bCapitalStartSentence )
    1977           0 :                     bFirstSent = true;
    1978             :                 /* fallthrough */
    1979             :             default:
    1980           0 :                 if( !( rAppCC.isLetterNumeric( *pText, nPos )
    1981           0 :                         || '/' == cChar )) //  '/' should not be a word separator (e.g. '1/2' needs to be handled as one word for replacement)
    1982             :                 {
    1983           0 :                     --nPos;     // revert ++nPos which was decremented in for loop
    1984           0 :                     ++bBreak;
    1985             :                 }
    1986           0 :                 break;
    1987             :             }
    1988             : 
    1989           0 :         if( nPos == nSttPos )
    1990             :         {
    1991           0 :             if (++nPos == pText->getLength())
    1992           0 :                 bCallACorr = true;
    1993             :         }
    1994             :         else
    1995           0 :             bCallACorr = true;
    1996             : 
    1997           0 :         if( bCallACorr )
    1998             :         {
    1999           0 :             bCallACorr = false;
    2000           0 :             m_aDelPam.GetPoint()->nContent = nPos;
    2001           0 :             SetRedlineText( STR_AUTOFMTREDL_USE_REPLACE );
    2002           0 :             if( m_aFlags.bAutoCorrect &&
    2003           0 :                 aACorrDoc.ChgAutoCorrWord( nSttPos, nPos, *pATst, 0 ) )
    2004             :             {
    2005           0 :                 nPos = m_aDelPam.GetPoint()->nContent.GetIndex();
    2006             : 
    2007           0 :                 if( m_aFlags.bWithRedlining )
    2008             :                 {
    2009           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    2010           0 :                     m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    2011           0 :                     pText = &m_pCurTextNd->GetText();
    2012           0 :                     m_aDelPam.SetMark();
    2013           0 :                     m_aDelPam.DeleteMark();
    2014             :                 }
    2015             : 
    2016           0 :                 continue;       // do not check further
    2017             :             }
    2018             : 
    2019             :             LanguageType eLang = bGetLanguage
    2020           0 :                                            ? m_pCurTextNd->GetLang( nSttPos )
    2021           0 :                                            : LANGUAGE_SYSTEM;
    2022             : 
    2023           0 :             if ( m_aFlags.bAddNonBrkSpace )
    2024             :             {
    2025           0 :                 SetRedlineText( STR_AUTOFMTREDL_NON_BREAK_SPACE );
    2026           0 :                 pATst->FnAddNonBrkSpace( aACorrDoc, *pText, nSttPos, nPos, eLang );
    2027             :             }
    2028             : 
    2029           0 :             if( ( m_aFlags.bChgOrdinalNumber &&
    2030           0 :                     SetRedlineText( STR_AUTOFMTREDL_ORDINAL ) &&
    2031           0 :                     pATst->FnChgOrdinalNumber( aACorrDoc, *pText, nSttPos, nPos, eLang ) ) ||
    2032           0 :                 ( m_aFlags.bChgToEnEmDash &&
    2033           0 :                     SetRedlineText( STR_AUTOFMTREDL_DASH ) &&
    2034           0 :                     pATst->FnChgToEnEmDash( aACorrDoc, *pText, nSttPos, nPos, eLang ) ) ||
    2035           0 :                 ( m_aFlags.bSetINetAttr &&
    2036           0 :                     (nPos == pText->getLength() || IsSpace((*pText)[nPos])) &&
    2037           0 :                     SetRedlineText( STR_AUTOFMTREDL_DETECT_URL ) &&
    2038           0 :                     pATst->FnSetINetAttr( aACorrDoc, *pText, nLastBlank, nPos, eLang ) ) )
    2039           0 :                     nPos = m_aDelPam.GetPoint()->nContent.GetIndex();
    2040             :             else
    2041             :             {
    2042             :                 // two capital letters at the beginning of a word?
    2043           0 :                 if( m_aFlags.bCapitalStartWord )
    2044             :                 {
    2045           0 :                     SetRedlineText( STR_AUTOFMTREDL_CPTL_STT_WORD );
    2046           0 :                     pATst->FnCapitalStartWord( aACorrDoc, *pText, nSttPos, nPos, eLang );
    2047             :                 }
    2048             :                 // capital letter at the beginning of a sentence?
    2049           0 :                 if( m_aFlags.bCapitalStartSentence && bFirst )
    2050             :                 {
    2051           0 :                     SetRedlineText( STR_AUTOFMTREDL_CPTL_STT_SENT );
    2052           0 :                     pATst->FnCapitalStartSentence( aACorrDoc, *pText, true, nSttPos, nPos, eLang);
    2053             :                 }
    2054             : 
    2055           0 :                 bFirst = bFirstSent;
    2056           0 :                 bFirstSent = false;
    2057             : 
    2058           0 :                 if( m_aFlags.bWithRedlining )
    2059             :                 {
    2060           0 :                     m_aNdIdx = m_aDelPam.GetPoint()->nNode;
    2061           0 :                     m_pCurTextNd = m_aNdIdx.GetNode().GetTextNode();
    2062           0 :                     pText = &m_pCurTextNd->GetText();
    2063           0 :                     m_aDelPam.SetMark();
    2064           0 :                     m_aDelPam.DeleteMark();
    2065             :                 }
    2066             :             }
    2067             :         }
    2068           0 :     } while (nPos < pText->getLength());
    2069           0 :     ClearRedlineText();
    2070             : }
    2071             : 
    2072           0 : SwAutoFormat::SwAutoFormat( SwEditShell* pEdShell, SvxSwAutoFormatFlags& rFlags,
    2073             :                             SwNodeIndex* pSttNd, SwNodeIndex* pEndNd )
    2074             :     : m_aFlags( rFlags ),
    2075           0 :     m_aDelPam( pEdShell->GetDoc()->GetNodes().GetEndOfExtras() ),
    2076           0 :     m_aNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfExtras(), +1 ),
    2077           0 :     m_aEndNdIdx( pEdShell->GetDoc()->GetNodes().GetEndOfContent() ),
    2078             :     m_pEditShell( pEdShell ),
    2079           0 :     m_pDoc( pEdShell->GetDoc() ),
    2080             :     m_pCurTextNd( 0 ), m_pCurTextFrm( 0 ),
    2081           0 :     m_nRedlAutoFormatSeqId( 0 )
    2082             : {
    2083             :     OSL_ENSURE( (pSttNd && pEndNd) || (!pSttNd && !pEndNd),
    2084             :             "Got no area" );
    2085             : 
    2086           0 :     if( m_aFlags.bSetNumRule && !m_aFlags.bAFormatByInput )
    2087           0 :         m_aFlags.bSetNumRule = false;
    2088             : 
    2089           0 :     bool bReplaceStyles = !m_aFlags.bAFormatByInput || m_aFlags.bReplaceStyles;
    2090             : 
    2091           0 :     const SwTextNode* pNxtNd = 0;
    2092           0 :     bool bNxtEmpty = false;
    2093           0 :     bool bNxtAlpha = false;
    2094           0 :     sal_uInt16 nNxtLevel = 0;
    2095             : 
    2096             :     // set area for autoformatting
    2097           0 :     if( pSttNd )
    2098             :     {
    2099           0 :         m_aNdIdx = *pSttNd;
    2100           0 :         --m_aNdIdx;           // for GoNextPara, one paragraph prior to that
    2101           0 :         m_aEndNdIdx = *pEndNd;
    2102           0 :         ++m_aEndNdIdx;
    2103             : 
    2104             :         // check the previous TextNode
    2105           0 :         pNxtNd = m_aNdIdx.GetNode().GetTextNode();
    2106           0 :         m_bEmptyLine = !pNxtNd ||
    2107           0 :                     IsEmptyLine( *pNxtNd ) ||
    2108           0 :                     IsNoAlphaLine( *pNxtNd );
    2109             :     }
    2110             :     else
    2111           0 :         m_bEmptyLine = true;      // at document beginning
    2112             : 
    2113           0 :     m_bEnd = false;
    2114             : 
    2115             :     // set value for percentage display
    2116           0 :     m_nEndNdIdx = m_aEndNdIdx.GetIndex();
    2117             : 
    2118           0 :     if( !m_aFlags.bAFormatByInput )
    2119           0 :         ::StartProgress( STR_STATSTR_AUTOFORMAT, m_aNdIdx.GetIndex(),
    2120           0 :                          m_nEndNdIdx = m_aEndNdIdx.GetIndex(),
    2121           0 :                          m_pDoc->GetDocShell() );
    2122             : 
    2123           0 :     RedlineMode_t eRedlMode = m_pDoc->getIDocumentRedlineAccess().GetRedlineMode(), eOldMode = eRedlMode;
    2124           0 :     if( m_aFlags.bWithRedlining )
    2125             :     {
    2126           0 :         m_pDoc->SetAutoFormatRedline( true );
    2127           0 :         eRedlMode = (RedlineMode_t)(nsRedlineMode_t::REDLINE_ON | nsRedlineMode_t::REDLINE_SHOW_INSERT);
    2128             :     }
    2129             :     else
    2130           0 :       eRedlMode = (RedlineMode_t)(nsRedlineMode_t::REDLINE_SHOW_INSERT | nsRedlineMode_t::REDLINE_IGNORE);
    2131           0 :     m_pDoc->getIDocumentRedlineAccess().SetRedlineMode( eRedlMode );
    2132             : 
    2133             :     // save undo state (might be turned off)
    2134           0 :     bool const bUndoState = m_pDoc->GetIDocumentUndoRedo().DoesUndo();
    2135             : 
    2136             :     // If multiple lines, then do not merge with next paragraph
    2137           0 :     m_bMoreLines = false;
    2138             : 
    2139           0 :     m_nLastCalcHeadLvl = 0;
    2140           0 :     m_nLastHeadLvl = USHRT_MAX;
    2141           0 :     sal_uInt16 nLevel = 0;
    2142           0 :     sal_uInt16 nDigitLvl = 0;
    2143             : 
    2144             :     // set defaults
    2145           0 :     SwTextFrmInfo aFInfo( 0 );
    2146             : 
    2147             :     // This is the automat for autoformatting
    2148           0 :     m_eStat = READ_NEXT_PARA;
    2149           0 :     while( !m_bEnd )
    2150             :     {
    2151           0 :         switch( m_eStat )
    2152             :         {
    2153             :         case READ_NEXT_PARA:
    2154             :             {
    2155           0 :                 GoNextPara();
    2156           0 :                 m_eStat = m_bEnd ? IS_END : TST_EMPTY_LINE;
    2157             :             }
    2158           0 :             break;
    2159             : 
    2160             :         case TST_EMPTY_LINE:
    2161           0 :             if( IsEmptyLine( *m_pCurTextNd ) )
    2162             :             {
    2163           0 :                 if( m_aFlags.bDelEmptyNode && !HasObjects( *m_pCurTextNd ) )
    2164             :                 {
    2165           0 :                     m_bEmptyLine = true;
    2166           0 :                     sal_uLong nOldCnt = m_pDoc->GetNodes().Count();
    2167           0 :                     DelEmptyLine();
    2168             :                     // Was there really a deletion of a node?
    2169           0 :                     if( nOldCnt != m_pDoc->GetNodes().Count() )
    2170           0 :                         --m_aNdIdx;       // do not skip the next paragraph
    2171             :                 }
    2172           0 :                 m_eStat = READ_NEXT_PARA;
    2173             :             }
    2174             :             else
    2175           0 :                 m_eStat = TST_ALPHA_LINE;
    2176           0 :             break;
    2177             : 
    2178             :         case TST_ALPHA_LINE:
    2179           0 :             if( IsNoAlphaLine( *m_pCurTextNd ))
    2180             :             {
    2181             :                 // recognize a table definition +---+---+
    2182           0 :                 if( m_aFlags.bAFormatByInput && m_aFlags.bCreateTable && DoTable() )
    2183             :                 {
    2184             :                     //JP 30.09.96: DoTable() builds on PopCrsr and MoveCrsr after AutoFormat!
    2185           0 :                     pEdShell->Pop( false );
    2186           0 :                     *pEdShell->GetCrsr() = m_aDelPam;
    2187           0 :                     pEdShell->Push();
    2188             : 
    2189           0 :                     m_eStat = IS_END;
    2190           0 :                     break;
    2191             :                 }
    2192             : 
    2193             :                 // Check for 3 "---" or "===". In this case, the previous paragraph should be
    2194             :                 // underlined and the current be deleted!
    2195           0 :                 if( !DoUnderline() && bReplaceStyles )
    2196             :                 {
    2197           0 :                     SetColl( RES_POOLCOLL_STANDARD, true );
    2198           0 :                     m_bEmptyLine = true;
    2199             :                 }
    2200           0 :                 m_eStat = READ_NEXT_PARA;
    2201             :             }
    2202             :             else
    2203           0 :                 m_eStat = GET_ALL_INFO;
    2204           0 :             break;
    2205             : 
    2206             :         case GET_ALL_INFO:
    2207             :             {
    2208           0 :                 if( m_pCurTextNd->GetNumRule() )
    2209             :                 {
    2210             :                     // do nothing in numbering, go to next
    2211           0 :                     m_bEmptyLine = false;
    2212           0 :                     m_eStat = READ_NEXT_PARA;
    2213             :                     // delete all blanks at beginning/end and in between
    2214             :                     //JP 29.04.98: first only "all in between"
    2215           0 :                     DelMoreLinesBlanks( false );
    2216           0 :                     break;
    2217             :                 }
    2218             : 
    2219           0 :                 aFInfo.SetFrm( m_pCurTextFrm );
    2220             : 
    2221             :                 // so far: if there were templates assigned, keep these and go to next node
    2222           0 :                 sal_uInt16 nPoolId = m_pCurTextNd->GetTextColl()->GetPoolFormatId();
    2223           0 :                 if( IsPoolUserFormat( nPoolId )
    2224           0 :                         ? !m_aFlags.bChgUserColl
    2225           0 :                         : ( RES_POOLCOLL_STANDARD != nPoolId &&
    2226           0 :                            ( !m_aFlags.bAFormatByInput ||
    2227           0 :                             (RES_POOLCOLL_TEXT_MOVE != nPoolId &&
    2228             :                              RES_POOLCOLL_TEXT != nPoolId )) ))
    2229             :                 {
    2230           0 :                     m_eStat = HAS_FMTCOLL;
    2231           0 :                     break;
    2232             :                 }
    2233             : 
    2234             :                 // check for hard spaces or LRSpaces set by the template
    2235           0 :                 if( IsPoolUserFormat( nPoolId ) ||
    2236             :                     RES_POOLCOLL_STANDARD == nPoolId )
    2237             :                 {
    2238             :                     short nSz;
    2239             :                     SvxLRSpaceItem const * pLRSpace;
    2240           0 :                     if( SfxItemState::SET == m_pCurTextNd->GetSwAttrSet().
    2241             :                         GetItemState( RES_LR_SPACE, true,
    2242           0 :                                         reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
    2243           0 :                         ( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) ||
    2244           0 :                             0 != pLRSpace->GetTextLeft() ) )
    2245             :                     {
    2246             :                         // exception: numbering/enumation can have an indentation
    2247           0 :                         if( IsEnumericChar( *m_pCurTextNd ))
    2248             :                         {
    2249           0 :                             nLevel = CalcLevel( *m_pCurTextNd, &nDigitLvl );
    2250           0 :                             if( nLevel >= MAXLEVEL )
    2251           0 :                                 nLevel = MAXLEVEL-1;
    2252           0 :                             BuildEnum( nLevel, nDigitLvl );
    2253           0 :                             m_eStat = READ_NEXT_PARA;
    2254           0 :                             break;
    2255             :                         }
    2256             : 
    2257             :                         // never merge (maybe only indent as exception)
    2258           0 :                         m_bMoreLines = true;
    2259             : 
    2260           0 :                         if( bReplaceStyles )
    2261             :                         {
    2262             :                             // then use one of our templates
    2263           0 :                             if( 0 < nSz )           // positive 1st line indentation
    2264           0 :                                 BuildIndent();
    2265           0 :                             else if( 0 > nSz )      // negative 1st line indentation
    2266           0 :                                 BuildNegIndent( aFInfo.GetLineStart() );
    2267           0 :                             else if( pLRSpace->GetTextLeft() )   // is indentation
    2268           0 :                                 BuildTextIndent();
    2269             :                         }
    2270           0 :                         m_eStat = READ_NEXT_PARA;
    2271           0 :                         break;
    2272             :                     }
    2273             :                 }
    2274             : 
    2275           0 :                 nLevel = CalcLevel( *m_pCurTextNd, &nDigitLvl );
    2276           0 :                 m_bMoreLines = !IsOneLine( *m_pCurTextNd );
    2277           0 :                 pNxtNd = GetNextNode();
    2278           0 :                 if( pNxtNd )
    2279             :                 {
    2280           0 :                     bNxtEmpty = IsEmptyLine( *pNxtNd );
    2281           0 :                     bNxtAlpha = IsNoAlphaLine( *pNxtNd );
    2282           0 :                     nNxtLevel = CalcLevel( *pNxtNd );
    2283             : 
    2284           0 :                     if( !m_bEmptyLine && HasBreakAttr( *m_pCurTextNd ) )
    2285           0 :                         m_bEmptyLine = true;
    2286           0 :                     if( !bNxtEmpty && HasBreakAttr( *pNxtNd ) )
    2287           0 :                         bNxtEmpty = true;
    2288             : 
    2289             :                 }
    2290             :                 else
    2291             :                 {
    2292           0 :                     bNxtEmpty = false;
    2293           0 :                     bNxtAlpha = false;
    2294           0 :                     nNxtLevel = 0;
    2295             :                 }
    2296           0 :                 m_eStat = !m_bMoreLines ? IS_ONE_LINE : TST_ENUMERIC;
    2297             :             }
    2298           0 :             break;
    2299             : 
    2300             :         case IS_ONE_LINE:
    2301             :             {
    2302           0 :                 m_eStat = TST_ENUMERIC;
    2303           0 :                 if( !bReplaceStyles )
    2304           0 :                     break;
    2305             : 
    2306           0 :                 const OUString sClrStr( DelLeadingBlanks(m_pCurTextNd->GetText()) );
    2307             : 
    2308           0 :                 if( sClrStr.isEmpty() )
    2309             :                 {
    2310           0 :                     m_bEmptyLine = true;
    2311           0 :                     m_eStat = READ_NEXT_PARA;
    2312           0 :                     break;      // read next paragraph
    2313             :                 }
    2314             : 
    2315             :                 // check if headline
    2316           0 :                 if( !m_bEmptyLine || !IsFirstCharCapital( *m_pCurTextNd ) ||
    2317           0 :                     IsBlanksInString( *m_pCurTextNd ) )
    2318           0 :                     break;
    2319             : 
    2320           0 :                 m_bEmptyLine = false;
    2321           0 :                 const OUString sEndClrStr( DelTrailingBlanks(sClrStr) );
    2322           0 :                 const sal_Unicode cLast = sEndClrStr[sEndClrStr.getLength() - 1];
    2323             : 
    2324             :                 // not, then check if headline
    2325           0 :                 if( ':' == cLast )
    2326             :                 {
    2327           0 :                     BuildHeadLine( 2 );
    2328           0 :                     m_eStat = READ_NEXT_PARA;
    2329           0 :                     break;
    2330             :                 }
    2331           0 :                 else if( 256 <= cLast || !strchr( ",.;", cLast ) )
    2332             :                 {
    2333           0 :                     if( bNxtEmpty || bNxtAlpha
    2334           0 :                         || ( pNxtNd && IsEnumericChar( *pNxtNd ))
    2335             : 
    2336             :                         )
    2337             :                     {
    2338             : 
    2339             :                         // one level below?
    2340           0 :                         if( nLevel >= MAXLEVEL )
    2341           0 :                             nLevel = MAXLEVEL-1;
    2342             : 
    2343           0 :                         if( USHRT_MAX == m_nLastHeadLvl )
    2344           0 :                             m_nLastHeadLvl = 0;
    2345           0 :                         else if( m_nLastCalcHeadLvl < nLevel )
    2346             :                         {
    2347           0 :                             if( m_nLastHeadLvl+1 < MAXLEVEL )
    2348           0 :                                 ++m_nLastHeadLvl;
    2349             :                         }
    2350             :                         // one level above?
    2351           0 :                         else if( m_nLastCalcHeadLvl > nLevel )
    2352             :                         {
    2353           0 :                             if( m_nLastHeadLvl )
    2354           0 :                                 --m_nLastHeadLvl;
    2355             :                         }
    2356           0 :                         m_nLastCalcHeadLvl = nLevel;
    2357             : 
    2358           0 :                         if( m_aFlags.bAFormatByInput )
    2359           0 :                             BuildHeadLine( nLevel );
    2360             :                         else
    2361           0 :                             BuildHeadLine( m_nLastHeadLvl );
    2362           0 :                         m_eStat = READ_NEXT_PARA;
    2363           0 :                         break;
    2364             :                     }
    2365           0 :                 }
    2366             :             }
    2367           0 :             break;
    2368             : 
    2369             :         case TST_ENUMERIC:
    2370             :             {
    2371           0 :                 m_bEmptyLine = false;
    2372           0 :                 if( IsEnumericChar( *m_pCurTextNd ))
    2373             :                 {
    2374           0 :                     if( nLevel >= MAXLEVEL )
    2375           0 :                         nLevel = MAXLEVEL-1;
    2376           0 :                     BuildEnum( nLevel, nDigitLvl );
    2377           0 :                     m_eStat = READ_NEXT_PARA;
    2378             :                 }
    2379           0 :                 else if( bReplaceStyles )
    2380           0 :                     m_eStat = nLevel ? TST_IDENT : TST_NEG_IDENT;
    2381             :                 else
    2382           0 :                     m_eStat = READ_NEXT_PARA;
    2383             :             }
    2384           0 :             break;
    2385             : 
    2386             :         case TST_IDENT:
    2387             :             // Spaces at the beginning, check again for indentation
    2388           0 :             if( m_bMoreLines && nLevel )
    2389             :             {
    2390           0 :                 SwTwips nSz = aFInfo.GetFirstIndent();
    2391           0 :                 if( 0 < nSz )           // positive 1st line indentation
    2392           0 :                     BuildIndent();
    2393           0 :                 else if( 0 > nSz )      // negative 1st line indentation
    2394           0 :                     BuildNegIndent( aFInfo.GetLineStart() );
    2395             :                 else                    // is indentation
    2396           0 :                     BuildTextIndent();
    2397           0 :                 m_eStat = READ_NEXT_PARA;
    2398             :             }
    2399           0 :             else if( nLevel && pNxtNd && !m_bEnd &&
    2400           0 :                      !bNxtEmpty && !bNxtAlpha && !nNxtLevel &&
    2401           0 :                      !IsEnumericChar( *pNxtNd ) )
    2402             :             {
    2403             :                 // is an indentation
    2404           0 :                 BuildIndent();
    2405           0 :                 m_eStat = READ_NEXT_PARA;
    2406             :             }
    2407             :             else
    2408           0 :                 m_eStat = TST_TXT_BODY;
    2409           0 :             break;
    2410             : 
    2411             :         case TST_NEG_IDENT:
    2412             :             // no spaces at the beginning, check again for negative indentation
    2413             :             {
    2414           0 :                 if( m_bMoreLines && !nLevel )
    2415             :                 {
    2416           0 :                     SwTwips nSz = aFInfo.GetFirstIndent();
    2417           0 :                     if( 0 < nSz )           // positive 1st line indentation
    2418           0 :                         BuildIndent();
    2419           0 :                     else if( 0 > nSz )      // negative 1st line indentation
    2420           0 :                         BuildNegIndent( aFInfo.GetLineStart() );
    2421             :                     else                    // is _no_ indentation
    2422           0 :                         BuildText();
    2423           0 :                     m_eStat = READ_NEXT_PARA;
    2424             :                 }
    2425           0 :                 else if( !nLevel && pNxtNd && !m_bEnd &&
    2426           0 :                          !bNxtEmpty && !bNxtAlpha && nNxtLevel &&
    2427           0 :                          !IsEnumericChar( *pNxtNd ) )
    2428             :                 {
    2429             :                     // is a negative indentation
    2430           0 :                     BuildNegIndent( aFInfo.GetLineStart() );
    2431           0 :                     m_eStat = READ_NEXT_PARA;
    2432             :                 }
    2433             :                 else
    2434           0 :                     m_eStat = TST_TXT_BODY;
    2435             :             }
    2436           0 :             break;
    2437             : 
    2438             :         case TST_TXT_BODY:
    2439             :             {
    2440           0 :                 if( m_bMoreLines )
    2441             :                 {
    2442           0 :                     SwTwips nSz = aFInfo.GetFirstIndent();
    2443           0 :                     if( 0 < nSz )           // positive 1st line indentation
    2444           0 :                         BuildIndent();
    2445           0 :                     else if( 0 > nSz )      // negative 1st line indentation
    2446           0 :                         BuildNegIndent( aFInfo.GetLineStart() );
    2447           0 :                     else if( nLevel )       // is indentation
    2448           0 :                         BuildTextIndent();
    2449             :                     else
    2450           0 :                         BuildText();
    2451             :                 }
    2452           0 :                 else if( nLevel )
    2453           0 :                     BuildTextIndent();
    2454             :                 else
    2455           0 :                     BuildText();
    2456           0 :                 m_eStat = READ_NEXT_PARA;
    2457             :             }
    2458           0 :             break;
    2459             : 
    2460             :         case HAS_FMTCOLL:
    2461             :             {
    2462             :                 // so far: if there were templates assigned, keep these and go to next node
    2463           0 :                 m_bEmptyLine = false;
    2464           0 :                 m_eStat = READ_NEXT_PARA;
    2465             :                 // delete all blanks at beginning/end and in between
    2466             :                 //JP 29.04.98: first only "all in between"
    2467           0 :                 DelMoreLinesBlanks( false );
    2468             : 
    2469             :                 // handle hard attributes
    2470           0 :                 if( m_pCurTextNd->HasSwAttrSet() )
    2471             :                 {
    2472             :                     short nSz;
    2473             :                     SvxLRSpaceItem const * pLRSpace;
    2474           0 :                     if( bReplaceStyles &&
    2475           0 :                         SfxItemState::SET == m_pCurTextNd->GetSwAttrSet().
    2476             :                         GetItemState( RES_LR_SPACE, false,
    2477           0 :                                         reinterpret_cast<const SfxPoolItem**>(&pLRSpace) ) &&
    2478           0 :                         ( 0 != (nSz = pLRSpace->GetTextFirstLineOfst()) ||
    2479           0 :                             0 != pLRSpace->GetTextLeft() ) )
    2480             :                     {
    2481             :                         // then use one of our templates
    2482           0 :                         if( 0 < nSz )           // positive 1st line indentation
    2483           0 :                             BuildIndent();
    2484           0 :                         else if( 0 > nSz )      // negative 1st line indentation
    2485             :                         {
    2486           0 :                             BuildNegIndent( aFInfo.GetLineStart() );
    2487             :                         }
    2488           0 :                         else if( pLRSpace->GetTextLeft() )   // is indentation
    2489           0 :                             BuildTextIndent();
    2490             :                         else
    2491           0 :                             BuildText();
    2492             :                     }
    2493             :                 }
    2494             :             }
    2495           0 :             break;
    2496             : 
    2497             :         case IS_END:
    2498           0 :             m_bEnd = true;
    2499           0 :             break;
    2500             :         }
    2501             :     }
    2502             : 
    2503           0 :     if( m_aFlags.bWithRedlining )
    2504           0 :         m_pDoc->SetAutoFormatRedline( false );
    2505           0 :     m_pDoc->getIDocumentRedlineAccess().SetRedlineMode( eOldMode );
    2506             : 
    2507             :     // restore undo (in case it has been changed)
    2508           0 :     m_pDoc->GetIDocumentUndoRedo().DoUndo(bUndoState);
    2509             : 
    2510             :     // disable display of percentage again
    2511           0 :     if( !m_aFlags.bAFormatByInput )
    2512           0 :         ::EndProgress( m_pDoc->GetDocShell() );
    2513           0 : }
    2514             : 
    2515           0 : void SwEditShell::AutoFormat( const SvxSwAutoFormatFlags* pAFlags )
    2516             : {
    2517           0 :     boost::scoped_ptr<SwWait> pWait;
    2518             : 
    2519           0 :     SET_CURR_SHELL( this );
    2520           0 :     StartAllAction();
    2521           0 :     StartUndo( UNDO_AUTOFORMAT );
    2522             : 
    2523           0 :     SvxSwAutoFormatFlags aAFFlags;     // use default values or add params?
    2524           0 :     if( pAFlags )
    2525             :     {
    2526           0 :         aAFFlags = *pAFlags;
    2527           0 :         if( !aAFFlags.bAFormatByInput )
    2528           0 :             pWait.reset(new SwWait( *GetDoc()->GetDocShell(), true ));
    2529             :     }
    2530             : 
    2531           0 :     SwPaM* pCrsr = GetCrsr();
    2532             :     // There are more than one or a selection is open
    2533           0 :     if( pCrsr->GetNext() != pCrsr || pCrsr->HasMark() )
    2534             :     {
    2535           0 :         for(SwPaM& rPaM : GetCrsr()->GetRingContainer())
    2536             :         {
    2537           0 :             if( rPaM.HasMark() )
    2538             :             {
    2539           0 :                 SwAutoFormat aFormat( this, aAFFlags, &(rPaM.Start()->nNode),
    2540           0 :                                      &(rPaM.End()->nNode) );
    2541             :             }
    2542             :         }
    2543             :     }
    2544             :     else
    2545             :     {
    2546           0 :         SwAutoFormat aFormat( this, aAFFlags );
    2547             :     }
    2548             : 
    2549           0 :     EndUndo( UNDO_AUTOFORMAT );
    2550           0 :     EndAllAction();
    2551           0 : }
    2552             : 
    2553           0 : void SwEditShell::AutoFormatBySplitNode()
    2554             : {
    2555           0 :     SET_CURR_SHELL( this );
    2556           0 :     SwPaM* pCrsr = GetCrsr();
    2557           0 :     if( !pCrsr->IsMultiSelection() && pCrsr->Move( fnMoveBackward, fnGoNode ) )
    2558             :     {
    2559           0 :         StartAllAction();
    2560           0 :         StartUndo( UNDO_AUTOFORMAT );
    2561             : 
    2562           0 :         bool bRange = false;
    2563           0 :         pCrsr->SetMark();
    2564           0 :         SwIndex* pContent = &pCrsr->GetMark()->nContent;
    2565           0 :         if( pContent->GetIndex() )
    2566             :         {
    2567           0 :             *pContent = 0;
    2568           0 :             bRange = true;
    2569             :         }
    2570             :         else
    2571             :         {
    2572             :             // then go one node backwards
    2573           0 :             SwNodeIndex m_aNdIdx( pCrsr->GetMark()->nNode, -1 );
    2574           0 :             SwTextNode* pTextNd = m_aNdIdx.GetNode().GetTextNode();
    2575           0 :             if (pTextNd && !pTextNd->GetText().isEmpty())
    2576             :             {
    2577           0 :                 pContent->Assign( pTextNd, 0 );
    2578           0 :                 pCrsr->GetMark()->nNode = m_aNdIdx;
    2579           0 :                 bRange = true;
    2580           0 :             }
    2581             :         }
    2582             : 
    2583           0 :         if( bRange )
    2584             :         {
    2585           0 :             Push();     // save cursor
    2586             : 
    2587           0 :             SvxSwAutoFormatFlags aAFFlags = *GetAutoFormatFlags(); // use default values so far
    2588             : 
    2589           0 :             SwAutoFormat aFormat( this, aAFFlags, &pCrsr->GetMark()->nNode,
    2590           0 :                                     &pCrsr->GetPoint()->nNode );
    2591             : 
    2592             :             //JP 30.09.96: DoTable() builds on PopCrsr and MoveCrsr!
    2593           0 :             Pop( false );
    2594           0 :             pCrsr = GetCrsr();
    2595             :         }
    2596           0 :         pCrsr->DeleteMark();
    2597           0 :         pCrsr->Move( fnMoveForward, fnGoNode );
    2598             : 
    2599           0 :         EndUndo( UNDO_AUTOFORMAT );
    2600           0 :         EndAllAction();
    2601           0 :     }
    2602           0 : }
    2603             : 
    2604          60 : SvxSwAutoFormatFlags* SwEditShell::GetAutoFormatFlags()
    2605             : {
    2606          60 :     if (!s_pAutoFormatFlags)
    2607          59 :         s_pAutoFormatFlags = new SvxSwAutoFormatFlags;
    2608             : 
    2609          60 :     return s_pAutoFormatFlags;
    2610             : }
    2611             : 
    2612          60 : void SwEditShell::SetAutoFormatFlags(SvxSwAutoFormatFlags * pFlags)
    2613             : {
    2614          60 :     SvxSwAutoFormatFlags* pEditFlags = GetAutoFormatFlags();
    2615             : 
    2616          60 :     pEditFlags->bSetNumRule     = pFlags->bSetNumRule;
    2617          60 :     pEditFlags->bChgEnumNum     = pFlags->bChgEnumNum;
    2618          60 :     pEditFlags->bSetBorder      = pFlags->bSetBorder;
    2619          60 :     pEditFlags->bCreateTable    = pFlags->bCreateTable;
    2620          60 :     pEditFlags->bReplaceStyles  = pFlags->bReplaceStyles;
    2621             :     pEditFlags->bAFormatByInpDelSpacesAtSttEnd =
    2622          60 :                                     pFlags->bAFormatByInpDelSpacesAtSttEnd;
    2623             :     pEditFlags->bAFormatByInpDelSpacesBetweenLines =
    2624          60 :                                     pFlags->bAFormatByInpDelSpacesBetweenLines;
    2625             : 
    2626             :     //JP 15.12.98: copy BulletChar and Font into "normal" ones
    2627             :     //             because AutoFormat can only work with the latter!
    2628          60 :     pEditFlags->cBullet             = pFlags->cByInputBullet;
    2629          60 :     pEditFlags->aBulletFont         = pFlags->aByInputBulletFont;
    2630          60 :     pEditFlags->cByInputBullet      = pFlags->cByInputBullet;
    2631          60 :     pEditFlags->aByInputBulletFont  = pFlags->aByInputBulletFont;
    2632         237 : }
    2633             : 
    2634             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11