fdo#50801 fix cross-reference text when Caption order is Numbering first

Change-Id: I7306f99c18d0f9cfb3b0ce147ecc200662d23b3d
This commit is contained in:
Uray M. János
2012-07-17 19:00:21 +02:00
committed by Andras Timar
parent 80de3c0fe6
commit 7dde426915
4 changed files with 103 additions and 63 deletions

View File

@@ -123,7 +123,7 @@ public:
virtual bool QueryValue( com::sun::star::uno::Any& rVal, sal_uInt16 nWhich ) const;
virtual bool PutValue( const com::sun::star::uno::Any& rVal, sal_uInt16 nWhich );
static sal_uInt16 GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc);
static sal_uInt16 GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc, unsigned nHint = 0);
// #i82544#
void SetLateInitialization() { bLateInitialization = true;}
};

View File

@@ -48,19 +48,19 @@ enum REFERENCESUBTYPE
enum REFERENCEMARK
{
REF_BEGIN,
REF_PAGE = REF_BEGIN,
REF_CHAPTER,
REF_CONTENT,
REF_UPDOWN,
REF_PAGE_PGDESC,
REF_ONLYNUMBER,
REF_ONLYCAPTION,
REF_ONLYSEQNO,
REF_PAGE = REF_BEGIN, // "Page"
REF_CHAPTER, // "Chapter"
REF_CONTENT, // "Reference"
REF_UPDOWN, // "Above/Below"
REF_PAGE_PGDESC, // "As Page Style"
REF_ONLYNUMBER, // "Category and Number"
REF_ONLYCAPTION, // "Caption Text"
REF_ONLYSEQNO, // "Numbering"
// --> #i81002#
// new reference format types for referencing bookmarks and set references
REF_NUMBER,
REF_NUMBER_NO_CONTEXT,
REF_NUMBER_FULL_CONTEXT,
REF_NUMBER, // "Number"
REF_NUMBER_NO_CONTEXT, // "Number (no context)"
REF_NUMBER_FULL_CONTEXT, // "Number (full context)"
REF_END
};
@@ -72,7 +72,7 @@ class SwGetRefFieldType : public SwFieldType
SwDoc* pDoc;
protected:
// Overlay in order to update all ref-fields.
virtual void Modify( const SfxPoolItem*, const SfxPoolItem * );
virtual void Modify( const SfxPoolItem*, const SfxPoolItem* );
public:
SwGetRefFieldType(SwDoc* pDoc );
virtual SwFieldType* Copy() const;

View File

@@ -895,19 +895,21 @@ void SwGetExpField::SetValue( const double& rAny )
/* --------------------------------------------------
Description: Find the index of the reference text
following the current field
nHint: search starting position after the current
field (or 0 if default)
--------------------------------------------------*/
xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc)
xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc, unsigned nHint)
{
//
const SwTxtFld* pTxtFld = rFmt.GetTxtFld();
const SwTxtNode& rTxtNode = pTxtFld->GetTxtNode();
//
xub_StrLen nRet = *pTxtFld->GetStart() + 1;
xub_StrLen nRet = nHint ? nHint : *pTxtFld->GetStart() + 1;
String sNodeText = rTxtNode.GetTxt();
sNodeText.Erase(0, nRet);
if(sNodeText.Len())
{
//now check if sNodeText starts with a non-alphanumeric character plus a blank
// now check if sNodeText starts with a non-alphanumeric character plus blanks
sal_uInt16 nSrcpt = pBreakIt->GetRealScriptOfText( sNodeText, 0 );
static sal_uInt16 nIds[] =
@@ -934,11 +936,14 @@ xub_StrLen SwGetExpField::GetReferenceTextPos( const SwFmtFld& rFmt, SwDoc& rDoc
if( !bIsAlphaNum ||
(c0 == ' ' || c0 == '\t'))
{
// ignoring blanks
nRet++;
if( sNodeText.Len() > 1 &&
(sNodeText.GetChar(1) == ' ' ||
sNodeText.GetChar(1) == '\t'))
nRet++;
unsigned i = 1;
while (i < sNodeText.Len() &&
(sNodeText.GetChar(i) == ' ' ||
sNodeText.GetChar(i) == '\t')
)
nRet++, i++;
}
}
}

View File

@@ -67,6 +67,7 @@
#include <set>
#include <map>
#include <algorithm> // min, max
#include <sfx2/childwin.hxx>
@@ -290,16 +291,28 @@ void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
sTxt.Erase();
SwDoc* pDoc = ((SwGetRefFieldType*)GetTyp())->GetDoc();
sal_uInt16 nStt = USHRT_MAX;
sal_uInt16 nEnd = USHRT_MAX;
SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor( pDoc, sSetRefName,
nSubType, nSeqNo, &nStt, &nEnd );
// finding the reference target (the number)
sal_uInt16 nNumStart, nNumEnd;
SwTxtNode* pTxtNd = SwGetRefFieldType::FindAnchor(
pDoc, sSetRefName, nSubType, nSeqNo, &nNumStart, &nNumEnd
);
// not found?
if ( !pTxtNd )
{
sTxt = ViewShell::GetShellRes()->aGetRefFld_RefItemNotFound;
return ;
}
// where is the category name (e.g. "Illustration")?
rtl::OUString const Text = pTxtNd->GetTxt();
unsigned const nCatStart = Text.indexOf(sSetRefName);
unsigned const nCatEnd = nCatStart == unsigned(-1) ?
unsigned(-1) : nCatStart + sSetRefName.getLength();
bool const bHasCat = nCatStart != unsigned(-1);
// length of the referenced text
unsigned const nLen = Text.getLength();
// which format?
switch( GetFormat() )
{
case REF_CONTENT:
@@ -307,73 +320,95 @@ void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
case REF_ONLYCAPTION:
case REF_ONLYSEQNO:
{
// needed part of Text
unsigned nStart, nEnd;
switch( nSubType )
{
case REF_SEQUENCEFLD:
nEnd = pTxtNd->GetTxt().Len();
switch( GetFormat() )
{
// "Category and Number"
case REF_ONLYNUMBER:
if( nStt + 1 < nEnd )
nEnd = nStt + 1;
nStt = 0;
break;
case REF_ONLYCAPTION:
{
const SwTxtAttr* const pTxtAttr =
pTxtNd->GetTxtAttrForCharAt(nStt, RES_TXTATR_FIELD);
if( pTxtAttr )
nStt = SwGetExpField::GetReferenceTextPos(
pTxtAttr->GetFld(), *pDoc );
else if( nStt + 1 < nEnd )
++nStt;
if (bHasCat) {
nStart = std::min<unsigned>(nNumStart, nCatStart);
nEnd = std::max<unsigned>(nNumEnd, nCatEnd);
} else {
nStart = nNumStart;
nEnd = nNumEnd;
}
break;
// "Caption Text"
case REF_ONLYCAPTION: {
// next alphanumeric character after category+number
if (const SwTxtAttr* const pTxtAttr =
pTxtNd->GetTxtAttrForCharAt(nNumStart, RES_TXTATR_FIELD)
) {
// start searching from nFrom
unsigned const nFrom = bHasCat ?
std::max<unsigned>(nNumStart + 1, nCatEnd) : nNumStart + 1;
nStart = SwGetExpField::GetReferenceTextPos(
pTxtAttr->GetFld(), *pDoc, nFrom
);
} else {
nStart = bHasCat ?
std::max<unsigned>(nNumEnd, nCatEnd) : nNumEnd;
}
nEnd = nLen;
break;
}
// "Numbering"
case REF_ONLYSEQNO:
if( nStt + 1 < nEnd )
nEnd = nStt + 1;
nStart = nNumStart;
nEnd = std::min<unsigned>(nStart + 1, nLen);
break;
// "Reference" (whole Text)
default:
nStt = 0;
nStart = 0;
nEnd = nLen;
break;
}
break;
case REF_BOOKMARK:
if( USHRT_MAX == nEnd )
{
// Text steht ueber verschiedene Nodes verteilt.
// Gesamten Text oder nur bis zum Ende vom Node?
nEnd = pTxtNd->GetTxt().Len();
}
nStart = nNumStart;
// Text steht ueber verschiedene Nodes verteilt.
// Gesamten Text oder nur bis zum Ende vom Node?
nEnd = nNumEnd == USHRT_MAX ? nLen : nNumEnd;
break;
case REF_OUTLINE:
nStart = nNumStart;
nEnd = nNumEnd;
break;
case REF_FOOTNOTE:
case REF_ENDNOTE:
// die Nummer oder den NumString besorgen
for( unsigned i = 0; i < pDoc->GetFtnIdxs().Count(); ++i )
{
// die Nummer oder den NumString besorgen
sal_uInt16 n, nFtnCnt = pDoc->GetFtnIdxs().Count();
SwTxtFtn* pFtnIdx;
for( n = 0; n < nFtnCnt; ++n )
if( nSeqNo == (pFtnIdx = pDoc->GetFtnIdxs()[ n ])->GetSeqRefNo() )
{
sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
break;
}
nStt = nEnd; // kein Bereich, der String ist fertig
SwTxtFtn* const pFtnIdx = pDoc->GetFtnIdxs()[i];
if( nSeqNo == pFtnIdx->GetSeqRefNo() )
{
sTxt = pFtnIdx->GetFtn().GetViewNumStr( *pDoc );
break;
}
}
return;
default:
nStart = nNumStart;
nEnd = nNumEnd;
break;
}
if( nStt != nEnd ) // ein Bereich?
if( nStart != nEnd ) // ein Bereich?
{
sTxt = pTxtNd->GetExpandTxt( nStt, nEnd - nStt );
sTxt = pTxtNd->GetExpandTxt( nStart, nEnd - nStart );
// alle Sonderzeichen entfernen (durch Blanks ersetzen):
if( sTxt.Len() )
@@ -396,7 +431,7 @@ void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
{
const SwTxtFrm* pFrm = (SwTxtFrm*)pTxtNd->getLayoutFrm( pDoc->GetCurrentLayout(), 0,0,sal_False),
*pSave = pFrm;
while( pFrm && !pFrm->IsInside( nStt ) )
while( pFrm && !pFrm->IsInside( nNumStart ) )
pFrm = (SwTxtFrm*)pFrm->GetFollow();
if( pFrm || 0 != ( pFrm = pSave ))
@@ -443,14 +478,14 @@ void SwGetRefField::UpdateField( const SwTxtFld* pFldTxtAttr )
// Node stehen!
if( pFldTxtAttr->GetpTxtNode() == pTxtNd )
{
sTxt = nStt < *pFldTxtAttr->GetStart()
sTxt = nNumStart < *pFldTxtAttr->GetStart()
? aLocaleData.getAboveWord()
: aLocaleData.getBelowWord();
break;
}
sTxt = ::IsFrameBehind( *pFldTxtAttr->GetpTxtNode(), *pFldTxtAttr->GetStart(),
*pTxtNd, nStt )
*pTxtNd, nNumStart )
? aLocaleData.getAboveWord()
: aLocaleData.getBelowWord();
}