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
lcl_GetAuthPattern(sal_uInt16 nTypeId)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
SwTOXMark()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
SwTOXMark(const SwTOXType * pTyp)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
SwTOXMark(const SwTOXMark & rCopy)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
~SwTOXMark()199 SwTOXMark::~SwTOXMark()
200 {
201 }
202
203
RegisterToTOXType(SwTOXType & rMark)204 void SwTOXMark::RegisterToTOXType( SwTOXType& rMark )
205 {
206 rMark.Add(this);
207 }
208
operator ==(const SfxPoolItem & rAttr) const209 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
Clone(SfxItemPool *) const216 SfxPoolItem* SwTOXMark::Clone( SfxItemPool* ) const
217 {
218 return new SwTOXMark( *this );
219 }
220
Modify(const SfxPoolItem * pOld,const SfxPoolItem * pNew)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
InvalidateTOXMark()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
GetText() const238 String SwTOXMark::GetText() const
239 {
240 String aStr;
241 if( aAltText.Len() )
242 aStr = aAltText;
243 else if( pTxtAttr && pTxtAttr->GetpTxtNd() )
244 {
245 const 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
InsertTOXMarks(SwTOXMarks & aMarks,const SwTOXType & rType)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
SwTOXType(TOXTypes eTyp,const String & rName)272 SwTOXType::SwTOXType( TOXTypes eTyp, const String& rName )
273 : SwModify(0),
274 aName(rName),
275 eType(eTyp)
276 {
277 }
278
279
SwTOXType(const SwTOXType & rCopy)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
SwForm(TOXTypes eTyp)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
SwForm(const SwForm & rForm)384 SwForm::SwForm(const SwForm& rForm)
385 : eType( rForm.eType )
386 {
387 *this = rForm;
388 }
389
390
operator =(const SwForm & rForm)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
GetFormMaxLevel(TOXTypes eTOXType)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#
operator ==(const SwFormToken & rToken,FormTokenType eType)425 bool operator == (const SwFormToken & rToken, FormTokenType eType)
426 {
427 return rToken.eTokenType == eType;
428 }
429
430 //-----------------------------------------------------------------------------
AdjustTabStops(SwDoc & rDoc,sal_Bool bInsertNewTapStops)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
SwTOXBase(const SwTOXType * pTyp,const SwForm & rForm,sal_uInt16 nCreaType,const String & rTitle)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
SwTOXBase(const SwTOXBase & rSource,SwDoc * pDoc)531 SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc )
532 : SwClient( rSource.GetRegisteredInNonConst() )
533 , mbKeepExpression(sal_True)
534 {
535 CopyTOXBase( pDoc, rSource );
536 }
537
RegisterToTOXType(SwTOXType & rType)538 void SwTOXBase::RegisterToTOXType( SwTOXType& rType )
539 {
540 rType.Add( this );
541 }
542
CopyTOXBase(SwDoc * pDoc,const SwTOXBase & rSource)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
~SwTOXBase()600 SwTOXBase::~SwTOXBase()
601 {
602 // if( GetTOXType()->GetType() == TOX_USER )
603 // delete aData.pTemplateName;
604 }
605
SetTitle(const String & rTitle)606 void SwTOXBase::SetTitle(const String& rTitle)
607 { aTitle = rTitle; }
608
609
operator =(const SwTOXBase & rSource)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
GetString() const667 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#
SwFormTokensHelper(const String & rPattern)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
BuildToken(const String & sPattern,xub_StrLen & nCurPatternPos) const788 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
SearchNextToken(const String & sPattern,xub_StrLen nStt) const866 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
GetTokenType(const String & sToken,xub_StrLen * pTokenLen) const899 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
SetPattern(sal_uInt16 nLevel,const SwFormTokens & rTokens)943 void SwForm::SetPattern(sal_uInt16 nLevel, const SwFormTokens& rTokens)
944 {
945 ASSERT(nLevel < GetFormMax(), "Index >= FORM_MAX");
946 aPattern[nLevel] = rTokens;
947 }
948
SetPattern(sal_uInt16 nLevel,const String & rStr)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
GetPattern(sal_uInt16 nLevel) const957 const SwFormTokens& SwForm::GetPattern(sal_uInt16 nLevel) const
958 {
959 ASSERT(nLevel < GetFormMax(), "Index >= FORM_MAX");
960 return aPattern[nLevel];
961 }
962
963