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