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