summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2021-10-17 21:10:06 -0800
committerJim Raykowski <raykowj@gmail.com>2021-10-21 23:35:51 +0200
commit827c0f9766f148520aed7fe3abe2b138a157a6d3 (patch)
tree63ca113d18419c9718ea000034878502149bb288
parent0cd8050ec70a4a5f02801cc38e6486defdf83bd7 (diff)
tdf#141634 Special end of para split for folded outline node
After split place the cursor on a new blank line after the folded content and at the same level as the split outline node. Change-Id: I4073a1c0047ab8479993d8e605cc038896cd4630 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/123747 Tested-by: Jenkins Reviewed-by: Jim Raykowski <raykowj@gmail.com>
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx134
1 files changed, 124 insertions, 10 deletions
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 215cdf2980a5..e74ac03bdec0 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -105,6 +105,10 @@
#include <frmtool.hxx>
#include <viewopt.hxx>
+#include <IDocumentUndoRedo.hxx>
+#include <UndoInsert.hxx>
+#include <UndoCore.hxx>
+
using namespace sw::mark;
using namespace com::sun::star;
namespace {
@@ -994,15 +998,121 @@ void SwWrtShell::InsertFootnote(const OUString &rStr, bool bEndNote, bool bEdit
m_aNavigationMgr.addEntry(aPos);
}
+// tdf#141634
+static bool lcl_FoldedOutlineNodeEndOfParaSplit(SwWrtShell *pThis)
+{
+ SwTextNode* pTextNode = pThis->GetCursor()->GetNode().GetTextNode();
+ if (pTextNode && pTextNode->IsOutline())
+ {
+ bool bVisible = true;
+ pTextNode->GetAttrOutlineContentVisible(bVisible);
+ if (!bVisible)
+ {
+ const SwNodes& rNodes = pThis->GetNodes();
+ const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
+ SwOutlineNodes::size_type nPos;
+ (void) rOutlineNodes.Seek_Entry(pTextNode, &nPos);
+
+ SwNode* pSttNd = rOutlineNodes[nPos];
+
+ // determine end node of folded outline content
+ SwNode* pEndNd = &rNodes.GetEndOfContent();
+ if (rOutlineNodes.size() > nPos + 1)
+ pEndNd = rOutlineNodes[nPos + 1];
+
+ if (pThis->GetViewOptions()->IsTreatSubOutlineLevelsAsContent())
+ {
+ // get the next outline node after the folded outline content (iPos)
+ // it is the next outline node with the same level or less
+ int nLevel = pSttNd->GetTextNode()->GetAttrOutlineLevel();
+ SwOutlineNodes::size_type iPos = nPos;
+ while (++iPos < rOutlineNodes.size() &&
+ rOutlineNodes[iPos]->GetTextNode()->GetAttrOutlineLevel() > nLevel);
+
+ // get the correct end node
+ // the outline node may be in frames, headers, footers special section of doc model
+ SwNode* pStartOfSectionNodeSttNd = pSttNd->StartOfSectionNode();
+ while (pStartOfSectionNodeSttNd->StartOfSectionNode()
+ != pStartOfSectionNodeSttNd->StartOfSectionNode()->StartOfSectionNode())
+ {
+ pStartOfSectionNodeSttNd = pStartOfSectionNodeSttNd->StartOfSectionNode();
+ }
+ pEndNd = pStartOfSectionNodeSttNd->EndOfSectionNode();
+
+ if (iPos < rOutlineNodes.size())
+ {
+ SwNode* pStartOfSectionNode = rOutlineNodes[iPos]->StartOfSectionNode();
+ while (pStartOfSectionNode->StartOfSectionNode()
+ != pStartOfSectionNode->StartOfSectionNode()->StartOfSectionNode())
+ {
+ pStartOfSectionNode = pStartOfSectionNode->StartOfSectionNode();
+ }
+ if (pStartOfSectionNodeSttNd == pStartOfSectionNode)
+ pEndNd = rOutlineNodes[iPos];
+ }
+ }
+
+ // table, text box, header, footer
+ if (pSttNd->GetTableBox() || pSttNd->GetIndex() < rNodes.GetEndOfExtras().GetIndex())
+ {
+ // insert before section end node
+ if (pSttNd->EndOfSectionIndex() < pEndNd->GetIndex())
+ {
+ SwNodeIndex aIdx(*pSttNd->EndOfSectionNode());
+ while (aIdx.GetNode().IsEndNode())
+ --aIdx;
+ ++aIdx;
+ pEndNd = &aIdx.GetNode();
+ }
+ }
+ // if pSttNd isn't in table but pEndNd is then insert after table
+ else if (pEndNd->GetTableBox())
+ {
+ pEndNd = pEndNd->FindTableNode();
+ SwNodeIndex aIdx(*pEndNd, -1);
+ // account for nested tables
+ while (aIdx.GetNode().GetTableBox())
+ {
+ pEndNd = aIdx.GetNode().FindTableNode();
+ aIdx.Assign(*pEndNd, -1);
+ }
+ aIdx.Assign(*pEndNd->EndOfSectionNode(), +1);
+ pEndNd = &aIdx.GetNode();
+ }
+ // end node determined
+
+ // now insert the new outline node
+ SwDoc* pDoc = pThis->GetDoc();
+
+ // insert at end of tablebox doesn't work correct without
+ MakeAllOutlineContentTemporarilyVisible a(pDoc);
+
+ SwTextNode* pNd = pDoc->GetNodes().MakeTextNode(*pEndNd, pTextNode->GetTextColl(), true);
+
+ (void) rOutlineNodes.Seek_Entry(pNd, &nPos);
+ pThis->GotoOutline(nPos);
+
+ if (pDoc->GetIDocumentUndoRedo().DoesUndo())
+ {
+ pDoc->GetIDocumentUndoRedo().ClearRedo();
+ pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoInsert>(*pNd));
+ pDoc->GetIDocumentUndoRedo().AppendUndo(std::make_unique<SwUndoFormatColl>
+ (*pNd, pNd->GetTextColl(), true, true));
+ }
+
+ pThis->SetModified();
+ return true;
+ }
+ }
+ return false;
+}
+
// SplitNode; also, because
// - of deleting selected content;
// - of reset of the Cursorstack if necessary.
void SwWrtShell::SplitNode( bool bAutoFormat )
{
- if (!lcl_IsAllowed(this))
- return;
-
ResetCursorStack();
if( !CanInsert() )
return;
@@ -1010,16 +1120,20 @@ void SwWrtShell::SplitNode( bool bAutoFormat )
SwActContext aActContext(this);
m_rView.GetEditWin().FlushInBuffer();
+ StartUndo(SwUndoId::SPLITNODE);
+
bool bHasSel = HasSelection();
- if( bHasSel )
- {
- StartUndo( SwUndoId::INSERT );
+ if (bHasSel)
DelRight();
- }
- SwFEShell::SplitNode( bAutoFormat );
- if( bHasSel )
- EndUndo( SwUndoId::INSERT );
+ bool bHandled = false;
+ if (GetViewOptions()->IsShowOutlineContentVisibilityButton() && IsEndPara())
+ bHandled = lcl_FoldedOutlineNodeEndOfParaSplit(this);
+
+ if (!bHandled)
+ SwFEShell::SplitNode( bAutoFormat );
+
+ EndUndo(SwUndoId::SPLITNODE);
}
// Turn on numbering