summaryrefslogtreecommitdiff
path: root/sw/source
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2023-05-26 21:29:47 -0800
committerJim Raykowski <raykowj@gmail.com>2023-06-03 20:47:39 +0200
commit4f69e1b07c12ebd8c3655f3205bff143d1ee1a1b (patch)
tree6c86588989c93961062e85d6997b4b2622aaf6d2 /sw/source
parent666925f2ab06e690c41c470713dc83f2d752bfb7 (diff)
tdf#153721 SwNavigator: fix chapter move
Fixes move chapter up/down regressions introduced by commit e27b936fe864cdd2753470e0fef1e3cb1f891555. For regression details please see comments 14 and 16 in the bug report. Change-Id: I0a57483fae51656c89e8b4f3711d8057174517e4 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152347 Tested-by: Jenkins Reviewed-by: Jim Raykowski <raykowj@gmail.com>
Diffstat (limited to 'sw/source')
-rw-r--r--sw/source/uibase/utlui/content.cxx80
1 files changed, 74 insertions, 6 deletions
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index 05721ad4e348..6d22bc53a91e 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -3267,7 +3267,8 @@ void SwContentTree::ExecCommand(std::u16string_view rCmd, bool bOutlineWithChild
SwWrtShell *const pShell = GetWrtShell();
const SwNodes& rNodes = pShell->GetNodes();
- const SwOutlineNodes::size_type nOutlineNdsSize = rNodes.GetOutLineNds().size();
+ const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
+ const SwOutlineNodes::size_type nOutlineNdsSize = rOutlineNodes.size();
std::vector<SwTextNode*> selectedOutlineNodes;
std::vector<std::unique_ptr<weld::TreeIter>> selected;
@@ -3323,13 +3324,27 @@ void SwContentTree::ExecCommand(std::u16string_view rCmd, bool bOutlineWithChild
MakeAllOutlineContentTemporarilyVisible a(GetWrtShell()->GetDoc());
+ // get first regular document content node outline node position in outline nodes array
+ SwOutlineNodes::size_type nFirstRegularDocContentOutlineNodePos = SwOutlineNodes::npos;
+ SwNodeOffset nEndOfExtrasIndex = rNodes.GetEndOfExtras().GetIndex();
+ for (SwOutlineNodes::size_type nPos = 0; nPos < nOutlineNdsSize; nPos++)
+ {
+ if (rOutlineNodes[nPos]->GetIndex() > nEndOfExtrasIndex)
+ {
+ nFirstRegularDocContentOutlineNodePos = nPos;
+ break;
+ }
+ }
+
for (auto const& pCurrentEntry : selected)
{
nActPos = weld::fromId<SwOutlineContent*>(
m_xTreeView->get_id(*pCurrentEntry))->GetOutlinePos();
// outline nodes in frames and tables are not up/down moveable
- if (nActPos == SwOutlineNodes::npos || (bUpDown && !pShell->IsOutlineMovable(nActPos)))
+ if (nActPos == SwOutlineNodes::npos ||
+ (bUpDown && (!pShell->IsOutlineMovable(nActPos) ||
+ nFirstRegularDocContentOutlineNodePos == SwOutlineNodes::npos)))
{
continue;
}
@@ -3352,13 +3367,66 @@ void SwContentTree::ExecCommand(std::u16string_view rCmd, bool bOutlineWithChild
{
// make outline selection for use by MoveOutlinePara
pShell->MakeOutlineSel(nActPos, nActPos, bOutlineWithChildren);
- if (pShell->MoveOutlinePara(nDir))
+
+ int nActPosOutlineLevel =
+ rOutlineNodes[nActPos]->GetTextNode()->GetAttrOutlineLevel();
+ SwOutlineNodes::size_type nPos = nActPos;
+ if (!bUp)
+ {
+ // move down
+ int nPosOutlineLevel = -1;
+ while (++nPos < nOutlineNdsSize)
+ {
+ nPosOutlineLevel =
+ rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
+ // discontinue if moving out of parent or equal level is found
+ if (nPosOutlineLevel <= nActPosOutlineLevel)
+ break;
+ // count the children of the node when they are not included in the move
+ if (!bOutlineWithChildren)
+ nDir++;
+ }
+ if (nPosOutlineLevel >= nActPosOutlineLevel)
+ {
+ // move past children
+ while (++nPos < nOutlineNdsSize)
+ {
+ nPosOutlineLevel =
+ rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
+ // discontinue if moving out of parent or equal level is found
+ if (nPosOutlineLevel <= nActPosOutlineLevel)
+ break;
+ nDir++;
+ }
+ }
+ }
+ else
{
- // Set cursor back to the current position
- pShell->GotoOutline(nActPos + nDir);
+ // move up
+ while (nPos && --nPos >= nFirstRegularDocContentOutlineNodePos)
+ {
+ int nPosOutlineLevel =
+ rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineLevel();
+ // discontinue if equal level is found
+ if (nPosOutlineLevel == nActPosOutlineLevel)
+ break;
+ // discontinue if moving out of parent
+ if (nPosOutlineLevel < nActPosOutlineLevel)
+ {
+ // Required for expected chapter placement when the chapter being moved
+ // up has an outline level less than the outline level of chapters it
+ // is being moved above and then encounters a chapter with an outline
+ // level that is greater before reaching a chapter with the same
+ // outline level as itself.
+ if (nDir < -1)
+ nDir++;
+ break;
+ }
+ nDir--;
+ }
}
+ pShell->MoveOutlinePara(nDir);
}
-
pShell->ClearMark();
}
else