diff options
Diffstat (limited to 'sw/source/filter/ww8/ww8par5.cxx')
-rw-r--r-- | sw/source/filter/ww8/ww8par5.cxx | 438 |
1 files changed, 252 insertions, 186 deletions
diff --git a/sw/source/filter/ww8/ww8par5.cxx b/sw/source/filter/ww8/ww8par5.cxx index 3aa79d63e707..47cb7e788223 100644 --- a/sw/source/filter/ww8/ww8par5.cxx +++ b/sw/source/filter/ww8/ww8par5.cxx @@ -18,6 +18,7 @@ */ #include <config_features.h> +#include <config_fuzzers.h> #include <sal/types.h> #include <tools/solar.h> @@ -33,6 +34,7 @@ #include <svl/cintitem.hxx> #include <svl/lngmisc.hxx> #include <svl/urihelper.hxx> +#include <svl/numformat.hxx> #include <svl/zforlist.hxx> #include <svl/zformat.hxx> #include <sfx2/linkmgr.hxx> @@ -56,6 +58,7 @@ #include <IDocumentState.hxx> #include <flddat.hxx> #include <docufld.hxx> +#include <usrfld.hxx> #include <reffld.hxx> #include <IMark.hxx> #include <expfld.hxx> @@ -76,11 +79,13 @@ #include "ww8par.hxx" #include "writerhelper.hxx" #include <o3tl/safeint.hxx> -#include <unotools/fltrcfg.hxx> +#include <o3tl/string_view.hxx> #include <xmloff/odffields.hxx> #include <osl/diagnose.h> +#include <officecfg/Office/Common.hxx> #include <algorithm> +#include <string_view> #define MAX_FIELDLEN 64000 @@ -90,16 +95,15 @@ using namespace ::com::sun::star; using namespace msfilter::util; using namespace sw::util; using namespace sw::mark; -using namespace std; // #i24377# using namespace nsSwDocInfoSubType; // Bookmarks namespace { // #120879# - helper method to identify a bookmark name to match the internal TOC bookmark naming convention - bool IsTOCBookmarkName(const OUString& rName) + bool IsTOCBookmarkName(std::u16string_view rName) { - return rName.startsWith("_Toc") || rName.startsWith(OUString(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()+"_Toc")); + return o3tl::starts_with(rName, u"_Toc") || o3tl::starts_with(rName, Concat2View(IDocumentMarkAccess::GetCrossRefHeadingBookmarkNamePrefix()+"_Toc")); } OUString EnsureTOCBookmarkName(const OUString& rName) @@ -155,7 +159,7 @@ tools::Long SwWW8ImplReader::Read_Book(WW8PLCFManResult*) if( nLen > MAX_FIELDLEN ) nLen = MAX_FIELDLEN; - tools::Long nOldPos = m_pStrm->Tell(); + sal_uInt64 nOldPos = m_pStrm->Tell(); m_xSBase->WW8ReadString( *m_pStrm, aVal, pB->GetStartPos(), nLen, m_eStructCharSet ); m_pStrm->Seek( nOldPos ); @@ -181,7 +185,7 @@ tools::Long SwWW8ImplReader::Read_Book(WW8PLCFManResult*) case 0x0d: if( bAllowCr ) { - aVal = aVal.replaceAt( nI, 1, "\n" ); + aVal = aVal.replaceAt( nI, 1, u"\n" ); bSetAsHex = false; } else @@ -299,27 +303,27 @@ static void lcl_ConvertSequenceName(OUString& rSequenceName) // FindParaStart() finds 1st Parameter that follows '\' and cToken // and returns start of this parameter or -1 -static sal_Int32 FindParaStart( const OUString& rStr, sal_Unicode cToken, sal_Unicode cToken2 ) +static sal_Int32 FindParaStart( std::u16string_view aStr, sal_Unicode cToken, sal_Unicode cToken2 ) { bool bStr = false; // ignore inside a string - for( sal_Int32 nBuf = 0; nBuf+1 < rStr.getLength(); nBuf++ ) + for( size_t nBuf = 0; nBuf+1 < aStr.size(); nBuf++ ) { - if( rStr[ nBuf ] == '"' ) + if( aStr[ nBuf ] == '"' ) bStr = !bStr; if( !bStr - && rStr[ nBuf ] == '\\' - && ( rStr[ nBuf + 1 ] == cToken - || rStr[ nBuf + 1 ] == cToken2 ) ) + && aStr[ nBuf ] == '\\' + && ( aStr[ nBuf + 1 ] == cToken + || aStr[ nBuf + 1 ] == cToken2 ) ) { nBuf += 2; // skip spaces between cToken and its parameters - while( nBuf < rStr.getLength() - && rStr[ nBuf ] == ' ' ) + while( nBuf < aStr.size() + && aStr[ nBuf ] == ' ' ) nBuf++; // return start of parameters - return nBuf < rStr.getLength() ? nBuf : -1; + return nBuf < aStr.size() ? nBuf : -1; } } return -1; @@ -328,37 +332,40 @@ static sal_Int32 FindParaStart( const OUString& rStr, sal_Unicode cToken, sal_Un // FindPara() finds the first parameter including '\' and cToken. // A new String will be allocated (has to be deallocated by the caller) // and everything that is part of the parameter will be returned. -static OUString FindPara( const OUString& rStr, sal_Unicode cToken, sal_Unicode cToken2 ) +static OUString FindPara( std::u16string_view aStr, sal_Unicode cToken, sal_Unicode cToken2 ) { sal_Int32 n2; // end - sal_Int32 n = FindParaStart( rStr, cToken, cToken2 ); // start + sal_Int32 n = FindParaStart( aStr, cToken, cToken2 ); // start if( n == -1) return OUString(); - if( rStr[ n ] == '"' - || rStr[ n ] == 132 ) + if( aStr[ n ] == '"' + || aStr[ n ] == 132 ) { // Quotationmark in front of parameter n++; // Skip quotationmark n2 = n; // search for the end starting from here - while( n2 < rStr.getLength() - && rStr[ n2 ] != 147 - && rStr[ n2 ] != '"' ) + while( n2 < sal_Int32(aStr.size()) + && aStr[ n2 ] != 147 + && aStr[ n2 ] != '"' ) n2++; // search end of parameter } else { // no quotationmarks n2 = n; // search for the end starting from here - while( n2 < rStr.getLength() - && rStr[ n2 ] != ' ' ) + while( n2 < sal_Int32(aStr.size()) + && aStr[ n2 ] != ' ' ) n2++; // search end of parameter } - return rStr.copy( n, n2-n ); + return OUString(aStr.substr( n, n2-n )); } static SvxNumType GetNumTypeFromName(const OUString& rStr, bool bAllowPageDesc = false) { SvxNumType eTyp = bAllowPageDesc ? SVX_NUM_PAGEDESC : SVX_NUM_ARABIC; + if (rStr.isEmpty()) + return eTyp; + if( rStr.startsWithIgnoreAsciiCase( "Arabi" ) ) // Arabisch, Arabic eTyp = SVX_NUM_ARABIC; else if( rStr.startsWith( "misch" ) ) // r"omisch @@ -376,9 +383,9 @@ static SvxNumType GetNumTypeFromName(const OUString& rStr, return eTyp; } -static SvxNumType GetNumberPara(const OUString& rStr, bool bAllowPageDesc = false) +static SvxNumType GetNumberPara(std::u16string_view aStr, bool bAllowPageDesc = false) { - OUString s( FindPara( rStr, '*', '*' ) ); // Type of number + OUString s( FindPara( aStr, '*', '*' ) ); // Type of number SvxNumType aType = GetNumTypeFromName( s, bAllowPageDesc ); return aType; } @@ -387,8 +394,7 @@ bool SwWW8ImplReader::ForceFieldLanguage(SwField &rField, LanguageType nLang) { bool bRet(false); - const SvxLanguageItem *pLang = - static_cast<const SvxLanguageItem*>(GetFormatAttr(RES_CHRATR_LANGUAGE)); + const SvxLanguageItem *pLang = GetFormatAttr(RES_CHRATR_LANGUAGE); OSL_ENSURE(pLang, "impossible"); LanguageType nDefault = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US; @@ -424,7 +430,7 @@ static OUString GetWordDefaultDateStringAsUS(SvNumberFormatter* pFormatter, Lang return sParams; } -SvNumFormatType SwWW8ImplReader::GetTimeDatePara(OUString const & rStr, sal_uInt32& rFormat, +SvNumFormatType SwWW8ImplReader::GetTimeDatePara(std::u16string_view aStr, sal_uInt32& rFormat, LanguageType &rLang, int nWhichDefault, bool bHijri) { bool bRTL = false; @@ -434,13 +440,13 @@ SvNumFormatType SwWW8ImplReader::GetTimeDatePara(OUString const & rStr, sal_uInt if (aResult.pSprm && aResult.nRemainingData >= 1 && *aResult.pSprm) bRTL = true; } - sal_uInt16 eLang = bRTL ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE; - const SvxLanguageItem *pLang = static_cast<const SvxLanguageItem*>(GetFormatAttr(eLang)); + TypedWhichId<SvxLanguageItem> eLang = bRTL ? RES_CHRATR_CTL_LANGUAGE : RES_CHRATR_LANGUAGE; + const SvxLanguageItem *pLang = GetFormatAttr(eLang); OSL_ENSURE(pLang, "impossible"); rLang = pLang ? pLang->GetValue() : LANGUAGE_ENGLISH_US; SvNumberFormatter* pFormatter = m_rDoc.GetNumberFormatter(); - OUString sParams( FindPara( rStr, '@', '@' ) );// Date/Time + OUString sParams( FindPara( aStr, '@', '@' ) );// Date/Time if (sParams.isEmpty()) { bool bHasTime = false; @@ -497,6 +503,20 @@ void SwWW8ImplReader::UpdateFields() m_rDoc.SetInitDBFields(true); // Also update fields in the database } +// Sanity check the PaM to see if it makes sense wrt sw::CalcBreaks +static bool SanityCheck(const SwPaM& rFieldPam) +{ + SwNodeOffset const nEndNode(rFieldPam.End()->GetNodeIndex()); + SwNodes const& rNodes(rFieldPam.GetPoint()->GetNodes()); + SwNode *const pFinalNode(rNodes[nEndNode]); + if (pFinalNode->IsTextNode()) + { + SwTextNode & rTextNode(*pFinalNode->GetTextNode()); + return (rTextNode.Len() >= rFieldPam.End()->GetContentIndex()); + } + return true; +} + sal_uInt16 SwWW8ImplReader::End_Field() { sal_uInt16 nRet = 0; @@ -506,8 +526,7 @@ sal_uInt16 SwWW8ImplReader::End_Field() if (!pF || !pF->EndPosIsFieldEnd(nCP)) return nRet; - const SvtFilterOptions &rOpt = SvtFilterOptions::Get(); - bool bUseEnhFields = rOpt.IsUseEnhancedFields(); + bool bUseEnhFields = officecfg::Office::Common::Filter::Microsoft::Import::ImportWWFieldsAsEnhancedFields::get(); OSL_ENSURE(!m_aFieldStack.empty(), "Empty field stack"); if (!m_aFieldStack.empty()) @@ -523,11 +542,12 @@ sal_uInt16 SwWW8ImplReader::End_Field() case ww::eFORMTEXT: if (bUseEnhFields && m_pPaM!=nullptr && m_pPaM->GetPoint()!=nullptr) { SwPosition aEndPos = *m_pPaM->GetPoint(); - SwPaM aFieldPam( m_aFieldStack.back().GetPtNode(), m_aFieldStack.back().GetPtContent(), aEndPos.nNode, aEndPos.nContent.GetIndex()); + SwPaM aFieldPam( m_aFieldStack.back().GetPtNode().GetNode(), m_aFieldStack.back().GetPtContent(), aEndPos.GetNode(), aEndPos.GetContentIndex()); + IDocumentMarkAccess* pMarksAccess = m_rDoc.getIDocumentMarkAccess( ); - IFieldmark *pFieldmark = pMarksAccess->makeFieldBookmark( + IFieldmark *pFieldmark = SanityCheck(aFieldPam) ? pMarksAccess->makeFieldBookmark( aFieldPam, m_aFieldStack.back().GetBookmarkName(), ODF_FORMTEXT, - aFieldPam.Start() /*same pos as start!*/ ); + aFieldPam.Start() /*same pos as start!*/ ) : nullptr; OSL_ENSURE(pFieldmark!=nullptr, "hmmm; why was the bookmark not created?"); if (pFieldmark!=nullptr) { // adapt redline positions to inserted field mark start @@ -553,8 +573,8 @@ sal_uInt16 SwWW8ImplReader::End_Field() m_aTOXEndCps.insert(nCP); m_bLoadingTOXCache = false; if ( m_pPaM->End() && - m_pPaM->End()->nNode.GetNode().GetTextNode() && - m_pPaM->End()->nNode.GetNode().GetTextNode()->Len() == 0 ) + m_pPaM->End()->GetNode().GetTextNode() && + m_pPaM->End()->GetNode().GetTextNode()->Len() == 0 ) { JoinNode(*m_pPaM); } @@ -563,10 +583,10 @@ sal_uInt16 SwWW8ImplReader::End_Field() m_bCareLastParaEndInToc = true; } - if (m_pPosAfterTOC) + if (m_oPosAfterTOC) { - *m_pPaM = *m_pPosAfterTOC; - m_pPosAfterTOC.reset(); + *m_pPaM = *m_oPosAfterTOC; + m_oPosAfterTOC.reset(); } } } @@ -584,18 +604,46 @@ sal_uInt16 SwWW8ImplReader::End_Field() break; case ww::eMERGEINC: case ww::eINCLUDETEXT: + { //Move outside the section associated with this type of field - *m_pPaM->GetPoint() = m_aFieldStack.back().maStartPos; + SwPosition aRestorePos(m_aFieldStack.back().maStartPos); + + SwContentNode* pNd = aRestorePos.GetNode().GetContentNode(); + sal_Int32 nMaxValidIndex = pNd ? pNd->Len() : 0; + if (aRestorePos.GetContentIndex() > nMaxValidIndex) + { + SAL_WARN("sw.ww8", "Attempt to restore to invalid content position"); + aRestorePos.SetContent(nMaxValidIndex); + } + + *m_pPaM->GetPoint() = aRestorePos; break; + } case ww::eIF: // IF-field { // conditional field parameters - const OUString& fieldDefinition = m_aFieldStack.back().GetBookmarkCode(); + OUString fieldDefinition = m_aFieldStack.back().GetBookmarkCode(); OUString paramCondition; OUString paramTrue; OUString paramFalse; + // ParseIfFieldDefinition expects: IF <some condition> "true result" "false result" + // while many fields include '\* MERGEFORMAT' after that. + // So first trim off the switches that are not supported anyway + sal_Int32 nLastIndex = fieldDefinition.lastIndexOf("\\*"); + sal_Int32 nOtherIndex = fieldDefinition.lastIndexOf("\\#"); //number format + if (nOtherIndex > 0 && (nOtherIndex < nLastIndex || nLastIndex < 0)) + nLastIndex = nOtherIndex; + nOtherIndex = fieldDefinition.lastIndexOf("\\@"); //date format + if (nOtherIndex > 0 && (nOtherIndex < nLastIndex || nLastIndex < 0)) + nLastIndex = nOtherIndex; + nOtherIndex = fieldDefinition.lastIndexOf("\\!"); //locked result + if (nOtherIndex > 0 && (nOtherIndex < nLastIndex || nLastIndex < 0)) + nLastIndex = nOtherIndex; + if (nLastIndex > 0) + fieldDefinition = fieldDefinition.copy(0, nLastIndex); + SwHiddenTextField::ParseIfFieldDefinition(fieldDefinition, paramCondition, paramTrue, paramFalse); // create new field @@ -613,13 +661,13 @@ sal_uInt16 SwWW8ImplReader::End_Field() } default: OUString aCode = m_aFieldStack.back().GetBookmarkCode(); - if (!aCode.isEmpty() && !aCode.trim().startsWith("SHAPE")) + if (!aCode.isEmpty() && !o3tl::starts_with(o3tl::trim(aCode), u"SHAPE")) { // Unhandled field with stored code SwPosition aEndPos = *m_pPaM->GetPoint(); SwPaM aFieldPam( - m_aFieldStack.back().GetPtNode(), m_aFieldStack.back().GetPtContent(), - aEndPos.nNode, aEndPos.nContent.GetIndex()); + m_aFieldStack.back().GetPtNode().GetNode(), m_aFieldStack.back().GetPtContent(), + aEndPos.GetNode(), aEndPos.GetContentIndex()); IDocumentMarkAccess* pMarksAccess = m_rDoc.getIDocumentMarkAccess( ); @@ -639,11 +687,11 @@ sal_uInt16 SwWW8ImplReader::End_Field() pFieldmark->GetParameters()->insert( std::pair< OUString, uno::Any > ( ODF_ID_PARAM, - uno::makeAny( sFieldId ) ) ); + uno::Any( sFieldId ) ) ); pFieldmark->GetParameters()->insert( std::pair< OUString, uno::Any > ( ODF_CODE_PARAM, - uno::makeAny( aCode ) ) ); + uno::Any( aCode ) ) ); if ( m_aFieldStack.back().mnObjLocFc > 0 ) { @@ -651,8 +699,8 @@ sal_uInt16 SwWW8ImplReader::End_Field() OUString sOleId = "_" + OUString::number( m_aFieldStack.back().mnObjLocFc ); - tools::SvRef<SotStorage> xSrc0 = m_pStg->OpenSotStorage(SL::aObjectPool); - tools::SvRef<SotStorage> xSrc1 = xSrc0->OpenSotStorage( sOleId, StreamMode::READ ); + rtl::Reference<SotStorage> xSrc0 = m_pStg->OpenSotStorage(SL::aObjectPool); + rtl::Reference<SotStorage> xSrc1 = xSrc0->OpenSotStorage( sOleId, StreamMode::READ ); // Store it now! uno::Reference< embed::XStorage > xDocStg = GetDoc().GetDocStorage(); @@ -660,7 +708,7 @@ sal_uInt16 SwWW8ImplReader::End_Field() { uno::Reference< embed::XStorage > xOleStg = xDocStg->openStorageElement( "OLELinks", embed::ElementModes::WRITE ); - tools::SvRef<SotStorage> xObjDst = SotStorage::OpenOLEStorage( xOleStg, sOleId ); + rtl::Reference<SotStorage> xObjDst = SotStorage::OpenOLEStorage( xOleStg, sOleId ); if ( xObjDst.is() ) { @@ -678,7 +726,7 @@ sal_uInt16 SwWW8ImplReader::End_Field() // Store the OLE Id as a parameter pFieldmark->GetParameters()->insert( std::pair< OUString, uno::Any >( - ODF_OLE_PARAM, uno::makeAny( sOleId ) ) ); + ODF_OLE_PARAM, uno::Any( sOleId ) ) ); } } } @@ -889,7 +937,7 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) if (bNested) return 0; - sal_uInt16 n = (aF.nId <= eMax) ? aF.nId : static_cast<sal_uInt16>(eMax); + sal_uInt16 n = (aF.nId <= eMax) ? aF.nId : o3tl::narrowing<sal_uInt16>(eMax); sal_uInt16 nI = n / 32; // # of sal_uInt32 sal_uInt32 nMask = 1 << ( n % 32 ); // Mask for bits @@ -920,8 +968,7 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) bool bHasHandler = aWW8FieldTab[aF.nId] != nullptr; if (aF.nId == 10) // STYLEREF { - // STYLEREF, by default these are not handled. - bHasHandler = false; + bool bHandledByChapter = false; sal_uInt64 nOldPos = m_pStrm->Tell(); OUString aStr; aF.nLCode = m_xSBase->WW8ReadString(*m_pStrm, aStr, m_xPlcxMan->GetCpOfs() + aF.nSCode, aF.nLCode, m_eTextCharSet); @@ -931,9 +978,9 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) sal_Int32 nRet = aReadParam.SkipToNextToken(); if (nRet == -2 && !aReadParam.GetResult().isEmpty()) // Single numeric argument: this can be handled by SwChapterField. - bHasHandler = rtl::isAsciiDigit(aReadParam.GetResult()[0]); + bHandledByChapter = rtl::isAsciiDigit(aReadParam.GetResult()[0]); - if (bHasHandler) + if (bHandledByChapter) { nRet = aReadParam.SkipToNextToken(); // Handle using SwChapterField only in case there is no \[a-z] @@ -951,7 +998,7 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) if (aF.bResNest && !AcceptableNestedField(aF.nId)) return aF.nLen; // Result nested -> unusable - tools::Long nOldPos = m_pStrm->Tell(); + sal_uInt64 nOldPos = m_pStrm->Tell(); OUString aStr; aF.nLCode = m_xSBase->WW8ReadString( *m_pStrm, aStr, m_xPlcxMan->GetCpOfs()+ aF.nSCode, aF.nLCode, m_eTextCharSet ); @@ -977,6 +1024,16 @@ tools::Long SwWW8ImplReader::Read_Field(WW8PLCFManResult* pRes) m_bEmbeddObj = true; // Field not supported: store the field code for later use m_aFieldStack.back().SetBookmarkCode( aStr ); + + if (aF.nId == ww::eIF) + { + // In MS Word, the IF field is editable and requires a manual refresh + // so the last, saved result might not match either of the true or false options. + // But in LO the field is automatically updated and not editable, + // so the previous result is of no value to import since it could never be seen. + return aF.nLen; + } + return aF.nLen - aF.nLRes - 1; // skipped too many, the resulted field will be read like main text } } @@ -1052,29 +1109,29 @@ void SwWW8ImplReader::MakeTagString( OUString& rStr, const OUString& rOrg ) case 132: // Exchange typographical quotation marks for normal ones case 148: case 147: - rStr = rStr.replaceAt( nI, 1, "\"" ); + rStr = rStr.replaceAt( nI, 1, u"\"" ); break; case 19: - rStr = rStr.replaceAt( nI, 1, "{" ); + rStr = rStr.replaceAt( nI, 1, u"{" ); break; // 19..21 to {|} case 20: - rStr = rStr.replaceAt( nI, 1, "|" ); + rStr = rStr.replaceAt( nI, 1, u"|" ); break; case 21: - rStr = rStr.replaceAt( nI, 1, "}" ); + rStr = rStr.replaceAt( nI, 1, u"}" ); break; case '\\': // Tag \{|} with \ ... case '{': case '|': case '}': - rStr = rStr.replaceAt( nI, 0, "\\" ); + rStr = rStr.replaceAt( nI, 0, u"\\" ); ++nI; break; case 0x0b: case 0x0c: case 0x0d: if( bAllowCr ) - rStr = rStr.replaceAt( nI, 1, "\n" ); + rStr = rStr.replaceAt( nI, 1, u"\n" ); else bSetAsHex = true; break; @@ -1130,7 +1187,7 @@ void SwWW8ImplReader::InsertTagField( const sal_uInt16 nId, const OUString& rTag WW8_CP SwWW8ImplReader::Read_F_Tag( WW8FieldDesc* pF ) { - tools::Long nOldPos = m_pStrm->Tell(); + sal_uInt64 nOldPos = m_pStrm->Tell(); WW8_CP nStart = pF->nSCode - 1; // starting with 0x19 WW8_CP nL = pF->nLen; // Total length with result and nest @@ -1190,7 +1247,7 @@ eF_ResT SwWW8ImplReader::Read_F_Input( WW8FieldDesc* pF, OUString& rStr ) // GetFieldResult allocates a string and reads the resulted field OUString SwWW8ImplReader::GetFieldResult( WW8FieldDesc const * pF ) { - tools::Long nOldPos = m_pStrm->Tell(); + sal_uInt64 nOldPos = m_pStrm->Tell(); WW8_CP nStart = pF->nSRes; // result start WW8_CP nL = pF->nLRes; // result length @@ -1298,13 +1355,13 @@ tools::Long SwWW8ImplReader::MapBookmarkVariables(const WW8FieldDesc* pF, } else { - nNo = m_xReffingStck->aFieldVarNames.size()+1; + nNo = m_xReffingStck->m_aFieldVarNames.size()+1; sName = "WWSetBkmk" + OUString::number(nNo); nNo += m_xPlcxMan->GetBook()->GetIMax(); } m_xReffedStck->NewAttr(*m_pPaM->GetPoint(), SwFltBookmark( BookmarkToWriter(sName), rData, nNo )); - m_xReffingStck->aFieldVarNames[rOrigName] = sName; + m_xReffingStck->m_aFieldVarNames[rOrigName] = sName; return nNo; } @@ -1327,14 +1384,14 @@ SwFltStackEntry *SwWW8FltRefStack::RefToVar(const SwField* pField, //Get the name of the ref field, and see if actually a variable const OUString sName = pField->GetPar1(); std::map<OUString, OUString, SwWW8::ltstr>::const_iterator - aResult = aFieldVarNames.find(sName); + aResult = m_aFieldVarNames.find(sName); - if (aResult != aFieldVarNames.end()) + if (aResult != m_aFieldVarNames.end()) { SwGetExpField aField( static_cast<SwGetExpFieldType*>( - rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetExp)), sName, nsSwGetSetExpType::GSE_STRING, 0); + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::GetExp)), sName, nsSwGetSetExpType::GSE_STRING, 0); SwFormatField aTmp(aField); - rEntry.pAttr.reset( aTmp.Clone() ); + rEntry.m_pAttr.reset( aTmp.Clone() ); pRet = &rEntry; } } @@ -1350,9 +1407,9 @@ OUString SwWW8ImplReader::GetMappedBookmark(std::u16string_view rOrigName) //See if there has been a variable set with this name, if so get //the pseudo bookmark name that was set with it. std::map<OUString, OUString, SwWW8::ltstr>::const_iterator aResult = - m_xReffingStck->aFieldVarNames.find(sName); + m_xReffingStck->m_aFieldVarNames.find(sName); - return (aResult == m_xReffingStck->aFieldVarNames.end()) + return (aResult == m_xReffingStck->m_aFieldVarNames.end()) ? sName : (*aResult).second; } @@ -1417,10 +1474,9 @@ eF_ResT SwWW8ImplReader::Read_F_ANumber( WW8FieldDesc*, OUString& rStr ) { if( !m_pNumFieldType ){ // 1st time SwSetExpFieldType aT( &m_rDoc, "AutoNr", nsSwGetSetExpType::GSE_SEQ ); - m_pNumFieldType = m_rDoc.getIDocumentFieldsAccess().InsertFieldType( aT ); + m_pNumFieldType = static_cast<SwSetExpFieldType*>(m_rDoc.getIDocumentFieldsAccess().InsertFieldType( aT )); } - SwSetExpField aField( static_cast<SwSetExpFieldType*>(m_pNumFieldType), OUString(), - GetNumberPara( rStr ) ); + SwSetExpField aField( m_pNumFieldType, OUString(), GetNumberPara( rStr ) ); aField.SetValue( ++m_nFieldNum, nullptr ); m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); return eF_ResT::OK; @@ -1530,6 +1586,7 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) // RegInfoFormat, DefaultFormat for DocInfoFields sal_uInt16 nReg = DI_SUB_AUTHOR; bool bDateTime = false; + const sal_uInt16 nFldLock = (pF->nOpt & 0x10) ? DI_SUB_FIXED : 0; if( 85 == pF->nId ) { @@ -1639,9 +1696,35 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) if( !bFieldFound ) { - SwDocInfoField aField( static_cast<SwDocInfoFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), DI_CUSTOM|nReg, aDocProperty, GetFieldResult( pF ) ); - m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField)); + // LO always automatically updates a DocInfo field from the File-Properties-Custom Prop + // while MS Word requires the user to manually refresh the field (with F9). + // In other words, Word lets the field to be out of sync with the controlling variable. + // Marking as FIXEDFLD solves the automatic replacement problem, but of course prevents + // Writer from making any changes, even on an F9 refresh. + // TODO: Extend LO to allow a linked field that doesn't automatically update. + IDocumentContentOperations& rIDCO(m_rDoc.getIDocumentContentOperations()); + const auto pType(static_cast<SwDocInfoFieldType*>( + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo))); + const OUString sDisplayed = GetFieldResult(pF); + SwDocInfoField aField(pType, DI_CUSTOM | nReg, aDocProperty); + + // If text already matches the DocProperty var, then safe to treat as refreshable field. + OUString sVariable = aField.ExpandField(/*bCache=*/false, nullptr); + if (sDisplayed.getLength() != sVariable.getLength()) + { + sal_Int32 nLen = sVariable.indexOf('\x0'); + if (nLen >= 0) + sVariable = sVariable.copy(0, nLen); + } + if (sDisplayed == sVariable) + rIDCO.InsertPoolItem(*m_pPaM, SwFormatField(aField)); + else + { + // They don't match, so use a fixed field to prevent LO from altering the contents. + SwDocInfoField aFixedField(pType, DI_CUSTOM | DI_SUB_FIXED | nReg, aDocProperty, + sDisplayed); + rIDCO.InsertPoolItem(*m_pPaM, SwFormatField(aFixedField)); + } return eF_ResT::OK; } @@ -1666,16 +1749,18 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) nSub = DI_COMMENT; break; case 20: - nSub = DI_CHANGE; + // MS Word never updates this automatically, so mark as fixed for best compatibility + nSub = DI_CHANGE | DI_SUB_FIXED; nReg = DI_SUB_AUTHOR; break; case 21: - nSub = DI_CREATE; + // The real create date can never change, so mark as fixed for best compatibility + nSub = DI_CREATE | DI_SUB_FIXED; nReg = DI_SUB_DATE; bDateTime = true; break; case 23: - nSub = DI_PRINT; + nSub = DI_PRINT | nFldLock; nReg = DI_SUB_DATE; bDateTime = true; break; @@ -1683,12 +1768,12 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) nSub = DI_DOCNO; break; case 22: - nSub = DI_CHANGE; + nSub = DI_CHANGE | nFldLock; nReg = DI_SUB_DATE; bDateTime = true; break; case 25: - nSub = DI_CHANGE; + nSub = DI_CHANGE | nFldLock; nReg = DI_SUB_TIME; bDateTime = true; break; @@ -1746,21 +1831,39 @@ eF_ResT SwWW8ImplReader::Read_F_DocInfo( WW8FieldDesc* pF, OUString& rStr ) aData = aData.replaceAll("\"", ""); } - SwDocInfoField aField( static_cast<SwDocInfoFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), nSub|nReg, aData, nFormat ); - if (bDateTime) - ForceFieldLanguage(aField, nLang); - m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField)); + bool bDone = false; + if (DI_CUSTOM == nSub) + { + const auto pType(static_cast<SwUserFieldType*>( + m_rDoc.getIDocumentFieldsAccess().GetFieldType(SwFieldIds::User, aData, false))); + if (pType) + { + SwUserField aField(pType, 0, nFormat); + if (bDateTime) + ForceFieldLanguage(aField, nLang); + m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField)); + bDone = true; + } + } + if (!bDone) + { + const auto pType(static_cast<SwDocInfoFieldType*>( + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DocInfo))); + SwDocInfoField aField(pType, nSub|nReg, aData, GetFieldResult(pF), nFormat); + if (bDateTime) + ForceFieldLanguage(aField, nLang); + m_rDoc.getIDocumentContentOperations().InsertPoolItem(*m_pPaM, SwFormatField(aField)); + } return eF_ResT::OK; } -eF_ResT SwWW8ImplReader::Read_F_Author( WW8FieldDesc*, OUString& ) +eF_ResT SwWW8ImplReader::Read_F_Author(WW8FieldDesc* pF, OUString&) { // SH: The SwAuthorField refers not to the original author but to the current user, better use DocInfo SwDocInfoField aField( static_cast<SwDocInfoFieldType*>( m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::DocInfo )), - DI_CREATE|DI_SUB_AUTHOR, OUString() ); + DI_CREATE|DI_SUB_AUTHOR|DI_SUB_FIXED, OUString(), GetFieldResult(pF)); m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); return eF_ResT::OK; } @@ -1819,31 +1922,22 @@ eF_ResT SwWW8ImplReader::Read_F_DateTime( WW8FieldDesc*pF, OUString& rStr ) } } - sal_uInt16 nDoNotRecalculate = (pF->nOpt & 0x10) ? FIXEDFLD : 0; - if (nDoNotRecalculate) - { - // TODO: Doing this properly would require setting the field to the original date/time. - // Unfortunately, none of the plumbing to do this exists AFAICS - //SAL_WARN("DEBUG","Need to aField.SetDateTime() to ["<<GetFieldResult(pF)<<"] based on format string["<<aReadParam.GetResult()<<"]"); - // So instead, just drop the field and insert the plain text. - // That is at least better than having the current date/time. - return eF_ResT::TEXT; - } - if (nDT & SvNumFormatType::DATE) + if (nDT & SvNumFormatType::DATE || nDT == SvNumFormatType::TIME) { SwDateTimeField aField(static_cast<SwDateTimeFieldType*>( m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime)), - (DATEFLD | nDoNotRecalculate), - nFormat); - ForceFieldLanguage(aField, nLang); - m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); - } - else if (nDT == SvNumFormatType::TIME) - { - SwDateTimeField aField(static_cast<SwDateTimeFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType(SwFieldIds::DateTime)), - (TIMEFLD | nDoNotRecalculate), - nFormat); + nDT & SvNumFormatType::DATE ? DATEFLD : TIMEFLD, nFormat); + if (pF->nOpt & 0x10) // Fixed field + { + double fSerial; + if (!m_rDoc.GetNumberFormatter()->IsNumberFormat(GetFieldResult(pF), nFormat, fSerial, + SvNumInputOptions::LAX_TIME)) + return eF_ResT::TEXT; // just drop the field and insert the plain text. + aField.SetSubType(aField.GetSubType() | FIXEDFLD); + DateTime aSetDateTime(m_rDoc.GetNumberFormatter()->GetNullDate()); + aSetDateTime.AddTime(fSerial); + aField.SetDateTime(aSetDateTime); + } ForceFieldLanguage(aField, nLang); m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); } @@ -2099,12 +2193,12 @@ eF_ResT SwWW8ImplReader::Read_F_Ref( WW8FieldDesc*, OUString& rStr ) { sBkmName = EnsureTOCBookmarkName(sBkmName); // track <sBookmarkName> as referenced TOC bookmark. - m_xReffedStck->aReferencedTOCBookmarks.insert( sBkmName ); + m_xReffedStck->m_aReferencedTOCBookmarks.insert( sBkmName ); } SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), - sBkmName,"",REF_BOOKMARK,0,eFormat); + sBkmName,"",REF_BOOKMARK,0,0,eFormat); if (eFormat == REF_CONTENT) { @@ -2159,14 +2253,14 @@ eF_ResT SwWW8ImplReader::Read_F_NoteReference( WW8FieldDesc*, OUString& rStr ) // set Sequence No of corresponding Foot-/Endnote to Zero // (will be corrected in SwGetRefField aField( static_cast<SwGetRefFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, "", REF_FOOTNOTE, 0, + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), aBkmName, "", REF_FOOTNOTE, 0, 0, REF_ONLYNUMBER ); m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField)); m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD); if (bAboveBelow) { SwGetRefField aField2( static_cast<SwGetRefFieldType*>( - m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0, + m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )),aBkmName, "", REF_FOOTNOTE, 0, 0, REF_UPDOWN ); m_xReffingStck->NewAttr(*m_pPaM->GetPoint(), SwFormatField(aField2)); m_xReffingStck->SetAttr(*m_pPaM->GetPoint(), RES_TXTATR_FIELD); @@ -2207,7 +2301,7 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) { sBookmarkName = EnsureTOCBookmarkName(sName); // track <sBookmarkName> as referenced TOC bookmark. - m_xReffedStck->aReferencedTOCBookmarks.insert( sBookmarkName ); + m_xReffedStck->m_aReferencedTOCBookmarks.insert( sBookmarkName ); } else { @@ -2215,7 +2309,7 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) } OUString sURL = "#" + sBookmarkName; SwFormatINetFormat aURL( sURL, "" ); - static const OUStringLiteral sLinkStyle(u"Index Link"); + static constexpr OUString sLinkStyle(u"Index Link"_ustr); const sal_uInt16 nPoolId = SwStyleNameMapper::GetPoolIdFromUIName( sLinkStyle, SwGetPoolIdFromName::ChrFmt ); aURL.SetVisitedFormatAndId( sLinkStyle, nPoolId); @@ -2232,14 +2326,14 @@ eF_ResT SwWW8ImplReader::Read_F_PgRef( WW8FieldDesc*, OUString& rStr ) { sPageRefBookmarkName = EnsureTOCBookmarkName(sName); // track <sPageRefBookmarkName> as referenced TOC bookmark. - m_xReffedStck->aReferencedTOCBookmarks.insert( sPageRefBookmarkName ); + m_xReffedStck->m_aReferencedTOCBookmarks.insert( sPageRefBookmarkName ); } else { sPageRefBookmarkName = sName; } SwGetRefField aField( static_cast<SwGetRefFieldType*>(m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::GetRef )), - sPageRefBookmarkName, "", REF_BOOKMARK, 0, REF_PAGE ); + sPageRefBookmarkName, "", REF_BOOKMARK, 0, 0, REF_PAGE ); m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); return eF_ResT::OK; @@ -2280,8 +2374,6 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) bool bBracket = false; WW8ReadFieldParams aReadParam( rStr ); - sal_Int32 nOffset = 0; - for (;;) { const sal_Int32 nRet = aReadParam.SkipToNextToken(); @@ -2294,8 +2386,6 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) aName = aReadParam.GetResult(); else if( aVText.isEmpty() || bBracket ) { - nOffset = aReadParam.GetTokenSttPtr() + 1; - if( bBracket ) aVText += " "; aVText += aReadParam.GetResult(); @@ -2323,19 +2413,7 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) m_rDoc.getIDocumentFieldsAccess().GetSysFieldType( SwFieldIds::Macro )), aName, aVText ); if( !bApplyWingdings ) - { - m_rDoc.getIDocumentContentOperations().InsertPoolItem( *m_pPaM, SwFormatField( aField ) ); - WW8_CP nOldCp = m_xPlcxMan->Where(); - WW8_CP nCp = nOldCp + nOffset; - - SwPaM aPaM(*m_pPaM, m_pPaM); - aPaM.SetMark(); - aPaM.Move(fnMoveBackward); - aPaM.Exchange(); - - m_pPostProcessAttrsInfo.reset(new WW8PostProcessAttrsInfo(nCp, nCp, aPaM)); - } else { //set Wingdings font @@ -2366,16 +2444,6 @@ eF_ResT SwWW8ImplReader::Read_F_Macro( WW8FieldDesc*, OUString& rStr) return eF_ResT::OK; } -WW8PostProcessAttrsInfo::WW8PostProcessAttrsInfo(WW8_CP nCpStart, WW8_CP nCpEnd, - SwPaM & rPaM) - : mbCopy(false) - , mnCpStart(nCpStart) - , mnCpEnd(nCpEnd) - , mPaM(*rPaM.GetMark(), *rPaM.GetPoint()) - , mItemSet(rPaM.GetDoc().GetAttrPool(), svl::Items<RES_CHRATR_BEGIN, RES_PARATR_END - 1>{}) -{ -} - bool CanUseRemoteLink(const OUString &rGrfName) { bool bUseRemote = false; @@ -2461,8 +2529,7 @@ eF_ResT SwWW8ImplReader::Read_F_IncludePicture( WW8FieldDesc*, OUString& rStr ) that we have inserted a graphic link and the suiting SwAttrSet will be inserted into the frame format. */ - SfxItemSet aFlySet( m_rDoc.GetAttrPool(), svl::Items<RES_FRMATR_BEGIN, - RES_FRMATR_END-1>{} ); + SfxItemSetFixed<RES_FRMATR_BEGIN, RES_FRMATR_END-1> aFlySet( m_rDoc.GetAttrPool() ); aFlySet.Put( SwFormatAnchor( RndStdIds::FLY_AS_CHAR ) ); aFlySet.Put( SwFormatVertOrient( 0, text::VertOrientation::TOP, text::RelOrientation::FRAME )); m_pFlyFormatOfJustInsertedGraphic = @@ -2542,12 +2609,11 @@ eF_ResT SwWW8ImplReader::Read_F_IncludeText( WW8FieldDesc* /*pF*/, OUString& rSt if (!pSectionNode) return eF_ResT::TEXT; - m_pPaM->GetPoint()->nNode = pSectionNode->GetIndex()+1; - m_pPaM->GetPoint()->nContent.Assign(m_pPaM->GetContentNode(), 0 ); + m_pPaM->GetPoint()->Assign( pSectionNode->GetIndex()+1 ); //we have inserted a section before this point, so adjust pos //for future page/section segment insertion - m_aSectionManager.PrependedInlineNode(aTmpPos, m_pPaM->GetNode()); + m_aSectionManager.PrependedInlineNode(aTmpPos, m_pPaM->GetPointNode()); return eF_ResT::TEXT; } @@ -2555,7 +2621,7 @@ eF_ResT SwWW8ImplReader::Read_F_IncludeText( WW8FieldDesc* /*pF*/, OUString& rSt // "SERIALPRINT" eF_ResT SwWW8ImplReader::Read_F_DBField( WW8FieldDesc* pF, OUString& rStr ) { -#if !HAVE_FEATURE_DBCONNECTIVITY +#if !HAVE_FEATURE_DBCONNECTIVITY || ENABLE_FUZZERS (void) pF; (void) rStr; #else @@ -2596,7 +2662,7 @@ eF_ResT SwWW8ImplReader::Read_F_DBField( WW8FieldDesc* pF, OUString& rStr ) // "NEXT" eF_ResT SwWW8ImplReader::Read_F_DBNext( WW8FieldDesc*, OUString& ) { -#if HAVE_FEATURE_DBCONNECTIVITY +#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS SwDBNextSetFieldType aN; SwFieldType* pFT = m_rDoc.getIDocumentFieldsAccess().InsertFieldType( aN ); SwDBNextSetField aField( static_cast<SwDBNextSetFieldType*>(pFT), OUString(), @@ -2609,7 +2675,7 @@ eF_ResT SwWW8ImplReader::Read_F_DBNext( WW8FieldDesc*, OUString& ) // "DATASET" eF_ResT SwWW8ImplReader::Read_F_DBNum( WW8FieldDesc*, OUString& ) { -#if HAVE_FEATURE_DBCONNECTIVITY +#if HAVE_FEATURE_DBCONNECTIVITY && !ENABLE_FUZZERS SwDBSetNumberFieldType aN; SwFieldType* pFT = m_rDoc.getIDocumentFieldsAccess().InsertFieldType( aN ); SwDBSetNumberField aField( static_cast<SwDBSetNumberFieldType*>(pFT), @@ -2675,7 +2741,7 @@ void SwWW8ImplReader::Read_SubF_Ruby( WW8ReadFieldParams& rReadParam) if( sTemp.startsWithIgnoreAsciiCase( "jc" ) ) { sTemp = sTemp.copy(2); - nJustificationCode = static_cast<sal_uInt16>(sTemp.toInt32()); + nJustificationCode = o3tl::narrowing<sal_uInt16>(sTemp.toInt32()); } else if( sTemp.startsWithIgnoreAsciiCase( "hps" ) ) { @@ -2772,11 +2838,11 @@ void SwWW8ImplReader::Read_SubF_Ruby( WW8ReadFieldParams& rReadParam) for(const auto& rpCharFormat : m_aRubyCharFormats) { const SvxFontHeightItem &rFH = - ItemGet<SvxFontHeightItem>(*rpCharFormat, - GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)); + rpCharFormat->GetFormatAttr( + GetWhichOfScript(RES_CHRATR_FONTSIZE,nScript)); if (rFH.GetHeight() == nFontSize*10) { - const SvxFontItem &rF = ItemGet<SvxFontItem>(*rpCharFormat, + const SvxFontItem &rF = rpCharFormat->GetFormatAttr( GetWhichOfScript(RES_CHRATR_FONT,nScript)); if (rF.GetFamilyName() == sFontName) { @@ -2887,13 +2953,13 @@ static void lcl_toxMatchTSwitch(SwWW8ImplReader const & rReader, SwTOXBase& rBas else while( -1 != nIndex ) { sal_Int32 nOldIndex=nIndex; - sal_uInt16 nLevel = static_cast<sal_uInt16>( - sParams.getToken(0, ';', nIndex).toInt32()); + sal_uInt16 nLevel = o3tl::narrowing<sal_uInt16>( + o3tl::toInt32(o3tl::getToken(sParams, 0, ';', nIndex))); if( -1 == nIndex ) { nIndex = nOldIndex; - nLevel = static_cast<sal_uInt16>( - sParams.getToken(0, ',', nIndex).toInt32()); + nLevel = o3tl::narrowing<sal_uInt16>( + o3tl::toInt32(o3tl::getToken(sParams, 0, ',', nIndex))); } if( (0 < nLevel) && (MAXLEVEL >= nLevel) ) @@ -2933,13 +2999,13 @@ sal_uInt16 wwSectionManager::CurrentSectionColCount() const //Will there be a new pagebreak at this position (don't know what type //until later) -bool wwSectionManager::WillHavePageDescHere(const SwNodeIndex& rIdx) const +bool wwSectionManager::WillHavePageDescHere(const SwNode& rNd) const { bool bRet = false; if (!maSegments.empty()) { if (!maSegments.back().IsContinuous() && - maSegments.back().maStart == rIdx) + maSegments.back().maStart == rNd) { bRet = true; } @@ -3023,7 +3089,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) // if NO OUString just ignore the \c if( !sParams.isEmpty() ) { - nIndexCols = static_cast<sal_uInt16>(sParams.toInt32()); + nIndexCols = o3tl::narrowing<sal_uInt16>(sParams.toInt32()); } } break; @@ -3070,7 +3136,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) aToken.sText = sDelimiter; *aIt = aToken; } - aForm.SetPattern(nLevel, aPattern); + aForm.SetPattern(nLevel, std::move(aPattern)); } eType = TOKEN_END; @@ -3192,7 +3258,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) *aIt = aToken; aForm.SetPattern(nLevel, - aPattern); + std::move(aPattern)); } eType = TOKEN_END; } @@ -3244,7 +3310,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) ) { aPattern.erase(aIt); - aForm.SetPattern(nLevel, aPattern); + aForm.SetPattern(nLevel, std::move(aPattern)); } eType = TOKEN_END; } @@ -3291,7 +3357,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) aPattern.insert(aItr, aLinkStart); } aPattern.push_back(aLinkEnd); - aForm.SetPattern(nLevel, aPattern); + aForm.SetPattern(nLevel, std::move(aPattern)); } pBase->SetTOXForm(aForm); @@ -3337,7 +3403,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) SwFormToken aNumberEntrySeparator( TOKEN_TEXT ); aNumberEntrySeparator.sText = " "; aPattern.insert( ++aIt, aNumberEntrySeparator ); - pForm->SetPattern( nStyleLevel, aPattern ); + pForm->SetPattern( nStyleLevel, std::move(aPattern) ); } } } @@ -3379,7 +3445,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) SwFormTokens::iterator new_end = remove_if(aPattern.begin(), aPattern.end(), SwFormTokenEqualToFormTokenType(TOKEN_ENTRY_NO)); aPattern.erase(new_end, aPattern.end() ); // table index imported with wrong page number format - aForm.SetPattern( nLevel, aPattern ); + aForm.SetPattern( nLevel, std::move(aPattern) ); aForm.SetTemplate( nLevel, aOldForm.GetTemplate(nLevel) ); } @@ -3404,13 +3470,13 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) //#i10028# inserting a toc implicitly acts like a parabreak in word and writer if ( m_pPaM->End() && - m_pPaM->End()->nNode.GetNode().GetTextNode() && - m_pPaM->End()->nNode.GetNode().GetTextNode()->Len() != 0 ) + m_pPaM->End()->GetNode().GetTextNode() && + m_pPaM->End()->GetNode().GetTextNode()->Len() != 0 ) { m_bCareFirstParaEndInToc = true; } - if (m_pPaM->GetPoint()->nContent.GetIndex()) + if (m_pPaM->GetPoint()->GetContentIndex()) AppendTextNode(*m_pPaM->GetPoint()); const SwPosition* pPos = m_pPaM->GetPoint(); @@ -3418,7 +3484,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) SwFltTOX aFltTOX( pBase ); // test if there is already a break item on this node - if(SwContentNode* pNd = pPos->nNode.GetNode().GetContentNode()) + if(SwContentNode* pNd = pPos->GetNode().GetContentNode()) { const SfxItemSet* pSet = pNd->GetpSwAttrSet(); if( pSet ) @@ -3432,7 +3498,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) //Will there be a new pagebreak at this position (don't know what type //until later) - if (m_aSectionManager.WillHavePageDescHere(pPos->nNode)) + if (m_aSectionManager.WillHavePageDescHere(pPos->GetNode())) aFltTOX.SetHadPageDescItem(true); // Set start in stack @@ -3442,7 +3508,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) //The TOC field representation contents should be inserted into TOC section, but not after TOC section. //So we need update the document position when loading TOC representation and after loading TOC; - m_pPosAfterTOC.reset(new SwPaM(*m_pPaM, m_pPaM)); + m_oPosAfterTOC.emplace(*m_pPaM, m_pPaM); (*m_pPaM).Move(fnMoveBackward); SwPaM aRegion(*m_pPaM, m_pPaM); @@ -3454,7 +3520,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) if ( nIndexCols > 1 ) { // Set the column number for index - SfxItemSet aSet( m_rDoc.GetAttrPool(), svl::Items<RES_COL, RES_COL>{} ); + SfxItemSetFixed<RES_COL, RES_COL> aSet( m_rDoc.GetAttrPool() ); SwFormatCol aCol; aCol.Init( nIndexCols, 708, USHRT_MAX ); aSet.Put( aCol ); @@ -3463,7 +3529,7 @@ eF_ResT SwWW8ImplReader::Read_F_Tox( WW8FieldDesc* pF, OUString& rStr ) // inserting a toc inserts a section before this point, so adjust pos // for future page/section segment insertion - m_aSectionManager.PrependedInlineNode( *m_pPosAfterTOC->GetPoint(), aRegion.GetNode() ); + m_aSectionManager.PrependedInlineNode( *m_oPosAfterTOC->GetPoint(), aRegion.GetPointNode() ); } // Set end in stack @@ -3528,7 +3594,7 @@ eF_ResT SwWW8ImplReader::Read_F_Hyperlink( WW8FieldDesc* /*pF*/, OUString& rStr { sMark = EnsureTOCBookmarkName(sMark); // track <sMark> as referenced TOC bookmark. - m_xReffedStck->aReferencedTOCBookmarks.insert( sMark ); + m_xReffedStck->m_aReferencedTOCBookmarks.insert( sMark ); } if (m_bLoadingTOXCache) @@ -3616,7 +3682,7 @@ static void lcl_ImportTox(SwDoc &rDoc, SwPaM const &rPaM, const OUString &rStr, // if NO String just ignore the \l if( !sParams.isEmpty() && sParams[0]>'0' && sParams[0]<='9' ) { - nLevel = static_cast<sal_uInt16>(sParams.toInt32()); + nLevel = o3tl::narrowing<sal_uInt16>(sParams.toInt32()); } } break; @@ -3684,7 +3750,7 @@ void SwWW8ImplReader::Read_FieldVanish( sal_uInt16, const sal_uInt8*, short nLen return; m_bIgnoreText = true; - tools::Long nOldPos = m_pStrm->Tell(); + sal_uInt64 nOldPos = m_pStrm->Tell(); WW8_CP nStartCp = m_xPlcxMan->Where() + m_xPlcxMan->GetCpOfs(); |