diff options
author | Jim Raykowski <raykowj@gmail.com> | 2022-04-16 19:38:07 -0800 |
---|---|---|
committer | Jim Raykowski <raykowj@gmail.com> | 2022-04-19 20:52:29 +0200 |
commit | c7ed23137f7601833793ea8c27e1c601b6d19290 (patch) | |
tree | 0e72122f1ab11727121bf1aa74d17274ca4f105a /sw | |
parent | 70bea73ffbe815c2d5b7067f20d3eebbb98df61f (diff) |
SwNavigator: List fields content type members in document order
Currently all Fields content type members may not be listed in the
order of document appearance. This happens because the sort is done
using *only* the document model position of the text node (paragraph)
the field is in. Fields in the same text node (parargraph) have the
same sort value which results in an alphabetical sort of these. This
patch uses both the document model text node index and start position
of the field in the text node text to make the fields content type
members list in the order of document appearance. This method is
already used to sort Hyperlinks content type members in the order of
document appearance.
Change-Id: I05f5ad0699764a265b5320047b67e7f418b7fa99
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/133101
Tested-by: Jenkins
Reviewed-by: Jim Raykowski <raykowj@gmail.com>
Diffstat (limited to 'sw')
-rw-r--r-- | sw/source/uibase/utlui/content.cxx | 113 |
1 files changed, 73 insertions, 40 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 02b07633f531..6321c9b7db41 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -301,6 +301,25 @@ sal_Int32 getYPos(const SwNodeIndex& rNodeIndex) } return sal_Int32(nIndex); } +// Gets the content node used to sort content members in Navigator's content types having a +// specific start position +SwContentNode* getContentNode(const SwNode& rNode) +{ + if (rNode.GetNodes().GetEndOfExtras().GetIndex() >= rNode.GetIndex()) + { + // Not a node of BodyText + // Are we in a fly? + if (const auto pFlyFormat = rNode.GetFlyFormat()) + { + // Get node index of anchor + if (auto pSwPosition = pFlyFormat->GetAnchor().GetContentAnchor()) + { + return getContentNode(pSwPosition->nNode.GetNode()); + } + } + } + return const_cast<SwContentNode*>(rNode.GetContentNode()); +} } // end of anonymous namespace SwContentType::SwContentType(SwWrtShell* pShell, ContentTypeId nType, sal_uInt8 nLevel) : @@ -575,6 +594,7 @@ void SwContentType::FillMemberList(bool* pbContentChanged) break; case ContentTypeId::TEXTFIELD: { + std::vector<SwTextField*> aArr; const SwFieldTypes& rFieldTypes = *m_pWrtShell->GetDoc()->getIDocumentFieldsAccess().GetFieldTypes(); const size_t nSize = rFieldTypes.size(); @@ -585,56 +605,69 @@ void SwContentType::FillMemberList(bool* pbContentChanged) continue; std::vector<SwFormatField*> vFields; pFieldType->GatherFields(vFields); - std::vector<OUString> aSubTypesList; - if (pFieldType->Which() == SwFieldIds::DocStat && !vFields.empty()) - { - SwFieldMgr(m_pWrtShell).GetSubTypes(SwFieldTypesEnum::DocumentStatistics, - aSubTypesList); - } for (SwFormatField* pFormatField: vFields) { if (SwTextField* pTextField = pFormatField->GetTextField()) { - const SwField* pField = pFormatField->GetField(); // fields in header footer don't behave well, skip them if (m_pWrtShell->GetDoc()->IsInHeaderFooter(pTextField->GetTextNode())) continue; - OUString sExpandField = pField->ExpandField(true, m_pWrtShell->GetLayout()); - if (!sExpandField.isEmpty()) - sExpandField = u" - " + sExpandField; - OUString sText; - if (pField->GetTypeId() == SwFieldTypesEnum::DocumentStatistics) - { - OUString sSubType; - if (pField->GetSubType() < aSubTypesList.size()) - sSubType = u" - " + aSubTypesList[pField->GetSubType()]; - sText = pField->GetDescription() + u" - " + pField->GetFieldName() - + sSubType + sExpandField; - } - else if (pField->GetTypeId() == SwFieldTypesEnum::GetRef) - { - OUString sFieldSubTypeOrName; - auto nSubType = pField->GetSubType(); - if (nSubType == REF_FOOTNOTE) - sFieldSubTypeOrName = SwResId(STR_FLDREF_FOOTNOTE); - else if (nSubType == REF_ENDNOTE) - sFieldSubTypeOrName = SwResId(STR_FLDREF_ENDNOTE); - else - sFieldSubTypeOrName = pField->GetFieldName(); - sText = pField->GetDescription() + u" - " + sFieldSubTypeOrName - + sExpandField; - } - else - sText = pField->GetDescription() + u" - " + pField->GetFieldName() - + sExpandField; - auto pCnt(std::make_unique<SwTextFieldContent>(this, sText, pFormatField, - m_bAlphabeticSort ? 0 : pTextField->GetTextNode().GetIndex().get())); - if (!pTextField->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout())) - pCnt->SetInvisible(); - m_pMember->insert(std::move(pCnt)); + aArr.emplace_back(pTextField); } } } + if (!m_bAlphabeticSort) + { + // use stable sort array to list fields in document order + std::stable_sort(aArr.begin(), aArr.end(), + [](const SwTextField* a, const SwTextField* b){ + SwPosition aSwPos(*getContentNode(a->GetTextNode()), a->GetStart()); + SwPosition bSwPos(*getContentNode(b->GetTextNode()), b->GetStart()); + return aSwPos < bSwPos;}); + } + std::vector<OUString> aDocumentStatisticsSubTypesList; + tools::Long nYPos = 0; + for (SwTextField* pTextField : aArr) + { + const SwField* pField = pTextField->GetFormatField().GetField(); + OUString sExpandField = pField->ExpandField(true, m_pWrtShell->GetLayout()); + if (!sExpandField.isEmpty()) + sExpandField = u" - " + sExpandField; + OUString sText; + if (pField->GetTypeId() == SwFieldTypesEnum::DocumentStatistics) + { + if (aDocumentStatisticsSubTypesList.empty()) + SwFieldMgr(m_pWrtShell).GetSubTypes(SwFieldTypesEnum::DocumentStatistics, + aDocumentStatisticsSubTypesList); + OUString sSubType; + if (pField->GetSubType() < aDocumentStatisticsSubTypesList.size()) + sSubType = u" - " + aDocumentStatisticsSubTypesList[pField->GetSubType()]; + sText = pField->GetDescription() + u" - " + pField->GetFieldName() + sSubType + + sExpandField; + } + else if (pField->GetTypeId() == SwFieldTypesEnum::GetRef) + { + OUString sFieldSubTypeOrName; + auto nSubType = pField->GetSubType(); + if (nSubType == REF_FOOTNOTE) + sFieldSubTypeOrName = SwResId(STR_FLDREF_FOOTNOTE); + else if (nSubType == REF_ENDNOTE) + sFieldSubTypeOrName = SwResId(STR_FLDREF_ENDNOTE); + else + sFieldSubTypeOrName = pField->GetFieldName(); + sText = pField->GetDescription() + u" - " + sFieldSubTypeOrName + + sExpandField; + } + else + sText = pField->GetDescription() + u" - " + pField->GetFieldName() + + sExpandField; + auto pCnt(std::make_unique<SwTextFieldContent>(this, sText, + &pTextField->GetFormatField(), + m_bAlphabeticSort ? 0 : nYPos++)); + if (!pTextField->GetTextNode().getLayoutFrame(m_pWrtShell->GetLayout())) + pCnt->SetInvisible(); + m_pMember->insert(std::move(pCnt)); + } } break; case ContentTypeId::FOOTNOTE: |