Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
5 : * This Source Code Form is subject to the terms of the Mozilla Public
6 : * License, v. 2.0. If a copy of the MPL was not distributed with this
7 : * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
11 : * Licensed to the Apache Software Foundation (ASF) under one or more
12 : * contributor license agreements. See the NOTICE file distributed
13 : * with this work for additional information regarding copyright
14 : * ownership. The ASF licenses this file to you under the Apache
15 : * License, Version 2.0 (the "License"); you may not use this file
16 : * except in compliance with the License. You may obtain a copy of
17 : * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 : */
19 :
20 : #include <tools/resid.hxx>
21 : #include <hintids.hxx>
22 : #include <swtypes.hxx>
23 : #include <txtatr.hxx>
24 : #include <ndtxt.hxx>
25 : #include <txttxmrk.hxx>
26 : #include <tox.hxx>
27 : #include <poolfmt.hrc>
28 : #include <doc.hxx>
29 : #include <docary.hxx>
30 : #include <paratr.hxx>
31 : #include <editeng/tstpitem.hxx>
32 : #include <SwStyleNameMapper.hxx>
33 : #include <hints.hxx>
34 : #include <functional>
35 : #include <switerator.hxx>
36 :
37 : #include <boost/optional.hpp>
38 :
39 : #include <algorithm>
40 :
41 :
42 : using namespace std;
43 :
44 :
45 : const sal_Unicode C_NUM_REPL = '@';
46 : const sal_Unicode C_END_PAGE_NUM = '~';
47 90 : const OUString S_PAGE_DELI(", ");
48 :
49 :
50 : namespace
51 : {
52 :
53 748 : static void lcl_FillAuthPattern(SwFormTokens &rAuthTokens, sal_uInt16 nTypeId)
54 : {
55 748 : rAuthTokens.reserve(9); // Worst case: Start+Sep1+Auth+3*(Sep2+Auth)
56 :
57 748 : SwFormToken aStartToken( TOKEN_AUTHORITY );
58 748 : aStartToken.nAuthorityField = AUTH_FIELD_IDENTIFIER;
59 748 : rAuthTokens.push_back( aStartToken );
60 1496 : SwFormToken aSeparatorToken( TOKEN_TEXT );
61 748 : aSeparatorToken.sText = ": ";
62 748 : rAuthTokens.push_back( aSeparatorToken );
63 :
64 748 : --nTypeId; // compensate +1 offset introduced by caller
65 :
66 1496 : SwFormToken aTextToken( TOKEN_TEXT );
67 748 : aTextToken.sText = ", ";
68 :
69 : const ToxAuthorityField nVals[4] = {
70 : AUTH_FIELD_AUTHOR,
71 : AUTH_FIELD_TITLE,
72 : AUTH_FIELD_YEAR,
73 : nTypeId == AUTH_TYPE_WWW ? AUTH_FIELD_URL : AUTH_FIELD_END
74 748 : };
75 :
76 3026 : for(size_t i = 0; i < SAL_N_ELEMENTS(nVals); ++i)
77 : {
78 2992 : if(nVals[i] == AUTH_FIELD_END)
79 714 : break;
80 2278 : if( i > 0 )
81 1530 : rAuthTokens.push_back( aTextToken );
82 :
83 : // -> #i21237#
84 2278 : SwFormToken aToken(TOKEN_AUTHORITY);
85 :
86 2278 : aToken.nAuthorityField = nVals[i];
87 2278 : rAuthTokens.push_back(aToken);
88 : // <- #i21237#
89 3026 : }
90 748 : }
91 :
92 : }
93 :
94 15457 : TYPEINIT2( SwTOXMark, SfxPoolItem, SwClient ); // fuers rtti
95 :
96 : /// pool default constructor
97 90 : SwTOXMark::SwTOXMark()
98 : : SfxPoolItem( RES_TXTATR_TOXMARK )
99 : , SwModify( 0 )
100 : ,
101 : pTxtAttr( 0 ), nLevel( 0 ),
102 : bAutoGenerated(false),
103 90 : bMainEntry(false)
104 : {
105 90 : }
106 :
107 334 : SwTOXMark::SwTOXMark( const SwTOXType* pTyp )
108 : : SfxPoolItem( RES_TXTATR_TOXMARK )
109 : , SwModify( const_cast<SwTOXType*>(pTyp) )
110 : ,
111 : pTxtAttr( 0 ), nLevel( 0 ),
112 : bAutoGenerated(false),
113 334 : bMainEntry(false)
114 : {
115 334 : }
116 :
117 1208 : SwTOXMark::SwTOXMark( const SwTOXMark& rCopy )
118 : : SfxPoolItem( RES_TXTATR_TOXMARK )
119 : , SwModify(rCopy.GetRegisteredInNonConst())
120 : ,
121 : aPrimaryKey( rCopy.aPrimaryKey ), aSecondaryKey( rCopy.aSecondaryKey ),
122 : aTextReading( rCopy.aTextReading ),
123 : aPrimaryKeyReading( rCopy.aPrimaryKeyReading ),
124 : aSecondaryKeyReading( rCopy.aSecondaryKeyReading ),
125 : pTxtAttr( 0 ), nLevel( rCopy.nLevel ),
126 : bAutoGenerated( rCopy.bAutoGenerated),
127 1208 : bMainEntry(rCopy.bMainEntry)
128 : {
129 : // Copy AlternativString
130 1208 : aAltText = rCopy.aAltText;
131 1208 : }
132 :
133 2896 : SwTOXMark::~SwTOXMark()
134 : {
135 2896 : }
136 :
137 0 : void SwTOXMark::RegisterToTOXType(SwTOXType& rType)
138 : {
139 0 : rType.Add(this);
140 0 : }
141 :
142 12 : bool SwTOXMark::operator==( const SfxPoolItem& rAttr ) const
143 : {
144 : assert(SfxPoolItem::operator==(rAttr));
145 12 : return GetRegisteredIn() == ((SwTOXMark&)rAttr).GetRegisteredIn();
146 : }
147 :
148 1174 : SfxPoolItem* SwTOXMark::Clone( SfxItemPool* ) const
149 : {
150 1174 : return new SwTOXMark( *this );
151 : }
152 :
153 0 : void SwTOXMark::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew)
154 : {
155 0 : NotifyClients(pOld, pNew);
156 0 : if (pOld && (RES_REMOVE_UNO_OBJECT == pOld->Which()))
157 : { // invalidate cached uno object
158 : SetXTOXMark(::com::sun::star::uno::Reference<
159 0 : ::com::sun::star::text::XDocumentIndexMark>(0));
160 : }
161 0 : }
162 :
163 342 : void SwTOXMark::InvalidateTOXMark()
164 : {
165 : SwPtrMsgPoolItem aMsgHint( RES_REMOVE_UNO_OBJECT,
166 342 : &static_cast<SwModify&>(*this) ); // cast to base class!
167 342 : NotifyClients(&aMsgHint, &aMsgHint);
168 342 : }
169 :
170 2 : OUString SwTOXMark::GetText() const
171 : {
172 2 : if( !aAltText.isEmpty() )
173 0 : return aAltText;
174 :
175 2 : if( pTxtAttr && pTxtAttr->GetpTxtNd() )
176 : {
177 2 : const sal_Int32* pEndIdx = pTxtAttr->GetEnd();
178 : OSL_ENSURE( pEndIdx, "TOXMark without mark!");
179 2 : if( pEndIdx )
180 : {
181 2 : const sal_Int32 nStt = pTxtAttr->GetStart();
182 2 : return pTxtAttr->GetpTxtNd()->GetExpandTxt( nStt, *pEndIdx-nStt );
183 : }
184 : }
185 :
186 0 : return OUString();
187 : }
188 :
189 4 : void SwTOXMark::InsertTOXMarks( SwTOXMarks& aMarks, const SwTOXType& rType )
190 : {
191 4 : SwIterator<SwTOXMark,SwTOXType> aIter(rType);
192 4 : SwTOXMark* pMark = aIter.First();
193 8 : while( pMark )
194 : {
195 0 : if(pMark->GetTxtTOXMark())
196 0 : aMarks.push_back(pMark);
197 0 : pMark = aIter.Next();
198 4 : }
199 4 : }
200 :
201 : // Manage types of TOX
202 40720 : SwTOXType::SwTOXType( TOXTypes eTyp, const OUString& rName )
203 : : SwModify(0),
204 : aName(rName),
205 40720 : eType(eTyp)
206 : {
207 40720 : }
208 :
209 0 : SwTOXType::SwTOXType(const SwTOXType& rCopy)
210 0 : : SwModify( (SwModify*)rCopy.GetRegisteredIn() ),
211 : aName(rCopy.aName),
212 0 : eType(rCopy.eType)
213 : {
214 0 : }
215 :
216 : // Edit forms
217 468 : SwForm::SwForm( TOXTypes eTyp ) // #i21237#
218 468 : : eType( eTyp ), nFormMaxLevel( SwForm::GetFormMaxLevel( eTyp )),
219 : // nFirstTabPos( lNumIndent ),
220 936 : bCommaSeparated(false)
221 : {
222 : //bHasFirstTabPos =
223 468 : bGenerateTabPos = false;
224 468 : bIsRelTabPos = true;
225 :
226 : // The table of contents has a certain number of headlines + headings
227 : // The user has 10 levels + headings
228 : // Keyword has 3 levels + headings+ separator
229 : // Indexes of tables, object illustrations and authorities consist of a heading and one level
230 :
231 : sal_uInt16 nPoolId;
232 468 : switch( eType )
233 : {
234 48 : case TOX_INDEX: nPoolId = STR_POOLCOLL_TOX_IDXH; break;
235 4 : case TOX_USER: nPoolId = STR_POOLCOLL_TOX_USERH; break;
236 356 : case TOX_CONTENT: nPoolId = STR_POOLCOLL_TOX_CNTNTH; break;
237 18 : case TOX_ILLUSTRATIONS: nPoolId = STR_POOLCOLL_TOX_ILLUSH; break;
238 4 : case TOX_OBJECTS : nPoolId = STR_POOLCOLL_TOX_OBJECTH; break;
239 4 : case TOX_TABLES : nPoolId = STR_POOLCOLL_TOX_TABLESH; break;
240 34 : case TOX_AUTHORITIES : nPoolId = STR_POOLCOLL_TOX_AUTHORITIESH; break;
241 0 : case TOX_CITATION : nPoolId = STR_POOLCOLL_TOX_CITATION; break;
242 : default:
243 : OSL_ENSURE( false, "invalid TOXTyp");
244 468 : return ;
245 : }
246 :
247 468 : SwFormTokens aTokens;
248 468 : if (TOX_CONTENT == eType || TOX_ILLUSTRATIONS == eType )
249 : {
250 374 : SwFormToken aLinkStt (TOKEN_LINK_START);
251 374 : aLinkStt.sCharStyleName = SW_RES(STR_POOLCHR_TOXJUMP);
252 374 : aTokens.push_back(aLinkStt);
253 : }
254 :
255 468 : if (TOX_CONTENT == eType)
256 : {
257 356 : aTokens.push_back(SwFormToken(TOKEN_ENTRY_NO));
258 356 : aTokens.push_back(SwFormToken(TOKEN_ENTRY_TEXT));
259 : }
260 : else
261 112 : aTokens.push_back(SwFormToken(TOKEN_ENTRY));
262 :
263 468 : if (TOX_AUTHORITIES != eType)
264 : {
265 434 : SwFormToken aToken(TOKEN_TAB_STOP);
266 434 : aToken.nTabStopPosition = 0;
267 :
268 : // #i36870# right aligned tab for all
269 434 : aToken.cTabFillChar = '.';
270 434 : aToken.eTabAlign = SVX_TAB_ADJUST_END;
271 :
272 434 : aTokens.push_back(aToken);
273 434 : aTokens.push_back(SwFormToken(TOKEN_PAGE_NUMS));
274 : }
275 :
276 468 : if (TOX_CONTENT == eType || TOX_ILLUSTRATIONS == eType)
277 374 : aTokens.push_back(SwFormToken(TOKEN_LINK_END));
278 :
279 468 : SetTemplate( 0, SW_RESSTR( nPoolId++ ));
280 :
281 468 : if(TOX_INDEX == eType)
282 : {
283 240 : for( sal_uInt16 i = 1; i < 5; ++i )
284 : {
285 192 : if(1 == i)
286 : {
287 48 : SwFormTokens aTmpTokens;
288 96 : SwFormToken aTmpToken(TOKEN_ENTRY);
289 48 : aTmpTokens.push_back(aTmpToken);
290 :
291 48 : SetPattern( i, aTmpTokens );
292 96 : SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDXBREAK ));
293 : }
294 : else
295 : {
296 144 : SetPattern( i, aTokens );
297 144 : SetTemplate( i, SW_RESSTR( STR_POOLCOLL_TOX_IDX1 + i - 2 ));
298 : }
299 : }
300 : }
301 : else
302 4794 : for( sal_uInt16 i = 1; i < GetFormMax(); ++i, ++nPoolId ) // Number 0 is the title
303 : {
304 4374 : if(TOX_AUTHORITIES == eType)
305 : {
306 748 : SwFormTokens aAuthTokens;
307 748 : lcl_FillAuthPattern(aAuthTokens, i);
308 748 : SetPattern(i, aAuthTokens);
309 : }
310 : else
311 3626 : SetPattern( i, aTokens );
312 :
313 4374 : if( TOX_CONTENT == eType && 6 == i )
314 356 : nPoolId = STR_POOLCOLL_TOX_CNTNT6;
315 4018 : else if( TOX_USER == eType && 6 == i )
316 4 : nPoolId = STR_POOLCOLL_TOX_USER6;
317 4014 : else if( TOX_AUTHORITIES == eType )
318 748 : nPoolId = STR_POOLCOLL_TOX_AUTHORITIES1;
319 4374 : SetTemplate( i, SW_RESSTR( nPoolId ) );
320 468 : }
321 : }
322 :
323 2904 : SwForm::SwForm(const SwForm& rForm)
324 2904 : : eType( rForm.eType )
325 : {
326 2904 : *this = rForm;
327 2904 : }
328 :
329 4452 : SwForm& SwForm::operator=(const SwForm& rForm)
330 : {
331 4452 : eType = rForm.eType;
332 4452 : nFormMaxLevel = rForm.nFormMaxLevel;
333 : // nFirstTabPos = rForm.nFirstTabPos;
334 : // bHasFirstTabPos = rForm.bHasFirstTabPos;
335 4452 : bGenerateTabPos = rForm.bGenerateTabPos;
336 4452 : bIsRelTabPos = rForm.bIsRelTabPos;
337 4452 : bCommaSeparated = rForm.bCommaSeparated;
338 52062 : for(sal_uInt16 i=0; i < nFormMaxLevel; ++i)
339 : {
340 47610 : aPattern[i] = rForm.aPattern[i];
341 47610 : aTemplate[i] = rForm.aTemplate[i];
342 : }
343 4452 : return *this;
344 : }
345 :
346 560 : sal_uInt16 SwForm::GetFormMaxLevel( TOXTypes eTOXType )
347 : {
348 560 : switch( eTOXType )
349 : {
350 : case TOX_INDEX:
351 48 : return 5;
352 : case TOX_USER:
353 : case TOX_CONTENT:
354 452 : return MAXLEVEL + 1;
355 : case TOX_ILLUSTRATIONS:
356 : case TOX_OBJECTS:
357 : case TOX_TABLES:
358 26 : return 2;
359 : case TOX_BIBLIOGRAPHY:
360 : case TOX_CITATION:
361 : case TOX_AUTHORITIES:
362 34 : return AUTH_TYPE_END + 1;
363 : }
364 0 : return 0;
365 : }
366 :
367 0 : void SwForm::AdjustTabStops( SwDoc& rDoc ) // #i21237#
368 : {
369 0 : const sal_uInt16 nFormMax = GetFormMax();
370 0 : for ( sal_uInt16 nLevel = 1; nLevel < nFormMax; ++nLevel )
371 : {
372 0 : SwTxtFmtColl* pColl = rDoc.FindTxtFmtCollByName( GetTemplate(nLevel) );
373 0 : if( pColl == NULL )
374 : {
375 : // Paragraph Style for this level has not been created.
376 : // --> No need to propagate default values
377 0 : continue;
378 : }
379 :
380 0 : const SvxTabStopItem& rTabStops = pColl->GetTabStops(false);
381 0 : const sal_uInt16 nTabCount = rTabStops.Count();
382 0 : if (nTabCount != 0)
383 : {
384 0 : SwFormTokens aCurrentPattern = GetPattern(nLevel);
385 0 : SwFormTokens::iterator aIt = aCurrentPattern.begin();
386 :
387 0 : bool bChanged = false;
388 0 : for(sal_uInt16 nTab = 0; nTab < nTabCount; ++nTab)
389 : {
390 0 : const SvxTabStop& rTab = rTabStops[nTab];
391 :
392 0 : if ( rTab.GetAdjustment() == SVX_TAB_ADJUST_DEFAULT )
393 0 : continue; // ignore the default tab stop
394 :
395 0 : aIt = find_if( aIt, aCurrentPattern.end(), SwFormTokenEqualToFormTokenType(TOKEN_TAB_STOP) );
396 0 : if ( aIt != aCurrentPattern.end() )
397 : {
398 0 : bChanged = true;
399 0 : aIt->nTabStopPosition = rTab.GetTabPos();
400 0 : aIt->eTabAlign =
401 0 : ( nTab == nTabCount - 1
402 0 : && rTab.GetAdjustment() == SVX_TAB_ADJUST_RIGHT )
403 : ? SVX_TAB_ADJUST_END
404 0 : : rTab.GetAdjustment();
405 0 : aIt->cTabFillChar = rTab.GetFill();
406 0 : ++aIt;
407 : }
408 : else
409 0 : break; // no more tokens to replace
410 : }
411 :
412 0 : if ( bChanged )
413 0 : SetPattern( nLevel, aCurrentPattern );
414 : }
415 : }
416 0 : }
417 :
418 98 : OUString SwForm::GetFormEntry() {return OUString("<E>");}
419 1132 : OUString SwForm::GetFormTab() {return OUString("<T>");}
420 1132 : OUString SwForm::GetFormPageNums() {return OUString("<#>");}
421 1930 : OUString SwForm::GetFormLinkStt() {return OUString("<LS>");}
422 1930 : OUString SwForm::GetFormLinkEnd() {return OUString("<LE>");}
423 1062 : OUString SwForm::GetFormEntryNum() {return OUString("<E#>");}
424 1062 : OUString SwForm::GetFormEntryTxt() {return OUString("<ET>");}
425 22 : OUString SwForm::GetFormChapterMark() {return OUString("<C>");}
426 290 : OUString SwForm::GetFormText() {return OUString("<X>");}
427 378 : OUString SwForm::GetFormAuth() {return OUString("<A>");}
428 :
429 226 : SwTOXBase::SwTOXBase(const SwTOXType* pTyp, const SwForm& rForm,
430 : sal_uInt16 nCreaType, const OUString& rTitle )
431 : : SwClient((SwModify*)pTyp)
432 : , aForm(rForm)
433 : , aTitle(rTitle)
434 226 : , eLanguage((LanguageType)::GetAppLanguage())
435 : , nCreateType(nCreaType)
436 : , nOLEOptions(0)
437 : , eCaptionDisplay(CAPTION_COMPLETE)
438 : , bProtected( true )
439 : , bFromChapter(false)
440 : , bFromObjectNames(false)
441 : , bLevelFromChapter(false)
442 : , maMSTOCExpression()
443 452 : , mbKeepExpression(true)
444 : {
445 226 : aData.nOptions = 0;
446 226 : }
447 :
448 238 : SwTOXBase::SwTOXBase( const SwTOXBase& rSource, SwDoc* pDoc )
449 : : SwClient( rSource.GetRegisteredInNonConst() )
450 238 : , mbKeepExpression(true)
451 : {
452 238 : CopyTOXBase( pDoc, rSource );
453 238 : }
454 :
455 0 : void SwTOXBase::RegisterToTOXType( SwTOXType& rType )
456 : {
457 0 : rType.Add( this );
458 0 : }
459 :
460 238 : SwTOXBase& SwTOXBase::CopyTOXBase( SwDoc* pDoc, const SwTOXBase& rSource )
461 : {
462 238 : maMSTOCExpression = rSource.maMSTOCExpression;
463 238 : SwTOXType* pType = (SwTOXType*)rSource.GetTOXType();
464 238 : if( pDoc && USHRT_MAX == pDoc->GetTOXTypes().GetPos( pType ))
465 : {
466 : // type not in pDoc, so create it now
467 0 : const SwTOXTypes& rTypes = pDoc->GetTOXTypes();
468 0 : bool bFound = false;
469 0 : for( size_t n = rTypes.size(); n; )
470 : {
471 0 : const SwTOXType* pCmp = rTypes[ --n ];
472 0 : if( pCmp->GetType() == pType->GetType() &&
473 0 : pCmp->GetTypeName() == pType->GetTypeName() )
474 : {
475 0 : pType = (SwTOXType*)pCmp;
476 0 : bFound = true;
477 0 : break;
478 : }
479 : }
480 :
481 0 : if( !bFound )
482 0 : pType = (SwTOXType*)pDoc->InsertTOXType( *pType );
483 : }
484 238 : pType->Add( this );
485 :
486 238 : nCreateType = rSource.nCreateType;
487 238 : aTitle = rSource.aTitle;
488 238 : aForm = rSource.aForm;
489 238 : m_aBookmarkName = rSource.m_aBookmarkName;
490 238 : m_aEntryTypeName = rSource.m_aEntryTypeName ;
491 238 : bProtected = rSource.bProtected;
492 238 : bFromChapter = rSource.bFromChapter;
493 238 : bFromObjectNames = rSource.bFromObjectNames;
494 238 : sMainEntryCharStyle = rSource.sMainEntryCharStyle;
495 238 : sSequenceName = rSource.sSequenceName;
496 238 : eCaptionDisplay = rSource.eCaptionDisplay;
497 238 : nOLEOptions = rSource.nOLEOptions;
498 238 : eLanguage = rSource.eLanguage;
499 238 : sSortAlgorithm = rSource.sSortAlgorithm;
500 238 : bLevelFromChapter = rSource.bLevelFromChapter;
501 :
502 2618 : for( sal_uInt16 i = 0; i < MAXLEVEL; ++i )
503 2380 : aStyleNames[i] = rSource.aStyleNames[i];
504 :
505 : // its the same data type!
506 238 : aData.nOptions = rSource.aData.nOptions;
507 :
508 238 : if( !pDoc || pDoc->IsCopyIsMove() )
509 238 : aName = rSource.GetTOXName();
510 : else
511 0 : aName = pDoc->GetUniqueTOXBaseName( *pType, rSource.GetTOXName() );
512 :
513 238 : return *this;
514 : }
515 :
516 : // TOX specific functions
517 702 : SwTOXBase::~SwTOXBase()
518 : {
519 : // if( GetTOXType()->GetType() == TOX_USER )
520 : // delete aData.pTemplateName;
521 702 : }
522 :
523 216 : void SwTOXBase::SetTitle(const OUString& rTitle)
524 216 : { aTitle = rTitle; }
525 :
526 6 : void SwTOXBase::SetBookmarkName(const OUString& bName)
527 : {
528 6 : m_aBookmarkName = bName;
529 6 : }
530 :
531 6 : void SwTOXBase::SetEntryTypeName(const OUString& sName)
532 : {
533 6 : m_aEntryTypeName = sName ;
534 6 : }
535 :
536 0 : SwTOXBase & SwTOXBase::operator = (const SwTOXBase & rSource)
537 : {
538 0 : aForm = rSource.aForm;
539 0 : aName = rSource.aName;
540 0 : aTitle = rSource.aTitle;
541 0 : m_aBookmarkName = rSource.m_aBookmarkName;
542 0 : m_aEntryTypeName = rSource.m_aEntryTypeName ;
543 0 : sMainEntryCharStyle = rSource.sMainEntryCharStyle;
544 0 : for(sal_uInt16 nLevel = 0; nLevel < MAXLEVEL; nLevel++)
545 0 : aStyleNames[nLevel] = rSource.aStyleNames[nLevel];
546 0 : sSequenceName = rSource.sSequenceName;
547 0 : eLanguage = rSource.eLanguage;
548 0 : sSortAlgorithm = rSource.sSortAlgorithm;
549 0 : aData = rSource.aData;
550 0 : nCreateType = rSource.nCreateType;
551 0 : nOLEOptions = rSource.nOLEOptions;
552 0 : eCaptionDisplay = rSource.eCaptionDisplay;
553 0 : bProtected = rSource.bProtected;
554 0 : bFromChapter = rSource.bFromChapter;
555 0 : bFromObjectNames = rSource.bFromObjectNames;
556 0 : bLevelFromChapter = rSource.bLevelFromChapter;
557 :
558 0 : if (rSource.GetAttrSet())
559 0 : SetAttrSet(*rSource.GetAttrSet());
560 :
561 0 : return *this;
562 : }
563 :
564 8816 : OUString SwFormToken::GetString() const
565 : {
566 8816 : OUString sToken;
567 :
568 8816 : switch( eTokenType )
569 : {
570 : case TOKEN_ENTRY_NO:
571 1040 : sToken = SwForm::GetFormEntryNum();
572 1040 : break;
573 : case TOKEN_ENTRY_TEXT:
574 1040 : sToken = SwForm::GetFormEntryTxt();
575 1040 : break;
576 : case TOKEN_ENTRY:
577 76 : sToken = SwForm::GetFormEntry();
578 76 : break;
579 : case TOKEN_TAB_STOP:
580 1110 : sToken = SwForm::GetFormTab();
581 1110 : break;
582 : case TOKEN_TEXT:
583 : // Return a Token only if Text is not empty!
584 268 : if( sText.isEmpty() )
585 : {
586 0 : return OUString();
587 : }
588 268 : sToken = SwForm::GetFormText();
589 268 : break;
590 : case TOKEN_PAGE_NUMS:
591 1110 : sToken = SwForm::GetFormPageNums();
592 1110 : break;
593 : case TOKEN_CHAPTER_INFO:
594 0 : sToken = SwForm::GetFormChapterMark();
595 0 : break;
596 : case TOKEN_LINK_START:
597 1908 : sToken = SwForm::GetFormLinkStt();
598 1908 : break;
599 : case TOKEN_LINK_END:
600 1908 : sToken = SwForm::GetFormLinkEnd();
601 1908 : break;
602 : case TOKEN_AUTHORITY:
603 : {
604 356 : sToken = SwForm::GetFormAuth();
605 : }
606 356 : break;
607 : case TOKEN_END:
608 0 : break;
609 : }
610 :
611 8816 : OUString sData = " " + sCharStyleName + "," + OUString::number( nPoolId ) + ",";
612 :
613 : // TabStopPosition and TabAlign or ChapterInfoFormat
614 8816 : switch (eTokenType)
615 : {
616 : case TOKEN_TAB_STOP:
617 2220 : sData += OUString::number( nTabStopPosition ) + ","
618 4440 : + OUString::number( static_cast< sal_Int32 >(eTabAlign) ) + ","
619 4440 : + OUString(cTabFillChar) + ","
620 3330 : + OUString::number( bWithTab ? 1 : 0 );
621 1110 : break;
622 : case TOKEN_CHAPTER_INFO:
623 : case TOKEN_ENTRY_NO:
624 : // add also maximum permitted level
625 2080 : sData += OUString::number( nChapterFormat ) + ","
626 3120 : + OUString::number( nOutlineLevel );
627 1040 : break;
628 : case TOKEN_TEXT:
629 : sData += OUString(TOX_STYLE_DELIMITER)
630 536 : + sText.replaceAll(OUString(TOX_STYLE_DELIMITER), OUString())
631 804 : + OUString(TOX_STYLE_DELIMITER);
632 268 : break;
633 : case TOKEN_AUTHORITY:
634 356 : if (nAuthorityField<10)
635 : {
636 176 : sData = "0" + OUString::number( nAuthorityField ) + sData;
637 : }
638 : else
639 : {
640 180 : sData = OUString::number( nAuthorityField ) + sData;
641 : }
642 : default:
643 6398 : break;
644 : }
645 :
646 8816 : return sToken.copy(0, sToken.getLength()-1) + sData + sToken.copy(sToken.getLength()-1);
647 : }
648 :
649 : // -> #i21237#
650 :
651 : /**
652 : Returns the type of a token.
653 :
654 : @param sToken the string representation of the token
655 : @param pTokenLen return parameter the length of the head of the token
656 :
657 : If pTokenLen is non-NULL the length of the token's head is
658 : written to *pTokenLen
659 :
660 : @return the type of the token
661 : */
662 8816 : static FormTokenType lcl_GetTokenType(const OUString & sToken,
663 : sal_Int32 *const pTokenLen)
664 : {
665 : static struct
666 220 : {
667 : OUString sNm;
668 : sal_uInt16 nOffset;
669 : FormTokenType eToken;
670 : } const aTokenArr[] = {
671 : { SwForm::GetFormTab(), 1, TOKEN_TAB_STOP },
672 : { SwForm::GetFormPageNums(), 1, TOKEN_PAGE_NUMS },
673 : { SwForm::GetFormLinkStt(), 1, TOKEN_LINK_START },
674 : { SwForm::GetFormLinkEnd(), 1, TOKEN_LINK_END },
675 : { SwForm::GetFormEntryNum(), 1, TOKEN_ENTRY_NO },
676 : { SwForm::GetFormEntryTxt(), 1, TOKEN_ENTRY_TEXT },
677 : { SwForm::GetFormChapterMark(), 1, TOKEN_CHAPTER_INFO },
678 : { SwForm::GetFormText(), 1, TOKEN_TEXT },
679 : { SwForm::GetFormEntry(), 1, TOKEN_ENTRY },
680 : { SwForm::GetFormAuth(), 3, TOKEN_AUTHORITY }
681 8838 : };
682 :
683 34514 : for( size_t i = 0; i<SAL_N_ELEMENTS(aTokenArr); ++i )
684 : {
685 34514 : const sal_Int32 nLen(aTokenArr[i].sNm.getLength());
686 34514 : if( sToken.startsWith( aTokenArr[i].sNm.copy(0, nLen - aTokenArr[i].nOffset) ))
687 : {
688 8816 : if (pTokenLen)
689 8816 : *pTokenLen = nLen;
690 8816 : return aTokenArr[ i ].eToken;
691 : }
692 : }
693 :
694 : SAL_WARN("sw.core", "SwFormTokensHelper: invalid token");
695 0 : return TOKEN_END;
696 : }
697 :
698 : /**
699 : Returns the string of a token.
700 :
701 : @param sPattern the whole pattern
702 : @param nStt starting position of the token
703 :
704 : @return the string representation of the token
705 : */
706 : static OUString
707 8816 : lcl_SearchNextToken(const OUString & sPattern, sal_Int32 const nStt)
708 : {
709 8816 : sal_Int32 nEnd = sPattern.indexOf( '>', nStt );
710 8816 : if (nEnd >= 0)
711 : {
712 : // apparently the TOX_STYLE_DELIMITER act as a bracketing for
713 : // TOKEN_TEXT tokens so that the user can have '>' inside the text...
714 8816 : const sal_Int32 nTextSeparatorFirst = sPattern.indexOf( TOX_STYLE_DELIMITER, nStt );
715 8816 : if ( nTextSeparatorFirst >= 0
716 536 : && nTextSeparatorFirst + 1 < sPattern.getLength()
717 9352 : && nTextSeparatorFirst < nEnd)
718 : {
719 : const sal_Int32 nTextSeparatorSecond = sPattern.indexOf( TOX_STYLE_DELIMITER,
720 268 : nTextSeparatorFirst + 1 );
721 : // Since nEnd>=0 we don't need to check if nTextSeparatorSecond<0!
722 268 : if( nEnd < nTextSeparatorSecond )
723 0 : nEnd = sPattern.indexOf( '>', nTextSeparatorSecond );
724 : // FIXME: No check to verify that nEnd is still >=0?
725 : assert(nEnd >= 0);
726 : }
727 :
728 8816 : ++nEnd;
729 :
730 8816 : return sPattern.copy( nStt, nEnd - nStt );
731 : }
732 :
733 0 : return OUString();
734 : }
735 :
736 : /**
737 : Builds a token from its string representation.
738 :
739 : @sPattern the whole pattern
740 : @nCurPatternPos starting position of the token
741 :
742 : @return the token
743 : */
744 : static boost::optional<SwFormToken>
745 8816 : lcl_BuildToken(const OUString & sPattern, sal_Int32 & nCurPatternPos)
746 : {
747 8816 : OUString sToken( lcl_SearchNextToken(sPattern, nCurPatternPos) );
748 8816 : nCurPatternPos += sToken.getLength();
749 8816 : sal_Int32 nTokenLen = 0;
750 8816 : FormTokenType const eTokenType = lcl_GetTokenType(sToken, &nTokenLen);
751 8816 : if (TOKEN_END == eTokenType) // invalid input? skip it
752 : {
753 0 : nCurPatternPos = sPattern.getLength();
754 0 : return boost::optional<SwFormToken>();
755 : }
756 :
757 : // at this point sPattern contains the
758 : // character style name, the PoolId, tab stop position, tab stop alignment, chapter info format
759 : // the form is: CharStyleName, PoolId[, TabStopPosition|ChapterInfoFormat[, TabStopAlignment[, TabFillChar]]]
760 : // in text tokens the form differs from the others: CharStyleName, PoolId[,\0xffinserted text\0xff]
761 17632 : SwFormToken eRet( eTokenType );
762 17632 : const OUString sAuthFieldEnum = sToken.copy( 2, 2 );
763 8816 : sToken = sToken.copy( nTokenLen, sToken.getLength() - nTokenLen - 1);
764 :
765 8816 : eRet.sCharStyleName = sToken.getToken( 0, ',');
766 17632 : OUString sTmp( sToken.getToken( 1, ',' ));
767 8816 : if( !sTmp.isEmpty() )
768 8816 : eRet.nPoolId = static_cast<sal_uInt16>(sTmp.toInt32());
769 :
770 8816 : switch( eTokenType )
771 : {
772 : //i53420
773 : case TOKEN_CHAPTER_INFO:
774 : //i53420
775 : case TOKEN_ENTRY_NO:
776 1040 : sTmp = sToken.getToken( 2, ',' );
777 1040 : if( !sTmp.isEmpty() )
778 1040 : eRet.nChapterFormat = static_cast<sal_uInt16>(sTmp.toInt32());
779 1040 : sTmp = sToken.getToken( 3, ',' );
780 1040 : if( !sTmp.isEmpty() )
781 1040 : eRet.nOutlineLevel = static_cast<sal_uInt16>(sTmp.toInt32()); //the maximum outline level to examine
782 1040 : break;
783 :
784 : case TOKEN_TEXT:
785 : {
786 268 : const sal_Int32 nStartText = sToken.indexOf( TOX_STYLE_DELIMITER );
787 268 : if( nStartText>=0 && nStartText+1<sToken.getLength())
788 : {
789 : const sal_Int32 nEndText = sToken.indexOf( TOX_STYLE_DELIMITER,
790 268 : nStartText + 1);
791 268 : if( nEndText>=0 )
792 : {
793 536 : eRet.sText = sToken.copy( nStartText + 1,
794 536 : nEndText - nStartText - 1);
795 : }
796 : }
797 : }
798 268 : break;
799 :
800 : case TOKEN_TAB_STOP:
801 1110 : sTmp = sToken.getToken( 2, ',' );
802 1110 : if( !sTmp.isEmpty() )
803 1110 : eRet.nTabStopPosition = sTmp.toInt32();
804 :
805 1110 : sTmp = sToken.getToken( 3, ',' );
806 1110 : if( !sTmp.isEmpty() )
807 1110 : eRet.eTabAlign = static_cast<SvxTabAdjust>(sTmp.toInt32());
808 :
809 1110 : sTmp = sToken.getToken( 4, ',' );
810 1110 : if( !sTmp.isEmpty() )
811 1110 : eRet.cTabFillChar = sTmp[0];
812 :
813 1110 : sTmp = sToken.getToken( 5, ',' );
814 1110 : if( !sTmp.isEmpty() )
815 1110 : eRet.bWithTab = 0 != sTmp.toInt32();
816 1110 : break;
817 :
818 : case TOKEN_AUTHORITY:
819 356 : eRet.nAuthorityField = static_cast<sal_uInt16>(sAuthFieldEnum.toInt32());
820 356 : break;
821 6042 : default: break;
822 : }
823 17632 : return eRet;
824 : }
825 :
826 1204 : SwFormTokensHelper::SwFormTokensHelper(const OUString & rPattern)
827 : {
828 1204 : sal_Int32 nCurPatternPos = 0;
829 :
830 11224 : while (nCurPatternPos < rPattern.getLength())
831 : {
832 : boost::optional<SwFormToken> const oToken(
833 8816 : lcl_BuildToken(rPattern, nCurPatternPos));
834 8816 : if (oToken)
835 8816 : m_Tokens.push_back(oToken.get());
836 8816 : }
837 1204 : }
838 :
839 : // <- #i21237#
840 :
841 4566 : void SwForm::SetPattern(sal_uInt16 nLevel, const SwFormTokens& rTokens)
842 : {
843 : OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
844 4566 : aPattern[nLevel] = rTokens;
845 4566 : }
846 :
847 1204 : void SwForm::SetPattern(sal_uInt16 nLevel, const OUString & rStr)
848 : {
849 : OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
850 :
851 1204 : SwFormTokensHelper aHelper(rStr);
852 1204 : aPattern[nLevel] = aHelper.GetTokens();
853 1204 : }
854 :
855 1354 : const SwFormTokens& SwForm::GetPattern(sal_uInt16 nLevel) const
856 : {
857 : OSL_ENSURE(nLevel < GetFormMax(), "Index >= FORM_MAX");
858 1354 : return aPattern[nLevel];
859 : }
860 :
861 0 : sal_uInt16 SwTOXTypes::GetPos(const SwTOXType* pTOXType) const
862 : {
863 0 : const_iterator it = std::find(begin(), end(), pTOXType);
864 0 : return it == end() ? USHRT_MAX : it - begin();
865 : }
866 :
867 10090 : SwTOXTypes::~SwTOXTypes()
868 : {
869 5045 : for(const_iterator it = begin(); it != end(); ++it)
870 0 : delete *it;
871 5315 : }
872 :
873 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|