1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sw.hxx" 26 27 #include <tools/resid.hxx> 28 #include <hintids.hxx> 29 #include <swtypes.hxx> 30 #include <errhdl.hxx> 31 #include <txtatr.hxx> 32 #include <ndtxt.hxx> 33 #include <txttxmrk.hxx> 34 #include <tox.hxx> 35 #include <poolfmt.hrc> 36 #include <doc.hxx> 37 #include <docary.hxx> 38 #include <paratr.hxx> 39 #include <editeng/tstpitem.hxx> 40 #include <SwStyleNameMapper.hxx> 41 #include <hints.hxx> // SwPtrMsgPoolItem 42 #include <algorithm> 43 #include <functional> 44 #include <switerator.hxx> 45 46 using namespace std; 47 48 const sal_Char* SwForm::aFormEntry = "<E>"; 49 const sal_Char* SwForm::aFormTab = "<T>"; 50 const sal_Char* SwForm::aFormPageNums = "<#>"; 51 const sal_Char* SwForm::aFormLinkStt = "<LS>"; 52 const sal_Char* SwForm::aFormLinkEnd = "<LE>"; 53 const sal_Char* SwForm::aFormEntryNum = "<E#>"; 54 const sal_Char* SwForm::aFormEntryTxt = "<ET>"; 55 const sal_Char* SwForm::aFormChapterMark= "<C>"; 56 const sal_Char* SwForm::aFormText = "<X>"; 57 const sal_Char* SwForm::aFormAuth = "<A>"; 58 sal_uInt8 SwForm::nFormTabLen = 3; 59 sal_uInt8 SwForm::nFormEntryLen = 3; 60 sal_uInt8 SwForm::nFormPageNumsLen = 3; 61 sal_uInt8 SwForm::nFormLinkSttLen = 4; 62 sal_uInt8 SwForm::nFormLinkEndLen = 4; 63 sal_uInt8 SwForm::nFormEntryNumLen = 4; 64 sal_uInt8 SwForm::nFormEntryTxtLen = 4; 65 sal_uInt8 SwForm::nFormChapterMarkLen = 3; 66 sal_uInt8 SwForm::nFormTextLen = 3; 67 sal_uInt8 SwForm::nFormAuthLen = 5; 68 69 SV_IMPL_PTRARR(SwTOXMarks, SwTOXMark*) 70 71 TYPEINIT2( SwTOXMark, SfxPoolItem, SwClient ); // fuers rtti 72 73 struct PatternIni 74 { 75 sal_uInt16 n1; 76 sal_uInt16 n2; 77 sal_uInt16 n3; 78 sal_uInt16 n4; 79 sal_uInt16 n5; 80 }; 81 const PatternIni aPatternIni[] = 82 { 83 {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX}, //Header - no pattern 84 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_ARTICLE, 85 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_BOOK, 86 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_BOOKLET, 87 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CONFERENCE, 88 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INBOOK, 89 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INCOLLECTION, 90 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_INPROCEEDINGS, 91 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_JOURNAL, 92 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MANUAL, 93 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MASTERSTHESIS, 94 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_MISC, 95 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_PHDTHESIS, 96 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_PROCEEDINGS, 97 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_TECHREPORT, 98 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_UNPUBLISHED, 99 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_EMAIL, 100 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, AUTH_FIELD_URL, USHRT_MAX},//AUTH_TYPE_WWW, 101 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM1, 102 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM2, 103 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM3, 104 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM4, 105 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_TYPE_CUSTOM5, 106 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_YEAR, 107 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_URL, 108 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM1, 109 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM2, 110 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM3, 111 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM4, 112 {AUTH_FIELD_AUTHOR, AUTH_FIELD_TITLE, AUTH_FIELD_YEAR, USHRT_MAX, USHRT_MAX}, //AUTH_FIELD_CUSTOM5, 113 {USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX, USHRT_MAX} 114 }; 115 116 SwFormTokens lcl_GetAuthPattern(sal_uInt16 nTypeId) 117 { 118 SwFormTokens aRet; 119 120 PatternIni aIni = aPatternIni[nTypeId]; 121 sal_uInt16 nVals[5]; 122 nVals[0] = aIni.n1; 123 nVals[1] = aIni.n2; 124 nVals[2] = aIni.n3; 125 nVals[3] = aIni.n4; 126 nVals[4] = aIni.n5; 127 128 SwFormToken aStartToken( TOKEN_AUTHORITY ); 129 aStartToken.nAuthorityField = AUTH_FIELD_IDENTIFIER; 130 aRet.push_back( aStartToken ); 131 SwFormToken aSeparatorToken( TOKEN_TEXT ); 132 aSeparatorToken.sText = String::CreateFromAscii( ": " ); 133 aRet.push_back( aSeparatorToken ); 134 SwFormToken aTextToken( TOKEN_TEXT ); 135 aTextToken.sText = String::CreateFromAscii( ", " ); 136 137 for(sal_uInt16 i = 0; i < 5 ; i++) 138 { 139 if(nVals[i] == USHRT_MAX) 140 break; 141 if( i > 0 ) 142 aRet.push_back( aTextToken ); 143 144 // -> #i21237# 145 SwFormToken aToken(TOKEN_AUTHORITY); 146 147 aToken.nAuthorityField = nVals[i]; 148 aRet.push_back(aToken); 149 // <- #i21237# 150 } 151 152 return aRet; 153 } 154 /*-------------------------------------------------------------------- 155 Beschreibung: Verzeichnis-Markierungen D/Ctor 156 --------------------------------------------------------------------*/ 157 158 159 /// pool default constructor 160 SwTOXMark::SwTOXMark() 161 : SfxPoolItem( RES_TXTATR_TOXMARK ) 162 , SwModify( 0 ) 163 , 164 pTxtAttr( 0 ), 165 bAutoGenerated(sal_False), 166 bMainEntry(sal_False) 167 { 168 } 169 170 171 SwTOXMark::SwTOXMark( const SwTOXType* pTyp ) 172 : SfxPoolItem( RES_TXTATR_TOXMARK ) 173 , SwModify( const_cast<SwTOXType*>(pTyp) ) 174 , 175 pTxtAttr( 0 ), nLevel( 0 ), 176 bAutoGenerated(sal_False), 177 bMainEntry(sal_False) 178 { 179 } 180 181 182 SwTOXMark::SwTOXMark( const SwTOXMark& rCopy ) 183 : SfxPoolItem( RES_TXTATR_TOXMARK ) 184 , SwModify(rCopy.GetRegisteredInNonConst()) 185 , 186 aPrimaryKey( rCopy.aPrimaryKey ), aSecondaryKey( rCopy.aSecondaryKey ), 187 aTextReading( rCopy.aTextReading ), 188 aPrimaryKeyReading( rCopy.aPrimaryKeyReading ), 189 aSecondaryKeyReading( rCopy.aSecondaryKeyReading ), 190 pTxtAttr( 0 ), nLevel( rCopy.nLevel ), 191 bAutoGenerated( rCopy.bAutoGenerated), 192 bMainEntry(rCopy.bMainEntry) 193 { 194 // AlternativString kopieren 195 aAltText = rCopy.aAltText; 196 } 197 198 199 SwTOXMark::~SwTOXMark() 200 { 201 } 202 203 204 void SwTOXMark::RegisterToTOXType( SwTOXType& rMark ) 205 { 206 rMark.Add(this); 207 } 208 209 int SwTOXMark::operator==( const SfxPoolItem& rAttr ) const 210 { 211 ASSERT( SfxPoolItem::operator==( rAttr ), "keine gleichen Attribute" ); 212 return GetRegisteredIn() == ((SwTOXMark&)rAttr).GetRegisteredIn(); 213 } 214 215 216 SfxPoolItem* SwTOXMark::Clone( SfxItemPool* ) const 217 { 218 return new SwTOXMark( *this ); 219 } 220 221 void SwTOXMark::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew) 222 { 223 NotifyClients(pOld, pNew); 224 if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which())) 225 { // invalidate cached uno object 226 SetXTOXMark(::com::sun::star::uno::Reference< 227 ::com::sun::star::text::XDocumentIndexMark>(0)); 228 } 229 } 230 231 void SwTOXMark::InvalidateTOXMark() 232 { 233 SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT, 234 &static_cast<SwModify&>(*this) ); // cast to base class! 235 NotifyClients(&aMsgHint, &aMsgHint); 236 } 237 238 String SwTOXMark::GetText() const 239 { 240 String aStr; 241 if( aAltText.Len() ) 242 aStr = aAltText; 243 else if( pTxtAttr && pTxtAttr->GetpTxtNd() ) 244 { 245 xub_StrLen* pEndIdx = pTxtAttr->GetEnd(); 246 ASSERT( pEndIdx, "TOXMark ohne Mark!!"); 247 if( pEndIdx ) 248 { 249 const xub_StrLen nStt = *pTxtAttr->GetStart(); 250 aStr = pTxtAttr->GetpTxtNd()->GetExpandTxt( nStt, *pEndIdx-nStt ); 251 } 252 } 253 return aStr; 254 } 255 256 void SwTOXMark::InsertTOXMarks( SwTOXMarks& aMarks, const SwTOXType& rType ) 257 { 258 SwIterator<SwTOXMark,SwTOXType> aIter(rType); 259 SwTOXMark* pMark = aIter.First(); 260 while( pMark ) 261 { 262 if(pMark->GetTxtTOXMark()) 263 aMarks.C40_INSERT(SwTOXMark, pMark, aMarks.Count()); 264 pMark = aIter.Next(); 265 } 266 } 267 268 /*-------------------------------------------------------------------- 269 Beschreibung: Typen von Verzeichnissen verwalten 270 --------------------------------------------------------------------*/ 271 272 SwTOXType::SwTOXType( TOXTypes eTyp, const String& rName ) 273 : SwModify(0), 274 aName(rName), 275 eType(eTyp) 276 { 277 } 278 279 280 SwTOXType::SwTOXType(const SwTOXType& rCopy) 281 : SwModify( (SwModify*)rCopy.GetRegisteredIn() ), 282 aName(rCopy.aName), 283 eType(rCopy.eType) 284 { 285 } 286 287 /*-------------------------------------------------------------------- 288 Beschreibung: Formen bearbeiten 289 --------------------------------------------------------------------*/ 290 291 SwForm::SwForm( TOXTypes eTyp ) // #i21237# 292 : eType( eTyp ), nFormMaxLevel( SwForm::GetFormMaxLevel( eTyp )), 293 // nFirstTabPos( lNumIndent ), 294 bCommaSeparated(sal_False) 295 { 296 //bHasFirstTabPos = 297 bGenerateTabPos = sal_False; 298 bIsRelTabPos = sal_True; 299 300 // Inhaltsverzeichnis hat entsprechend Anzahl Headlines + Ueberschrift 301 // Benutzer hat 10 Ebenen + Ueberschrift 302 // Stichwort hat 3 Ebenen + Ueberschrift + Trenner 303 // indexes of tables, objects illustrations and authorities consist of a heading and one level 304 305 sal_uInt16 nPoolId; 306 switch( eType ) 307 { 308 case TOX_INDEX: nPoolId = STR_POOLCOLL_TOX_IDXH; break; 309 case TOX_USER: nPoolId = STR_POOLCOLL_TOX_USERH; break; 310 case TOX_CONTENT: nPoolId = STR_POOLCOLL_TOX_CNTNTH; break; 311 case TOX_ILLUSTRATIONS: nPoolId = STR_POOLCOLL_TOX_ILLUSH; break; 312 case TOX_OBJECTS : nPoolId = STR_POOLCOLL_TOX_OBJECTH; break; 313 case TOX_TABLES : nPoolId = STR_POOLCOLL_TOX_TABLESH; break; 314 case TOX_AUTHORITIES : nPoolId = STR_POOLCOLL_TOX_AUTHORITIESH; break; 315 default: 316 ASSERT( !this, "ungueltiger TOXTyp"); 317 return ; 318 } 319 320 SwFormTokens aTokens; 321 if (TOX_CONTENT == eType) 322 { 323 aTokens.push_back(SwFormToken(TOKEN_ENTRY_NO)); 324 aTokens.push_back(SwFormToken(TOKEN_ENTRY_TEXT)); 325 } 326 else 327 aTokens.push_back(SwFormToken(TOKEN_ENTRY)); 328 329 if (TOX_AUTHORITIES != eType) 330 { 331 SwFormToken aToken(TOKEN_TAB_STOP); 332 aToken.nTabStopPosition = 0; 333 334 // --> FME 2004-12-10 #i36870# right aligned tab for all 335 aToken.cTabFillChar = '.'; 336 aToken.eTabAlign = SVX_TAB_ADJUST_END; 337 // <-- 338 339 aTokens.push_back(aToken); 340 aTokens.push_back(SwFormToken(TOKEN_PAGE_NUMS)); 341 } 342 343 SetTemplate( 0, SW_RESSTR( nPoolId++ )); 344 345 if(TOX_INDEX == eType) 346 { 347 for( sal_uInt16 i = 1; i < 5; ++i ) 348 { 349 if(1 == i) 350 { 351 SwFormTokens aTmpTokens; 352 SwFormToken aTmpToken(TOKEN_ENTRY); 353 aTmpTokens.push_back(aTmpToken); 354 355 SetPattern( i, aTmpTokens ); 356 SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDXBREAK )); 357 } 358 else 359 { 360 SetPattern( i, aTokens ); 361 SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDX1 + i - 2 )); 362 } 363 } 364 } 365 else 366 for( sal_uInt16 i = 1; i < GetFormMax(); ++i, ++nPoolId ) // Nr 0 ist der Titel 367 { 368 if(TOX_AUTHORITIES == eType) 369 SetPattern(i, lcl_GetAuthPattern(i)); 370 else 371 SetPattern( i, aTokens ); 372 373 if( TOX_CONTENT == eType && 6 == i ) 374 nPoolId = STR_POOLCOLL_TOX_CNTNT6; 375 else if( TOX_USER == eType && 6 == i ) 376 nPoolId = STR_POOLCOLL_TOX_USER6; 377 else if( TOX_AUTHORITIES == eType ) 378 nPoolId = STR_POOLCOLL_TOX_AUTHORITIES1; 379 SetTemplate( i, SW_RESSTR( nPoolId ) ); 380 } 381 } 382 383 384 SwForm::SwForm(const SwForm& rForm) 385 : eType( rForm.eType ) 386 { 387 *this = rForm; 388 } 389 390 391 SwForm& SwForm::operator=(const SwForm& rForm) 392 { 393 eType = rForm.eType; 394 nFormMaxLevel = rForm.nFormMaxLevel; 395 // nFirstTabPos = rForm.nFirstTabPos; 396 // bHasFirstTabPos = rForm.bHasFirstTabPos; 397 bGenerateTabPos = rForm.bGenerateTabPos; 398 bIsRelTabPos = rForm.bIsRelTabPos; 399 bCommaSeparated = rForm.bCommaSeparated; 400 for(sal_uInt16 i=0; i < nFormMaxLevel; ++i) 401 { 402 aPattern[i] = rForm.aPattern[i]; 403 aTemplate[i] = rForm.aTemplate[i]; 404 } 405 return *this; 406 } 407 408 sal_uInt16 SwForm::GetFormMaxLevel( TOXTypes eTOXType ) 409 { 410 sal_uInt16 nRet = 0; 411 switch( eTOXType ) 412 { 413 case TOX_INDEX: nRet = 5; break; 414 case TOX_USER: nRet = MAXLEVEL+1; break; 415 case TOX_CONTENT: nRet = MAXLEVEL+1; break; 416 case TOX_ILLUSTRATIONS: 417 case TOX_OBJECTS : 418 case TOX_TABLES : nRet = 2; break; 419 case TOX_AUTHORITIES : nRet = AUTH_TYPE_END + 1; break; 420 } 421 return nRet; 422 } 423 424 // #i21237# 425 bool operator == (const SwFormToken & rToken, FormTokenType eType) 426 { 427 return rToken.eTokenType == eType; 428 } 429 430 //----------------------------------------------------------------------------- 431 void SwForm::AdjustTabStops(SwDoc& rDoc, sal_Bool bInsertNewTapStops) // #i21237# 432 { 433 for(sal_uInt16 nLevel = 1; nLevel < GetFormMax(); nLevel++) 434 { 435 const String& sTemplateName = GetTemplate(nLevel); 436 437 SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName( sTemplateName ); 438 if( !pColl ) 439 { 440 sal_uInt16 nId = SwStyleNameMapper::GetPoolIdFromUIName 441 ( sTemplateName, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL ); // #i21237# 442 if( USHRT_MAX != nId ) 443 pColl = rDoc.GetTxtCollFromPool( nId ); 444 } 445 446 const SvxTabStopItem* pTabStops = 0; 447 sal_uInt16 nTabCount = 0; 448 if( pColl && 449 0 != ( pTabStops = &pColl->GetTabStops(sal_False) ) && 450 0 != ( nTabCount = pTabStops->Count() ) ) 451 { 452 // #i21237# 453 SwFormTokens aCurrentPattern = GetPattern(nLevel); 454 SwFormTokens::iterator aIt = aCurrentPattern.begin(); 455 456 sal_Bool bChanged = sal_False; 457 458 for(sal_uInt16 nTab = 0; nTab < nTabCount; ++nTab) 459 { 460 const SvxTabStop& rTab = (*pTabStops)[nTab]; 461 462 // --> FME 2004-12-16 #i29178# 463 // For Word import, we do not want to replace exising tokens, 464 // we insert new tabstop tokens without a tabstop character: 465 if ( bInsertNewTapStops ) 466 { 467 if ( SVX_TAB_ADJUST_DEFAULT != rTab.GetAdjustment() ) 468 { 469 bChanged = sal_True; 470 SwFormToken aToken(TOKEN_TAB_STOP); 471 aToken.bWithTab = sal_False; 472 aToken.nTabStopPosition = rTab.GetTabPos(); 473 aToken.eTabAlign = rTab.GetAdjustment(); 474 aToken.cTabFillChar = rTab.GetFill(); 475 aCurrentPattern.push_back(aToken); 476 } 477 } 478 // <-- 479 else 480 { 481 aIt = find_if(aIt, aCurrentPattern.end(), 482 SwFormTokenEqualToFormTokenType 483 (TOKEN_TAB_STOP)); 484 if ( aIt != aCurrentPattern.end() ) 485 { 486 bChanged = sal_True; 487 aIt->nTabStopPosition = rTab.GetTabPos(); 488 aIt->eTabAlign = nTab == nTabCount - 1 && 489 SVX_TAB_ADJUST_RIGHT == rTab.GetAdjustment() ? 490 SVX_TAB_ADJUST_END : 491 rTab.GetAdjustment(); 492 aIt->cTabFillChar = rTab.GetFill(); 493 ++aIt; 494 } 495 else 496 break; // no more tokens to replace 497 } 498 } 499 // <-- 500 501 if(bChanged) 502 SetPattern(nLevel, aCurrentPattern); // #i21237# 503 } 504 } 505 } 506 /*-------------------------------------------------------------------- 507 Beschreibung: Ctor TOXBase 508 --------------------------------------------------------------------*/ 509 510 511 SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm, 512 sal_uInt16 nCreaType, const String& rTitle ) 513 : SwClient((SwModify*)pTyp) 514 , aForm(rForm) 515 , aTitle(rTitle) 516 , eLanguage((LanguageType)::GetAppLanguage()) 517 , nCreateType(nCreaType) 518 , nOLEOptions(0) 519 , eCaptionDisplay(CAPTION_COMPLETE) 520 , bProtected( sal_True ) 521 , bFromChapter(sal_False) 522 , bFromObjectNames(sal_False) 523 , bLevelFromChapter(sal_False) 524 , maMSTOCExpression() 525 , mbKeepExpression(sal_True) 526 { 527 aData.nOptions = 0; 528 } 529 530 531 SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc ) 532 : SwClient( rSource.GetRegisteredInNonConst() ) 533 , mbKeepExpression(sal_True) 534 { 535 CopyTOXBase( pDoc, rSource ); 536 } 537 538 void SwTOXBase::RegisterToTOXType( SwTOXType& rType ) 539 { 540 rType.Add( this ); 541 } 542 543 SwTOXBase& SwTOXBase::CopyTOXBase( SwDoc* pDoc, const SwTOXBase& rSource ) 544 { 545 maMSTOCExpression = rSource.maMSTOCExpression; 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