1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: autofmt.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #define _SVSTDARR_LONGS
36 #define _SVSTDARR_USHORTS
39 #include <hintids.hxx>
41 #include <svtools/svstdarr.hxx>
42 #include <unotools/charclass.hxx>
43 #include <svx/boxitem.hxx>
44 #include <svx/lrspitem.hxx>
45 #include <svx/brkitem.hxx>
46 #include <svx/adjitem.hxx>
47 #ifndef _SVX_TSTPITEM_HXX //autogen
48 #include <svx/tstpitem.hxx>
50 #include <svx/fontitem.hxx>
51 #include <svx/langitem.hxx>
52 #include <svx/cscoitem.hxx>
53 #include <svx/unolingu.hxx>
55 #include <svx/acorrcfg.hxx>
57 #include <fmtpdsc.hxx>
58 #include <fmtanchr.hxx>
66 #include <swundo.hxx> // fuer die UndoIds
67 #include <poolfmt.hxx>
71 #include <pagedesc.hxx>
73 #include <swtable.hxx>
74 #include <acorrect.hxx>
75 #include <shellres.hxx>
76 #include <section.hxx>
77 #include <fmthbsh.hxx>
79 #include <charatr.hxx>
82 #include <statstr.hrc>
85 #include <comcore.hrc>
87 #include <vcl/msgbox.hxx>
88 #include <numrule.hxx>
90 using namespace ::com::sun::star
;
92 //-------------------------------------------------------------------
94 //JP 16.12.99: definition:
95 // from pos cPosEnDash to cPosEmDash all chars changed to endashes,
96 // from pos cPosEmDash to cPosEnd all chars changed to emdashes
97 // all other chars are changed to the user configuration
99 const sal_Unicode pBulletChar
[6] = { '+', '*', '-', 0x2013, 0x2014, 0 };
100 const int cnPosEnDash
= 2, cnPosEmDash
= 4, cnPosEnd
= 5;
102 const sal_Unicode cStarSymbolEnDash
= 0x2013;
103 const sal_Unicode cStarSymbolEmDash
= 0x2014;
106 SvxSwAutoFmtFlags
* SwEditShell::pAutoFmtFlags
= 0;
108 // Anzahl von Num-/Bullet-Absatzvorlagen. MAXLEVEL wird demnaechst auf
109 // x erhoeht, die Anzahl Vorlagen aber nicht (Ueberbleibsel aus <= 4.0)
110 const USHORT cnNumBullColls
= 4;
114 SvxSwAutoFmtFlags aFlags
;
115 SwPaM aDelPam
; // ein Pam der benutzt werden kann
116 SwNodeIndex aNdIdx
; // der Index auf den akt. TextNode
117 SwNodeIndex aEndNdIdx
; // Index auf das Ende vom Bereich
119 SwEditShell
* pEditShell
;
121 SwTxtNode
* pAktTxtNd
; // der akt. TextNode
122 SwTxtFrm
* pAktTxtFrm
; // Frame vom akt. TextNode
123 CharClass
* pCharClass
; // Character classification
124 ULONG nEndNdIdx
; // fuer die Prozent-Anzeige
125 LanguageType eCharClassLang
;
127 USHORT nLastHeadLvl
, nLastCalcHeadLvl
;
128 USHORT nLastEnumLvl
, nLastCalcEnumLvl
;
129 USHORT nRedlAutoFmtSeqId
;
141 NO_DELIM
= (DIGIT
|LOWER_ALPHA
|UPPER_ALPHA
|LOWER_ROMAN
|UPPER_ROMAN
)
163 static BOOL m_bAskForCancelUndoWhileBufferOverflow
;
164 static short m_nActionWhileAutoformatUndoBufferOverflow
;
167 // ------------- private methods -----------------------------
168 void _GetCharClass( LanguageType eLang
);
169 CharClass
& GetCharClass( LanguageType eLang
) const
171 if( !pCharClass
|| eLang
!= eCharClassLang
)
173 SwAutoFormat
* pThis
= (SwAutoFormat
*)this;
174 pThis
->_GetCharClass( eLang
);
180 BOOL
IsSpace( const sal_Unicode c
) const
181 { return (' ' == c
|| '\t' == c
|| 0x0a == c
|| 0x3000 == c
/* Jap. space */) ? TRUE
: FALSE
; }
183 void SetColl( USHORT nId
, BOOL bHdLineOrText
= FALSE
);
185 BOOL
HasObjects( const SwNode
& rNd
);
188 const SwTxtNode
* GetNextNode() const;
189 BOOL
IsEmptyLine( const SwTxtNode
& rNd
) const
190 { return 0 == rNd
.GetTxt().Len() ||
191 rNd
.GetTxt().Len() == GetLeadingBlanks( rNd
.GetTxt() ); }
193 BOOL
IsOneLine( const SwTxtNode
& ) const;
194 BOOL
IsFastFullLine( const SwTxtNode
& ) const;
195 BOOL
IsNoAlphaLine( const SwTxtNode
&) const;
196 BOOL
IsEnumericChar( const SwTxtNode
&) const;
197 BOOL
IsBlanksInString( const SwTxtNode
&) const;
198 USHORT
CalcLevel( const SwTxtNode
&, USHORT
*pDigitLvl
= 0 ) const;
199 xub_StrLen
GetBigIndent( xub_StrLen
& rAktSpacePos
) const;
201 String
& DelLeadingBlanks( String
& rStr
) const;
202 String
& DelTrailingBlanks( String
& rStr
) const;
203 xub_StrLen
GetLeadingBlanks( const String
& rStr
) const;
204 xub_StrLen
GetTrailingBlanks( const String
& rStr
) const;
206 BOOL
IsFirstCharCapital( const SwTxtNode
& rNd
) const;
207 USHORT
GetDigitLevel( const SwTxtNode
& rTxtNd
, xub_StrLen
& rPos
,
208 String
* pPreFix
= 0, String
* pPostFix
= 0,
209 String
* pNumTypes
= 0 ) const;
210 // hole den FORMATIERTEN TextFrame
211 SwTxtFrm
* GetFrm( const SwTxtNode
& rTxtNd
) const;
215 void BuildTextIndent();
216 void BuildEnum( USHORT nLvl
, USHORT nDigitLevel
);
217 void BuildNegIndent( SwTwips nSpaces
);
218 void BuildHeadLine( USHORT nLvl
);
220 BOOL
HasSelBlanks( SwPaM
& rPam
) const;
221 BOOL
HasBreakAttr( const SwTxtNode
& ) const;
222 void DeleteSel( SwPaM
& rPam
);
223 BOOL
DeleteAktNxtPara( const String
& rNxtPara
);
224 // loesche im Node Anfang oder/und Ende
225 void DeleteAktPara( BOOL bStart
= TRUE
, BOOL nEnd
= TRUE
);
226 void DelEmptyLine( BOOL bTstNextPara
= TRUE
);
227 // loesche bei mehrzeiligen Absaetzen die "linken" und/oder
229 void DelMoreLinesBlanks( BOOL bWithLineBreaks
= FALSE
);
230 // loesche den vorherigen Absatz
232 // dann lasse doch mal das AutoCorrect auf den akt. TextNode los
233 void AutoCorrect( xub_StrLen nSttPos
= 0 );
235 BOOL
CanJoin( const SwTxtNode
* pTxtNd
) const
237 return !bEnde
&& pTxtNd
&&
238 !IsEmptyLine( *pTxtNd
) &&
239 !IsNoAlphaLine( *pTxtNd
) &&
240 !IsEnumericChar( *pTxtNd
) &&
241 ((STRING_MAXLEN
- 50 - pTxtNd
->GetTxt().Len()) >
242 pAktTxtNd
->GetTxt().Len()) &&
243 !HasBreakAttr( *pTxtNd
);
246 // ist ein Punkt am Ende ??
247 BOOL
IsSentenceAtEnd( const SwTxtNode
& rTxtNd
) const;
252 void _SetRedlineTxt( USHORT nId
);
253 BOOL
SetRedlineTxt( USHORT nId
)
254 { if( aFlags
.bWithRedlining
) _SetRedlineTxt( nId
); return TRUE
; }
255 BOOL
ClearRedlineTxt()
256 { if( aFlags
.bWithRedlining
) pDoc
->SetAutoFmtRedlineComment(0); return TRUE
; }
259 SwAutoFormat( SwEditShell
* pEdShell
, SvxSwAutoFmtFlags
& rFlags
,
260 SwNodeIndex
* pSttNd
= 0, SwNodeIndex
* pEndNd
= 0 );
266 BOOL
SwAutoFormat::m_bAskForCancelUndoWhileBufferOverflow
= TRUE
;
267 short SwAutoFormat::m_nActionWhileAutoformatUndoBufferOverflow
= RET_YES
;
269 const sal_Unicode
* StrChr( const sal_Unicode
* pSrc
, sal_Unicode c
)
271 while( *pSrc
&& *pSrc
!= c
)
273 return *pSrc
? pSrc
: 0;
276 SwTxtFrm
* SwAutoFormat::GetFrm( const SwTxtNode
& rTxtNd
) const
278 // besorge mal den Frame
279 const SwCntntFrm
*pFrm
= rTxtNd
.GetFrm();
280 ASSERT( pFrm
, "zum Autoformat muss das Layout vorhanden sein" );
281 if( aFlags
.bAFmtByInput
&& !pFrm
->IsValid() )
283 SwRect
aTmpFrm( pFrm
->Frm() );
284 SwRect
aTmpPrt( pFrm
->Prt() );
286 if( pFrm
->Frm() != aTmpFrm
|| pFrm
->Prt() != aTmpPrt
||
287 ( pFrm
->IsTxtFrm() && !((SwTxtFrm
*)pFrm
)->Paint().IsEmpty() ) )
288 pFrm
->SetCompletePaint();
290 return ((SwTxtFrm
*)pFrm
)->GetFormatted();
293 void SwAutoFormat::_GetCharClass( LanguageType eLang
)
296 pCharClass
= new CharClass( SvxCreateLocale( eLang
));
297 eCharClassLang
= eLang
;
300 void SwAutoFormat::_SetRedlineTxt( USHORT nActionId
)
304 if( STR_AUTOFMTREDL_END
> nActionId
)
306 sTxt
= *ViewShell::GetShellRes()->GetAutoFmtNameLst()[ nActionId
];
309 case STR_AUTOFMTREDL_SET_NUMBULET
:
310 case STR_AUTOFMTREDL_DEL_MORELINES
:
312 // AutoCorrect-Actions
313 case STR_AUTOFMTREDL_USE_REPLACE
:
314 case STR_AUTOFMTREDL_CPTL_STT_WORD
:
315 case STR_AUTOFMTREDL_CPTL_STT_SENT
:
316 case STR_AUTOFMTREDL_TYPO
:
317 case STR_AUTOFMTREDL_UNDER
:
318 case STR_AUTOFMTREDL_BOLD
:
319 case STR_AUTOFMTREDL_FRACTION
:
320 case STR_AUTOFMTREDL_DASH
:
321 case STR_AUTOFMTREDL_ORDINAL
:
322 case STR_AUTOFMTREDL_NON_BREAK_SPACE
:
323 nSeqNo
= ++nRedlAutoFmtSeqId
;
327 #if OSL_DEBUG_LEVEL > 1
329 sTxt
= String::CreateFromAscii(
330 RTL_CONSTASCII_STRINGPARAM( "Action-Text fehlt" ));
333 pDoc
->SetAutoFmtRedlineComment( &sTxt
, nSeqNo
);
336 String
SwAutoFormat::GoNextPara()
340 //has to be checed twice before and after incrementation
341 if( aNdIdx
.GetIndex() >= aEndNdIdx
.GetIndex() )
348 if( aNdIdx
.GetIndex() >= aEndNdIdx
.GetIndex() )
354 pNewNd
= &aNdIdx
.GetNode();
357 // TableNode : Tabelle ueberspringen
358 // NoTxtNode : Nodes ueberspringen
359 // EndNode : Ende erreicht, beenden
360 if( pNewNd
->IsEndNode() )
365 else if( pNewNd
->IsTableNode() )
366 aNdIdx
= *pNewNd
->EndOfSectionNode();
367 else if( pNewNd
->IsSectionNode() )
369 const SwSection
& rSect
= pNewNd
->GetSectionNode()->GetSection();
370 if( rSect
.IsHiddenFlag() || rSect
.IsProtectFlag() )
371 aNdIdx
= *pNewNd
->EndOfSectionNode();
373 } while( !pNewNd
->IsTxtNode() );
375 if( !aFlags
.bAFmtByInput
)
376 ::SetProgressState( aNdIdx
.GetIndex() + nEndNdIdx
- aEndNdIdx
.GetIndex(),
377 pDoc
->GetDocShell() );
379 pAktTxtNd
= (SwTxtNode
*)pNewNd
;
380 pAktTxtFrm
= GetFrm( *pAktTxtNd
);
381 return pAktTxtNd
->GetTxt();
384 BOOL
SwAutoFormat::HasObjects( const SwNode
& rNd
)
386 // haengt irgend etwas absatzgebundenes am Absatz?
387 // z.B. Rahmen, DrawObjecte, ..
389 const SwSpzFrmFmts
& rFmts
= *pDoc
->GetSpzFrmFmts();
390 for( USHORT n
= 0; n
< rFmts
.Count(); ++n
)
392 const SwFmtAnchor
& rAnchor
= rFmts
[ n
]->GetAnchor();
393 if( FLY_PAGE
!= rAnchor
.GetAnchorId() &&
394 rAnchor
.GetCntntAnchor() &&
395 &rAnchor
.GetCntntAnchor()->nNode
.GetNode() == &rNd
)
404 const SwTxtNode
* SwAutoFormat::GetNextNode() const
406 if( aNdIdx
.GetIndex()+1 >= aEndNdIdx
.GetIndex() )
408 return pDoc
->GetNodes()[ aNdIdx
.GetIndex() + 1 ]->GetTxtNode();
412 BOOL
SwAutoFormat::IsOneLine( const SwTxtNode
& rNd
) const
414 SwTxtFrmInfo
aFInfo( GetFrm( rNd
) );
415 return aFInfo
.IsOneLine();
419 BOOL
SwAutoFormat::IsFastFullLine( const SwTxtNode
& rNd
) const
421 BOOL bRet
= aFlags
.bRightMargin
;
424 SwTxtFrmInfo
aFInfo( GetFrm( rNd
) );
425 bRet
= aFInfo
.IsFilled( aFlags
.nRightMargin
);
431 BOOL
SwAutoFormat::IsEnumericChar( const SwTxtNode
& rNd
) const
433 const String
& rTxt
= rNd
.GetTxt();
435 xub_StrLen nBlnks
= GetLeadingBlanks( sTmp
);
436 xub_StrLen nLen
= rTxt
.Len() - nBlnks
;
440 // -, +, * getrennt durch Blank ??
441 if( 2 < nLen
&& IsSpace( rTxt
.GetChar( nBlnks
+ 1 ) ) )
443 if( StrChr( pBulletChar
, rTxt
.GetChar( nBlnks
) ) )
445 // sollte an der Position ein Symbolfont existieren ?
446 SwTxtFrmInfo
aFInfo( GetFrm( rNd
) );
447 if( aFInfo
.IsBullet( nBlnks
))
451 // 1.) / 1. / 1.1.1 / (1). / (1) / ....
452 return USHRT_MAX
!= GetDigitLevel( rNd
, nBlnks
);
456 BOOL
SwAutoFormat::IsBlanksInString( const SwTxtNode
& rNd
) const
458 // suche im String mehr als 5 Blanks/Tabs
459 String
sTmp( rNd
.GetTxt() );
460 DelTrailingBlanks( DelLeadingBlanks( sTmp
));
461 const sal_Unicode
* pTmp
= sTmp
.GetBuffer();
464 if( IsSpace( *pTmp
) )
466 if( IsSpace( *++pTmp
)) // 2 Space nach einander
468 const sal_Unicode
* pStt
= pTmp
;
469 while( *pTmp
&& IsSpace( *++pTmp
))
471 if( 5 <= pTmp
- pStt
)
484 USHORT
SwAutoFormat::CalcLevel( const SwTxtNode
& rNd
, USHORT
*pDigitLvl
) const
486 USHORT nLvl
= 0, nBlnk
= 0;
487 const String
& rTxt
= rNd
.GetTxt();
489 *pDigitLvl
= USHRT_MAX
;
491 if( RES_POOLCOLL_TEXT_MOVE
== rNd
.GetTxtColl()->GetPoolFmtId() )
493 if( aFlags
.bAFmtByInput
)
495 nLvl
= rNd
.GetAutoFmtLvl();
496 ((SwTxtNode
&)rNd
).SetAutoFmtLvl( 0 );
504 for( xub_StrLen n
= 0, nEnd
= rTxt
.Len(); n
< nEnd
; ++n
)
506 switch( rTxt
.GetChar( n
) )
508 case ' ': if( 3 == ++nBlnk
)
511 case '\t': ++nLvl
, nBlnk
= 0;
515 // Teste auf 1.) / 1. / 1.1.1 / (1). / (1) / ....
516 *pDigitLvl
= GetDigitLevel( rNd
, n
);
525 xub_StrLen
SwAutoFormat::GetBigIndent( xub_StrLen
& rAktSpacePos
) const
527 SwTxtFrmInfo
aFInfo( GetFrm( *pAktTxtNd
) );
528 const SwTxtFrm
* pNxtFrm
= 0;
532 const SwTxtNode
* pNxtNd
= GetNextNode();
533 if( !CanJoin( pNxtNd
) || !IsOneLine( *pNxtNd
) )
536 pNxtFrm
= GetFrm( *pNxtNd
);
539 return aFInfo
.GetBigIndent( rAktSpacePos
, pNxtFrm
);
543 BOOL
SwAutoFormat::IsNoAlphaLine( const SwTxtNode
& rNd
) const
545 const String
& rStr
= rNd
.GetTxt();
548 // oder besser: ueber die Anzahl von Alpha/Num- und !AN-Zeichen
550 xub_StrLen nANChar
= 0, nBlnk
= 0;
552 CharClass
& rCC
= GetCharClass( rNd
.GetSwAttrSet().GetLanguage().GetLanguage() );
553 for( xub_StrLen n
= 0, nEnd
= rStr
.Len(); n
< nEnd
; ++n
)
554 if( IsSpace( rStr
.GetChar( n
) ) )
556 else if( rCC
.isLetterNumeric( rStr
, n
))
559 // sind zu 75% keine Alpha-Nummerische-Zeichen, dann TRUE
560 ULONG nLen
= rStr
.Len() - nBlnk
;
561 nLen
= ( nLen
* 3 ) / 4; // long overflow, if the strlen > USHORT
562 return xub_StrLen(nLen
) < (rStr
.Len() - nANChar
- nBlnk
);
567 BOOL
SwAutoFormat::DoUnderline()
569 if( !aFlags
.bSetBorder
)
572 const sal_Unicode
* pStr
= pAktTxtNd
->GetTxt().GetBuffer();
577 //JP 29.03.96: Spaces unterbrechen die Umrandung!
578 // if( !IsSpace( *pStr ) )
583 case '-': eTmp
= 1; break;
584 case '_': eTmp
= 2; break;
585 case '=': eTmp
= 3; break;
586 case '*': eTmp
= 4; break;
587 case '~': eTmp
= 5; break;
588 case '#': eTmp
= 6; break;
594 else if( eState
!= eTmp
)
603 // dann unterstreiche mal den vorherigen Absatz, wenn es diesen gibt!
604 DelEmptyLine( FALSE
);
606 aDelPam
.GetMark()->nContent
= 0;
607 //JP 19.03.96: kein Underline sondern eine Umrandung setzen!
608 // pDoc->Insert( aDelPam, SvxUnderlineItem( eState ) );
613 case 1: // einfach, 0,05 pt
614 aLine
.SetOutWidth( DEF_LINE_WIDTH_0
);
616 case 2: // einfach, 1,0 pt
617 aLine
.SetOutWidth( DEF_LINE_WIDTH_1
);
619 case 3: // doppelt, 1,1 pt
620 aLine
.SetOutWidth( DEF_DOUBLE_LINE0_OUT
);
621 aLine
.SetInWidth( DEF_DOUBLE_LINE0_IN
);
622 aLine
.SetDistance( DEF_DOUBLE_LINE0_DIST
);
624 case 4: // doppelt, 4,5 pt
625 aLine
.SetOutWidth( DEF_DOUBLE_LINE4_OUT
);
626 aLine
.SetInWidth( DEF_DOUBLE_LINE4_IN
);
627 aLine
.SetDistance( DEF_DOUBLE_LINE4_DIST
);
629 case 5: // doppelt, 6,0 pt
630 aLine
.SetOutWidth( DEF_DOUBLE_LINE5_OUT
);
631 aLine
.SetInWidth( DEF_DOUBLE_LINE5_IN
);
632 aLine
.SetDistance( DEF_DOUBLE_LINE5_DIST
);
634 case 6: // doppelt, 9,0 pt
635 aLine
.SetOutWidth( DEF_DOUBLE_LINE6_OUT
);
636 aLine
.SetInWidth( DEF_DOUBLE_LINE6_IN
);
637 aLine
.SetDistance( DEF_DOUBLE_LINE6_DIST
);
640 SfxItemSet
aSet(pDoc
->GetAttrPool(),
641 RES_PARATR_CONNECT_BORDER
, RES_PARATR_CONNECT_BORDER
,
644 aSet
.Put( SwParaConnectBorderItem( FALSE
) );
645 SvxBoxItem
aBox( RES_BOX
);
646 aBox
.SetLine( &aLine
, BOX_LINE_BOTTOM
);
647 aBox
.SetDistance( 42 ); // ~0,75 mm
649 pDoc
->Insert( aDelPam
, aSet
, 0 );
651 aDelPam
.DeleteMark();
657 BOOL
SwAutoFormat::DoTable()
659 if( !aFlags
.bCreateTable
|| !aFlags
.bAFmtByInput
||
660 pAktTxtNd
->FindTableNode() )
663 const String
& rTmp
= pAktTxtNd
->GetTxt();
664 xub_StrLen nSttPlus
= GetLeadingBlanks( rTmp
);
665 xub_StrLen nEndPlus
= GetTrailingBlanks( rTmp
);
668 if( 2 > nEndPlus
- nSttPlus
||
669 ( '+' != ( cChar
= rTmp
.GetChar( nSttPlus
)) && '|' != cChar
) ||
670 ( '+' != ( cChar
= rTmp
.GetChar( nEndPlus
- 1)) && '|' != cChar
))
673 SwTxtFrmInfo
aInfo( pAktTxtFrm
);
675 xub_StrLen n
= nSttPlus
;
676 const sal_Unicode
* pStr
= rTmp
.GetBuffer() + n
;
677 SvUShorts
aPosArr( 5, 5 );
692 aPosArr
.Insert( static_cast<USHORT
>(aInfo
.GetCharPos(n
)), aPosArr
.Count() );
698 if( ++n
== nEndPlus
)
704 if( 1 < aPosArr
.Count() )
706 // Ausrichtung vom Textnode besorgen:
707 USHORT nColCnt
= aPosArr
.Count() - 1;
708 SwTwips nSttPos
= aPosArr
[ 0 ];
710 switch( pAktTxtNd
->GetSwAttrSet().GetAdjust().GetAdjust() )
712 case SVX_ADJUST_CENTER
: eHori
= text::HoriOrientation::CENTER
; break;
713 case SVX_ADJUST_RIGHT
: eHori
= text::HoriOrientation::RIGHT
; break;
718 eHori
= text::HoriOrientation::NONE
;
719 // dann muss als letztes noch die akt. FrameBreite
721 aPosArr
.Insert( static_cast<USHORT
>(pAktTxtFrm
->Frm().Width()), aPosArr
.Count() );
724 eHori
= text::HoriOrientation::LEFT
;
728 // dann erzeuge eine Tabelle, die den Zeichen entspricht
730 SwNodeIndex
aIdx( aDelPam
.GetPoint()->nNode
);
731 aDelPam
.Move( fnMoveForward
);
732 pDoc
->InsertTable( SwInsertTableOptions( tabopts::ALL_TBL_INS_ATTR
, 1 ),
733 *aDelPam
.GetPoint(), 1, nColCnt
, eHori
,
735 aDelPam
.GetPoint()->nNode
= aIdx
;
737 return 1 < aPosArr
.Count();
741 String
& SwAutoFormat::DelLeadingBlanks( String
& rStr
) const
746 for( nL
= rStr
.Len(), n
= 0; n
< nL
&& IsSpace( rStr
.GetChar(n
) ); ++n
)
748 if( n
) // keine Spaces
754 String
& SwAutoFormat::DelTrailingBlanks( String
& rStr
) const
756 xub_StrLen nL
= rStr
.Len(), n
= nL
;
760 while( --n
&& IsSpace( rStr
.GetChar( n
) ) )
762 if( n
+1 != nL
) // keine Spaces
768 xub_StrLen
SwAutoFormat::GetLeadingBlanks( const String
& rStr
) const
773 for( nL
= rStr
.Len(), n
= 0; n
< nL
&& IsSpace( rStr
.GetChar( n
) ); ++n
)
779 xub_StrLen
SwAutoFormat::GetTrailingBlanks( const String
& rStr
) const
781 xub_StrLen nL
= rStr
.Len(), n
= nL
;
785 while( --n
&& IsSpace( rStr
.GetChar( n
) ) )
791 BOOL
SwAutoFormat::IsFirstCharCapital( const SwTxtNode
& rNd
) const
793 const String
& rTxt
= rNd
.GetTxt();
794 for( xub_StrLen n
= 0, nEnd
= rTxt
.Len(); n
< nEnd
; ++n
)
795 if( !IsSpace( rTxt
.GetChar( n
) ) )
797 CharClass
& rCC
= GetCharClass( rNd
.GetSwAttrSet().
798 GetLanguage().GetLanguage() );
799 sal_Int32 nCharType
= rCC
.getCharacterType( rTxt
, n
);
800 return CharClass::isLetterType( nCharType
) &&
801 0 != ( i18n::KCharacterType::UPPER
&
808 USHORT
SwAutoFormat::GetDigitLevel( const SwTxtNode
& rNd
, xub_StrLen
& rPos
,
809 String
* pPreFix
, String
* pPostFix
, String
* pNumTypes
) const
811 // Teste auf 1.) / 1. / 1.1.1 / (1). / (1) / ....
812 const String
& rTxt
= rNd
.GetTxt();
813 xub_StrLen nPos
= rPos
;
817 BYTE nDigitLvl
= 0, nDigitCnt
= 0;
818 //count number of parenthesis to assure a sensible order is found
819 USHORT nOpeningParentheses
= 0;
820 USHORT nClosingParentheses
= 0;
822 CharClass
& rCC
= GetCharClass( rNd
.GetSwAttrSet().GetLanguage().GetLanguage() );
824 while( nPos
< rTxt
.Len() && nDigitLvl
< MAXLEVEL
- 1)
826 const sal_Unicode cCurrentChar
= rTxt
.GetChar( nPos
);
827 if( ('0' <= cCurrentChar
&& '9' >= cCurrentChar
) ||
828 (0xff10 <= cCurrentChar
&& 0xff19 >= cCurrentChar
) )
832 if( eScan
& CHG
) // nicht wenns mit einer Zahl beginnt
836 *pPostFix
+= (sal_Unicode
)1;
840 *pNumTypes
+= (sal_Unicode
)('0' + SVX_NUM_ARABIC
);
844 else if( pNumTypes
&& !(eScan
& DIGIT
) )
845 *pNumTypes
+= (sal_Unicode
)('0' + SVX_NUM_ARABIC
);
847 eScan
&= ~DELIM
; // Delim raus
848 if( 0 != (eScan
& ~CHG
) && DIGIT
!= (eScan
& ~CHG
))
851 eScan
|= DIGIT
; // Digit rein
852 if( 3 == ++nDigitCnt
) // mehr als 2 Nummern sind kein Enum mehr
856 nStart
+= cCurrentChar
<= '9' ? cCurrentChar
- '0' : cCurrentChar
- 0xff10;
858 else if( rCC
.isAlpha( rTxt
, nPos
) )
861 0 != ( i18n::KCharacterType::UPPER
&
862 rCC
.getCharacterType( rTxt
, nPos
));
863 sal_Unicode cLow
= rCC
.toLower( rTxt
, nPos
, 1 ).GetChar(0), cNumTyp
;
866 // roemische Zeichen sind "mdclxvi". Da man aber eher mal eine
867 // Numerierung mit c oder d anfangen will, werden diese erstmal
868 // zu chars und spaeter ggfs. zu romischen Zeichen!
869 // if( strchr( "mdclxvi", cLow ))
870 #ifdef WITH_ALPHANUM_AS_NUMFMT
871 //detection of 'c' and 'd' a ROMAN numbering should not be done here
872 if( 256 > cLow
&&( (eScan
& (LOWER_ROMAN
|UPPER_ROMAN
))
873 ? strchr( "mdclxvi", cLow
)
874 : strchr( "mlxvi", cLow
) ))
876 if( 256 > cLow
&& ( strchr( "mdclxvi", cLow
) ))
880 cNumTyp
= '0' + SVX_NUM_ROMAN_UPPER
, eTmpScan
= UPPER_ROMAN
;
882 cNumTyp
= '0' + SVX_NUM_ROMAN_LOWER
, eTmpScan
= LOWER_ROMAN
;
885 cNumTyp
= '0' + SVX_NUM_CHARS_UPPER_LETTER
, eTmpScan
= UPPER_ALPHA
;
887 cNumTyp
= '0' + SVX_NUM_CHARS_LOWER_LETTER
, eTmpScan
= LOWER_ALPHA
;
890 //ggfs. auf roemische Zeichen umschalten (nur bei c/d!)?
891 if( 1 == nDigitCnt
&& ( eScan
& (UPPER_ALPHA
|LOWER_ALPHA
) ) &&
892 ( 3 == nStart
|| 4 == nStart
) && 256 > cLow
&&
893 strchr( "mdclxvi", cLow
) &&
894 (( eScan
& UPPER_ALPHA
) ? (eTmpScan
& (UPPER_ALPHA
|UPPER_ROMAN
))
895 : (eTmpScan
& (LOWER_ALPHA
|LOWER_ROMAN
))) )
898 nStart
= 3 == nStart
? 100 : 500;
899 if( UPPER_ALPHA
== eTmpScan
)
900 eTmpScan
= UPPER_ROMAN
, c
+= SVX_NUM_ROMAN_UPPER
;
902 eTmpScan
= LOWER_ROMAN
, c
+= SVX_NUM_ROMAN_LOWER
;
904 ( eScan
&= ~(UPPER_ALPHA
|LOWER_ALPHA
)) |= eTmpScan
;
906 pNumTypes
->SetChar( pNumTypes
->Len() - 1, c
);
911 if( eScan
& CHG
) // nicht wenns mit einer Zahl beginnt
915 *pPostFix
+= (sal_Unicode
)1;
919 *pNumTypes
+= cNumTyp
;
922 else if( pNumTypes
&& !(eScan
& eTmpScan
) )
923 *pNumTypes
+= cNumTyp
;
925 eScan
&= ~DELIM
; // Delim raus
927 // falls ein andere Type gesetzt ist, brechen wir ab
928 if( 0 != ( eScan
& ~CHG
) && eTmpScan
!= ( eScan
& ~CHG
))
931 if( eTmpScan
& (UPPER_ALPHA
| LOWER_ALPHA
) )
933 // Buchstaben nur zulassen, wenn sie einmalig vorkommen
938 // roemische Zahlen: checke ob das gueltige Zeichen sind
943 case 'm': nVal
= 1000; goto CHECK_ROMAN_1
;
944 case 'd': nVal
= 500; goto CHECK_ROMAN_5
;
945 case 'c': nVal
= 100; goto CHECK_ROMAN_1
;
946 case 'l': nVal
= 50; goto CHECK_ROMAN_5
;
947 case 'x': nVal
= 10; goto CHECK_ROMAN_1
;
948 case 'v': nVal
= 5; goto CHECK_ROMAN_5
;
952 int nMod5
= nStart
% (nVal
* 5);
953 int nLast
= nStart
% nVal
;
956 if( nMod5
== ((3 * nVal
) + n10
) ||
957 nMod5
== ((4 * nVal
) + n10
) ||
959 nStart
= static_cast<USHORT
>(nStart
+ (n10
* 8));
960 else if( nMod5
== 0 ||
961 nMod5
== (1 * nVal
) ||
962 nMod5
== (2 * nVal
) )
963 nStart
= nStart
+ nVal
;
971 if( ( nStart
/ nVal
) & 1 )
975 int nMod
= nStart
% nVal
;
978 nStart
= static_cast<USHORT
>(nStart
+ (3 * n10
));
980 nStart
= nStart
+ nVal
;
988 if( nStart
% 5 >= 3 )
1001 eScan
|= eTmpScan
; // Digit rein
1004 else if( (256 > cCurrentChar
&&
1005 strchr( ".)(", cCurrentChar
)) ||
1006 0x3002 == cCurrentChar
/* Chinese trad. dot */||
1007 0xff0e == cCurrentChar
/* Japanese dot */||
1008 0xFF08 == cCurrentChar
/* opening bracket Chin./Jap.*/||
1009 0xFF09 == cCurrentChar
)/* closing bracket Chin./Jap. */
1011 if(cCurrentChar
== '(' || cCurrentChar
== 0xFF09)
1012 nOpeningParentheses
++;
1013 else if(cCurrentChar
== ')'|| cCurrentChar
== 0xFF08)
1014 nClosingParentheses
++;
1015 // nur wenn noch keine Zahlen gelesen wurden!
1016 if( pPreFix
&& !( eScan
& ( NO_DELIM
| CHG
)) )
1017 *pPreFix
+= rTxt
.GetChar( nPos
);
1019 *pPostFix
+= rTxt
.GetChar( nPos
);
1021 if( NO_DELIM
& eScan
)
1025 (*pPreFix
+= (sal_Unicode
)1)
1026 += String::CreateFromInt32( nStart
);
1028 eScan
&= ~NO_DELIM
; // Delim raus
1029 eScan
|= DELIM
; // Digit rein
1037 if( !( CHG
& eScan
) || rPos
== nPos
||
1038 nPos
== rTxt
.Len() || !IsSpace( rTxt
.GetChar( nPos
) ) ||
1039 (nOpeningParentheses
> nClosingParentheses
))
1042 if( (NO_DELIM
& eScan
) && pPreFix
) // den letzen nicht vergessen
1043 (*pPreFix
+= (sal_Unicode
)1) += String::CreateFromInt32( nStart
);
1046 return nDigitLvl
; // 0 .. 9 (MAXLEVEL - 1)
1050 void SwAutoFormat::SetColl( USHORT nId
, BOOL bHdLineOrText
)
1052 aDelPam
.DeleteMark();
1053 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1054 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1056 // behalte harte Tabs, Ausrichtung, Sprache, Silbentrennung,
1057 // DropCaps und fast alle Frame-Attribute
1058 SfxItemSet
aSet( pDoc
->GetAttrPool(),
1059 RES_PARATR_ADJUST
, RES_PARATR_ADJUST
,
1060 RES_PARATR_TABSTOP
, RES_PARATR_DROP
,
1061 RES_CHRATR_LANGUAGE
, RES_CHRATR_LANGUAGE
,
1062 RES_BACKGROUND
, RES_SHADOW
,
1065 if( pAktTxtNd
->HasSwAttrSet() )
1067 aSet
.Put( *pAktTxtNd
->GetpSwAttrSet() );
1068 // einige Sonderbedingungen:
1069 // HeaderLine/Textkoerper: nur zentriert oder rechts mitnehmem
1070 // sonst nur den Blocksatz
1071 SvxAdjustItem
* pAdj
;
1072 if( SFX_ITEM_SET
== aSet
.GetItemState( RES_PARATR_ADJUST
,
1073 FALSE
, (const SfxPoolItem
**)&pAdj
))
1075 SvxAdjust eAdj
= pAdj
->GetAdjust();
1076 if( bHdLineOrText
? (SVX_ADJUST_RIGHT
!= eAdj
&&
1077 SVX_ADJUST_CENTER
!= eAdj
)
1078 : SVX_ADJUST_BLOCK
!= eAdj
)
1079 aSet
.ClearItem( RES_PARATR_ADJUST
);
1083 pDoc
->SetTxtFmtCollByAutoFmt( *aDelPam
.GetPoint(), nId
, &aSet
);
1087 BOOL
SwAutoFormat::HasSelBlanks( SwPaM
& rPam
) const
1089 // noch ein Blank am Anfang oder Ende ?
1090 // nicht loeschen, wird wieder eingefuegt.
1091 SwPosition
* pPos
= rPam
.End();
1092 xub_StrLen nBlnkPos
= pPos
->nContent
.GetIndex();
1093 SwTxtNode
* pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
1094 if( nBlnkPos
&& nBlnkPos
-- < pTxtNd
->GetTxt().Len() &&
1095 ( ' ' == pTxtNd
->GetTxt().GetChar( nBlnkPos
) ))
1096 // JP 23.08.95: keine Tabs stehen lassen, diese in Blanks wandeln
1097 // ( ' ' == ( cCh = pTxtNd->GetTxt()[ nBlnkPos ] ) || '\t' == cCh ))
1101 pPos
= rPam
.GetPoint() == pPos
? rPam
.GetMark() : rPam
.GetPoint();
1102 nBlnkPos
= pPos
->nContent
.GetIndex();
1103 pTxtNd
= pPos
->nNode
.GetNode().GetTxtNode();
1104 if( nBlnkPos
< pTxtNd
->GetTxt().Len() &&
1105 ( ' ' == pTxtNd
->GetTxt().GetChar( nBlnkPos
)))
1106 // JP 23.08.95: keine Tabs stehen lassen, diese in Blanks wandeln
1107 // ( ' ' == ( cCh = pTxtNd->GetTxt()[ nBlnkPos ] ) || '\t' == cCh ))
1116 BOOL
SwAutoFormat::HasBreakAttr( const SwTxtNode
& rTxtNd
) const
1118 const SfxItemSet
* pSet
= rTxtNd
.GetpSwAttrSet();
1122 const SfxPoolItem
* pItem
;
1123 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_BREAK
, FALSE
, &pItem
)
1124 && SVX_BREAK_NONE
!= ((SvxFmtBreakItem
*)pItem
)->GetBreak() )
1127 if( SFX_ITEM_SET
== pSet
->GetItemState( RES_PAGEDESC
, FALSE
, &pItem
)
1128 && ((SwFmtPageDesc
*)pItem
)->GetPageDesc()
1129 && nsUseOnPage::PD_NONE
!= ((SwFmtPageDesc
*)pItem
)->GetPageDesc()->GetUseOn() )
1135 // ist ein Punkt am Ende ??
1136 BOOL
SwAutoFormat::IsSentenceAtEnd( const SwTxtNode
& rTxtNd
) const
1138 const String
& rStr
= rTxtNd
.GetTxt();
1139 xub_StrLen n
= rStr
.Len();
1143 while( --n
&& IsSpace( rStr
.GetChar( n
) ) )
1145 return '.' == rStr
.GetChar( n
);
1149 // loesche im Node Anfang oder/und Ende
1150 void SwAutoFormat::DeleteAktPara( BOOL bStart
, BOOL bEnd
)
1152 if( aFlags
.bAFmtByInput
1153 ? aFlags
.bAFmtByInpDelSpacesAtSttEnd
1154 : aFlags
.bAFmtDelSpacesAtSttEnd
)
1156 // Loesche Blanks am Ende vom akt. und am Anfang vom naechsten
1157 aDelPam
.DeleteMark();
1158 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1160 if( bStart
&& 0 != ( nPos
= GetLeadingBlanks( pAktTxtNd
->GetTxt() )))
1162 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1164 aDelPam
.GetPoint()->nContent
= nPos
;
1165 DeleteSel( aDelPam
);
1166 aDelPam
.DeleteMark();
1168 if( bEnd
&& pAktTxtNd
->GetTxt().Len() !=
1169 ( nPos
= GetTrailingBlanks( pAktTxtNd
->GetTxt() )) )
1171 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, pAktTxtNd
->GetTxt().Len() );
1173 aDelPam
.GetPoint()->nContent
= nPos
;
1174 DeleteSel( aDelPam
);
1175 aDelPam
.DeleteMark();
1180 void SwAutoFormat::DeleteSel( SwPaM
& rDelPam
)
1182 if( aFlags
.bWithRedlining
)
1184 // damit der DelPam auch verschoben wird, in den Shell-Cursr-Ring
1186 SwPaM
* pShCrsr
= pEditShell
->_GetCrsr();
1187 SwPaM
aTmp( *pAktTxtNd
, 0, pShCrsr
);
1189 Ring
*pPrev
= rDelPam
.GetPrev();
1190 rDelPam
.MoveRingTo( pShCrsr
);
1192 pEditShell
->DeleteSel( rDelPam
);
1194 // und den Pam wieder herausnehmen:
1195 Ring
*p
, *pNext
= (Ring
*)&rDelPam
;
1198 pNext
= p
->GetNext();
1199 p
->MoveTo( &rDelPam
);
1200 } while( p
!= pPrev
);
1202 aNdIdx
= aTmp
.GetPoint()->nNode
;
1203 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
1206 pEditShell
->DeleteSel( rDelPam
);
1209 BOOL
SwAutoFormat::DeleteAktNxtPara( const String
& rNxtPara
)
1211 // Loesche Blanks am Ende vom akt. und am Anfang vom naechsten
1212 aDelPam
.DeleteMark();
1213 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1214 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
,
1215 GetTrailingBlanks( pAktTxtNd
->GetTxt() ) );
1218 aDelPam
.GetPoint()->nNode
++;
1219 SwTxtNode
* pTNd
= aDelPam
.GetNode()->GetTxtNode();
1222 // dann nur bis zum Ende von Absatz loeschen
1223 aDelPam
.GetPoint()->nNode
--;
1224 aDelPam
.GetPoint()->nContent
= pAktTxtNd
->GetTxt().Len();
1227 aDelPam
.GetPoint()->nContent
.Assign( pTNd
,
1228 GetLeadingBlanks( rNxtPara
));
1230 // noch ein Blank am Anfang oder Ende ?
1231 // nicht loeschen, wird wieder eingefuegt.
1232 BOOL bHasBlnks
= HasSelBlanks( aDelPam
);
1234 if( *aDelPam
.GetPoint() != *aDelPam
.GetMark() )
1235 DeleteSel( aDelPam
);
1236 aDelPam
.DeleteMark();
1242 void SwAutoFormat::DelEmptyLine( BOOL bTstNextPara
)
1244 SetRedlineTxt( STR_AUTOFMTREDL_DEL_EMPTY_PARA
);
1245 // Loesche Blanks den leeren Absatz
1246 aDelPam
.DeleteMark();
1247 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1248 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, pAktTxtNd
->GetTxt().Len() );
1251 aDelPam
.GetMark()->nNode
--;
1252 SwTxtNode
* pTNd
= aDelPam
.GetNode( FALSE
)->GetTxtNode();
1254 // erstmal den vorherigen Textnode benutzen.
1255 aDelPam
.GetMark()->nContent
.Assign( pTNd
, pTNd
->GetTxt().Len() );
1256 else if( bTstNextPara
)
1258 // dann versuche den naechsten (am Anfang vom Dok, Tabellen-Zellen,
1260 aDelPam
.GetMark()->nNode
+= 2;
1261 pTNd
= aDelPam
.GetNode( FALSE
)->GetTxtNode();
1264 aDelPam
.GetMark()->nContent
.Assign( pTNd
, 0 );
1265 aDelPam
.GetPoint()->nContent
= 0;
1270 aDelPam
.GetMark()->nNode
= aNdIdx
;
1271 aDelPam
.GetMark()->nContent
= 0;
1275 DeleteSel( aDelPam
);
1277 aDelPam
.DeleteMark();
1282 void SwAutoFormat::DelMoreLinesBlanks( BOOL bWithLineBreaks
)
1284 if( aFlags
.bAFmtByInput
1285 ? aFlags
.bAFmtByInpDelSpacesBetweenLines
1286 : aFlags
.bAFmtDelSpacesBetweenLines
)
1288 // loesche alle "Blanks" Links und Rechts vom Einzug
1289 aDelPam
.DeleteMark();
1290 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1291 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1293 SwTxtFrmInfo
aFInfo( pAktTxtFrm
);
1294 aFInfo
.GetSpaces( aDelPam
, !aFlags
.bAFmtByInput
|| bWithLineBreaks
);
1298 pNxt
= (SwPaM
*)aDelPam
.GetNext();
1299 if( pNxt
->HasMark() && *pNxt
->GetPoint() != *pNxt
->GetMark() )
1301 BOOL bHasBlnks
= HasSelBlanks( *pNxt
);
1304 pDoc
->Insert( *pNxt
, ' ' );
1307 if( pNxt
== &aDelPam
)
1312 aDelPam
.DeleteMark();
1317 // loesche den vorherigen Absatz
1318 void SwAutoFormat::DelPrevPara()
1320 aDelPam
.DeleteMark();
1321 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1322 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1325 aDelPam
.GetPoint()->nNode
--;
1326 SwTxtNode
* pTNd
= aDelPam
.GetNode()->GetTxtNode();
1329 // erstmal den vorherigen Textnode benutzen.
1330 aDelPam
.GetPoint()->nContent
.Assign( pTNd
, pTNd
->GetTxt().Len() );
1331 DeleteSel( aDelPam
);
1333 aDelPam
.DeleteMark();
1337 void SwAutoFormat::BuildIndent()
1339 SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_INDENT
);
1341 // lese alle nachfolgenden Absaetze die zu diesem Einzug gehoeren
1344 DelMoreLinesBlanks( TRUE
);
1346 bBreak
= !IsFastFullLine( *pAktTxtNd
) ||
1347 IsBlanksInString( *pAktTxtNd
) ||
1348 IsSentenceAtEnd( *pAktTxtNd
);
1349 SetColl( RES_POOLCOLL_TEXT_IDENT
);
1352 SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES
);
1353 const SwTxtNode
* pNxtNd
= GetNextNode();
1354 if( pNxtNd
&& !bEnde
)
1357 bBreak
= !IsFastFullLine( *pNxtNd
) ||
1358 IsBlanksInString( *pNxtNd
) ||
1359 IsSentenceAtEnd( *pNxtNd
);
1360 if( DeleteAktNxtPara( pNxtNd
->GetTxt() ))
1361 pDoc
->Insert( aDelPam
, ' ' );
1364 pNxtNd
= GetNextNode();
1365 } while( CanJoin( pNxtNd
) &&
1366 !CalcLevel( *pNxtNd
) );
1369 DeleteAktPara( TRUE
, TRUE
);
1374 void SwAutoFormat::BuildTextIndent()
1376 SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT_INDENT
);
1377 // lese alle nachfolgenden Absaetze die zu diesem Einzug gehoeren
1380 DelMoreLinesBlanks( TRUE
);
1382 bBreak
= !IsFastFullLine( *pAktTxtNd
) ||
1383 IsBlanksInString( *pAktTxtNd
) ||
1384 IsSentenceAtEnd( *pAktTxtNd
);
1386 if( aFlags
.bAFmtByInput
)
1387 pAktTxtNd
->SetAutoFmtLvl( (BYTE
)CalcLevel( *pAktTxtNd
) );
1389 SetColl( RES_POOLCOLL_TEXT_MOVE
);
1392 SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES
);
1393 const SwTxtNode
* pNxtNd
= GetNextNode();
1394 while( CanJoin( pNxtNd
) &&
1395 CalcLevel( *pNxtNd
) )
1397 bBreak
= !IsFastFullLine( *pNxtNd
) || IsBlanksInString( *pNxtNd
) ||
1398 IsSentenceAtEnd( *pNxtNd
);
1399 if( DeleteAktNxtPara( pNxtNd
->GetTxt() ) )
1400 pDoc
->Insert( aDelPam
, ' ' );
1403 pNxtNd
= GetNextNode();
1406 DeleteAktPara( TRUE
, TRUE
);
1411 void SwAutoFormat::BuildText()
1413 SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_TEXT
);
1414 // lese alle nachfolgenden Absaetze die zu diesem Text
1415 // ohne Einzug gehoeren
1418 DelMoreLinesBlanks();
1420 bBreak
= !IsFastFullLine( *pAktTxtNd
) ||
1421 IsBlanksInString( *pAktTxtNd
) ||
1422 IsSentenceAtEnd( *pAktTxtNd
);
1423 SetColl( RES_POOLCOLL_TEXT
, TRUE
);
1426 SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES
);
1427 const SwTxtNode
* pNxtNd
= GetNextNode();
1428 while( CanJoin( pNxtNd
) &&
1429 !CalcLevel( *pNxtNd
) )
1431 bBreak
= !IsFastFullLine( *pNxtNd
) || IsBlanksInString( *pNxtNd
) ||
1432 IsSentenceAtEnd( *pNxtNd
);
1433 if( DeleteAktNxtPara( pNxtNd
->GetTxt() ) )
1434 pDoc
->Insert( aDelPam
, ' ' );
1437 const SwTxtNode
* pCurrNode
= pNxtNd
;
1438 pNxtNd
= GetNextNode();
1439 if(!pNxtNd
|| pCurrNode
== pNxtNd
)
1443 DeleteAktPara( TRUE
, TRUE
);
1448 void SwAutoFormat::BuildEnum( USHORT nLvl
, USHORT nDigitLevel
)
1450 SetRedlineTxt( STR_AUTOFMTREDL_SET_NUMBULET
);
1454 // als erstes den akt. Einzug bestimmen und die Framebreite bestimmen
1455 SwTwips nFrmWidth
= pAktTxtFrm
->Prt().Width();;
1456 SwTwips nLeftTxtPos
;
1458 const sal_Unicode
* pTxt
= pAktTxtNd
->GetTxt().GetBuffer(), *pSav
= pTxt
;
1459 while( IsSpace( *pTxt
) )
1462 SwTxtFrmInfo
aInfo( pAktTxtFrm
);
1463 nLeftTxtPos
= aInfo
.GetCharPos( static_cast<xub_StrLen
>(pTxt
- pSav
) );
1464 nLeftTxtPos
-= pAktTxtNd
->GetSwAttrSet().GetLRSpace().GetLeft();
1468 DelMoreLinesBlanks();
1470 bBreak
= !IsFastFullLine( *pAktTxtNd
) ||
1471 IsBlanksInString( *pAktTxtNd
) ||
1472 IsSentenceAtEnd( *pAktTxtNd
);
1473 sal_Bool bRTL
= pEditShell
->IsInRightToLeftText();
1474 // SetColl( RES_POOLCOLL_NUM_LEVEL1 + ( nLvl * 4 ) );
1475 DeleteAktPara( TRUE
, TRUE
);
1477 BOOL bChgBullet
= FALSE
, bChgEnum
= FALSE
;
1478 xub_StrLen nAutoCorrPos
= 0;
1480 // falls die Numerierung gesetzt werden, die akt. besorgen
1481 // --> OD 2008-02-11 #newlistlevelattrs#
1482 SwNumRule
aRule( pDoc
->GetUniqueNumRuleName(),
1483 // --> OD 2008-06-06 #i89178#
1484 numfunc::GetDefaultPositionAndSpaceMode() );
1487 const SwNumRule
* pCur
= 0;
1488 if( aFlags
.bSetNumRule
&& 0 != (pCur
= pAktTxtNd
->GetNumRule()) )
1491 // ersetze das Bullet-Zeichen mit dem definiertem
1492 const String
& rStr
= pAktTxtNd
->GetTxt();
1493 xub_StrLen nTxtStt
= 0, nOrigTxtStt
= 0;
1494 const sal_Unicode
* pFndBulletChr
;
1495 // if( aFlags.bAFmtByInput ? aFlags.bSetNumRule : aFlags.bChgEnumNum &&
1496 if( aFlags
.bChgEnumNum
&&
1498 0 != ( pFndBulletChr
= StrChr( pBulletChar
, rStr
.GetChar( nTxtStt
) ))
1499 && IsSpace( rStr
.GetChar( nTxtStt
+ 1 ) ) )
1501 if( aFlags
.bAFmtByInput
)
1503 if( aFlags
.bSetNumRule
)
1505 SwCharFmt
* pCFmt
= pDoc
->GetCharFmtFromPool(
1506 RES_POOLCHR_BUL_LEVEL
);
1508 // wurde das Format schon mal angepasst?
1509 if( !aRule
.GetNumFmt( nLvl
) )
1511 int nBulletPos
= pFndBulletChr
- pBulletChar
;
1512 sal_Unicode cBullChar
;
1513 const Font
* pBullFnt( 0 );
1514 if( nBulletPos
< cnPosEnDash
)
1516 cBullChar
= aFlags
.cBullet
;
1517 pBullFnt
= &aFlags
.aBulletFont
;
1521 cBullChar
= nBulletPos
< cnPosEmDash
1523 : cStarSymbolEmDash
;
1524 // --> OD 2008-06-03 #i63395#
1525 // Only apply user defined default bullet font
1526 if ( numfunc::IsDefBulletFontUserDefined() )
1528 pBullFnt
= &numfunc::GetDefBulletFont();
1533 USHORT nAbsPos
= lBullIndent
;
1534 USHORT nSpaceSteps
= nLvl
1535 ? USHORT(nLeftTxtPos
/ nLvl
)
1537 for( BYTE n
= 0; n
< MAXLEVEL
; ++n
, nAbsPos
= nAbsPos
+ nSpaceSteps
)
1539 SwNumFmt
aFmt( aRule
.Get( n
) );
1540 aFmt
.SetBulletFont( pBullFnt
);
1541 aFmt
.SetBulletChar( cBullChar
);
1542 aFmt
.SetNumberingType(SVX_NUM_CHAR_SPECIAL
);
1543 aFmt
.SetFirstLineOffset( lBullFirstLineOffset
);
1544 aFmt
.SetAbsLSpace( nAbsPos
);
1545 if( !aFmt
.GetCharFmt() )
1546 aFmt
.SetCharFmt( pCFmt
);
1548 aFmt
.SetNumAdjust( SVX_ADJUST_RIGHT
);
1550 aRule
.Set( n
, aFmt
);
1553 nFrmWidth
< ( nSpaceSteps
* MAXLEVEL
) )
1554 nSpaceSteps
= static_cast<USHORT
>(( nFrmWidth
- nLeftTxtPos
) /
1555 ( MAXLEVEL
- nLvl
));
1563 SetColl( static_cast<USHORT
>(RES_POOLCOLL_BUL_LEVEL1
+ ( Min( nLvl
, cnNumBullColls
) * 4 )) );
1568 // dann ist das eine Nummerierung
1570 //JP 21.11.97: Der NumLevel wird entweder der DigitLevel oder
1571 // wenn der nicht vorhanden oder 0 ist, durch den
1572 // (Einrueckungs-)Level.
1574 String aPostFix
, aPreFix
, aNumTypes
;
1575 if( USHRT_MAX
!= ( nDigitLevel
= GetDigitLevel( *pAktTxtNd
, nTxtStt
,
1576 &aPreFix
, &aPostFix
, &aNumTypes
)) )
1580 // Ebene 0 und Einrueckung dann wird die Ebene durch den linken
1581 // Einzug und der default NumEinrueckung bestimmt.
1582 if( !nDigitLevel
&& nLeftTxtPos
)
1583 nLvl
= Min( USHORT( nLeftTxtPos
/ lNumIndent
),
1584 USHORT( MAXLEVEL
- 1 ) );
1589 if( bChgEnum
&& aFlags
.bSetNumRule
)
1591 if( !pCur
) // NumRule anpassen, wenn sie neu ist
1593 SwCharFmt
* pCFmt
= pDoc
->GetCharFmtFromPool(
1594 RES_POOLCHR_NUM_LEVEL
);
1597 SwNumFmt
aFmt( aRule
.Get( nLvl
) );
1598 aFmt
.SetStart( static_cast<USHORT
>(aPreFix
.GetToken( 1,
1599 (sal_Unicode
)1 ).ToInt32()));
1600 aFmt
.SetPrefix( aPreFix
.GetToken( 0, (sal_Unicode
)1 ));
1601 aFmt
.SetSuffix( aPostFix
.GetToken( 0, (sal_Unicode
)1 ));
1602 aFmt
.SetIncludeUpperLevels( 0 );
1604 if( !aFmt
.GetCharFmt() )
1605 aFmt
.SetCharFmt( pCFmt
);
1607 if( aNumTypes
.Len() )
1608 aFmt
.SetNumberingType(aNumTypes
.GetChar( 0 ) - '0');
1611 aFmt
.SetNumAdjust( SVX_ADJUST_RIGHT
);
1612 aRule
.Set( nLvl
, aFmt
);
1616 USHORT nSpaceSteps
= nLvl
? USHORT(nLeftTxtPos
/ nLvl
) : 0;
1618 for( n
= 0; n
<= nLvl
; ++n
)
1620 SwNumFmt
aFmt( aRule
.Get( n
) );
1622 aFmt
.SetStart( static_cast<USHORT
>(aPreFix
.GetToken( n
+1,
1623 (sal_Unicode
)1 ).ToInt32() ));
1625 aFmt
.SetPrefix( aPreFix
.GetToken( n
, (sal_Unicode
)1 ));
1626 aFmt
.SetSuffix( aPostFix
.GetToken( n
, (sal_Unicode
)1 ));
1627 aFmt
.SetIncludeUpperLevels( MAXLEVEL
);
1628 if( n
< aNumTypes
.Len() )
1629 aFmt
.SetNumberingType((aNumTypes
.GetChar( n
) - '0'));
1631 aFmt
.SetAbsLSpace( USHORT( nSpaceSteps
* n
)
1634 if( !aFmt
.GetCharFmt() )
1635 aFmt
.SetCharFmt( pCFmt
);
1637 aFmt
.SetNumAdjust( SVX_ADJUST_RIGHT
);
1639 aRule
.Set( n
, aFmt
);
1642 // passt alles vollstaendig in den Frame?
1643 BOOL bDefStep
= nFrmWidth
< (nSpaceSteps
* MAXLEVEL
);
1644 for( ; n
< MAXLEVEL
; ++n
)
1646 SwNumFmt
aFmt( aRule
.Get( n
) );
1647 aFmt
.SetIncludeUpperLevels( MAXLEVEL
);
1649 aFmt
.SetAbsLSpace( USHORT( (nLeftTxtPos
+
1650 SwNumRule::GetNumIndent(static_cast<BYTE
>(n
-nLvl
)))));
1652 aFmt
.SetAbsLSpace( USHORT( nSpaceSteps
* n
)
1654 aRule
.Set( n
, aFmt
);
1659 else if( !aFlags
.bAFmtByInput
)
1660 SetColl( static_cast<USHORT
>(RES_POOLCOLL_NUM_LEVEL1
+ ( Min( nLvl
, cnNumBullColls
) * 4 ) ));
1665 if( bChgEnum
|| bChgBullet
)
1667 aDelPam
.DeleteMark();
1668 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1670 if( aFlags
.bSetNumRule
)
1672 if( aFlags
.bAFmtByInput
)
1675 aDelPam
.GetMark()->nNode
++;
1676 aDelPam
.GetNode(FALSE
)->GetTxtNode()->SetAttrListLevel( nLvl
);
1679 pAktTxtNd
->SetAttrListLevel(nLvl
);
1680 pAktTxtNd
->SetNumLSpace( TRUE
);
1682 // --> OD 2008-03-17 #refactorlists#
1684 pDoc
->SetNumRule( aDelPam
, aRule
, true );
1686 aDelPam
.DeleteMark();
1688 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1691 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
,
1692 bChgEnum
? (nTxtStt
- nOrigTxtStt
) : 0 );
1698 while( nTxtStt
< rStr
.Len() && IsSpace( rStr
.GetChar( nTxtStt
) ))
1701 aDelPam
.GetPoint()->nContent
= nTxtStt
- nOrigTxtStt
;
1702 DeleteSel( aDelPam
);
1704 if( !aFlags
.bSetNumRule
)
1706 String
sChgStr( '\t' );
1708 sChgStr
.Insert( aFlags
.cBullet
, 0 );
1709 pDoc
->Insert( aDelPam
, sChgStr
, true );
1711 SfxItemSet
aSet( pDoc
->GetAttrPool(), aTxtNodeSetRange
);
1714 aDelPam
.GetPoint()->nContent
= 0;
1716 aDelPam
.GetMark()->nContent
= 1;
1717 SetAllScriptItem( aSet
,
1718 SvxFontItem( aFlags
.aBulletFont
.GetFamily(),
1719 aFlags
.aBulletFont
.GetName(),
1720 aFlags
.aBulletFont
.GetStyleName(),
1721 aFlags
.aBulletFont
.GetPitch(),
1722 aFlags
.aBulletFont
.GetCharSet(),
1723 RES_CHRATR_FONT
) );
1724 pDoc
->SetFmtItemByAutoFmt( aDelPam
, aSet
);
1725 aDelPam
.DeleteMark();
1729 SvxTabStopItem
aTStops( RES_PARATR_TABSTOP
); aTStops
.Insert( SvxTabStop( 0 ));
1730 aSet
.Put( aTStops
);
1731 pDoc
->SetFmtItemByAutoFmt( aDelPam
, aSet
);
1737 AutoCorrect( nAutoCorrPos
); /* Offset wegen Bullet + Tab */
1741 const SwTxtNode
* pNxtNd
= GetNextNode();
1742 while( CanJoin( pNxtNd
) &&
1743 nLvl
== CalcLevel( *pNxtNd
) )
1745 SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES
);
1746 bBreak
= !IsFastFullLine( *pNxtNd
) || IsBlanksInString( *pNxtNd
) ||
1747 IsSentenceAtEnd( *pNxtNd
);
1748 if( DeleteAktNxtPara( pNxtNd
->GetTxt() ) )
1749 pDoc
->Insert( aDelPam
, ' ' );
1752 const SwTxtNode
* pCurrNode
= pNxtNd
;
1753 pNxtNd
= GetNextNode();
1754 if(!pNxtNd
|| pCurrNode
== pNxtNd
)
1757 DeleteAktPara( FALSE
, TRUE
);
1758 AutoCorrect( nAutoCorrPos
);
1762 void SwAutoFormat::BuildNegIndent( SwTwips nSpaces
)
1764 SetRedlineTxt( STR_AUTOFMTREDL_SET_TMPL_NEG_INDENT
);
1765 // Test auf Gegenueberstellung:
1766 // (n Worte, durch Space/Tabs getrennt, mit gleicher
1767 // Einrueckung in der 2.Zeile)
1769 // lese alle nachfolgenden Absaetze die zu dieser Aufzaehlung gehoeren
1771 xub_StrLen nSpacePos
, nTxtPos
= GetBigIndent( nSpacePos
);
1773 DelMoreLinesBlanks( TRUE
);
1775 bBreak
= !IsFastFullLine( *pAktTxtNd
) ||
1776 ( !nTxtPos
&& IsBlanksInString( *pAktTxtNd
)) ||
1777 IsSentenceAtEnd( *pAktTxtNd
);
1779 SetColl( static_cast<USHORT
>( nTxtPos
1780 ? RES_POOLCOLL_CONFRONTATION
1781 : RES_POOLCOLL_TEXT_NEGIDENT
) );
1785 const String
& rStr
= pAktTxtNd
->GetTxt();
1786 BOOL bInsTab
= TRUE
;
1788 if( '\t' == rStr
.GetChar( nSpacePos
+1 )) // ein Tab, das belassen wir
1794 xub_StrLen nSpaceStt
= nSpacePos
;
1795 while( nSpaceStt
&& IsSpace( rStr
.GetChar( --nSpaceStt
) ) )
1799 if( bInsTab
&& '\t' == rStr
.GetChar( nSpaceStt
) ) // ein Tab, das belassen wir
1806 aDelPam
.DeleteMark();
1807 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1808 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, nSpacePos
);
1810 // alten Spaces, usw. loeschen
1811 if( nSpaceStt
< nSpacePos
)
1814 aDelPam
.GetMark()->nContent
= nSpaceStt
;
1815 DeleteSel( aDelPam
);
1817 pDoc
->Insert( aDelPam
, '\t' );
1823 SetRedlineTxt( STR_AUTOFMTREDL_DEL_MORELINES
);
1824 SwTxtFrmInfo
aFInfo( pAktTxtFrm
);
1825 const SwTxtNode
* pNxtNd
= GetNextNode();
1826 while( CanJoin( pNxtNd
) &&
1827 20 < Abs( (long)(nSpaces
- aFInfo
.SetFrm(
1828 GetFrm( *pNxtNd
) ).GetLineStart() ))
1831 bBreak
= !IsFastFullLine( *pNxtNd
) ||
1832 IsBlanksInString( *pNxtNd
) ||
1833 IsSentenceAtEnd( *pNxtNd
);
1834 if( DeleteAktNxtPara( pNxtNd
->GetTxt() ) )
1835 pDoc
->Insert( aDelPam
, ' ' );
1838 pNxtNd
= GetNextNode();
1841 DeleteAktPara( TRUE
, TRUE
);
1846 void SwAutoFormat::BuildHeadLine( USHORT nLvl
)
1848 if( aFlags
.bWithRedlining
)
1850 String
sTxt( *ViewShell::GetShellRes()->GetAutoFmtNameLst()[
1851 STR_AUTOFMTREDL_SET_TMPL_HEADLINE
] );
1852 sTxt
.SearchAndReplace( String::CreateFromAscii(
1853 RTL_CONSTASCII_STRINGPARAM( "$(ARG1)" )),
1854 String::CreateFromInt32( nLvl
+ 1 ) );
1855 pDoc
->SetAutoFmtRedlineComment( &sTxt
);
1858 SetColl( static_cast<USHORT
>(RES_POOLCOLL_HEADLINE1
+ nLvl
), TRUE
);
1859 if( aFlags
.bAFmtByInput
)
1861 SwTxtFmtColl
& rNxtColl
= pAktTxtNd
->GetTxtColl()->GetNextTxtFmtColl();
1865 DeleteAktPara( TRUE
, FALSE
);
1866 DeleteAktNxtPara( aEmptyStr
);
1868 aDelPam
.DeleteMark();
1869 aDelPam
.GetPoint()->nNode
= aNdIdx
.GetIndex() + 1;
1870 aDelPam
.GetPoint()->nContent
.Assign( aDelPam
.GetCntntNode(), 0 );
1871 pDoc
->SetTxtFmtColl( aDelPam
, &rNxtColl
);
1875 DeleteAktPara( TRUE
, TRUE
);
1881 // dann lasse doch mal das AutoCorrect auf den akt. TextNode los
1882 void SwAutoFormat::AutoCorrect( xub_StrLen nPos
)
1884 if( aFlags
.bAFmtByInput
||
1885 (!aFlags
.bAutoCorrect
&& !aFlags
.bReplaceQuote
&&
1886 !aFlags
.bCptlSttSntnc
&& !aFlags
.bCptlSttWrd
&&
1887 !aFlags
.bChgFracionSymbol
&& !aFlags
.bChgOrdinalNumber
&&
1888 !aFlags
.bChgToEnEmDash
&& !aFlags
.bSetINetAttr
&&
1889 !aFlags
.bChgWeightUnderl
&& !aFlags
.bAddNonBrkSpace
) )
1892 const String
* pTxt
= &pAktTxtNd
->GetTxt();
1893 if( nPos
>= pTxt
->Len() )
1896 BOOL bGetLanguage
= aFlags
.bChgOrdinalNumber
||
1897 aFlags
.bChgToEnEmDash
|| aFlags
.bSetINetAttr
||
1898 aFlags
.bCptlSttWrd
|| aFlags
.bCptlSttSntnc
||
1899 aFlags
.bAddNonBrkSpace
;
1902 aDelPam
.DeleteMark();
1903 aDelPam
.GetPoint()->nNode
= aNdIdx
;
1904 aDelPam
.GetPoint()->nContent
.Assign( pAktTxtNd
, 0 );
1906 SwAutoCorrDoc
aACorrDoc( *pEditShell
, aDelPam
);
1907 SvxAutoCorrect
* pATst
= SvxAutoCorrCfg::Get()->GetAutoCorrect();
1909 SwTxtFrmInfo
aFInfo( 0 );
1911 xub_StrLen nSttPos
, nLastBlank
= nPos
;
1912 BOOL bFirst
= aFlags
.bCptlSttSntnc
, bFirstSent
= bFirst
;
1913 sal_Unicode cChar
= 0;
1915 CharClass
& rAppCC
= GetAppCharClass();
1918 while( nPos
< pTxt
->Len() && IsSpace( cChar
= pTxt
->GetChar( nPos
) ))
1920 if( nPos
== pTxt
->Len() )
1923 if( aFlags
.bReplaceQuote
&&
1924 ( '\"' == cChar
|| '\'' == cChar
) &&
1925 ( !nPos
|| ' ' == pTxt
->GetChar( nPos
-1 ) ) )
1927 // --------------------------------------
1928 // beachte: Sonderfall Symbolfonts !!!
1929 if( !aFInfo
.GetFrm() )
1930 aFInfo
.SetFrm( GetFrm( *pAktTxtNd
) );
1931 if( !aFInfo
.IsBullet( nPos
))
1933 SetRedlineTxt( STR_AUTOFMTREDL_TYPO
);
1934 aDelPam
.GetPoint()->nContent
= nPos
;
1935 BOOL bSetHardBlank
= FALSE
;
1937 String
sReplace( pATst
->GetQuote( aACorrDoc
,
1938 nPos
, cChar
, TRUE
));
1941 aDelPam
.GetPoint()->nContent
= nPos
+1;
1942 if( 2 == sReplace
.Len() && ' ' == sReplace
.GetChar( 1 ))
1944 sReplace
.Erase( 1 );
1945 bSetHardBlank
= TRUE
;
1947 pDoc
->Replace( aDelPam
, sReplace
, FALSE
);
1949 if( aFlags
.bWithRedlining
)
1951 aNdIdx
= aDelPam
.GetPoint()->nNode
;
1952 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
1953 pTxt
= &pAktTxtNd
->GetTxt();
1958 nPos
+= sReplace
.Len() - 1;
1959 aDelPam
.DeleteMark();
1962 pDoc
->Insert( aDelPam
, CHAR_HARDBLANK
);
1968 int bCallACorr
= FALSE
;
1970 if( nPos
&& IsSpace( pTxt
->GetChar( nPos
-1 )))
1972 for( nSttPos
= nPos
; !bBreak
&& nPos
< pTxt
->Len(); ++nPos
)
1973 switch( cChar
= pTxt
->GetChar( nPos
) )
1977 if( aFlags
.bReplaceQuote
)
1979 // --------------------------------------
1980 // beachte: Sonderfall Symbolfonts !!!
1981 if( !aFInfo
.GetFrm() )
1982 aFInfo
.SetFrm( GetFrm( *pAktTxtNd
) );
1983 if( !aFInfo
.IsBullet( nPos
))
1985 SetRedlineTxt( STR_AUTOFMTREDL_TYPO
);
1986 BOOL bSetHardBlank
= FALSE
;
1987 aDelPam
.GetPoint()->nContent
= nPos
;
1988 String
sReplace( pATst
->GetQuote( aACorrDoc
,
1989 nPos
, cChar
, FALSE
));
1991 if( 2 == sReplace
.Len() && ' ' == sReplace
.GetChar( 0 ))
1993 sReplace
.Erase( 0, 1 );
1994 bSetHardBlank
= TRUE
;
1998 aDelPam
.GetPoint()->nContent
= nPos
+1;
1999 pDoc
->Replace( aDelPam
, sReplace
, FALSE
);
2001 if( aFlags
.bWithRedlining
)
2003 aNdIdx
= aDelPam
.GetPoint()->nNode
;
2004 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
2005 pTxt
= &pAktTxtNd
->GetTxt();
2007 aDelPam
.DeleteMark();
2011 nPos
+= sReplace
.Len() - 1;
2012 aDelPam
.DeleteMark();
2016 aDelPam
.GetPoint()->nContent
= nPos
;
2017 pDoc
->Insert( aDelPam
, CHAR_HARDBLANK
);
2018 aDelPam
.GetPoint()->nContent
= ++nPos
;
2025 if( aFlags
.bChgWeightUnderl
)
2027 // --------------------------------------
2028 // beachte: Sonderfall Symbolfonts !!!
2029 if( !aFInfo
.GetFrm() )
2030 aFInfo
.SetFrm( GetFrm( *pAktTxtNd
) );
2031 if( !aFInfo
.IsBullet( nPos
))
2033 SetRedlineTxt( '*' == cChar
2034 ? STR_AUTOFMTREDL_BOLD
2035 : STR_AUTOFMTREDL_UNDER
);
2037 sal_Unicode cBlank
= nSttPos
? pTxt
->GetChar(nSttPos
- 1) : 0;
2038 aDelPam
.GetPoint()->nContent
= nPos
;
2040 if( pATst
->FnChgWeightUnderl( aACorrDoc
, *pTxt
,
2043 if( aFlags
.bWithRedlining
)
2045 aNdIdx
= aDelPam
.GetPoint()->nNode
;
2046 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
2047 pTxt
= &pAktTxtNd
->GetTxt();
2049 aDelPam
.DeleteMark();
2052 //#125102# in case of the mode REDLINE_SHOW_DELETE the ** are still contained in pTxt
2053 if(0 == (pDoc
->GetRedlineMode() & nsRedlineMode_t::REDLINE_SHOW_DELETE
))
2054 nPos
= aDelPam
.GetPoint()->nContent
.GetIndex() - 1;
2055 // wurde vorm Start ein Zeichen entfernt?
2056 if( cBlank
&& cBlank
!= pTxt
->GetChar(nSttPos
- 1) )
2066 if( aFlags
.bCptlSttSntnc
)
2068 //alle Wortrenner loesen die Autokorrektur aus!
2072 //alle Wortrenner loesen die Autokorrektur aus!
2075 if( !( rAppCC
.isLetterNumeric( *pTxt
, nPos
)
2076 || '/' == cChar
)) // '/' should not be a word seperator (e.g. '1/2' needs to be handled as one word for replacement)
2078 --nPos
; // ++nPos von dem for ungueltig machen !
2084 if( nPos
== nSttPos
)
2086 if( ++nPos
== pTxt
->Len() )
2096 aDelPam
.GetPoint()->nContent
= nPos
;
2097 SetRedlineTxt( STR_AUTOFMTREDL_USE_REPLACE
);
2098 if( aFlags
.bAutoCorrect
&&
2099 aACorrDoc
.ChgAutoCorrWord( nSttPos
, nPos
, *pATst
, 0 ) )
2101 nPos
= aDelPam
.GetPoint()->nContent
.GetIndex();
2103 if( aFlags
.bWithRedlining
)
2105 aNdIdx
= aDelPam
.GetPoint()->nNode
;
2106 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
2107 pTxt
= &pAktTxtNd
->GetTxt();
2109 aDelPam
.DeleteMark();
2112 continue; // nichts weiter mehr abpruefen
2115 LanguageType eLang
= (bGetLanguage
&& pAktTxtNd
)
2116 ? pAktTxtNd
->GetLang( nSttPos
)
2119 if( ( aFlags
.bChgFracionSymbol
&&
2120 SetRedlineTxt( STR_AUTOFMTREDL_FRACTION
) &&
2121 pATst
->FnChgFractionSymbol( aACorrDoc
, *pTxt
, nSttPos
, nPos
) ) ||
2122 ( aFlags
.bChgOrdinalNumber
&&
2123 SetRedlineTxt( STR_AUTOFMTREDL_ORDINAL
) &&
2124 pATst
->FnChgOrdinalNumber( aACorrDoc
, *pTxt
, nSttPos
, nPos
, eLang
) ) ||
2125 ( aFlags
.bChgToEnEmDash
&&
2126 SetRedlineTxt( STR_AUTOFMTREDL_DASH
) &&
2127 pATst
->FnChgToEnEmDash( aACorrDoc
, *pTxt
, nSttPos
, nPos
, eLang
) ) ||
2128 ( aFlags
.bAddNonBrkSpace
&&
2129 SetRedlineTxt( STR_AUTOFMTREDL_NON_BREAK_SPACE
) &&
2130 pATst
->FnAddNonBrkSpace( aACorrDoc
, *pTxt
, nSttPos
, nPos
, eLang
) ) ||
2131 ( aFlags
.bSetINetAttr
&&
2132 ( nPos
== pTxt
->Len() || IsSpace( pTxt
->GetChar( nPos
)) ) &&
2133 SetRedlineTxt( STR_AUTOFMTREDL_DETECT_URL
) &&
2134 pATst
->FnSetINetAttr( aACorrDoc
, *pTxt
, nLastBlank
, nPos
, eLang
) ) )
2135 nPos
= aDelPam
.GetPoint()->nContent
.GetIndex();
2138 // Zwei Grossbuchstaben am Wort-Anfang ??
2139 if( aFlags
.bCptlSttWrd
)
2141 SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_WORD
);
2142 pATst
->FnCptlSttWrd( aACorrDoc
, *pTxt
, nSttPos
, nPos
, eLang
);
2144 // Grossbuchstabe am Satz-Anfang ??
2145 if( aFlags
.bCptlSttSntnc
&& bFirst
)
2147 SetRedlineTxt( STR_AUTOFMTREDL_CPTL_STT_SENT
);
2148 pATst
->FnCptlSttSntnc( aACorrDoc
, *pTxt
, TRUE
, nSttPos
, nPos
, eLang
);
2152 bFirst
= bFirstSent
;
2155 if( aFlags
.bWithRedlining
)
2157 aNdIdx
= aDelPam
.GetPoint()->nNode
;
2158 pAktTxtNd
= aNdIdx
.GetNode().GetTxtNode();
2159 pTxt
= &pAktTxtNd
->GetTxt();
2161 aDelPam
.DeleteMark();
2165 } while( nPos
< pTxt
->Len() );
2170 SwAutoFormat::SwAutoFormat( SwEditShell
* pEdShell
, SvxSwAutoFmtFlags
& rFlags
,
2171 SwNodeIndex
* pSttNd
, SwNodeIndex
* pEndNd
)
2173 aDelPam( pEdShell
->GetDoc()->GetNodes().GetEndOfExtras() ),
2174 aNdIdx( pEdShell
->GetDoc()->GetNodes().GetEndOfExtras(), +1 ),
2175 aEndNdIdx( pEdShell
->GetDoc()->GetNodes().GetEndOfContent() ),
2176 pEditShell( pEdShell
),
2177 pDoc( pEdShell
->GetDoc() ),
2178 pAktTxtNd( 0 ), pAktTxtFrm( 0 ),
2180 nRedlAutoFmtSeqId( 0 )
2182 ASSERT( (pSttNd
&& pEndNd
) || (!pSttNd
&& !pEndNd
),
2183 "Kein Bereich angegeben" );
2185 if( aFlags
.bSetNumRule
&& !aFlags
.bAFmtByInput
)
2186 aFlags
.bSetNumRule
= FALSE
;
2188 BOOL bReplaceStyles
= !aFlags
.bAFmtByInput
|| aFlags
.bReplaceStyles
;
2190 const SwTxtNode
* pNxtNd
= 0;
2191 BOOL bNxtEmpty
= FALSE
;
2192 BOOL bNxtAlpha
= FALSE
;
2193 USHORT nNxtLevel
= 0;
2195 // setze den Bereich zum Autoformatieren
2199 aNdIdx
--; // fuer GoNextPara, ein Absatz davor
2200 aEndNdIdx
= *pEndNd
;
2203 // teste den vorhergehenden TextNode
2204 pNxtNd
= aNdIdx
.GetNode().GetTxtNode();
2205 bEmptyLine
= !pNxtNd
||
2206 IsEmptyLine( *pNxtNd
) ||
2207 IsNoAlphaLine( *pNxtNd
);
2210 bEmptyLine
= TRUE
; // am Dokument Anfang
2214 // setze die Werte fuer die Prozent-Anzeige
2215 nEndNdIdx
= aEndNdIdx
.GetIndex();
2217 if( !aFlags
.bAFmtByInput
)
2218 ::StartProgress( STR_STATSTR_AUTOFORMAT
, aNdIdx
.GetIndex(),
2219 nEndNdIdx
= aEndNdIdx
.GetIndex(),
2220 pDoc
->GetDocShell() );
2222 RedlineMode_t eRedlMode
= pDoc
->GetRedlineMode(), eOldMode
= eRedlMode
;
2223 if( aFlags
.bWithRedlining
)
2225 pDoc
->SetAutoFmtRedline( TRUE
);
2226 eRedlMode
= (RedlineMode_t
)(nsRedlineMode_t::REDLINE_ON
| nsRedlineMode_t::REDLINE_SHOW_INSERT
);
2229 eRedlMode
= (RedlineMode_t
)(nsRedlineMode_t::REDLINE_SHOW_INSERT
| nsRedlineMode_t::REDLINE_IGNORE
);
2230 pDoc
->SetRedlineMode( eRedlMode
);
2232 // save undo state (might be turned off)
2233 sal_Bool bUndoState
= pDoc
->DoesUndo();
2235 // wenn mehrere Zeilen, dann erstmal nicht mit
2236 // dem nachfolgenden Absatz zusammenfassen.
2239 nLastCalcHeadLvl
= nLastCalcEnumLvl
= 0;
2240 nLastHeadLvl
= nLastEnumLvl
= USHRT_MAX
;
2242 USHORT nDigitLvl
= 0;
2245 SwTxtFrmInfo
aFInfo( 0 );
2247 // das ist unser Automat fuer die Auto-Formatierung
2248 eStat
= READ_NEXT_PARA
;
2251 // #95884# limit redline array size to prevent overflow and to conserve
2253 if( pDoc
->HasTooManyUndos() )
2255 DBG_ASSERT( bUndoState
, "undo overflow without undo?" );
2258 short nResult
= m_nActionWhileAutoformatUndoBufferOverflow
; // TODO: #102007# read the last decision of the user from configuration
2259 if(m_bAskForCancelUndoWhileBufferOverflow
) // #102007# TODO: read the last decision of the user from configuration
2261 Window
* pParent
= pEditShell
?pEditShell
->GetWin():NULL
;
2262 WarningBox
aWarning( pParent
,SW_RES(MSG_DISABLE_UNDO_QUESTION
));
2263 aWarning
.SetDefaultCheckBoxText();
2264 USHORT nDefaultButton
= nResult
==RET_YES
?BUTTONID_YES
:(nResult
==RET_NO
?BUTTONID_NO
:BUTTONID_CANCEL
);
2265 aWarning
.SetFocusButton(nDefaultButton
);
2266 nResult
= aWarning
.Execute();
2267 m_bAskForCancelUndoWhileBufferOverflow
= !aWarning
.GetCheckBoxState();
2268 m_nActionWhileAutoformatUndoBufferOverflow
= nResult
;
2269 // TODO: #102007# store m_bAskForCancelUndoWhileBufferOverflow in configuration
2270 // TODO: #102007# store m_nActionWhileAutoformatUndoBufferOverflow in configuration
2273 DBG_ASSERT( (nResult
== RET_YES
) || (nResult
== RET_CANCEL
) || (nResult
== RET_NO
),
2274 "unexpected result" );
2276 if( nResult
== RET_YES
)
2278 // turn off undo and continue
2279 pDoc
->DoUndo( sal_False
);
2280 pDoc
->DelAllUndoObj();
2282 else if( nResult
== RET_NO
)
2284 //stop autoformatting and keep changes
2287 else if( nResult
== RET_CANCEL
)
2289 //cancel autoformatting and undo changes
2292 // TODO: #102004# undo changes
2298 case READ_NEXT_PARA
:
2301 eStat
= bEnde
? IS_ENDE
: TST_EMPTY_LINE
;
2305 case TST_EMPTY_LINE
:
2306 if( IsEmptyLine( *pAktTxtNd
) )
2308 if( aFlags
.bDelEmptyNode
&& !HasObjects( *pAktTxtNd
) )
2311 ULONG nOldCnt
= pDoc
->GetNodes().Count();
2313 // wurde wiklich ein Node geloescht ?
2314 if( nOldCnt
!= pDoc
->GetNodes().Count() )
2315 aNdIdx
--; // nicht den naechsten Absatz ueberspringen
2317 eStat
= READ_NEXT_PARA
;
2320 eStat
= TST_ALPHA_LINE
;
2323 case TST_ALPHA_LINE
:
2324 if( IsNoAlphaLine( *pAktTxtNd
))
2326 // erkenne eine Tabellendefinition +---+---+
2327 if( aFlags
.bAFmtByInput
&& aFlags
.bCreateTable
&& DoTable() )
2329 //JP 30.09.96: das DoTable() verlaesst sich auf das
2330 // Pop und Move - Crsr nach dem AutoFormat!
2331 pEdShell
->Pop( FALSE
);
2332 *pEdShell
->GetCrsr() = aDelPam
;
2339 // dann teste mal auf 3 "---" oder "===". In dem Fall
2340 // soll der vorherige Absatz unterstrichen und dieser
2341 // geloescht werden!
2342 if( !DoUnderline() && bReplaceStyles
)
2344 SetColl( RES_POOLCOLL_STANDARD
, TRUE
);
2347 eStat
= READ_NEXT_PARA
;
2350 eStat
= GET_ALL_INFO
;
2355 if( pAktTxtNd
->GetNumRule() )
2357 // in Numerierung nichts machen, zum naechsten
2359 eStat
= READ_NEXT_PARA
;
2360 // loesche alle Blanks am Anfang/Ende
2361 // und alle mitten drin
2362 //JP 29.04.98: erstmal nur alle "mitten drin".
2363 DelMoreLinesBlanks( FALSE
);
2367 aFInfo
.SetFrm( pAktTxtFrm
);
2369 // erstmal: wurden schon mal entsprechende Vorlagen
2370 // vergeben, so behalte die bei, gehe zum
2372 USHORT nPoolId
= pAktTxtNd
->GetTxtColl()->GetPoolFmtId();
2373 if( IsPoolUserFmt( nPoolId
)
2374 ? !aFlags
.bChgUserColl
2375 : ( RES_POOLCOLL_STANDARD
!= nPoolId
&&
2376 ( !aFlags
.bAFmtByInput
||
2377 (RES_POOLCOLL_TEXT_MOVE
!= nPoolId
&&
2378 RES_POOLCOLL_TEXT
!= nPoolId
)) ))
2380 eStat
= HAS_FMTCOLL
;
2384 // teste auf Harte oder aus Vorlagen gesetzte LRSpaces
2385 if( IsPoolUserFmt( nPoolId
) ||
2386 RES_POOLCOLL_STANDARD
== nPoolId
)
2389 SvxLRSpaceItem
* pLRSpace
;
2390 if( SFX_ITEM_SET
== pAktTxtNd
->GetSwAttrSet().
2391 GetItemState( RES_LR_SPACE
, TRUE
,
2392 (const SfxPoolItem
**)&pLRSpace
) &&
2393 ( 0 != (nSz
= pLRSpace
->GetTxtFirstLineOfst()) ||
2394 0 != pLRSpace
->GetTxtLeft() ) )
2396 // Ausnahme: Numerierun/Aufzaehlung kann mit Einzug
2398 if( IsEnumericChar( *pAktTxtNd
))
2400 nLevel
= CalcLevel( *pAktTxtNd
, &nDigitLvl
);
2401 if( nLevel
>= MAXLEVEL
)
2402 nLevel
= MAXLEVEL
-1;
2403 BuildEnum( nLevel
, nDigitLvl
);
2404 eStat
= READ_NEXT_PARA
;
2409 // nie zusammenfassen, so belassen
2410 // (Opt. vielleicht als Ausnahmen nur Einzug)
2413 if( bReplaceStyles
)
2415 // dann setze doch eine unserer Vorlagen
2416 if( 0 < nSz
) // positiver 1. Zeileneinzug
2418 else if( 0 > nSz
) // negativer 1. Zeileneinzug
2419 BuildNegIndent( aFInfo
.GetLineStart() );
2420 else if( pLRSpace
->GetTxtLeft() ) // ist ein Einzug
2423 eStat
= READ_NEXT_PARA
;
2428 nLevel
= CalcLevel( *pAktTxtNd
, &nDigitLvl
);
2429 bMoreLines
= !IsOneLine( *pAktTxtNd
);
2430 pNxtNd
= GetNextNode();
2433 bNxtEmpty
= IsEmptyLine( *pNxtNd
);
2434 bNxtAlpha
= IsNoAlphaLine( *pNxtNd
);
2435 nNxtLevel
= CalcLevel( *pNxtNd
);
2437 if( !bEmptyLine
&& HasBreakAttr( *pAktTxtNd
) )
2439 if( !bNxtEmpty
&& HasBreakAttr( *pNxtNd
) )
2442 // fuer z.B. selbst definierte Einzuege oder
2443 // rechts/zentierte Ausrichtung
2444 // if( !nLevel && 0 != aFInfo.GetLineStart() )
2449 bNxtEmpty
= FALSE
; // TRUE;
2453 eStat
= !bMoreLines
? IS_ONE_LINE
: TST_ENUMERIC
;
2459 eStat
= TST_ENUMERIC
;
2460 if( !bReplaceStyles
)
2463 String
sClrStr( pAktTxtNd
->GetTxt() );
2465 if( !DelLeadingBlanks( sClrStr
).Len() )
2468 eStat
= READ_NEXT_PARA
;
2469 break; // naechsten Absatz lesen
2472 // Teste auf Ueberschrift
2473 if( !bEmptyLine
|| !IsFirstCharCapital( *pAktTxtNd
) ||
2474 IsBlanksInString( *pAktTxtNd
) )
2478 String
sEndClrStr( sClrStr
);
2479 xub_StrLen nLen
= DelTrailingBlanks( sEndClrStr
).Len();
2481 // nicht, dann teste auf Ueberschrift
2482 if( ':' == sEndClrStr
.GetChar( nLen
- 1 ) )
2484 //---------------------------------------------------------------------------
2485 // Wie ist denn nun die Bedingung fuer die Ueberschrift auf Ebene 3 ??
2486 // Zur Zeit: generell wenn am Ende ein ':' ist.
2488 // if( bNxtEmpty || bNxtAlpha )
2489 // !IsEnumericChar( *pNxtNd ) )
2490 //---------------------------------------------------------------------------
2493 eStat
= READ_NEXT_PARA
;
2497 else if( 256 <= sEndClrStr
.GetChar( nLen
-1 ) ||
2498 !strchr( ",.;", sEndClrStr
.GetChar( nLen
-1 )) )
2500 if( bNxtEmpty
|| bNxtAlpha
2501 || ( pNxtNd
&& IsEnumericChar( *pNxtNd
))
2503 //---------------------------------------------------------------------------
2504 // ist zum Verwechseln mit neg. Einzug !!
2505 /*|| nLevel < nNxtLevel*/
2506 //---------------------------------------------------------------------------
2510 // wurde Level vom Text vorgegeben ?
2511 // if( USHRT_MAX != nDigitLvl )
2512 // nLevel = nDigitLvl;
2514 // eine Ebene runter ?
2515 if( nLevel
>= MAXLEVEL
)
2516 nLevel
= MAXLEVEL
-1;
2518 if( USHRT_MAX
== nLastHeadLvl
)
2520 else if( nLastCalcHeadLvl
< nLevel
)
2522 if( nLastHeadLvl
+1 < MAXLEVEL
)
2525 // eine Ebene hoch ?
2526 else if( nLastCalcHeadLvl
> nLevel
)
2531 nLastCalcHeadLvl
= nLevel
;
2533 if( aFlags
.bAFmtByInput
)
2534 BuildHeadLine( nLevel
);
2536 BuildHeadLine( nLastHeadLvl
);
2537 eStat
= READ_NEXT_PARA
;
2547 if( IsEnumericChar( *pAktTxtNd
))
2549 if( nLevel
>= MAXLEVEL
)
2550 nLevel
= MAXLEVEL
-1;
2551 BuildEnum( nLevel
, nDigitLvl
);
2552 eStat
= READ_NEXT_PARA
;
2554 //JP 25.03.96: Vorlagen fuer Einzug zulassen
2555 // else if( aFlags.bAFmtByInput )
2556 // eStat = READ_NEXT_PARA;
2557 else if( bReplaceStyles
)
2558 eStat
= nLevel
? TST_IDENT
: TST_NEG_IDENT
;
2560 eStat
= READ_NEXT_PARA
;
2565 // Spaces am Anfang, dann teste doch mal auf Einzuege
2566 if( bMoreLines
&& nLevel
)
2568 SwTwips nSz
= aFInfo
.GetFirstIndent();
2569 if( 0 < nSz
) // positiver 1. Zeileneinzug
2571 else if( 0 > nSz
) // negativer 1. Zeileneinzug
2572 BuildNegIndent( aFInfo
.GetLineStart() );
2573 else // ist ein Einzug
2575 eStat
= READ_NEXT_PARA
;
2577 else if( nLevel
&& pNxtNd
&& !bEnde
&&
2578 !bNxtEmpty
&& !bNxtAlpha
&& !nNxtLevel
&&
2579 !IsEnumericChar( *pNxtNd
) )
2583 eStat
= READ_NEXT_PARA
;
2586 eStat
= TST_TXT_BODY
;
2590 // keine Spaces am Anfang, dann teste doch mal auf neg. Einzuege
2592 if( bMoreLines
&& !nLevel
)
2594 SwTwips nSz
= aFInfo
.GetFirstIndent();
2595 if( 0 < nSz
) // positiver 1. Zeileneinzug
2597 else if( 0 > nSz
) // negativer 1. Zeileneinzug
2598 BuildNegIndent( aFInfo
.GetLineStart() );
2599 else // ist ein kein Einzug
2601 eStat
= READ_NEXT_PARA
;
2603 else if( !nLevel
&& pNxtNd
&& !bEnde
&&
2604 !bNxtEmpty
&& !bNxtAlpha
&& nNxtLevel
&&
2605 !IsEnumericChar( *pNxtNd
) )
2607 // ist ein neg. Einzug
2608 BuildNegIndent( aFInfo
.GetLineStart() );
2609 eStat
= READ_NEXT_PARA
;
2612 eStat
= TST_TXT_BODY
;
2620 SwTwips nSz
= aFInfo
.GetFirstIndent();
2621 if( 0 < nSz
) // positiver 1. Zeileneinzug
2623 else if( 0 > nSz
) // negativer 1. Zeileneinzug
2624 BuildNegIndent( aFInfo
.GetLineStart() );
2625 else if( nLevel
) // ist ein Einzug
2634 eStat
= READ_NEXT_PARA
;
2640 // erstmal: wurden schon mal entsprechende Vorlagen
2641 // vergeben, so behalte die bei, gehe zum
2644 eStat
= READ_NEXT_PARA
;
2645 // loesche alle Blanks am Anfang/Ende
2646 // und alle mitten drin
2647 //JP 29.04.98: erstmal nur alle "mitten drin".
2648 DelMoreLinesBlanks( FALSE
);
2650 // behandel die harte Attributierung
2651 if( pAktTxtNd
->HasSwAttrSet() )
2654 SvxLRSpaceItem
* pLRSpace
;
2655 if( bReplaceStyles
&&
2656 SFX_ITEM_SET
== pAktTxtNd
->GetSwAttrSet().
2657 GetItemState( RES_LR_SPACE
, FALSE
,
2658 (const SfxPoolItem
**)&pLRSpace
) &&
2659 ( 0 != (nSz
= pLRSpace
->GetTxtFirstLineOfst()) ||
2660 0 != pLRSpace
->GetTxtLeft() ) )
2662 // dann setze doch eine unserer Vorlagen
2663 if( 0 < nSz
) // positiver 1. Zeileneinzug
2665 else if( 0 > nSz
) // negativer 1. Zeileneinzug
2667 BuildNegIndent( aFInfo
.GetLineStart() );
2669 else if( pLRSpace
->GetTxtLeft() ) // ist ein Einzug
2684 if( aFlags
.bWithRedlining
)
2685 pDoc
->SetAutoFmtRedline( FALSE
);
2686 pDoc
->SetRedlineMode( eOldMode
);
2688 // restore undo (in case it has been changed)
2689 pDoc
->DoUndo( bUndoState
);
2691 // Prozent-Anzeige wieder abschalten
2692 if( !aFlags
.bAFmtByInput
)
2693 ::EndProgress( pDoc
->GetDocShell() );
2696 void SwEditShell::AutoFormat( const SvxSwAutoFmtFlags
* pAFlags
)
2700 SET_CURR_SHELL( this );
2702 StartUndo( UNDO_AUTOFORMAT
);
2704 SvxSwAutoFmtFlags aAFFlags
; // erst mal default - Werte
2705 if( pAFlags
) // oder doch angegeben ??
2707 aAFFlags
= *pAFlags
;
2708 if( !aAFFlags
.bAFmtByInput
)
2709 pWait
= new SwWait( *GetDoc()->GetDocShell(), TRUE
);
2712 SwPaM
* pCrsr
= GetCrsr();
2713 // es gibt mehr als einen oder ist eine Selektion offen
2714 if( pCrsr
->GetNext() != pCrsr
|| pCrsr
->HasMark() )
2716 FOREACHPAM_START(this)
2717 if( PCURCRSR
->HasMark() )
2719 SwAutoFormat
aFmt( this, aAFFlags
, &PCURCRSR
->Start()->nNode
,
2720 &PCURCRSR
->End()->nNode
);
2726 SwAutoFormat
aFmt( this, aAFFlags
);
2729 EndUndo( UNDO_AUTOFORMAT
);
2736 void SwEditShell::AutoFmtBySplitNode()
2738 SET_CURR_SHELL( this );
2739 SwPaM
* pCrsr
= GetCrsr();
2740 if( pCrsr
->GetNext() == pCrsr
&& pCrsr
->Move( fnMoveBackward
, fnGoNode
) )
2743 StartUndo( UNDO_AUTOFORMAT
);
2745 BOOL bRange
= FALSE
;
2747 SwIndex
* pCntnt
= &pCrsr
->GetMark()->nContent
;
2748 if( pCntnt
->GetIndex() )
2755 // dann einen Node zurueckspringen
2756 SwNodeIndex
aNdIdx( pCrsr
->GetMark()->nNode
, -1 );
2757 SwTxtNode
* pTxtNd
= aNdIdx
.GetNode().GetTxtNode();
2758 if( pTxtNd
&& pTxtNd
->GetTxt().Len() )
2760 pCntnt
->Assign( pTxtNd
, 0 );
2761 pCrsr
->GetMark()->nNode
= aNdIdx
;
2768 Push(); // Cursor sichern
2770 SvxSwAutoFmtFlags aAFFlags
= *GetAutoFmtFlags(); // erst mal default - Werte
2772 SwAutoFormat
aFmt( this, aAFFlags
, &pCrsr
->GetMark()->nNode
,
2773 &pCrsr
->GetPoint()->nNode
);
2775 //JP 30.09.96: das DoTable() verlaesst sich auf das PopCrsr
2780 pCrsr
->DeleteMark();
2781 pCrsr
->Move( fnMoveForward
, fnGoNode
);
2783 EndUndo( UNDO_AUTOFORMAT
);
2788 SvxSwAutoFmtFlags
* SwEditShell::GetAutoFmtFlags()
2791 pAutoFmtFlags
= new SvxSwAutoFmtFlags
;
2793 return pAutoFmtFlags
;
2796 void SwEditShell::SetAutoFmtFlags(SvxSwAutoFmtFlags
* pFlags
)
2798 SvxSwAutoFmtFlags
* pEditFlags
= GetAutoFmtFlags();
2800 pEditFlags
->bSetNumRule
= pFlags
->bSetNumRule
;
2801 pEditFlags
->bChgEnumNum
= pFlags
->bChgEnumNum
;
2802 pEditFlags
->bSetBorder
= pFlags
->bSetBorder
;
2803 pEditFlags
->bCreateTable
= pFlags
->bCreateTable
;
2804 pEditFlags
->bReplaceStyles
= pFlags
->bReplaceStyles
;
2805 pEditFlags
->bAFmtByInpDelSpacesAtSttEnd
=
2806 pFlags
->bAFmtByInpDelSpacesAtSttEnd
;
2807 pEditFlags
->bAFmtByInpDelSpacesBetweenLines
=
2808 pFlags
->bAFmtByInpDelSpacesBetweenLines
;
2810 //JP 15.12.98: BulletZeichen und Font in die "normalen" kopieren,
2811 // weil beim Autoformat nur mit diesen gearbeitet wird!
2812 pEditFlags
->cBullet
= pFlags
->cByInputBullet
;
2813 pEditFlags
->aBulletFont
= pFlags
->aByInputBulletFont
;
2814 pEditFlags
->cByInputBullet
= pFlags
->cByInputBullet
;
2815 pEditFlags
->aByInputBulletFont
= pFlags
->aByInputBulletFont
;