1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sw.hxx" 30 31 #include <tools/resid.hxx> 32 #include <hintids.hxx> 33 #include <swtypes.hxx> 34 #include <errhdl.hxx> 35 #include <txtatr.hxx> 36 #include <ndtxt.hxx> 37 #include <txttxmrk.hxx> 38 #include <tox.hxx> 39 #include <poolfmt.hrc> 40 #include <doc.hxx> 41 #include <docary.hxx> 42 #include <paratr.hxx> 43 #include <editeng/tstpitem.hxx> 44 #include <SwStyleNameMapper.hxx> 45 #include <hints.hxx> // SwPtrMsgPoolItem 46 #include <algorithm> 47 #include <functional> 48 #include <switerator.hxx> 49 50 using namespace std; 51 52 const sal_Char* SwForm::aFormEntry = "<E>"; 53 const sal_Char* SwForm::aFormTab = "<T>"; 54 const sal_Char* SwForm::aFormPageNums = "<#>"; 55 const sal_Char* SwForm::aFormLinkStt = "<LS>"; 56 const sal_Char* SwForm::aFormLinkEnd = "<LE>"; 57 const sal_Char* SwForm::aFormEntryNum = "<E#>"; 58 const sal_Char* SwForm::aFormEntryTxt = "<ET>"; 59 const sal_Char* SwForm::aFormChapterMark= "<C>"; 60 const sal_Char* SwForm::aFormText = "<X>"; 61 const sal_Char* SwForm::aFormAuth = "<A>"; 62 sal_uInt8 SwForm::nFormTabLen = 3; 63 sal_uInt8 SwForm::nFormEntryLen = 3; 64 sal_uInt8 SwForm::nFormPageNumsLen = 3; 65 sal_uInt8 SwForm::nFormLinkSttLen = 4; 66 sal_uInt8 SwForm::nFormLinkEndLen = 4; 67 sal_uInt8 SwForm::nFormEntryNumLen = 4; 68 sal_uInt8 SwForm::nFormEntryTxtLen = 4; 69 sal_uInt8 SwForm::nFormChapterMarkLen = 3; 70 sal_uInt8 SwForm::nFormTextLen = 3; 71 sal_uInt8 SwForm::nFormAuthLen = 5; 72 73 SV_IMPL_PTRARR(SwTOXMarks, SwTOXMark*) 74 75 TYPEINIT2( SwTOXMark, SfxPoolItem, SwClient ); // fuers rtti 76 77 struct PatternIni 78 { 79 sal_uInt16 n1; 80 sal_uInt16 n2; 81 sal_uInt16 n3; 82 sal_uInt16 n4; 83 sal_uInt16 n5; 84 }; 85 const PatternIni aPatternIni[] = 86 { 87 {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}, //Header - no pattern 88 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_ARTICLE, 89 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_BOOK, 90 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_BOOKLET, 91 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CONFERENCE, 92 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INBOOK, 93 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INCOLLECTION, 94 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INPROCEEDINGS, 95 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_JOURNAL, 96 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MANUAL, 97 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MASTERSTHESIS, 98 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MISC, 99 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_PHDTHESIS, 100 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_PROCEEDINGS, 101 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_TECHREPORT, 102 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_UNPUBLISHED, 103 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_EMAIL, 104 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, AUTH_FIELD_URL, USHRT_MAX},//AUTH_TYPE_WWW, 105 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM1, 106 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM2, 107 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM3, 108 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM4, 109 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM5, 110 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_YEAR, 111 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_URL, 112 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM1, 113 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM2, 114 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM3, 115 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM4, 116 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM5, 117 {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX} 118 }; 119 120 SwFormTokens lcl_GetAuthPattern(sal_uInt16 nTypeId) 121 { 122 SwFormTokens aRet; 123 124 PatternIni aIni = aPatternIni[nTypeId]; 125 sal_uInt16 nVals[5]; 126 nVals[0] = aIni.n1; 127 nVals[1] = aIni.n2; 128 nVals[2] = aIni.n3; 129 nVals[3] = aIni.n4; 130 nVals[4] = aIni.n5; 131 132 SwFormToken aStartToken( TOKEN_AUTHORITY ); 133 aStartToken.nAuthorityField = AUTH_FIELD_IDENTIFIER; 134 aRet.push_back( aStartToken ); 135 SwFormToken aSeparatorToken( TOKEN_TEXT ); 136 aSeparatorToken.sText = String::CreateFromAscii( ": " ); 137 aRet.push_back( aSeparatorToken ); 138 SwFormToken aTextToken( TOKEN_TEXT ); 139 aTextToken.sText = String::CreateFromAscii( ", " ); 140 141 for(sal_uInt16 i = 0; i < 5 ; i++) 142 { 143 if(nVals[i] == USHRT_MAX) 144 break; 145 if( i > 0 ) 146 aRet.push_back( aTextToken ); 147 148 // -> #i21237# 149 SwFormToken aToken(TOKEN_AUTHORITY); 150 151 aToken.nAuthorityField = nVals[i]; 152 aRet.push_back(aToken); 153 // <- #i21237# 154 } 155 156 return aRet; 157 } 158 /*-------------------------------------------------------------------- 159 Beschreibung: Verzeichnis-Markierungen D/Ctor 160 --------------------------------------------------------------------*/ 161 162 163 /// pool default constructor 164 SwTOXMark::SwTOXMark() 165 : SfxPoolItem( RES_TXTATR_TOXMARK ) 166 , SwModify( 0 ) 167 , 168 pTxtAttr( 0 ), 169 bAutoGenerated(sal_False), 170 bMainEntry(sal_False) 171 { 172 } 173 174 175 SwTOXMark::SwTOXMark( const SwTOXType* pTyp ) 176 : SfxPoolItem( RES_TXTATR_TOXMARK ) 177 , SwModify( const_cast<SwTOXType*>(pTyp) ) 178 , 179 pTxtAttr( 0 ), nLevel( 0 ), 180 bAutoGenerated(sal_False), 181 bMainEntry(sal_False) 182 { 183 } 184 185 186 SwTOXMark::SwTOXMark( const SwTOXMark& rCopy ) 187 : SfxPoolItem( RES_TXTATR_TOXMARK ) 188 , SwModify(rCopy.GetRegisteredInNonConst()) 189 , 190 aPrimaryKey( rCopy.aPrimaryKey ), aSecondaryKey( rCopy.aSecondaryKey ), 191 aTextReading( rCopy.aTextReading ), 192 aPrimaryKeyReading( rCopy.aPrimaryKeyReading ), 193 aSecondaryKeyReading( rCopy.aSecondaryKeyReading ), 194 pTxtAttr( 0 ), nLevel( rCopy.nLevel ), 195 bAutoGenerated( rCopy.bAutoGenerated), 196 bMainEntry(rCopy.bMainEntry) 197 { 198 // AlternativString kopieren 199 aAltText = rCopy.aAltText; 200 } 201 202 203 SwTOXMark::~SwTOXMark() 204 { 205 } 206 207 208 void SwTOXMark::RegisterToTOXType( SwTOXType& rMark ) 209 { 210 rMark.Add(this); 211 } 212 213 int SwTOXMark::operator==( const SfxPoolItem& rAttr ) const 214 { 215 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); 216 return GetRegisteredIn() == ((SwTOXMark&)rAttr).GetRegisteredIn(); 217 } 218 219 220 SfxPoolItem* SwTOXMark::Clone( SfxItemPool* ) const 221 { 222 return new SwTOXMark( *this ); 223 } 224 225 void SwTOXMark::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew) 226 { 227 NotifyClients(pOld, pNew); 228 if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which())) 229 { // invalidate cached uno object 230 SetXTOXMark(::com::sun::star::uno::Reference< 231 ::com::sun::star::text::XDocumentIndexMark>(0)); 232 } 233 } 234 235 void SwTOXMark::InvalidateTOXMark() 236 { 237 SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, 238 &static_cast<SwModify&>(*this) ); // cast to base class! 239 NotifyClients(&aMsgHint, &aMsgHint); 240 } 241 242 String SwTOXMark::GetText() const 243 { 244 String aStr; 245 if( aAltText.Len() ) 246 aStr = aAltText; 247 else if( pTxtAttr && pTxtAttr->GetpTxtNd() ) 248 { 249 xub_StrLen* pEndIdx = pTxtAttr->GetEnd(); 250 ASSERT( pEndIdx, "TOXMark ohne Mark!!"); 251 if( pEndIdx ) 252 { 253 const xub_StrLen nStt = *pTxtAttr->GetStart(); 254 aStr = pTxtAttr->GetpTxtNd()->GetExpandTxt( nStt, *pEndIdx-nStt ); 255 } 256 } 257 return aStr; 258 } 259 260 void SwTOXMark::InsertTOXMarks( SwTOXMarks& aMarks, const SwTOXType& rType ) 261 { 262 SwIterator<SwTOXMark,SwTOXType> aIter(rType); 263 SwTOXMark* pMark = aIter.First(); 264 while( pMark ) 265 { 266 if(pMark->GetTxtTOXMark()) 267 aMarks.C40_INSERT(SwTOXMark, pMark, aMarks.Count()); 268 pMark = aIter.Next(); 269 } 270 } 271 272 /*-------------------------------------------------------------------- 273 Beschreibung: Typen von Verzeichnissen verwalten 274 --------------------------------------------------------------------*/ 275 276 SwTOXType::SwTOXType( TOXTypes eTyp, const String& rName ) 277 : SwModify(0), 278 aName(rName), 279 eType(eTyp) 280 { 281 } 282 283 284 SwTOXType::SwTOXType(const SwTOXType& rCopy) 285 : SwModify( (SwModify*)rCopy.GetRegisteredIn() ), 286 aName(rCopy.aName), 287 eType(rCopy.eType) 288 { 289 } 290 291 /*-------------------------------------------------------------------- 292 Beschreibung: Formen bearbeiten 293 --------------------------------------------------------------------*/ 294 295 SwForm::SwForm( TOXTypes eTyp ) // #i21237# 296 : eType( eTyp ), nFormMaxLevel( SwForm::GetFormMaxLevel( eTyp )), 297 // nFirstTabPos( lNumIndent ), 298 bCommaSeparated(sal_False) 299 { 300 //bHasFirstTabPos = 301 bGenerateTabPos = sal_False; 302 bIsRelTabPos = sal_True; 303 304 // Inhaltsverzeichnis hat entsprechend Anzahl Headlines + Ueberschrift 305 // Benutzer hat 10 Ebenen + Ueberschrift 306 // Stichwort hat 3 Ebenen + Ueberschrift + Trenner 307 // indexes of tables, objects illustrations and authorities consist of a heading and one level 308 309 sal_uInt16 nPoolId; 310 switch( eType ) 311 { 312 case TOX_INDEX: nPoolId = STR_POOLCOLL_TOX_IDXH; break; 313 case TOX_USER: nPoolId = STR_POOLCOLL_TOX_USERH; break; 314 case TOX_CONTENT: nPoolId = STR_POOLCOLL_TOX_CNTNTH; break; 315 case TOX_ILLUSTRATIONS: nPoolId = STR_POOLCOLL_TOX_ILLUSH; break; 316 case TOX_OBJECTS : nPoolId = STR_POOLCOLL_TOX_OBJECTH; break; 317 case TOX_TABLES : nPoolId = STR_POOLCOLL_TOX_TABLESH; break; 318 case TOX_AUTHORITIES : nPoolId = STR_POOLCOLL_TOX_AUTHORITIESH; break; 319 default: 320 ASSERT( !this, "ungueltiger TOXTyp"); 321 return ; 322 } 323 324 SwFormTokens aTokens; 325 if (TOX_CONTENT == eType) 326 { 327 aTokens.push_back(SwFormToken(TOKEN_ENTRY_NO)); 328 aTokens.push_back(SwFormToken(TOKEN_ENTRY_TEXT)); 329 } 330 else 331 aTokens.push_back(SwFormToken(TOKEN_ENTRY)); 332 333 if (TOX_AUTHORITIES != eType) 334 { 335 SwFormToken aToken(TOKEN_TAB_STOP); 336 aToken.nTabStopPosition = 0; 337 338 // --> FME 2004-12-10 #i36870# right aligned tab for all 339 aToken.cTabFillChar = '.'; 340 aToken.eTabAlign = SVX_TAB_ADJUST_END; 341 // <-- 342 343 aTokens.push_back(aToken); 344 aTokens.push_back(SwFormToken(TOKEN_PAGE_NUMS)); 345 } 346 347 SetTemplate( 0, SW_RESSTR( nPoolId++ )); 348 349 if(TOX_INDEX == eType) 350 { 351 for( sal_uInt16 i = 1; i < 5; ++i ) 352 { 353 if(1 == i) 354 { 355 SwFormTokens aTmpTokens; 356 SwFormToken aTmpToken(TOKEN_ENTRY); 357 aTmpTokens.push_back(aTmpToken); 358 359 SetPattern( i, aTmpTokens ); 360 SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDXBREAK )); 361 } 362 else 363 { 364 SetPattern( i, aTokens ); 365 SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDX1 + i - 2 )); 366 } 367 } 368 } 369 else 370 for( sal_uInt16 i = 1; i < GetFormMax(); ++i, ++nPoolId ) // Nr 0 ist der Titel 371 { 372 if(TOX_AUTHORITIES == eType) 373 SetPattern(i, lcl_GetAuthPattern(i)); 374 else 375 SetPattern( i, aTokens ); 376 377 if( TOX_CONTENT == eType && 6 == i ) 378 nPoolId = STR_POOLCOLL_TOX_CNTNT6; 379 else if( TOX_USER == eType && 6 == i ) 380 nPoolId = STR_POOLCOLL_TOX_USER6; 381 else if( TOX_AUTHORITIES == eType ) 382 nPoolId = STR_POOLCOLL_TOX_AUTHORITIES1; 383 SetTemplate( i, SW_RESSTR( nPoolId ) ); 384 } 385 } 386 387 388 SwForm::SwForm(const SwForm& rForm) 389 : eType( rForm.eType ) 390 { 391 *this = rForm; 392 } 393 394 395 SwForm& SwForm::operator=(const SwForm& rForm) 396 { 397 eType = rForm.eType; 398 nFormMaxLevel = rForm.nFormMaxLevel; 399 // nFirstTabPos = rForm.nFirstTabPos; 400 // bHasFirstTabPos = rForm.bHasFirstTabPos; 401 bGenerateTabPos = rForm.bGenerateTabPos; 402 bIsRelTabPos = rForm.bIsRelTabPos; 403 bCommaSeparated = rForm.bCommaSeparated; 404 for(sal_uInt16 i=0; i < nFormMaxLevel; ++i) 405 { 406 aPattern[i] = rForm.aPattern[i]; 407 aTemplate[i] = rForm.aTemplate[i]; 408 } 409 return *this; 410 } 411 412 sal_uInt16 SwForm::GetFormMaxLevel( TOXTypes eTOXType ) 413 { 414 sal_uInt16 nRet = 0; 415 switch( eTOXType ) 416 { 417 case TOX_INDEX: nRet = 5; break; 418 case TOX_USER: nRet = MAXLEVEL+1; break; 419 case TOX_CONTENT: nRet = MAXLEVEL+1; break; 420 case TOX_ILLUSTRATIONS: 421 case TOX_OBJECTS : 422 case TOX_TABLES : nRet = 2; break; 423 case TOX_AUTHORITIES : nRet = AUTH_TYPE_END + 1; break; 424 } 425 return nRet; 426 } 427 428 // #i21237# 429 bool operator == (const SwFormToken & rToken, FormTokenType eType) 430 { 431 return rToken.eTokenType == eType; 432 } 433 434 //----------------------------------------------------------------------------- 435 void SwForm::AdjustTabStops(SwDoc& rDoc, sal_Bool bInsertNewTapStops) // #i21237# 436 { 437 for(sal_uInt16 nLevel = 1; nLevel < GetFormMax(); nLevel++) 438 { 439 const String& sTemplateName = GetTemplate(nLevel); 440 441 SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName( sTemplateName ); 442 if( !pColl ) 443 { 444 sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName 445 ( sTemplateName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ); // #i21237# 446 if( USHRT_MAX != nId ) 447 pColl = rDoc.GetTxtCollFromPool( nId ); 448 } 449 450 const SvxTabStopItem* pTabStops = 0; 451 sal_uInt16 nTabCount = 0; 452 if( pColl && 453 0 != ( pTabStops = &pColl->GetTabStops(sal_False) ) && 454 0 != ( nTabCount = pTabStops->Count() ) ) 455 { 456 // #i21237# 457 SwFormTokens aCurrentPattern = GetPattern(nLevel); 458 SwFormTokens::iterator aIt = aCurrentPattern.begin(); 459 460 sal_Bool bChanged = sal_False; 461 462 for(sal_uInt16 nTab = 0; nTab < nTabCount; ++nTab) 463 { 464 const SvxTabStop& rTab = (*pTabStops)[nTab]; 465 466 // --> FME 2004-12-16 #i29178# 467 // For Word import, we do not want to replace exising tokens, 468 // we insert new tabstop tokens without a tabstop character: 469 if ( bInsertNewTapStops ) 470 { 471 if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() ) 472 { 473 bChanged = sal_True; 474 SwFormToken aToken(TOKEN_TAB_STOP); 475 aToken.bWithTab = sal_False; 476 aToken.nTabStopPosition = rTab.GetTabPos(); 477 aToken.eTabAlign = rTab.GetAdjustment(); 478 aToken.cTabFillChar = rTab.GetFill(); 479 aCurrentPattern.push_back(aToken); 480 } 481 } 482 // <-- 483 else 484 { 485 aIt = find_if(aIt, aCurrentPattern.end(), 486 SwFormTokenEqualToFormTokenType 487 (TOKEN_TAB_STOP)); 488 if ( aIt != aCurrentPattern.end() ) 489 { 490 bChanged = sal_True; 491 aIt->nTabStopPosition = rTab.GetTabPos(); 492 aIt->eTabAlign = nTab == nTabCount - 1 && 493 SVX_TAB_ADJUST_RIGHT == rTab.GetAdjustment() ? 494 SVX_TAB_ADJUST_END : 495 rTab.GetAdjustment(); 496 aIt->cTabFillChar = rTab.GetFill(); 497 ++aIt; 498 } 499 else 500 break; // no more tokens to replace 501 } 502 } 503 // <-- 504 505 if(bChanged) 506 SetPattern(nLevel, aCurrentPattern); // #i21237# 507 } 508 } 509 } 510 /*-------------------------------------------------------------------- 511 Beschreibung: Ctor TOXBase 512 --------------------------------------------------------------------*/ 513 514 515 SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm, 516 sal_uInt16 nCreaType, const String& rTitle ) 517 : SwClient((SwModify*)pTyp), 518 aForm(rForm), 519 aTitle(rTitle), 520 eLanguage((LanguageType)::GetAppLanguage()), 521 nCreateType(nCreaType), 522 nOLEOptions(0), 523 eCaptionDisplay(CAPTION_COMPLETE), 524 bProtected( sal_True ), 525 bFromChapter(sal_False), 526 bFromObjectNames(sal_False), 527 bLevelFromChapter(sal_False) 528 { 529 aData.nOptions = 0; 530 } 531 532 533 SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc ) 534 : SwClient( rSource.GetRegisteredInNonConst() ) 535 { 536 CopyTOXBase( pDoc, rSource ); 537 } 538 539 void SwTOXBase::RegisterToTOXType( SwTOXType& rType ) 540 { 541 rType.Add( this ); 542 } 543 544 SwTOXBase& SwTOXBase::CopyTOXBase( SwDoc* pDoc, const SwTOXBase& rSource ) 545 { 546 SwTOXType* pType = (SwTOXType*)rSource.GetTOXType(); 547 if( pDoc && USHRT_MAX == pDoc->GetTOXTypes().GetPos( pType )) 548 { 549 // type not in pDoc, so create it now 550 const SwTOXTypes& rTypes = pDoc->GetTOXTypes(); 551 sal_Bool bFound = sal_False; 552 for( sal_uInt16 n = rTypes.Count(); n; ) 553 { 554 const SwTOXType* pCmp = rTypes[ --n ]; 555 if( pCmp->GetType() == pType->GetType() && 556 pCmp->GetTypeName() == pType->GetTypeName() ) 557 { 558 pType = (SwTOXType*)pCmp; 559 bFound = sal_True; 560 break; 561 } 562 } 563 564 if( !bFound ) 565 pType = (SwTOXType*)pDoc->InsertTOXType( *pType ); 566 } 567 pType->Add( this ); 568 569 nCreateType = rSource.nCreateType; 570 aTitle = rSource.aTitle; 571 aForm = rSource.aForm; 572 bProtected = rSource.bProtected; 573 bFromChapter = rSource.bFromChapter; 574 bFromObjectNames = rSource.bFromObjectNames; 575 sMainEntryCharStyle = rSource.sMainEntryCharStyle; 576 sSequenceName = rSource.sSequenceName; 577 eCaptionDisplay = rSource.eCaptionDisplay; 578 nOLEOptions = rSource.nOLEOptions; 579 eLanguage = rSource.eLanguage; 580 sSortAlgorithm = rSource.sSortAlgorithm; 581 582 for( sal_uInt16 i = 0; i < MAXLEVEL; ++i ) 583 aStyleNames[i] = rSource.aStyleNames[i]; 584 585 // its the same data type! 586 aData.nOptions = rSource.aData.nOptions; 587 588 if( !pDoc || pDoc->IsCopyIsMove() ) 589 aName = rSource.GetTOXName(); 590 else 591 aName = pDoc->GetUniqueTOXBaseName( *pType, &rSource.GetTOXName() ); 592 593 return *this; 594 } 595 596 /*-------------------------------------------------------------------- 597 Beschreibung: Verzeichnisspezifische Funktionen 598 --------------------------------------------------------------------*/ 599 600 SwTOXBase::~SwTOXBase() 601 { 602 // if( GetTOXType()->GetType() == TOX_USER ) 603 // delete aData.pTemplateName; 604 } 605 606 void SwTOXBase::SetTitle(const String& rTitle) 607 { aTitle = rTitle; } 608 609 610 SwTOXBase & SwTOXBase::operator = (const SwTOXBase & rSource) 611 { 612 ByteString aTmpStr(aTitle, RTL_TEXTENCODING_ASCII_US); 613 ByteString aTmpStr1(rSource.aTitle, RTL_TEXTENCODING_ASCII_US); 614 615 aForm = rSource.aForm; 616 aName = rSource.aName; 617 aTitle = rSource.aTitle; 618 sMainEntryCharStyle = rSource.sMainEntryCharStyle; 619 for(sal_uInt16 nLevel = 0; nLevel < MAXLEVEL; nLevel++) 620 aStyleNames[nLevel] = rSource.aStyleNames[nLevel]; 621 sSequenceName = rSource.sSequenceName; 622 eLanguage = rSource.eLanguage; 623 sSortAlgorithm = rSource.sSortAlgorithm; 624 aData = rSource.aData; 625 nCreateType = rSource.nCreateType; 626 nOLEOptions = rSource.nOLEOptions; 627 eCaptionDisplay = rSource.eCaptionDisplay; 628 bProtected = rSource.bProtected; 629 bFromChapter = rSource.bFromChapter; 630 bFromObjectNames = rSource.bFromObjectNames; 631 bLevelFromChapter = rSource.bLevelFromChapter; 632 633 if (rSource.GetAttrSet()) 634 SetAttrSet(*rSource.GetAttrSet()); 635 636 return *this; 637 } 638 639 /* -----------------16.07.99 16:02------------------- 640 641 SwTOXBase & SwTOXBase::operator = (const SwTOXBase & rSource) 642 { 643 aForm = rSource.aForm; 644 aName = rSource.aName; 645 aTitle = rSource.aTitle; 646 sMainEntryCharStyle = rSource.sMainEntryCharStyle; 647 sSequenceName = rSource.sSequenceName; 648 eLanguage = rSource.eLanguage; 649 sSortAlgorithm = rSource.sSortAlgorithm; 650 aData = rSource.aData; 651 nCreateType = rSource.nCreateType; 652 nOLEOptions = rSource.nOLEOptions; 653 eCaptionDisplay = rSource.eCaptionDisplay; 654 bProtected = rSource.bProtected; 655 bFromChapter = rSource.bFromChapter; 656 bFromObjectNames = rSource.bFromObjectNames; 657 bLevelFromChapter = rSource.bLevelFromChapter; 658 659 if (rSource.GetAttrSet()) 660 SetAttrSet(*rSource.GetAttrSet()); 661 662 return *this; 663 } 664 665 --------------------------------------------------*/ 666 667 String SwFormToken::GetString() const 668 { 669 String sRet; 670 671 sal_Bool bAppend = sal_True; 672 switch( eTokenType ) 673 { 674 case TOKEN_ENTRY_NO: 675 sRet.AssignAscii( SwForm::aFormEntryNum ); 676 break; 677 case TOKEN_ENTRY_TEXT: 678 sRet.AssignAscii( SwForm::aFormEntryTxt ); 679 break; 680 case TOKEN_ENTRY: 681 sRet.AssignAscii( SwForm::aFormEntry ); 682 break; 683 case TOKEN_TAB_STOP: 684 sRet.AssignAscii( SwForm::aFormTab ); 685 break; 686 case TOKEN_TEXT: 687 sRet.AssignAscii( SwForm::aFormText ); 688 break; 689 case TOKEN_PAGE_NUMS: 690 sRet.AssignAscii( SwForm::aFormPageNums ); 691 break; 692 case TOKEN_CHAPTER_INFO: 693 sRet.AssignAscii( SwForm::aFormChapterMark ); 694 break; 695 case TOKEN_LINK_START: 696 sRet.AssignAscii( SwForm::aFormLinkStt ); 697 break; 698 case TOKEN_LINK_END: 699 sRet.AssignAscii( SwForm::aFormLinkEnd ); 700 break; 701 case TOKEN_AUTHORITY: 702 { 703 sRet.AssignAscii( SwForm::aFormAuth ); 704 String sTmp( String::CreateFromInt32( nAuthorityField )); 705 if( sTmp.Len() < 2 ) 706 sTmp.Insert('0', 0); 707 sRet.Insert( sTmp, 2 ); 708 } 709 break; 710 case TOKEN_END: 711 break; 712 } 713 sRet.Erase( sRet.Len() - 1 ); 714 sRet += ' '; 715 sRet += sCharStyleName; 716 sRet += ','; 717 sRet += String::CreateFromInt32( nPoolId ); 718 sRet += ','; 719 720 // TabStopPosition and TabAlign or ChapterInfoFormat 721 if(TOKEN_TAB_STOP == eTokenType) 722 { 723 sRet += String::CreateFromInt32( nTabStopPosition ); 724 sRet += ','; 725 sRet += String::CreateFromInt32( static_cast< sal_Int32 >(eTabAlign) ); 726 sRet += ','; 727 sRet += cTabFillChar; 728 sRet += ','; 729 sRet += String::CreateFromInt32( bWithTab ); 730 } 731 else if(TOKEN_CHAPTER_INFO == eTokenType) 732 { 733 sRet += String::CreateFromInt32( nChapterFormat ); 734 //add maximum permetted level 735 sRet += ','; 736 sRet += String::CreateFromInt32( nOutlineLevel ); 737 } 738 else if(TOKEN_TEXT == eTokenType) 739 { 740 //append Text if Len() > 0 only! 741 if( sText.Len() ) 742 { 743 sRet += TOX_STYLE_DELIMITER; 744 String sTmp( sText ); 745 sTmp.EraseAllChars( TOX_STYLE_DELIMITER ); 746 sRet += sTmp; 747 sRet += TOX_STYLE_DELIMITER; 748 } 749 else 750 bAppend = sal_False; 751 } 752 else if(TOKEN_ENTRY_NO == eTokenType) 753 { 754 sRet += String::CreateFromInt32( nChapterFormat ); 755 //add maximum permitted level 756 sRet += ','; 757 sRet += String::CreateFromInt32( nOutlineLevel ); 758 } 759 760 if(bAppend) 761 { 762 sRet += '>'; 763 } 764 else 765 { 766 // don't append empty text tokens 767 sRet.Erase(); 768 } 769 770 return sRet; 771 } 772 773 // -> #i21237# 774 SwFormTokensHelper::SwFormTokensHelper(const String & rPattern) 775 { 776 xub_StrLen nCurPatternPos = 0; 777 xub_StrLen nCurPatternLen = 0; 778 779 while (nCurPatternPos < rPattern.Len()) 780 { 781 nCurPatternPos = nCurPatternPos + nCurPatternLen; 782 783 SwFormToken aToken = BuildToken(rPattern, nCurPatternPos); 784 aTokens.push_back(aToken); 785 } 786 } 787 788 SwFormToken SwFormTokensHelper::BuildToken( const String & sPattern, 789 xub_StrLen & nCurPatternPos ) const 790 { 791 String sToken( SearchNextToken(sPattern, nCurPatternPos) ); 792 nCurPatternPos = nCurPatternPos + sToken.Len(); 793 xub_StrLen nTokenLen; 794 FormTokenType eTokenType = GetTokenType(sToken, &nTokenLen); 795 796 // at this point sPattern contains the 797 // character style name, the PoolId, tab stop position, tab stop alignment, chapter info format 798 // the form is: CharStyleName, PoolId[, TabStopPosition|ChapterInfoFormat[, TabStopAlignment[, TabFillChar]]] 799 // in text tokens the form differs from the others: CharStyleName, PoolId[,\0xffinserted text\0xff] 800 SwFormToken eRet( eTokenType ); 801 String sAuthFieldEnum = sToken.Copy( 2, 2 ); 802 sToken = sToken.Copy( nTokenLen, sToken.Len() - nTokenLen - 1); 803 804 eRet.sCharStyleName = sToken.GetToken( 0, ','); 805 String sTmp( sToken.GetToken( 1, ',' )); 806 if( sTmp.Len() ) 807 eRet.nPoolId = static_cast<sal_uInt16>(sTmp.ToInt32()); 808 809 switch( eTokenType ) 810 { 811 //i53420 812 case TOKEN_ENTRY_NO: 813 if( (sTmp = sToken.GetToken( 2, ',' ) ).Len() ) 814 eRet.nChapterFormat = static_cast<sal_uInt16>(sTmp.ToInt32()); 815 if( (sTmp = sToken.GetToken( 3, ',' ) ).Len() ) 816 eRet.nOutlineLevel = static_cast<sal_uInt16>(sTmp.ToInt32()); //the maximum outline level to examine 817 break; 818 819 case TOKEN_TEXT: 820 { 821 xub_StrLen nStartText = sToken.Search( TOX_STYLE_DELIMITER ); 822 if( STRING_NOTFOUND != nStartText ) 823 { 824 xub_StrLen nEndText = sToken.Search( TOX_STYLE_DELIMITER, 825 nStartText + 1); 826 if( STRING_NOTFOUND != nEndText ) 827 { 828 eRet.sText = sToken.Copy( nStartText + 1, 829 nEndText - nStartText - 1); 830 } 831 } 832 } 833 break; 834 835 case TOKEN_TAB_STOP: 836 if( (sTmp = sToken.GetToken( 2, ',' ) ).Len() ) 837 eRet.nTabStopPosition = sTmp.ToInt32(); 838 839 if( (sTmp = sToken.GetToken( 3, ',' ) ).Len() ) 840 eRet.eTabAlign = static_cast<SvxTabAdjust>(sTmp.ToInt32()); 841 842 if( (sTmp = sToken.GetToken( 4, ',' ) ).Len() ) 843 eRet.cTabFillChar = sTmp.GetChar(0); 844 845 if( (sTmp = sToken.GetToken( 5, ',' ) ).Len() ) 846 eRet.bWithTab = 0 != sTmp.ToInt32(); 847 break; 848 849 case TOKEN_CHAPTER_INFO: 850 if( (sTmp = sToken.GetToken( 2, ',' ) ).Len() ) 851 eRet.nChapterFormat = static_cast<sal_uInt16>(sTmp.ToInt32()); //SwChapterFormat; 852 //i53420 853 if( (sTmp = sToken.GetToken( 3, ',' ) ).Len() ) 854 eRet.nOutlineLevel = static_cast<sal_uInt16>(sTmp.ToInt32()); //the maximum outline level to examine 855 856 break; 857 858 case TOKEN_AUTHORITY: 859 eRet.nAuthorityField = static_cast<sal_uInt16>(sAuthFieldEnum.ToInt32()); 860 break; 861 default: break; 862 } 863 return eRet; 864 } 865 866 String SwFormTokensHelper::SearchNextToken( const String & sPattern, 867 xub_StrLen nStt ) const 868 { 869 //it's not so easy - it doesn't work if the text part contains a '>' 870 //sal_uInt16 nTokenEnd = sPattern.Search('>'); 871 872 String aResult; 873 874 xub_StrLen nEnd = sPattern.Search( '>', nStt ); 875 if( STRING_NOTFOUND == nEnd ) 876 { 877 nEnd = sPattern.Len(); 878 } 879 else 880 { 881 xub_StrLen nTextSeparatorFirst = sPattern.Search( TOX_STYLE_DELIMITER, nStt ); 882 if( STRING_NOTFOUND != nTextSeparatorFirst ) 883 { 884 xub_StrLen nTextSeparatorSecond = sPattern.Search( TOX_STYLE_DELIMITER, 885 nTextSeparatorFirst + 1 ); 886 if( STRING_NOTFOUND != nTextSeparatorSecond && 887 nEnd > nTextSeparatorFirst ) 888 nEnd = sPattern.Search( '>', nTextSeparatorSecond ); 889 } 890 891 ++nEnd; 892 893 aResult = sPattern.Copy( nStt, nEnd - nStt ); 894 } 895 896 return aResult; 897 } 898 899 FormTokenType SwFormTokensHelper::GetTokenType(const String & sToken, 900 xub_StrLen * pTokenLen) const 901 { 902 static struct 903 { 904 const sal_Char* pNm; 905 sal_uInt16 nLen; 906 sal_uInt16 nOffset; 907 FormTokenType eToken; 908 } __READONLY_DATA aTokenArr[] = { 909 { SwForm::aFormTab, SwForm::nFormEntryLen, 1, TOKEN_TAB_STOP }, 910 { SwForm::aFormPageNums, SwForm::nFormPageNumsLen, 1, TOKEN_PAGE_NUMS }, 911 { SwForm::aFormLinkStt, SwForm::nFormLinkSttLen, 1, TOKEN_LINK_START }, 912 { SwForm::aFormLinkEnd, SwForm::nFormLinkEndLen, 1, TOKEN_LINK_END }, 913 { SwForm::aFormEntryNum, SwForm::nFormEntryNumLen, 1, TOKEN_ENTRY_NO }, 914 { SwForm::aFormEntryTxt, SwForm::nFormEntryTxtLen, 1, TOKEN_ENTRY_TEXT }, 915 { SwForm::aFormChapterMark,SwForm::nFormChapterMarkLen,1,TOKEN_CHAPTER_INFO }, 916 { SwForm::aFormText, SwForm::nFormTextLen, 1, TOKEN_TEXT }, 917 { SwForm::aFormEntry, SwForm::nFormEntryLen, 1, TOKEN_ENTRY }, 918 { SwForm::aFormAuth, SwForm::nFormAuthLen, 3, TOKEN_AUTHORITY }, 919 { 0, 0, 0, TOKEN_END } 920 }; 921 922 FormTokenType eTokenType = TOKEN_TEXT; 923 xub_StrLen nTokenLen = 0; 924 const sal_Char* pNm; 925 for( int i = 0; 0 != ( pNm = aTokenArr[ i ].pNm ); ++i ) 926 if( COMPARE_EQUAL == sToken.CompareToAscii( pNm, 927 aTokenArr[ i ].nLen - aTokenArr[ i ].nOffset )) 928 { 929 eTokenType = aTokenArr[ i ].eToken; 930 nTokenLen = aTokenArr[ i ].nLen; 931 break; 932 } 933 934 ASSERT( pNm, "wrong token" ); 935 if (pTokenLen) 936 *pTokenLen = nTokenLen; 937 938 return eTokenType; 939 } 940 941 // <- #i21237# 942 943 void SwForm::SetPattern(sal_uInt16 nLevel, const SwFormTokens& rTokens) 944 { 945 ASSERT(nLevel < GetFormMax(), "Index >= FORM_MAX"); 946 aPattern[nLevel] = rTokens; 947 } 948 949 void SwForm::SetPattern(sal_uInt16 nLevel, const String & rStr) 950 { 951 ASSERT(nLevel < GetFormMax(), "Index >= FORM_MAX"); 952 953 SwFormTokensHelper aHelper(rStr); 954 aPattern[nLevel] = aHelper.GetTokens(); 955 } 956 957 const SwFormTokens& SwForm::GetPattern(sal_uInt16 nLevel) const 958 { 959 ASSERT(nLevel < GetFormMax(), "Index >= FORM_MAX"); 960 return aPattern[nLevel]; 961 } 962 963