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 <com/sun/star/text/ReferenceFieldPart.hpp>
21 : #include <com/sun/star/text/ReferenceFieldSource.hpp>
22 : #include <unotools/localedatawrapper.hxx>
23 : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
24 : #include <comphelper/processfactory.hxx>
25 : #include <comphelper/string.hxx>
26 : #include <editeng/unolingu.hxx>
27 : #include <doc.hxx>
28 : #include <pam.hxx>
29 : #include <cntfrm.hxx>
30 : #include <pagefrm.hxx>
31 : #include <docary.hxx>
32 : #include <fmtfld.hxx>
33 : #include <txtfld.hxx>
34 : #include <txtftn.hxx>
35 : #include <fmtrfmrk.hxx>
36 : #include <txtrfmrk.hxx>
37 : #include <fmtftn.hxx>
38 : #include <ndtxt.hxx>
39 : #include <chpfld.hxx>
40 : #include <reffld.hxx>
41 : #include <expfld.hxx>
42 : #include <txtfrm.hxx>
43 : #include <flyfrm.hxx>
44 : #include <pagedesc.hxx>
45 : #include <IMark.hxx>
46 : #include <crossrefbookmark.hxx>
47 : #include <ftnidx.hxx>
48 : #include <viewsh.hxx>
49 : #include <unofldmid.h>
50 : #include <SwStyleNameMapper.hxx>
51 : #include <shellres.hxx>
52 : #include <poolfmt.hxx>
53 : #include <poolfmt.hrc>
54 : #include <comcore.hrc>
55 : #include <numrule.hxx>
56 : #include <SwNodeNum.hxx>
57 : #include <switerator.hxx>
58 :
59 : #include <set>
60 : #include <map>
61 : #include <algorithm> // min, max
62 :
63 : #include <sfx2/childwin.hxx>
64 :
65 : using namespace ::com::sun::star;
66 : using namespace ::com::sun::star::text;
67 : using namespace ::com::sun::star::lang;
68 :
69 : extern void InsertSort( std::vector<sal_uInt16>& rArr, sal_uInt16 nIdx, sal_uInt16* pInsPos = 0 );
70 :
71 0 : static void lcl_GetLayTree( const SwFrm* pFrm, std::vector<const SwFrm*>& rArr )
72 : {
73 0 : while( pFrm )
74 : {
75 0 : if( pFrm->IsBodyFrm() ) // unspectacular
76 0 : pFrm = pFrm->GetUpper();
77 : else
78 : {
79 0 : rArr.push_back( pFrm );
80 :
81 : // this is the last page
82 0 : if( pFrm->IsPageFrm() )
83 0 : break;
84 :
85 0 : if( pFrm->IsFlyFrm() )
86 0 : pFrm = ((SwFlyFrm*)pFrm)->GetAnchorFrm();
87 : else
88 0 : pFrm = pFrm->GetUpper();
89 : }
90 : }
91 0 : }
92 :
93 0 : bool IsFrameBehind( const SwTxtNode& rMyNd, sal_uInt16 nMySttPos,
94 : const SwTxtNode& rBehindNd, sal_uInt16 nSttPos )
95 : {
96 0 : const SwTxtFrm *pMyFrm = (SwTxtFrm*)rMyNd.getLayoutFrm( rMyNd.GetDoc()->GetCurrentLayout(), 0,0,sal_False),
97 0 : *pFrm = (SwTxtFrm*)rBehindNd.getLayoutFrm( rBehindNd.GetDoc()->GetCurrentLayout(), 0,0,sal_False);
98 :
99 0 : while( pFrm && !pFrm->IsInside( nSttPos ) )
100 0 : pFrm = (SwTxtFrm*)pFrm->GetFollow();
101 0 : while( pMyFrm && !pMyFrm->IsInside( nMySttPos ) )
102 0 : pMyFrm = (SwTxtFrm*)pMyFrm->GetFollow();
103 :
104 0 : if( !pFrm || !pMyFrm || pFrm == pMyFrm )
105 0 : return false;
106 :
107 0 : std::vector<const SwFrm*> aRefArr, aArr;
108 0 : ::lcl_GetLayTree( pFrm, aRefArr );
109 0 : ::lcl_GetLayTree( pMyFrm, aArr );
110 :
111 0 : sal_uInt16 nRefCnt = aRefArr.size() - 1, nCnt = aArr.size() - 1;
112 0 : sal_Bool bVert = sal_False;
113 0 : sal_Bool bR2L = sal_False;
114 :
115 : // Loop as long as a frame does not equal?
116 0 : while( nRefCnt && nCnt && aRefArr[ nRefCnt ] == aArr[ nCnt ] )
117 : {
118 0 : const SwFrm* pTmpFrm = aArr[ nCnt ];
119 0 : bVert = pTmpFrm->IsVertical();
120 0 : bR2L = pTmpFrm->IsRightToLeft();
121 0 : --nCnt, --nRefCnt;
122 : }
123 :
124 : // If a counter overflows?
125 0 : if( aRefArr[ nRefCnt ] == aArr[ nCnt ] )
126 : {
127 0 : if( nCnt )
128 0 : --nCnt;
129 : else
130 0 : --nRefCnt;
131 : }
132 :
133 0 : const SwFrm* pRefFrm = aRefArr[ nRefCnt ];
134 0 : const SwFrm* pFldFrm = aArr[ nCnt ];
135 :
136 : // different frames, check their Y-/X-position
137 0 : bool bRefIsLower = false;
138 0 : if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() ||
139 0 : ( FRM_COLUMN | FRM_CELL ) & pRefFrm->GetType() )
140 : {
141 0 : if( pFldFrm->GetType() == pRefFrm->GetType() )
142 : {
143 : // here, the X-pos is more important
144 0 : if( bVert )
145 : {
146 0 : if( bR2L )
147 0 : bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
148 0 : ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
149 0 : pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
150 : else
151 0 : bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
152 0 : ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
153 0 : pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
154 : }
155 0 : else if( bR2L )
156 0 : bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
157 0 : ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
158 0 : pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
159 : else
160 0 : bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
161 0 : ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
162 0 : pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
163 0 : pRefFrm = 0;
164 : }
165 0 : else if( ( FRM_COLUMN | FRM_CELL ) & pFldFrm->GetType() )
166 0 : pFldFrm = aArr[ nCnt - 1 ];
167 : else
168 0 : pRefFrm = aRefArr[ nRefCnt - 1 ];
169 : }
170 :
171 0 : if( pRefFrm ) // misuse as flag
172 : {
173 0 : if( bVert )
174 : {
175 0 : if( bR2L )
176 0 : bRefIsLower = pRefFrm->Frm().Left() < pFldFrm->Frm().Left() ||
177 0 : ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
178 0 : pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
179 : else
180 0 : bRefIsLower = pRefFrm->Frm().Left() > pFldFrm->Frm().Left() ||
181 0 : ( pRefFrm->Frm().Left() == pFldFrm->Frm().Left() &&
182 0 : pRefFrm->Frm().Top() < pFldFrm->Frm().Top() );
183 : }
184 0 : else if( bR2L )
185 0 : bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
186 0 : ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
187 0 : pRefFrm->Frm().Left() > pFldFrm->Frm().Left() );
188 : else
189 0 : bRefIsLower = pRefFrm->Frm().Top() < pFldFrm->Frm().Top() ||
190 0 : ( pRefFrm->Frm().Top() == pFldFrm->Frm().Top() &&
191 0 : pRefFrm->Frm().Left() < pFldFrm->Frm().Left() );
192 : }
193 0 : return bRefIsLower;
194 : }
195 :
196 : /// get references
197 38 : SwGetRefField::SwGetRefField( SwGetRefFieldType* pFldType,
198 : const String& rSetRef, sal_uInt16 nSubTyp,
199 : sal_uInt16 nSeqenceNo, sal_uLong nFmt )
200 : : SwField( pFldType, nFmt ),
201 : sSetRefName( rSetRef ),
202 : nSubType( nSubTyp ),
203 38 : nSeqNo( nSeqenceNo )
204 : {
205 38 : }
206 :
207 76 : SwGetRefField::~SwGetRefField()
208 : {
209 76 : }
210 :
211 0 : String SwGetRefField::GetDescription() const
212 : {
213 0 : return SW_RES(STR_REFERENCE);
214 : }
215 :
216 0 : sal_uInt16 SwGetRefField::GetSubType() const
217 : {
218 0 : return nSubType;
219 : }
220 :
221 0 : void SwGetRefField::SetSubType( sal_uInt16 n )
222 : {
223 0 : nSubType = n;
224 0 : }
225 :
226 : // #i81002#
227 0 : bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const
228 : {
229 0 : return GetSubType() == REF_BOOKMARK &&
230 0 : ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName);
231 : }
232 :
233 0 : bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
234 : {
235 0 : return GetSubType() == REF_BOOKMARK &&
236 0 : ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName);
237 : }
238 :
239 0 : const SwTxtNode* SwGetRefField::GetReferencedTxtNode() const
240 : {
241 0 : SwDoc* pDoc = dynamic_cast<SwGetRefFieldType*>(GetTyp())->GetDoc();
242 0 : sal_uInt16 nDummy = USHRT_MAX;
243 0 : return SwGetRefFieldType::FindAnchor( pDoc, sSetRefName, nSubType, nSeqNo, &nDummy );
244 : }
245 :
246 : // #i85090#
247 0 : String SwGetRefField::GetExpandedTxtOfReferencedTxtNode() const
248 : {
249 0 : const SwTxtNode* pReferencedTxtNode( GetReferencedTxtNode() );
250 : return pReferencedTxtNode
251 : ? pReferencedTxtNode->GetExpandTxt( 0, STRING_LEN, true, true )
252 0 : : aEmptyStr;
253 : }
254 :
255 168 : String SwGetRefField::Expand() const
256 : {
257 168 : return sTxt;
258 : }
259 :
260 0 : String SwGetRefField::GetFieldName() const
261 : {
262 0 : if ( GetTyp()->GetName().getLength() > 0 || sSetRefName.getLength() > 0 )
263 : {
264 0 : String aStr(GetTyp()->GetName());
265 0 : aStr += ' ';
266 0 : aStr += sSetRefName;
267 0 : return aStr;
268 : }
269 : else
270 0 : return Expand();
271 : }
272 :
273 : // #i81002# - parameter <pFldTxtAttr> added
274 124 : void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
275 : {
276 124 : sTxt.Erase();
277 :
278 124 : SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
279 : // finding the reference target (the number)
280 : sal_uInt16 nNumStart, nNumEnd;
281 : SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor(
282 : pDoc, sSetRefName, nSubType, nSeqNo, &nNumStart, &nNumEnd
283 124 : );
284 : // not found?
285 124 : if ( !pTxtNd )
286 : {
287 0 : sTxt = ViewShell::GetShellRes()->aGetRefFld_RefItemNotFound;
288 0 : return ;
289 : }
290 : // where is the category name (e.g. "Illustration")?
291 124 : OUString const Text = pTxtNd->GetTxt();
292 124 : unsigned const nCatStart = Text.indexOf(sSetRefName);
293 124 : unsigned const nCatEnd = nCatStart == unsigned(-1) ?
294 124 : unsigned(-1) : nCatStart + sSetRefName.getLength();
295 124 : bool const bHasCat = nCatStart != unsigned(-1);
296 :
297 : // length of the referenced text
298 124 : unsigned const nLen = Text.getLength();
299 :
300 : // which format?
301 124 : switch( GetFormat() )
302 : {
303 : case REF_CONTENT:
304 : case REF_ONLYNUMBER:
305 : case REF_ONLYCAPTION:
306 : case REF_ONLYSEQNO:
307 : {
308 : // needed part of Text
309 : unsigned nStart, nEnd;
310 :
311 4 : switch( nSubType )
312 : {
313 : case REF_SEQUENCEFLD:
314 :
315 0 : switch( GetFormat() )
316 : {
317 : // "Category and Number"
318 : case REF_ONLYNUMBER:
319 0 : if (bHasCat) {
320 0 : nStart = std::min<unsigned>(nNumStart, nCatStart);
321 0 : nEnd = std::max<unsigned>(nNumEnd, nCatEnd);
322 : } else {
323 0 : nStart = nNumStart;
324 0 : nEnd = nNumEnd;
325 : }
326 0 : break;
327 :
328 : // "Caption Text"
329 : case REF_ONLYCAPTION: {
330 : // next alphanumeric character after category+number
331 0 : if (const SwTxtAttr* const pTxtAttr =
332 0 : pTxtNd->GetTxtAttrForCharAt(nNumStart, RES_TXTATR_FIELD)
333 : ) {
334 : // start searching from nFrom
335 : unsigned const nFrom = bHasCat ?
336 0 : std::max<unsigned>(nNumStart + 1, nCatEnd) : nNumStart + 1;
337 : nStart = SwGetExpField::GetReferenceTextPos(
338 0 : pTxtAttr->GetFld(), *pDoc, nFrom
339 0 : );
340 : } else {
341 : nStart = bHasCat ?
342 0 : std::max<unsigned>(nNumEnd, nCatEnd) : nNumEnd;
343 : }
344 0 : nEnd = nLen;
345 0 : break;
346 : }
347 :
348 : // "Numbering"
349 : case REF_ONLYSEQNO:
350 0 : nStart = nNumStart;
351 0 : nEnd = std::min<unsigned>(nStart + 1, nLen);
352 0 : break;
353 :
354 : // "Reference" (whole Text)
355 : default:
356 0 : nStart = 0;
357 0 : nEnd = nLen;
358 0 : break;
359 : }
360 0 : break;
361 :
362 : case REF_BOOKMARK:
363 4 : nStart = nNumStart;
364 : // Text steht ueber verschiedene Nodes verteilt.
365 : // Gesamten Text oder nur bis zum Ende vom Node?
366 4 : nEnd = nNumEnd == USHRT_MAX ? nLen : nNumEnd;
367 4 : break;
368 :
369 : case REF_OUTLINE:
370 0 : nStart = nNumStart;
371 0 : nEnd = nNumEnd;
372 0 : break;
373 :
374 : case REF_FOOTNOTE:
375 : case REF_ENDNOTE:
376 : // die Nummer oder den NumString besorgen
377 0 : for( unsigned i = 0; i < pDoc->GetFtnIdxs().size(); ++i )
378 : {
379 0 : SwTxtFtn* const pFtnIdx = pDoc->GetFtnIdxs()[i];
380 0 : if( nSeqNo == pFtnIdx->GetSeqRefNo() )
381 : {
382 0 : sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
383 0 : break;
384 : }
385 : }
386 0 : return;
387 :
388 : default:
389 0 : nStart = nNumStart;
390 0 : nEnd = nNumEnd;
391 0 : break;
392 : }
393 :
394 4 : if( nStart != nEnd ) // ein Bereich?
395 : {
396 4 : sTxt = pTxtNd->GetExpandTxt( nStart, nEnd - nStart );
397 :
398 : // alle Sonderzeichen entfernen (durch Blanks ersetzen):
399 4 : if( sTxt.Len() )
400 : {
401 4 : sTxt = comphelper::string::remove(sTxt, 0xad);
402 48 : for( sal_Unicode* p = sTxt.GetBufferAccess(); *p; ++p )
403 : {
404 44 : if( *p < 0x20 )
405 0 : *p = 0x20;
406 44 : else if(*p == 0x2011)
407 0 : *p = '-';
408 : }
409 : }
410 : }
411 : }
412 4 : break;
413 :
414 : case REF_PAGE:
415 : case REF_PAGE_PGDESC:
416 : {
417 0 : const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0,0,sal_False),
418 0 : *pSave = pFrm;
419 0 : while( pFrm && !pFrm->IsInside( nNumStart ) )
420 0 : pFrm = (SwTxtFrm*)pFrm->GetFollow();
421 :
422 0 : if( pFrm || 0 != ( pFrm = pSave ))
423 : {
424 0 : sal_uInt16 nPageNo = pFrm->GetVirtPageNum();
425 : const SwPageFrm *pPage;
426 0 : if( REF_PAGE_PGDESC == GetFormat() &&
427 0 : 0 != ( pPage = pFrm->FindPageFrm() ) &&
428 0 : pPage->GetPageDesc() )
429 0 : sTxt = pPage->GetPageDesc()->GetNumType().GetNumStr( nPageNo );
430 : else
431 0 : sTxt = OUString::number(nPageNo);
432 : }
433 : }
434 0 : break;
435 :
436 : case REF_CHAPTER:
437 : {
438 : // ein bischen trickreich: suche irgend einen Frame
439 0 : const SwFrm* pFrm = pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout() );
440 0 : if( pFrm )
441 : {
442 0 : SwChapterFieldType aFldTyp;
443 0 : SwChapterField aFld( &aFldTyp, 0 );
444 0 : aFld.SetLevel( MAXLEVEL - 1 );
445 0 : aFld.ChangeExpansion( pFrm, pTxtNd, sal_True );
446 0 : sTxt = aFld.GetNumber();
447 : }
448 : }
449 0 : break;
450 :
451 : case REF_UPDOWN:
452 : {
453 : // #i81002#
454 : // simplified: use parameter <pFldTxtAttr>
455 0 : if( !pFldTxtAttr || !pFldTxtAttr->GetpTxtNode() )
456 0 : break;
457 :
458 0 : LanguageTag aLanguageTag( GetLanguage());
459 0 : LocaleDataWrapper aLocaleData( aLanguageTag );
460 :
461 : // erstmal ein "Kurz" - Test - falls beide im selben
462 : // Node stehen!
463 0 : if( pFldTxtAttr->GetpTxtNode() == pTxtNd )
464 : {
465 0 : sTxt = nNumStart < *pFldTxtAttr->GetStart()
466 : ? aLocaleData.getAboveWord()
467 0 : : aLocaleData.getBelowWord();
468 0 : break;
469 : }
470 :
471 0 : sTxt = ::IsFrameBehind( *pFldTxtAttr->GetpTxtNode(), *pFldTxtAttr->GetStart(),
472 0 : *pTxtNd, nNumStart )
473 : ? aLocaleData.getAboveWord()
474 0 : : aLocaleData.getBelowWord();
475 : }
476 0 : break;
477 : // #i81002#
478 : case REF_NUMBER:
479 : case REF_NUMBER_NO_CONTEXT:
480 : case REF_NUMBER_FULL_CONTEXT:
481 : {
482 120 : if ( pFldTxtAttr && pFldTxtAttr->GetpTxtNode() )
483 : {
484 120 : sTxt = MakeRefNumStr( pFldTxtAttr->GetTxtNode(), *pTxtNd, GetFormat() );
485 : }
486 : }
487 120 : break;
488 : default:
489 : OSL_FAIL("<SwGetRefField::UpdateField(..)> - unknown format type");
490 124 : }
491 : }
492 :
493 : // #i81002#
494 120 : String SwGetRefField::MakeRefNumStr( const SwTxtNode& rTxtNodeOfField,
495 : const SwTxtNode& rTxtNodeOfReferencedItem,
496 : const sal_uInt32 nRefNumFormat ) const
497 : {
498 240 : if ( rTxtNodeOfReferencedItem.HasNumber() &&
499 120 : rTxtNodeOfReferencedItem.IsCountedInList() )
500 : {
501 : OSL_ENSURE( rTxtNodeOfReferencedItem.GetNum(),
502 : "<SwGetRefField::MakeRefNumStr(..)> - referenced paragraph has number, but no <SwNodeNum> instance --> please inform OD!" );
503 :
504 : // Determine, up to which level the superior list labels have to be
505 : // included - default is to include all superior list labels.
506 120 : sal_uInt8 nRestrictInclToThisLevel( 0 );
507 : // Determine for format REF_NUMBER the level, up to which the superior
508 : // list labels have to be restricted, if the text node of the reference
509 : // field and the text node of the referenced item are in the same
510 : // document context.
511 171 : if ( nRefNumFormat == REF_NUMBER &&
512 51 : rTxtNodeOfField.FindFlyStartNode()
513 102 : == rTxtNodeOfReferencedItem.FindFlyStartNode() &&
514 51 : rTxtNodeOfField.FindFootnoteStartNode()
515 102 : == rTxtNodeOfReferencedItem.FindFootnoteStartNode() &&
516 51 : rTxtNodeOfField.FindHeaderStartNode()
517 222 : == rTxtNodeOfReferencedItem.FindHeaderStartNode() &&
518 51 : rTxtNodeOfField.FindFooterStartNode()
519 51 : == rTxtNodeOfReferencedItem.FindFooterStartNode() )
520 : {
521 51 : const SwNodeNum* pNodeNumForTxtNodeOfField( 0 );
522 75 : if ( rTxtNodeOfField.HasNumber() &&
523 24 : rTxtNodeOfField.GetNumRule() == rTxtNodeOfReferencedItem.GetNumRule() )
524 : {
525 24 : pNodeNumForTxtNodeOfField = rTxtNodeOfField.GetNum();
526 : }
527 : else
528 : {
529 : pNodeNumForTxtNodeOfField =
530 27 : rTxtNodeOfReferencedItem.GetNum()->GetPrecedingNodeNumOf( rTxtNodeOfField );
531 : }
532 51 : if ( pNodeNumForTxtNodeOfField )
533 : {
534 51 : const SwNumberTree::tNumberVector rFieldNumVec = pNodeNumForTxtNodeOfField->GetNumberVector();
535 102 : const SwNumberTree::tNumberVector rRefItemNumVec = rTxtNodeOfReferencedItem.GetNum()->GetNumberVector();
536 51 : sal_uInt8 nLevel( 0 );
537 147 : while ( nLevel < rFieldNumVec.size() && nLevel < rRefItemNumVec.size() )
538 : {
539 85 : if ( rRefItemNumVec[nLevel] == rFieldNumVec[nLevel] )
540 : {
541 45 : nRestrictInclToThisLevel = nLevel + 1;
542 : }
543 : else
544 : {
545 40 : break;
546 : }
547 45 : ++nLevel;
548 51 : }
549 : }
550 : }
551 :
552 : // Determine, if superior list labels have to be included
553 : const bool bInclSuperiorNumLabels(
554 217 : ( nRestrictInclToThisLevel < rTxtNodeOfReferencedItem.GetActualListLevel() &&
555 189 : ( nRefNumFormat == REF_NUMBER || nRefNumFormat == REF_NUMBER_FULL_CONTEXT ) ) );
556 :
557 : OSL_ENSURE( rTxtNodeOfReferencedItem.GetNumRule(),
558 : "<SwGetRefField::MakeRefNumStr(..)> - referenced numbered paragraph has no numbering rule set --> please inform OD!" );
559 : return rTxtNodeOfReferencedItem.GetNumRule()->MakeRefNumString(
560 120 : *(rTxtNodeOfReferencedItem.GetNum()),
561 : bInclSuperiorNumLabels,
562 240 : nRestrictInclToThisLevel );
563 : }
564 :
565 0 : return String();
566 : }
567 :
568 31 : SwField* SwGetRefField::Copy() const
569 : {
570 31 : SwGetRefField* pFld = new SwGetRefField( (SwGetRefFieldType*)GetTyp(),
571 : sSetRefName, nSubType,
572 31 : nSeqNo, GetFormat() );
573 31 : pFld->sTxt = sTxt;
574 31 : return pFld;
575 : }
576 :
577 : /// get reference name
578 0 : const OUString& SwGetRefField::GetPar1() const
579 : {
580 0 : return sSetRefName;
581 : }
582 :
583 : /// set reference name
584 0 : void SwGetRefField::SetPar1( const OUString& rName )
585 : {
586 0 : sSetRefName = rName;
587 0 : }
588 :
589 0 : OUString SwGetRefField::GetPar2() const
590 : {
591 0 : return Expand();
592 : }
593 :
594 18 : bool SwGetRefField::QueryValue( uno::Any& rAny, sal_uInt16 nWhichId ) const
595 : {
596 18 : switch( nWhichId )
597 : {
598 : case FIELD_PROP_USHORT1:
599 : {
600 18 : sal_Int16 nPart = 0;
601 18 : switch(GetFormat())
602 : {
603 0 : case REF_PAGE : nPart = ReferenceFieldPart::PAGE ; break;
604 0 : case REF_CHAPTER : nPart = ReferenceFieldPart::CHAPTER ; break;
605 0 : case REF_CONTENT : nPart = ReferenceFieldPart::TEXT ; break;
606 0 : case REF_UPDOWN : nPart = ReferenceFieldPart::UP_DOWN ; break;
607 0 : case REF_PAGE_PGDESC: nPart = ReferenceFieldPart::PAGE_DESC ; break;
608 0 : case REF_ONLYNUMBER : nPart = ReferenceFieldPart::CATEGORY_AND_NUMBER ; break;
609 0 : case REF_ONLYCAPTION: nPart = ReferenceFieldPart::ONLY_CAPTION ; break;
610 0 : case REF_ONLYSEQNO : nPart = ReferenceFieldPart::ONLY_SEQUENCE_NUMBER; break;
611 : // #i81002#
612 12 : case REF_NUMBER: nPart = ReferenceFieldPart::NUMBER; break;
613 6 : case REF_NUMBER_NO_CONTEXT: nPart = ReferenceFieldPart::NUMBER_NO_CONTEXT; break;
614 0 : case REF_NUMBER_FULL_CONTEXT: nPart = ReferenceFieldPart::NUMBER_FULL_CONTEXT; break;
615 : }
616 18 : rAny <<= nPart;
617 : }
618 18 : break;
619 : case FIELD_PROP_USHORT2:
620 : {
621 0 : sal_Int16 nSource = 0;
622 0 : switch(nSubType)
623 : {
624 0 : case REF_SETREFATTR : nSource = ReferenceFieldSource::REFERENCE_MARK; break;
625 0 : case REF_SEQUENCEFLD: nSource = ReferenceFieldSource::SEQUENCE_FIELD; break;
626 0 : case REF_BOOKMARK : nSource = ReferenceFieldSource::BOOKMARK; break;
627 0 : case REF_OUTLINE : OSL_FAIL("not implemented"); break;
628 0 : case REF_FOOTNOTE : nSource = ReferenceFieldSource::FOOTNOTE; break;
629 0 : case REF_ENDNOTE : nSource = ReferenceFieldSource::ENDNOTE; break;
630 : }
631 0 : rAny <<= nSource;
632 : }
633 0 : break;
634 : case FIELD_PROP_PAR1:
635 : {
636 0 : String sTmp(GetPar1());
637 0 : if(REF_SEQUENCEFLD == nSubType)
638 : {
639 0 : sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sTmp, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
640 0 : switch( nPoolId )
641 : {
642 : case RES_POOLCOLL_LABEL_ABB:
643 : case RES_POOLCOLL_LABEL_TABLE:
644 : case RES_POOLCOLL_LABEL_FRAME:
645 : case RES_POOLCOLL_LABEL_DRAWING:
646 0 : SwStyleNameMapper::FillProgName(nPoolId, sTmp) ;
647 0 : break;
648 : }
649 : }
650 0 : rAny <<= OUString(sTmp);
651 : }
652 0 : break;
653 : case FIELD_PROP_PAR3:
654 0 : rAny <<= OUString(Expand());
655 0 : break;
656 : case FIELD_PROP_SHORT1:
657 0 : rAny <<= (sal_Int16)nSeqNo;
658 0 : break;
659 : default:
660 : OSL_FAIL("illegal property");
661 : }
662 18 : return true;
663 : }
664 :
665 39 : bool SwGetRefField::PutValue( const uno::Any& rAny, sal_uInt16 nWhichId )
666 : {
667 39 : String sTmp;
668 39 : switch( nWhichId )
669 : {
670 : case FIELD_PROP_USHORT1:
671 : {
672 25 : sal_Int16 nPart = 0;
673 25 : rAny >>= nPart;
674 25 : switch(nPart)
675 : {
676 0 : case ReferenceFieldPart::PAGE: nPart = REF_PAGE; break;
677 0 : case ReferenceFieldPart::CHAPTER: nPart = REF_CHAPTER; break;
678 1 : case ReferenceFieldPart::TEXT: nPart = REF_CONTENT; break;
679 0 : case ReferenceFieldPart::UP_DOWN: nPart = REF_UPDOWN; break;
680 0 : case ReferenceFieldPart::PAGE_DESC: nPart = REF_PAGE_PGDESC; break;
681 0 : case ReferenceFieldPart::CATEGORY_AND_NUMBER: nPart = REF_ONLYNUMBER; break;
682 0 : case ReferenceFieldPart::ONLY_CAPTION: nPart = REF_ONLYCAPTION; break;
683 0 : case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER : nPart = REF_ONLYSEQNO; break;
684 : // #i81002#
685 12 : case ReferenceFieldPart::NUMBER: nPart = REF_NUMBER; break;
686 6 : case ReferenceFieldPart::NUMBER_NO_CONTEXT: nPart = REF_NUMBER_NO_CONTEXT; break;
687 6 : case ReferenceFieldPart::NUMBER_FULL_CONTEXT: nPart = REF_NUMBER_FULL_CONTEXT; break;
688 0 : default: return false;
689 : }
690 25 : SetFormat(nPart);
691 : }
692 25 : break;
693 : case FIELD_PROP_USHORT2:
694 : {
695 7 : sal_Int16 nSource = 0;
696 7 : rAny >>= nSource;
697 7 : switch(nSource)
698 : {
699 0 : case ReferenceFieldSource::REFERENCE_MARK : nSubType = REF_SETREFATTR ; break;
700 : case ReferenceFieldSource::SEQUENCE_FIELD :
701 : {
702 0 : if(REF_SEQUENCEFLD == nSubType)
703 0 : break;
704 0 : nSubType = REF_SEQUENCEFLD;
705 0 : ConvertProgrammaticToUIName();
706 : }
707 0 : break;
708 7 : case ReferenceFieldSource::BOOKMARK : nSubType = REF_BOOKMARK ; break;
709 0 : case ReferenceFieldSource::FOOTNOTE : nSubType = REF_FOOTNOTE ; break;
710 0 : case ReferenceFieldSource::ENDNOTE : nSubType = REF_ENDNOTE ; break;
711 : }
712 : }
713 7 : break;
714 : case FIELD_PROP_PAR1:
715 : {
716 0 : OUString sTmpStr;
717 0 : rAny >>= sTmpStr;
718 0 : SetPar1(sTmpStr);
719 0 : ConvertProgrammaticToUIName();
720 : }
721 0 : break;
722 : case FIELD_PROP_PAR3:
723 0 : SetExpand( ::GetString( rAny, sTmp ));
724 0 : break;
725 : case FIELD_PROP_SHORT1:
726 : {
727 7 : sal_Int16 nSetSeq = 0;
728 7 : rAny >>= nSetSeq;
729 7 : if(nSetSeq >= 0)
730 7 : nSeqNo = nSetSeq;
731 : }
732 7 : break;
733 : default:
734 : OSL_FAIL("illegal property");
735 : }
736 39 : return true;
737 : }
738 :
739 0 : void SwGetRefField::ConvertProgrammaticToUIName()
740 : {
741 0 : if(GetTyp() && REF_SEQUENCEFLD == nSubType)
742 : {
743 0 : SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
744 0 : const String& rPar1 = GetPar1();
745 : // don't convert when the name points to an existing field type
746 0 : if(!pDoc->GetFldType(RES_SETEXPFLD, rPar1, false))
747 : {
748 0 : sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromProgName( rPar1, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL );
749 0 : sal_uInt16 nResId = USHRT_MAX;
750 0 : switch( nPoolId )
751 : {
752 : case RES_POOLCOLL_LABEL_ABB:
753 0 : nResId = STR_POOLCOLL_LABEL_ABB;
754 0 : break;
755 : case RES_POOLCOLL_LABEL_TABLE:
756 0 : nResId = STR_POOLCOLL_LABEL_TABLE;
757 0 : break;
758 : case RES_POOLCOLL_LABEL_FRAME:
759 0 : nResId = STR_POOLCOLL_LABEL_FRAME;
760 0 : break;
761 : case RES_POOLCOLL_LABEL_DRAWING:
762 0 : nResId = STR_POOLCOLL_LABEL_DRAWING;
763 0 : break;
764 : }
765 0 : if( nResId != USHRT_MAX )
766 0 : SetPar1(SW_RESSTR( nResId ));
767 0 : }
768 : }
769 0 : }
770 :
771 898 : SwGetRefFieldType::SwGetRefFieldType( SwDoc* pDc )
772 898 : : SwFieldType( RES_GETREFFLD ), pDoc( pDc )
773 898 : {}
774 :
775 0 : SwFieldType* SwGetRefFieldType::Copy() const
776 : {
777 0 : return new SwGetRefFieldType( pDoc );
778 : }
779 :
780 72 : void SwGetRefFieldType::Modify( const SfxPoolItem* pOld, const SfxPoolItem* pNew )
781 : {
782 : // update to all GetReference fields
783 72 : if( !pNew && !pOld )
784 : {
785 72 : SwIterator<SwFmtFld,SwFieldType> aIter( *this );
786 196 : for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
787 : {
788 : // update only the GetRef fields
789 : //JP 3.4.2001: Task 71231 - we need the correct language
790 124 : SwGetRefField* pGRef = (SwGetRefField*)pFld->GetFld();
791 : const SwTxtFld* pTFld;
792 250 : if( !pGRef->GetLanguage() &&
793 124 : 0 != ( pTFld = pFld->GetTxtFld()) &&
794 0 : pTFld->GetpTxtNode() )
795 : {
796 : pGRef->SetLanguage( pTFld->GetpTxtNode()->GetLang(
797 0 : *pTFld->GetStart() ) );
798 : }
799 :
800 : // #i81002#
801 124 : pGRef->UpdateField( pFld->GetTxtFld() );
802 72 : }
803 : }
804 : // forward to text fields, they "expand" the text
805 72 : NotifyClients( pOld, pNew );
806 72 : }
807 :
808 124 : SwTxtNode* SwGetRefFieldType::FindAnchor( SwDoc* pDoc, const String& rRefMark,
809 : sal_uInt16 nSubType, sal_uInt16 nSeqNo,
810 : sal_uInt16* pStt, sal_uInt16* pEnd )
811 : {
812 : OSL_ENSURE( pStt, "Why did noone check the StartPos?" );
813 :
814 124 : SwTxtNode* pTxtNd = 0;
815 124 : switch( nSubType )
816 : {
817 : case REF_SETREFATTR:
818 : {
819 0 : const SwFmtRefMark *pRef = pDoc->GetRefMark( rRefMark );
820 0 : if( pRef && pRef->GetTxtRefMark() )
821 : {
822 0 : pTxtNd = (SwTxtNode*)&pRef->GetTxtRefMark()->GetTxtNode();
823 0 : *pStt = *pRef->GetTxtRefMark()->GetStart();
824 0 : if( pEnd )
825 0 : *pEnd = *pRef->GetTxtRefMark()->GetAnyEnd();
826 : }
827 : }
828 0 : break;
829 :
830 : case REF_SEQUENCEFLD:
831 : {
832 0 : SwFieldType* pFldType = pDoc->GetFldType( RES_SETEXPFLD, rRefMark, false );
833 0 : if( pFldType && pFldType->GetDepends() &&
834 0 : nsSwGetSetExpType::GSE_SEQ & ((SwSetExpFieldType*)pFldType)->GetType() )
835 : {
836 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pFldType );
837 0 : for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
838 : {
839 0 : if( pFld->GetTxtFld() && nSeqNo ==
840 0 : ((SwSetExpField*)pFld->GetFld())->GetSeqNumber() )
841 : {
842 0 : SwTxtFld* pTxtFld = pFld->GetTxtFld();
843 0 : pTxtNd = (SwTxtNode*)pTxtFld->GetpTxtNode();
844 0 : *pStt = *pTxtFld->GetStart();
845 0 : if( pEnd )
846 0 : *pEnd = (*pStt) + 1;
847 0 : break;
848 : }
849 0 : }
850 : }
851 : }
852 0 : break;
853 :
854 : case REF_BOOKMARK:
855 : {
856 124 : IDocumentMarkAccess::const_iterator_t ppMark = pDoc->getIDocumentMarkAccess()->findMark(rRefMark);
857 124 : if(ppMark != pDoc->getIDocumentMarkAccess()->getMarksEnd())
858 : {
859 124 : const ::sw::mark::IMark* pBkmk = ppMark->get();
860 124 : const SwPosition* pPos = &pBkmk->GetMarkStart();
861 :
862 124 : pTxtNd = pPos->nNode.GetNode().GetTxtNode();
863 124 : *pStt = pPos->nContent.GetIndex();
864 124 : if(pEnd)
865 : {
866 124 : if(!pBkmk->IsExpanded())
867 : {
868 124 : *pEnd = *pStt;
869 : // #i81002#
870 124 : if(dynamic_cast< ::sw::mark::CrossRefBookmark const *>(pBkmk))
871 : {
872 : OSL_ENSURE( pTxtNd,
873 : "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" );
874 124 : *pEnd = pTxtNd->Len();
875 : }
876 : }
877 0 : else if(pBkmk->GetOtherMarkPos().nNode == pBkmk->GetMarkPos().nNode)
878 0 : *pEnd = pBkmk->GetMarkEnd().nContent.GetIndex();
879 : else
880 0 : *pEnd = USHRT_MAX;
881 : }
882 : }
883 : }
884 124 : break;
885 :
886 : case REF_OUTLINE:
887 0 : break;
888 :
889 : case REF_FOOTNOTE:
890 : case REF_ENDNOTE:
891 : {
892 0 : sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().size();
893 : SwTxtFtn* pFtnIdx;
894 0 : for( n = 0; n < nFtnCnt; ++n )
895 0 : if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
896 : {
897 0 : SwNodeIndex* pIdx = pFtnIdx->GetStartNode();
898 0 : if( pIdx )
899 : {
900 0 : SwNodeIndex aIdx( *pIdx, 1 );
901 0 : if( 0 == ( pTxtNd = aIdx.GetNode().GetTxtNode()))
902 0 : pTxtNd = (SwTxtNode*)pDoc->GetNodes().GoNext( &aIdx );
903 : }
904 0 : *pStt = 0;
905 0 : if( pEnd )
906 0 : *pEnd = 0;
907 0 : break;
908 : }
909 : }
910 0 : break;
911 : }
912 :
913 124 : return pTxtNd;
914 : }
915 :
916 7 : struct _RefIdsMap
917 : {
918 : private:
919 : String aName;
920 : std::set<sal_uInt16> aIds;
921 : std::set<sal_uInt16> aDstIds;
922 : std::map<sal_uInt16, sal_uInt16> sequencedIds; /// ID numbers sorted by sequence number.
923 : bool bInit;
924 :
925 : void Init(SwDoc& rDoc, SwDoc& rDestDoc, bool bField );
926 : void GetNoteIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds );
927 : void GetFieldIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds );
928 : void AddId( sal_uInt16 id, sal_uInt16 seqNum );
929 : sal_uInt16 GetFirstUnusedId( std::set<sal_uInt16> &rIds );
930 :
931 : public:
932 7 : _RefIdsMap( const String& rName ) : aName( rName ), bInit( false ) {}
933 :
934 : void Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld, bool bField );
935 :
936 0 : String GetName() { return aName; }
937 : };
938 :
939 : typedef boost::ptr_vector<_RefIdsMap> _RefIdsMaps;
940 :
941 : /// Get a sorted list of the field IDs from a document.
942 : /// @param[in] rDoc The document to search.
943 : /// @param[in,out] rIds The list of IDs found in the document.
944 0 : void _RefIdsMap::GetFieldIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds)
945 : {
946 : const SwTxtNode* pNd;
947 : SwFieldType* pType;
948 :
949 0 : if( 0 != ( pType = rDoc.GetFldType( RES_SETEXPFLD, aName, false ) ))
950 : {
951 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
952 0 : for( SwFmtFld* pF = aIter.First(); pF; pF = aIter.Next() )
953 0 : if( pF->GetTxtFld() &&
954 0 : 0 != ( pNd = pF->GetTxtFld()->GetpTxtNode() ) &&
955 0 : pNd->GetNodes().IsDocNodes() )
956 0 : rIds.insert( ((SwSetExpField*)pF->GetFld())->GetSeqNumber() );
957 : }
958 0 : }
959 :
960 : /// Get a sorted list of the footnote/endnote IDs from a document.
961 : /// @param[in] rDoc The document to search.
962 : /// @param[in,out] rIds The list of IDs found in the document.
963 0 : void _RefIdsMap::GetNoteIdsFromDoc( SwDoc& rDoc, std::set<sal_uInt16> &rIds)
964 : {
965 0 : for( sal_uInt16 n = rDoc.GetFtnIdxs().size(); n; )
966 0 : rIds.insert( rDoc.GetFtnIdxs()[ --n ]->GetSeqRefNo() );
967 0 : }
968 :
969 : /// Initialise the aIds and aDestIds collections from the source documents.
970 : /// @param[in] rDoc The source document.
971 : /// @param[in] rDestDoc The destination document.
972 : /// @param[in] bField True if we're interested in all fields, false for footnotes.
973 0 : void _RefIdsMap::Init( SwDoc& rDoc, SwDoc& rDestDoc, bool bField )
974 : {
975 0 : if( bInit )
976 0 : return;
977 :
978 0 : if( bField )
979 : {
980 0 : GetFieldIdsFromDoc( rDestDoc, aIds );
981 0 : GetFieldIdsFromDoc( rDoc, aDstIds );
982 :
983 : // Map all the new src fields to the next available unused id
984 0 : for ( std::set<sal_uInt16>::iterator pIt = aDstIds.begin(); pIt != aDstIds.end(); ++pIt )
985 0 : AddId( GetFirstUnusedId(aIds), *pIt );
986 :
987 : // Change the Sequence number of all the SetExp fields in the destination document
988 0 : SwFieldType* pType = rDoc.GetFldType( RES_SETEXPFLD, aName, false );
989 0 : if( pType )
990 : {
991 0 : SwIterator<SwFmtFld,SwFieldType> aIter( *pType );
992 0 : for( SwFmtFld* pF = aIter.First(); pF; pF = aIter.Next() )
993 0 : if( pF->GetTxtFld() )
994 : {
995 0 : sal_uInt16 n = ((SwSetExpField*)pF->GetFld())->GetSeqNumber( );
996 0 : ((SwSetExpField*)pF->GetFld())->SetSeqNumber( sequencedIds[ n ] );
997 0 : }
998 : }
999 : }
1000 : else
1001 : {
1002 0 : GetNoteIdsFromDoc( rDestDoc, aIds );
1003 0 : GetNoteIdsFromDoc( rDoc, aDstIds );
1004 : }
1005 0 : bInit = true;
1006 : }
1007 :
1008 : /// Get the lowest number unused in the passed set.
1009 : /// @param[in] rIds The set of used ID numbers.
1010 : /// @returns The lowest number unused by the passed set
1011 0 : sal_uInt16 _RefIdsMap::GetFirstUnusedId( std::set<sal_uInt16> &rIds )
1012 : {
1013 0 : sal_uInt16 num(0);
1014 0 : std::set<sal_uInt16>::iterator it;
1015 :
1016 0 : for( it = rIds.begin(); it != rIds.end(); ++it )
1017 : {
1018 0 : if( num != *it )
1019 : {
1020 0 : return num;
1021 : }
1022 0 : ++num;
1023 : }
1024 0 : return num;
1025 : }
1026 :
1027 : /// Add a new ID and sequence number to the "occupied" collection.
1028 : /// @param[in] id The ID number.
1029 : /// @param[in] seqNum The sequence number.
1030 0 : void _RefIdsMap::AddId( sal_uInt16 id, sal_uInt16 seqNum )
1031 : {
1032 0 : aIds.insert( id );
1033 0 : sequencedIds[ seqNum ] = id;
1034 0 : }
1035 :
1036 0 : void _RefIdsMap::Check( SwDoc& rDoc, SwDoc& rDestDoc, SwGetRefField& rFld,
1037 : bool bField )
1038 : {
1039 0 : Init( rDoc, rDestDoc, bField);
1040 :
1041 : // dann teste mal, ob die Nummer schon vergeben ist
1042 : // oder ob eine neue bestimmt werden muss.
1043 0 : sal_uInt16 nSeqNo = rFld.GetSeqNo();
1044 0 : if( aIds.count( nSeqNo ) && aDstIds.count( nSeqNo ))
1045 : {
1046 : // Number already taken, so need a new one.
1047 0 : if( sequencedIds.count(nSeqNo) )
1048 0 : rFld.SetSeqNo( sequencedIds[nSeqNo] );
1049 : else
1050 : {
1051 0 : sal_uInt16 n = GetFirstUnusedId( aIds );
1052 :
1053 : // die neue SeqNo eintragen, damit die "belegt" ist
1054 0 : AddId( n, nSeqNo );
1055 0 : rFld.SetSeqNo( n );
1056 :
1057 : // und noch die Fuss-/EndNote auf die neue Id umsetzen
1058 0 : if( !bField )
1059 : {
1060 : SwTxtFtn* pFtnIdx;
1061 0 : for( sal_uInt16 i = 0, nCnt = rDoc.GetFtnIdxs().size(); i < nCnt; ++i )
1062 0 : if( nSeqNo == (pFtnIdx = rDoc.GetFtnIdxs()[ i ])->GetSeqRefNo() )
1063 : {
1064 0 : pFtnIdx->SetSeqNo( n );
1065 0 : break;
1066 : }
1067 : }
1068 : }
1069 : }
1070 : else
1071 : {
1072 0 : AddId( nSeqNo, nSeqNo );
1073 : }
1074 0 : }
1075 :
1076 7 : void SwGetRefFieldType::MergeWithOtherDoc( SwDoc& rDestDoc )
1077 : {
1078 7 : if( &rDestDoc != pDoc )
1079 : {
1080 : // then there are RefFields in the DescDox - so all RefFields in the SourceDoc
1081 : // need to be converted to have unique IDs for both documents
1082 7 : _RefIdsMap aFntMap( aEmptyStr );
1083 14 : _RefIdsMaps aFldMap;
1084 :
1085 14 : SwIterator<SwFmtFld,SwFieldType> aIter( *this );
1086 7 : for( SwFmtFld* pFld = aIter.First(); pFld; pFld = aIter.Next() )
1087 : {
1088 0 : SwGetRefField& rRefFld = *(SwGetRefField*)pFld->GetFld();
1089 0 : switch( rRefFld.GetSubType() )
1090 : {
1091 : case REF_SEQUENCEFLD:
1092 : {
1093 0 : _RefIdsMap* pMap = 0;
1094 0 : for( sal_uInt16 n = aFldMap.size(); n; )
1095 : {
1096 0 : if( aFldMap[ --n ].GetName().Equals(rRefFld.GetSetRefName()) )
1097 : {
1098 0 : pMap = &aFldMap[ n ];
1099 0 : break;
1100 : }
1101 : }
1102 0 : if( !pMap )
1103 : {
1104 0 : pMap = new _RefIdsMap( rRefFld.GetSetRefName() );
1105 0 : aFldMap.push_back( pMap );
1106 : }
1107 :
1108 0 : pMap->Check( *pDoc, rDestDoc, rRefFld, true );
1109 : }
1110 0 : break;
1111 :
1112 : case REF_FOOTNOTE:
1113 : case REF_ENDNOTE:
1114 0 : aFntMap.Check( *pDoc, rDestDoc, rRefFld, false );
1115 0 : break;
1116 : }
1117 7 : }
1118 : }
1119 106 : }
1120 :
1121 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|