1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: reffld.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_sw.hxx"
35 #define _SVSTDARR_USHORTSSORT
36 #define _SVSTDARR_USHORTS
37 #include <svtools/svstdarr.hxx>
38 #include <com/sun/star/text/ReferenceFieldPart.hpp>
39 #include <com/sun/star/text/ReferenceFieldSource.hpp>
40 #include <unotools/localedatawrapper.hxx>
41 #include <com/sun/star/lang/XMultiServiceFactory.hpp>
42 #include <comphelper/processfactory.hxx>
43 #include <svx/unolingu.hxx>
47 #include <pagefrm.hxx>
52 #include <fmtrfmrk.hxx>
53 #include <txtrfmrk.hxx>
61 #include <pagedesc.hxx>
63 // --> OD 2007-10-18 #i81002#
64 #include <crossrefbookmark.hxx>
69 #include <unofldmid.h>
71 #include <SwStyleNameMapper.hxx>
72 #include <shellres.hxx>
73 #include <poolfmt.hxx>
75 #include <poolfmt.hrc>
78 #include <comcore.hrc>
80 #include <numrule.hxx>
81 #include <SwNodeNum.hxx>
83 using namespace ::com::sun::star
;
84 using namespace ::com::sun::star::text
;
85 using namespace ::com::sun::star::lang
;
86 using ::rtl::OUString
;
88 extern void InsertSort( SvUShorts
& rArr
, USHORT nIdx
, USHORT
* pInsPos
= 0 );
90 void lcl_GetLayTree( const SwFrm
* pFrm
, SvPtrarr
& rArr
)
94 if( pFrm
->IsBodyFrm() ) // soll uns nicht weiter interessieren
95 pFrm
= pFrm
->GetUpper();
98 void* p
= (void*)pFrm
;
99 rArr
.Insert( p
, rArr
.Count() );
101 // bei der Seite ist schluss
102 if( pFrm
->IsPageFrm() )
105 if( pFrm
->IsFlyFrm() )
106 pFrm
= ((SwFlyFrm
*)pFrm
)->GetAnchorFrm();
108 pFrm
= pFrm
->GetUpper();
114 BOOL
IsFrameBehind( const SwTxtNode
& rMyNd
, USHORT nMySttPos
,
115 const SwTxtNode
& rBehindNd
, USHORT nSttPos
)
117 const SwTxtFrm
*pMyFrm
= (SwTxtFrm
*)rMyNd
.GetFrm(0,0,FALSE
),
118 *pFrm
= (SwTxtFrm
*)rBehindNd
.GetFrm(0,0,FALSE
);
120 while( pFrm
&& !pFrm
->IsInside( nSttPos
) )
121 pFrm
= (SwTxtFrm
*)pFrm
->GetFollow();
122 while( pMyFrm
&& !pMyFrm
->IsInside( nMySttPos
) )
123 pMyFrm
= (SwTxtFrm
*)pMyFrm
->GetFollow();
125 if( !pFrm
|| !pMyFrm
|| pFrm
== pMyFrm
)
128 SvPtrarr
aRefArr( 10, 10 ), aArr( 10, 10 );
129 ::lcl_GetLayTree( pFrm
, aRefArr
);
130 ::lcl_GetLayTree( pMyFrm
, aArr
);
132 USHORT nRefCnt
= aRefArr
.Count() - 1, nCnt
= aArr
.Count() - 1;
136 // solange bis ein Frame ungleich ist ?
137 while( nRefCnt
&& nCnt
&& aRefArr
[ nRefCnt
] == aArr
[ nCnt
] )
139 const SwFrm
* pTmpFrm
= (const SwFrm
*)aArr
[ nCnt
];
140 bVert
= pTmpFrm
->IsVertical();
141 bR2L
= pTmpFrm
->IsRightToLeft();
145 // sollte einer der Counter ueberlaeufen?
146 if( aRefArr
[ nRefCnt
] == aArr
[ nCnt
] )
154 const SwFrm
* pRefFrm
= (const SwFrm
*)aRefArr
[ nRefCnt
];
155 const SwFrm
* pFldFrm
= (const SwFrm
*)aArr
[ nCnt
];
157 // unterschiedliche Frames, dann ueberpruefe deren Y-/X-Position
158 BOOL bRefIsLower
= FALSE
;
159 if( ( FRM_COLUMN
| FRM_CELL
) & pFldFrm
->GetType() ||
160 ( FRM_COLUMN
| FRM_CELL
) & pRefFrm
->GetType() )
162 if( pFldFrm
->GetType() == pRefFrm
->GetType() )
164 // hier ist die X-Pos wichtiger!
168 bRefIsLower
= pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() ||
169 ( pRefFrm
->Frm().Top() == pFldFrm
->Frm().Top() &&
170 pRefFrm
->Frm().Left() < pFldFrm
->Frm().Left() );
172 bRefIsLower
= pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() ||
173 ( pRefFrm
->Frm().Top() == pFldFrm
->Frm().Top() &&
174 pRefFrm
->Frm().Left() > pFldFrm
->Frm().Left() );
177 bRefIsLower
= pRefFrm
->Frm().Left() > pFldFrm
->Frm().Left() ||
178 ( pRefFrm
->Frm().Left() == pFldFrm
->Frm().Left() &&
179 pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() );
181 bRefIsLower
= pRefFrm
->Frm().Left() < pFldFrm
->Frm().Left() ||
182 ( pRefFrm
->Frm().Left() == pFldFrm
->Frm().Left() &&
183 pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() );
186 else if( ( FRM_COLUMN
| FRM_CELL
) & pFldFrm
->GetType() )
187 pFldFrm
= (const SwFrm
*)aArr
[ nCnt
- 1 ];
189 pRefFrm
= (const SwFrm
*)aRefArr
[ nRefCnt
- 1 ];
192 if( pRefFrm
) // als Flag missbrauchen
197 bRefIsLower
= pRefFrm
->Frm().Left() < pFldFrm
->Frm().Left() ||
198 ( pRefFrm
->Frm().Left() == pFldFrm
->Frm().Left() &&
199 pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() );
201 bRefIsLower
= pRefFrm
->Frm().Left() > pFldFrm
->Frm().Left() ||
202 ( pRefFrm
->Frm().Left() == pFldFrm
->Frm().Left() &&
203 pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() );
206 bRefIsLower
= pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() ||
207 ( pRefFrm
->Frm().Top() == pFldFrm
->Frm().Top() &&
208 pRefFrm
->Frm().Left() > pFldFrm
->Frm().Left() );
210 bRefIsLower
= pRefFrm
->Frm().Top() < pFldFrm
->Frm().Top() ||
211 ( pRefFrm
->Frm().Top() == pFldFrm
->Frm().Top() &&
212 pRefFrm
->Frm().Left() < pFldFrm
->Frm().Left() );
217 /*--------------------------------------------------------------------
218 Beschreibung: Referenzen holen
219 --------------------------------------------------------------------*/
222 SwGetRefField::SwGetRefField( SwGetRefFieldType
* pFldType
,
223 const String
& rSetRef
, USHORT nSubTyp
,
224 USHORT nSeqenceNo
, ULONG nFmt
)
225 : SwField( pFldType
, nFmt
),
226 sSetRefName( rSetRef
),
232 SwGetRefField::~SwGetRefField()
236 String
SwGetRefField::GetDescription() const
238 return SW_RES(STR_REFERENCE
);
241 USHORT
SwGetRefField::GetSubType() const
246 void SwGetRefField::SetSubType( USHORT n
)
251 // --> OD 2007-11-09 #i81002#
252 bool SwGetRefField::IsRefToHeadingCrossRefBookmark() const
254 return GetSubType() == REF_BOOKMARK
&&
255 ::sw::mark::CrossRefHeadingBookmark::IsLegalName(sSetRefName
);
258 bool SwGetRefField::IsRefToNumItemCrossRefBookmark() const
260 return GetSubType() == REF_BOOKMARK
&&
261 ::sw::mark::CrossRefNumItemBookmark::IsLegalName(sSetRefName
);
264 const SwTxtNode
* SwGetRefField::GetReferencedTxtNode() const
266 SwDoc
* pDoc
= dynamic_cast<SwGetRefFieldType
*>(GetTyp())->GetDoc();
267 USHORT nDummy
= USHRT_MAX
;
268 return SwGetRefFieldType::FindAnchor( pDoc
, sSetRefName
, nSubType
, nSeqNo
, &nDummy
);
271 // --> OD 2008-01-09 #i85090#
272 String
SwGetRefField::GetExpandedTxtOfReferencedTxtNode() const
274 const SwTxtNode
* pReferencedTxtNode( GetReferencedTxtNode() );
275 return pReferencedTxtNode
276 ? pReferencedTxtNode
->GetExpandTxt( 0, STRING_LEN
, true, true )
280 String
SwGetRefField::Expand() const
286 String
SwGetRefField::GetCntnt(BOOL bName
) const
291 String
aStr(GetTyp()->GetName());
297 // --> OD 2007-09-07 #i81002# - parameter <pFldTxtAttr> added
298 void SwGetRefField::UpdateField( const SwTxtFld
* pFldTxtAttr
)
302 SwDoc
* pDoc
= ((SwGetRefFieldType
*)GetTyp())->GetDoc();
303 USHORT nStt
= USHRT_MAX
;
304 USHORT nEnd
= USHRT_MAX
;
305 SwTxtNode
* pTxtNd
= SwGetRefFieldType::FindAnchor( pDoc
, sSetRefName
,
306 nSubType
, nSeqNo
, &nStt
, &nEnd
);
309 sTxt
= ViewShell::GetShellRes()->aGetRefFld_RefItemNotFound
;
313 switch( GetFormat() )
317 case REF_ONLYCAPTION
:
322 case REF_SEQUENCEFLD
:
323 nEnd
= pTxtNd
->GetTxt().Len();
324 switch( GetFormat() )
327 if( nStt
+ 1 < nEnd
)
332 case REF_ONLYCAPTION
:
334 const SwTxtAttr
* const pTxtAttr
=
335 pTxtNd
->GetTxtAttrForCharAt(nStt
, RES_TXTATR_FIELD
);
337 nStt
= SwGetExpField::GetReferenceTextPos(
338 pTxtAttr
->GetFld(), *pDoc
);
339 else if( nStt
+ 1 < nEnd
)
345 if( nStt
+ 1 < nEnd
)
356 if( USHRT_MAX
== nEnd
)
358 // Text steht ueber verschiedene Nodes verteilt.
359 // Gesamten Text oder nur bis zum Ende vom Node?
360 nEnd
= pTxtNd
->GetTxt().Len();
370 // die Nummer oder den NumString besorgen
371 USHORT n
, nFtnCnt
= pDoc
->GetFtnIdxs().Count();
373 for( n
= 0; n
< nFtnCnt
; ++n
)
374 if( nSeqNo
== (pFtnIdx
= pDoc
->GetFtnIdxs()[ n
])->GetSeqRefNo() )
376 sTxt
= pFtnIdx
->GetFtn().GetViewNumStr( *pDoc
);
379 nStt
= nEnd
; // kein Bereich, der String ist fertig
384 if( nStt
!= nEnd
) // ein Bereich?
386 sTxt
= pTxtNd
->GetExpandTxt( nStt
, nEnd
- nStt
);
388 // alle Sonderzeichen entfernen (durch Blanks ersetzen):
391 sTxt
.EraseAllChars( 0xad );
392 for( sal_Unicode
* p
= sTxt
.GetBufferAccess(); *p
; ++p
)
396 else if(*p
== 0x2011)
405 case REF_PAGE_PGDESC
:
407 const SwTxtFrm
* pFrm
= (SwTxtFrm
*)pTxtNd
->GetFrm(0,0,FALSE
),
409 while( pFrm
&& !pFrm
->IsInside( nStt
) )
410 pFrm
= (SwTxtFrm
*)pFrm
->GetFollow();
412 if( pFrm
|| 0 != ( pFrm
= pSave
))
414 USHORT nPageNo
= pFrm
->GetVirtPageNum();
415 const SwPageFrm
*pPage
;
416 if( REF_PAGE_PGDESC
== GetFormat() &&
417 0 != ( pPage
= pFrm
->FindPageFrm() ) &&
418 pPage
->GetPageDesc() )
419 sTxt
= pPage
->GetPageDesc()->GetNumType().GetNumStr( nPageNo
);
421 sTxt
= String::CreateFromInt32(nPageNo
);
428 // ein bischen trickreich: suche irgend einen Frame
429 const SwFrm
* pFrm
= pTxtNd
->GetFrm();
432 SwChapterFieldType aFldTyp
;
433 SwChapterField
aFld( &aFldTyp
, 0 );
434 aFld
.SetLevel( MAXLEVEL
- 1 );
435 aFld
.ChangeExpansion( pFrm
, pTxtNd
, TRUE
);
436 sTxt
= aFld
.GetNumber();
443 // --> OD 2007-09-07 #i81002#
444 // simplified: use parameter <pFldTxtAttr>
445 if( !pFldTxtAttr
|| !pFldTxtAttr
->GetpTxtNode() )
448 LocaleDataWrapper
aLocaleData(
449 ::comphelper::getProcessServiceFactory(),
450 SvxCreateLocale( GetLanguage() ) );
452 // erstmal ein "Kurz" - Test - falls beide im selben
454 if( pFldTxtAttr
->GetpTxtNode() == pTxtNd
)
456 sTxt
= nStt
< *pFldTxtAttr
->GetStart()
457 ? aLocaleData
.getAboveWord()
458 : aLocaleData
.getBelowWord();
462 sTxt
= ::IsFrameBehind( *pFldTxtAttr
->GetpTxtNode(), *pFldTxtAttr
->GetStart(),
464 ? aLocaleData
.getAboveWord()
465 : aLocaleData
.getBelowWord();
468 // --> OD 2007-08-24 #i81002#
470 case REF_NUMBER_NO_CONTEXT
:
471 case REF_NUMBER_FULL_CONTEXT
:
473 if ( pFldTxtAttr
&& pFldTxtAttr
->GetpTxtNode() )
475 sTxt
= MakeRefNumStr( pFldTxtAttr
->GetTxtNode(), *pTxtNd
, GetFormat() );
481 DBG_ERROR("<SwGetRefField::UpdateField(..)> - unknown format type");
485 // --> OD 2007-09-06 #i81002#
486 String
SwGetRefField::MakeRefNumStr( const SwTxtNode
& rTxtNodeOfField
,
487 const SwTxtNode
& rTxtNodeOfReferencedItem
,
488 const sal_uInt32 nRefNumFormat
) const
490 if ( rTxtNodeOfReferencedItem
.HasNumber() &&
491 rTxtNodeOfReferencedItem
.IsCountedInList() )
493 ASSERT( rTxtNodeOfReferencedItem
.GetNum(),
494 "<SwGetRefField::MakeRefNumStr(..)> - referenced paragraph has number, but no <SwNodeNum> instance --> please inform OD!" );
496 // Determine, up to which level the superior list labels have to be
497 // included - default is to include all superior list labels.
498 sal_uInt8
nRestrictInclToThisLevel( 0 );
499 // Determine for format REF_NUMBER the level, up to which the superior
500 // list labels have to be restricted, if the text node of the reference
501 // field and the text node of the referenced item are in the same
503 if ( nRefNumFormat
== REF_NUMBER
&&
504 rTxtNodeOfField
.FindFlyStartNode()
505 == rTxtNodeOfReferencedItem
.FindFlyStartNode() &&
506 rTxtNodeOfField
.FindFootnoteStartNode()
507 == rTxtNodeOfReferencedItem
.FindFootnoteStartNode() &&
508 rTxtNodeOfField
.FindHeaderStartNode()
509 == rTxtNodeOfReferencedItem
.FindHeaderStartNode() &&
510 rTxtNodeOfField
.FindFooterStartNode()
511 == rTxtNodeOfReferencedItem
.FindFooterStartNode() )
513 const SwNodeNum
* pNodeNumForTxtNodeOfField( 0 );
514 if ( rTxtNodeOfField
.HasNumber() &&
515 rTxtNodeOfField
.GetNumRule() == rTxtNodeOfReferencedItem
.GetNumRule() )
517 pNodeNumForTxtNodeOfField
= rTxtNodeOfField
.GetNum();
521 pNodeNumForTxtNodeOfField
=
522 rTxtNodeOfReferencedItem
.GetNum()->GetPrecedingNodeNumOf( rTxtNodeOfField
);
524 if ( pNodeNumForTxtNodeOfField
)
526 const SwNumberTree::tNumberVector rFieldNumVec
= pNodeNumForTxtNodeOfField
->GetNumberVector();
527 const SwNumberTree::tNumberVector rRefItemNumVec
= rTxtNodeOfReferencedItem
.GetNum()->GetNumberVector();
528 sal_uInt8
nLevel( 0 );
529 while ( nLevel
< rFieldNumVec
.size() && nLevel
< rRefItemNumVec
.size() )
531 if ( rRefItemNumVec
[nLevel
] == rFieldNumVec
[nLevel
] )
533 nRestrictInclToThisLevel
= nLevel
+ 1;
544 // Determine, if superior list labels have to be included
545 const bool bInclSuperiorNumLabels(
546 ( nRestrictInclToThisLevel
< rTxtNodeOfReferencedItem
.GetActualListLevel() &&
547 ( nRefNumFormat
== REF_NUMBER
|| nRefNumFormat
== REF_NUMBER_FULL_CONTEXT
) ) );
549 ASSERT( rTxtNodeOfReferencedItem
.GetNumRule(),
550 "<SwGetRefField::MakeRefNumStr(..)> - referenced numbered paragraph has no numbering rule set --> please inform OD!" );
551 return rTxtNodeOfReferencedItem
.GetNumRule()->MakeRefNumString(
552 *(rTxtNodeOfReferencedItem
.GetNum()),
553 bInclSuperiorNumLabels
,
554 nRestrictInclToThisLevel
);
561 SwField
* SwGetRefField::Copy() const
563 SwGetRefField
* pFld
= new SwGetRefField( (SwGetRefFieldType
*)GetTyp(),
564 sSetRefName
, nSubType
,
565 nSeqNo
, GetFormat() );
570 /*--------------------------------------------------------------------
571 Beschreibung: ReferenzName holen
572 --------------------------------------------------------------------*/
575 const String
& SwGetRefField::GetPar1() const
581 void SwGetRefField::SetPar1( const String
& rName
)
587 String
SwGetRefField::GetPar2() const
592 /*-----------------06.03.98 13:34-------------------
594 --------------------------------------------------*/
595 BOOL
SwGetRefField::QueryValue( uno::Any
& rAny
, USHORT nWhichId
) const
599 case FIELD_PROP_USHORT1
:
604 case REF_PAGE
: nPart
= ReferenceFieldPart::PAGE
; break;
605 case REF_CHAPTER
: nPart
= ReferenceFieldPart::CHAPTER
; break;
606 case REF_CONTENT
: nPart
= ReferenceFieldPart::TEXT
; break;
607 case REF_UPDOWN
: nPart
= ReferenceFieldPart::UP_DOWN
; break;
608 case REF_PAGE_PGDESC
: nPart
= ReferenceFieldPart::PAGE_DESC
; break;
609 case REF_ONLYNUMBER
: nPart
= ReferenceFieldPart::CATEGORY_AND_NUMBER
; break;
610 case REF_ONLYCAPTION
: nPart
= ReferenceFieldPart::ONLY_CAPTION
; break;
611 case REF_ONLYSEQNO
: nPart
= ReferenceFieldPart::ONLY_SEQUENCE_NUMBER
; break;
612 // --> OD 2007-09-06 #i81002#
613 case REF_NUMBER
: nPart
= ReferenceFieldPart::NUMBER
; break;
614 case REF_NUMBER_NO_CONTEXT
: nPart
= ReferenceFieldPart::NUMBER_NO_CONTEXT
; break;
615 case REF_NUMBER_FULL_CONTEXT
: nPart
= ReferenceFieldPart::NUMBER_FULL_CONTEXT
; break;
621 case FIELD_PROP_USHORT2
:
623 sal_Int16 nSource
= 0;
626 case REF_SETREFATTR
: nSource
= ReferenceFieldSource::REFERENCE_MARK
; break;
627 case REF_SEQUENCEFLD
: nSource
= ReferenceFieldSource::SEQUENCE_FIELD
; break;
628 case REF_BOOKMARK
: nSource
= ReferenceFieldSource::BOOKMARK
; break;
629 case REF_OUTLINE
: DBG_ERROR("not implemented"); break;
630 case REF_FOOTNOTE
: nSource
= ReferenceFieldSource::FOOTNOTE
; break;
631 case REF_ENDNOTE
: nSource
= ReferenceFieldSource::ENDNOTE
; break;
636 case FIELD_PROP_PAR1
:
638 String
sTmp(GetPar1());
639 if(REF_SEQUENCEFLD
== nSubType
)
641 sal_uInt16 nPoolId
= SwStyleNameMapper::GetPoolIdFromUIName( sTmp
, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL
);
644 case RES_POOLCOLL_LABEL_ABB
:
645 case RES_POOLCOLL_LABEL_TABLE
:
646 case RES_POOLCOLL_LABEL_FRAME
:
647 case RES_POOLCOLL_LABEL_DRAWING
:
648 SwStyleNameMapper::FillProgName(nPoolId
, sTmp
) ;
652 rAny
<<= rtl::OUString(sTmp
);
655 case FIELD_PROP_PAR3
:
656 rAny
<<= rtl::OUString(Expand());
658 case FIELD_PROP_SHORT1
:
659 rAny
<<= (sal_Int16
)nSeqNo
;
662 DBG_ERROR("illegal property");
666 /*-----------------06.03.98 13:34-------------------
668 --------------------------------------------------*/
669 BOOL
SwGetRefField::PutValue( const uno::Any
& rAny
, USHORT nWhichId
)
674 case FIELD_PROP_USHORT1
:
680 case ReferenceFieldPart::PAGE
: nPart
= REF_PAGE
; break;
681 case ReferenceFieldPart::CHAPTER
: nPart
= REF_CHAPTER
; break;
682 case ReferenceFieldPart::TEXT
: nPart
= REF_CONTENT
; break;
683 case ReferenceFieldPart::UP_DOWN
: nPart
= REF_UPDOWN
; break;
684 case ReferenceFieldPart::PAGE_DESC
: nPart
= REF_PAGE_PGDESC
; break;
685 case ReferenceFieldPart::CATEGORY_AND_NUMBER
: nPart
= REF_ONLYNUMBER
; break;
686 case ReferenceFieldPart::ONLY_CAPTION
: nPart
= REF_ONLYCAPTION
; break;
687 case ReferenceFieldPart::ONLY_SEQUENCE_NUMBER
: nPart
= REF_ONLYSEQNO
; break;
688 // --> OD 2007-09-06 #i81002#
689 case ReferenceFieldPart::NUMBER
: nPart
= REF_NUMBER
; break;
690 case ReferenceFieldPart::NUMBER_NO_CONTEXT
: nPart
= REF_NUMBER_NO_CONTEXT
; break;
691 case ReferenceFieldPart::NUMBER_FULL_CONTEXT
: nPart
= REF_NUMBER_FULL_CONTEXT
; break;
693 default: return FALSE
;
698 case FIELD_PROP_USHORT2
:
700 sal_Int16 nSource
= 0;
704 case ReferenceFieldSource::REFERENCE_MARK
: nSubType
= REF_SETREFATTR
; break;
705 case ReferenceFieldSource::SEQUENCE_FIELD
:
707 if(REF_SEQUENCEFLD
== nSubType
)
709 nSubType
= REF_SEQUENCEFLD
;
710 ConvertProgrammaticToUIName();
713 case ReferenceFieldSource::BOOKMARK
: nSubType
= REF_BOOKMARK
; break;
714 case ReferenceFieldSource::FOOTNOTE
: nSubType
= REF_FOOTNOTE
; break;
715 case ReferenceFieldSource::ENDNOTE
: nSubType
= REF_ENDNOTE
; break;
719 case FIELD_PROP_PAR1
:
724 ConvertProgrammaticToUIName();
727 case FIELD_PROP_PAR3
:
728 SetExpand( ::GetString( rAny
, sTmp
));
730 case FIELD_PROP_SHORT1
:
732 sal_Int16 nSetSeq
= 0;
739 DBG_ERROR("illegal property");
743 /* -----------------------------11.01.2002 12:50------------------------------
745 ---------------------------------------------------------------------------*/
746 void SwGetRefField::ConvertProgrammaticToUIName()
748 if(GetTyp() && REF_SEQUENCEFLD
== nSubType
)
750 SwDoc
* pDoc
= ((SwGetRefFieldType
*)GetTyp())->GetDoc();
751 const String
& rPar1
= GetPar1();
752 //don't convert when the name points to an existing field type
753 if(!pDoc
->GetFldType(RES_SETEXPFLD
, rPar1
, false))
755 sal_uInt16 nPoolId
= SwStyleNameMapper::GetPoolIdFromProgName( rPar1
, nsSwGetPoolIdFromName::GET_POOLID_TXTCOLL
);
756 USHORT nResId
= USHRT_MAX
;
759 case RES_POOLCOLL_LABEL_ABB
:
760 nResId
= STR_POOLCOLL_LABEL_ABB
;
762 case RES_POOLCOLL_LABEL_TABLE
:
763 nResId
= STR_POOLCOLL_LABEL_TABLE
;
765 case RES_POOLCOLL_LABEL_FRAME
:
766 nResId
= STR_POOLCOLL_LABEL_FRAME
;
768 case RES_POOLCOLL_LABEL_DRAWING
:
769 nResId
= STR_POOLCOLL_LABEL_DRAWING
;
772 if( nResId
!= USHRT_MAX
)
773 SetPar1(SW_RESSTR( nResId
));
777 /*-----------------JP: 18.06.93 -------------------
779 --------------------------------------------------*/
782 SwGetRefFieldType::SwGetRefFieldType( SwDoc
* pDc
)
783 : SwFieldType( RES_GETREFFLD
), pDoc( pDc
)
787 SwFieldType
* SwGetRefFieldType::Copy() const
789 return new SwGetRefFieldType( pDoc
);
793 void SwGetRefFieldType::Modify( SfxPoolItem
* pOld
, SfxPoolItem
* pNew
)
795 // Update auf alle GetReferenz-Felder
798 SwClientIter
aIter( *this );
799 for( SwFmtFld
* pFld
= (SwFmtFld
*)aIter
.First( TYPE(SwFmtFld
) );
800 pFld
; pFld
= (SwFmtFld
*)aIter
.Next() )
802 // nur die GetRef-Felder Updaten
803 //JP 3.4.2001: Task 71231 - we need the correct language
804 SwGetRefField
* pGRef
= (SwGetRefField
*)pFld
->GetFld();
805 const SwTxtFld
* pTFld
;
806 if( !pGRef
->GetLanguage() &&
807 0 != ( pTFld
= pFld
->GetTxtFld()) &&
808 pTFld
->GetpTxtNode() )
810 pGRef
->SetLanguage( pTFld
->GetpTxtNode()->GetLang(
811 *pTFld
->GetStart() ) );
814 // --> OD 2007-09-06 #i81002#
815 pGRef
->UpdateField( pFld
->GetTxtFld() );
819 // weiter an die Text-Felder, diese "Expandieren" den Text
820 SwModify::Modify( pOld
, pNew
);
823 SwTxtNode
* SwGetRefFieldType::FindAnchor( SwDoc
* pDoc
, const String
& rRefMark
,
824 USHORT nSubType
, USHORT nSeqNo
,
825 USHORT
* pStt
, USHORT
* pEnd
)
827 ASSERT( pStt
, "warum wird keine StartPos abgefragt?" );
829 SwTxtNode
* pTxtNd
= 0;
834 const SwFmtRefMark
*pRef
= pDoc
->GetRefMark( rRefMark
);
835 if( pRef
&& pRef
->GetTxtRefMark() )
837 pTxtNd
= (SwTxtNode
*)&pRef
->GetTxtRefMark()->GetTxtNode();
838 *pStt
= *pRef
->GetTxtRefMark()->GetStart();
840 *pEnd
= *pRef
->GetTxtRefMark()->GetAnyEnd();
845 case REF_SEQUENCEFLD
:
847 SwFieldType
* pFldType
= pDoc
->GetFldType( RES_SETEXPFLD
, rRefMark
, false );
848 if( pFldType
&& pFldType
->GetDepends() &&
849 nsSwGetSetExpType::GSE_SEQ
& ((SwSetExpFieldType
*)pFldType
)->GetType() )
851 SwClientIter
aIter( *pFldType
);
852 for( SwFmtFld
* pFld
= (SwFmtFld
*)aIter
.First( TYPE(SwFmtFld
) );
853 pFld
; pFld
= (SwFmtFld
*)aIter
.Next() )
855 if( pFld
->GetTxtFld() && nSeqNo
==
856 ((SwSetExpField
*)pFld
->GetFld())->GetSeqNumber() )
858 SwTxtFld
* pTxtFld
= pFld
->GetTxtFld();
859 pTxtNd
= (SwTxtNode
*)pTxtFld
->GetpTxtNode();
860 *pStt
= *pTxtFld
->GetStart();
872 IDocumentMarkAccess::const_iterator_t ppMark
= pDoc
->getIDocumentMarkAccess()->findMark(rRefMark
);
873 if(ppMark
!= pDoc
->getIDocumentMarkAccess()->getMarksEnd())
875 const ::sw::mark::IMark
* pBkmk
= ppMark
->get();
876 const SwPosition
* pPos
= &pBkmk
->GetMarkStart();
878 pTxtNd
= pDoc
->GetNodes()[ pPos
->nNode
]->GetTxtNode();
879 *pStt
= pPos
->nContent
.GetIndex();
882 if(!pBkmk
->IsExpanded())
885 // --> OD 2007-10-18 #i81002#
886 if(dynamic_cast< ::sw::mark::CrossRefBookmark
const *>(pBkmk
))
889 "<SwGetRefFieldType::FindAnchor(..)> - node marked by cross-reference bookmark isn't a text node --> crash" );
890 *pEnd
= pTxtNd
->Len();
894 else if(pBkmk
->GetOtherMarkPos().nNode
== pBkmk
->GetMarkPos().nNode
)
895 *pEnd
= pBkmk
->GetMarkEnd().nContent
.GetIndex();
909 USHORT n
, nFtnCnt
= pDoc
->GetFtnIdxs().Count();
911 for( n
= 0; n
< nFtnCnt
; ++n
)
912 if( nSeqNo
== (pFtnIdx
= pDoc
->GetFtnIdxs()[ n
])->GetSeqRefNo() )
914 SwNodeIndex
* pIdx
= pFtnIdx
->GetStartNode();
917 SwNodeIndex
aIdx( *pIdx
, 1 );
918 if( 0 == ( pTxtNd
= aIdx
.GetNode().GetTxtNode()))
919 pTxtNd
= (SwTxtNode
*)pDoc
->GetNodes().GoNext( &aIdx
);
937 SvUShortsSort aIds
, aDstIds
, aIdsMap
;
941 _RefIdsMap( const String
& rName
)
942 : aName( rName
), aIds( 16, 16 ), aIdsMap( 16, 16 ), aMap( 16, 16 ),
946 void Check( SwDoc
& rDoc
, SwDoc
& rDestDoc
, SwGetRefField
& rFld
,
947 BOOL bField
= TRUE
);
949 BOOL
IsInit() const { return bInit
; }
952 SV_DECL_PTRARR_DEL( _RefIdsMaps
, _RefIdsMap
*, 5, 5 )
953 SV_IMPL_PTRARR( _RefIdsMaps
, _RefIdsMap
* )
955 void _RefIdsMap::Check( SwDoc
& rDoc
, SwDoc
& rDestDoc
, SwGetRefField
& rFld
,
963 const SwTxtNode
* pNd
;
965 if( 0 != ( pMod
= rDestDoc
.GetFldType( RES_SETEXPFLD
, aName
, false ) ))
967 SwClientIter
aIter( *pMod
);
968 for( SwFmtFld
* pF
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
)); pF
;
969 pF
= (SwFmtFld
*)aIter
.Next() )
970 if( pF
->GetTxtFld() &&
971 0 != ( pNd
= pF
->GetTxtFld()->GetpTxtNode() ) &&
972 pNd
->GetNodes().IsDocNodes() )
973 aIds
.Insert( ((SwSetExpField
*)pF
->GetFld())->GetSeqNumber() );
975 if( 0 != ( pMod
= rDoc
.GetFldType( RES_SETEXPFLD
, aName
, false ) ))
977 SwClientIter
aIter( *pMod
);
978 for( SwFmtFld
* pF
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
)); pF
;
979 pF
= (SwFmtFld
*)aIter
.Next() )
980 if( pF
->GetTxtFld() &&
981 0 != ( pNd
= pF
->GetTxtFld()->GetpTxtNode() ) &&
982 pNd
->GetNodes().IsDocNodes() )
983 aDstIds
.Insert( ((SwSetExpField
*)pF
->GetFld())->GetSeqNumber() );
990 for( n
= rDestDoc
.GetFtnIdxs().Count(); n
; )
991 aIds
.Insert( rDestDoc
.GetFtnIdxs()[ --n
]->GetSeqRefNo() );
992 for( n
= rDoc
.GetFtnIdxs().Count(); n
; )
993 aDstIds
.Insert( rDoc
.GetFtnIdxs()[ --n
]->GetSeqRefNo() );
998 // dann teste mal, ob die Nummer schon vergeben ist
999 // oder ob eine neue bestimmt werden muss.
1000 USHORT nPos
, nSeqNo
= rFld
.GetSeqNo();
1001 if( aIds
.Seek_Entry( nSeqNo
) && aDstIds
.Seek_Entry( nSeqNo
))
1003 // ist schon vergeben, also muss eine neue
1005 if( aIdsMap
.Seek_Entry( nSeqNo
, &nPos
))
1006 rFld
.SetSeqNo( aMap
[ nPos
] );
1011 for( n
= 0; n
< aIds
.Count(); ++n
)
1012 if( n
!= aIds
[ n
] )
1015 // die neue SeqNo eintragen, damit die "belegt" ist
1017 aIdsMap
.Insert( nSeqNo
, nPos
);
1018 aMap
.Insert( n
, nPos
);
1021 // und noch die Felder oder Fuss-/EndNote auf die neue
1025 SwModify
* pMod
= rDoc
.GetFldType( RES_SETEXPFLD
, aName
, false );
1028 SwClientIter
aIter( *pMod
);
1029 for( SwFmtFld
* pF
= (SwFmtFld
*)aIter
.First( TYPE( SwFmtFld
)); pF
;
1030 pF
= (SwFmtFld
*)aIter
.Next() )
1031 if( pF
->GetTxtFld() && nSeqNo
==
1032 ((SwSetExpField
*)pF
->GetFld())->GetSeqNumber() )
1033 ((SwSetExpField
*)pF
->GetFld())->SetSeqNumber( n
);
1039 for( USHORT i
= 0, nCnt
= rDoc
.GetFtnIdxs().Count(); i
< nCnt
; ++i
)
1040 if( nSeqNo
== (pFtnIdx
= rDoc
.GetFtnIdxs()[ i
])->GetSeqRefNo() )
1042 pFtnIdx
->SetSeqNo( n
);
1050 aIds
.Insert( nSeqNo
);
1051 aIdsMap
.Insert( nSeqNo
, nPos
);
1052 aMap
.Insert( nSeqNo
, nPos
);
1057 void SwGetRefFieldType::MergeWithOtherDoc( SwDoc
& rDestDoc
)
1059 if( &rDestDoc
!= pDoc
&&
1060 rDestDoc
.GetSysFldType( RES_GETREFFLD
)->GetDepends() )
1062 // dann gibt es im DestDoc RefFelder, also muessen im SourceDoc
1063 // alle RefFelder auf einduetige Ids in beiden Docs umgestellt
1065 _RefIdsMap
aFntMap( aEmptyStr
);
1066 _RefIdsMaps aFldMap
;
1068 SwClientIter
aIter( *this );
1069 for( SwClient
* pFld
= aIter
.First( TYPE( SwFmtFld
));
1070 pFld
; pFld
= aIter
.Next() )
1072 SwGetRefField
& rRefFld
= *(SwGetRefField
*)((SwFmtFld
*)pFld
)->GetFld();
1073 switch( rRefFld
.GetSubType() )
1075 case REF_SEQUENCEFLD
:
1077 _RefIdsMap
* pMap
= 0;
1078 for( USHORT n
= aFldMap
.Count(); n
; )
1079 if( aFldMap
[ --n
]->aName
== rRefFld
.GetSetRefName() )
1081 pMap
= aFldMap
[ n
];
1086 pMap
= new _RefIdsMap( rRefFld
.GetSetRefName() );
1087 aFldMap
.C40_INSERT( _RefIdsMap
, pMap
, aFldMap
.Count() );
1090 pMap
->Check( *pDoc
, rDestDoc
, rRefFld
, TRUE
);
1096 aFntMap
.Check( *pDoc
, rDestDoc
, rRefFld
, FALSE
);