summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--sw/Library_sw.mk1
-rw-r--r--sw/inc/ndtxt.hxx8
-rw-r--r--sw/inc/strings.hrc2
-rw-r--r--sw/inc/swtypes.hxx3
-rw-r--r--sw/source/core/crsr/crstrvl.cxx8
-rw-r--r--sw/source/core/txtnode/ndtxt.cxx20
-rw-r--r--sw/source/uibase/docvw/FrameControlsManager.cxx108
-rw-r--r--sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx237
-rw-r--r--sw/source/uibase/docvw/edtwin.cxx133
-rw-r--r--sw/source/uibase/docvw/edtwin2.cxx4
-rw-r--r--sw/source/uibase/inc/FrameControlsManager.hxx5
-rw-r--r--sw/source/uibase/inc/OutlineContentVisibilityWin.hxx49
-rw-r--r--sw/source/uibase/inc/edtwin.hxx7
-rw-r--r--sw/source/uibase/inc/wrtsh.hxx4
-rw-r--r--sw/source/uibase/utlui/content.cxx61
-rw-r--r--sw/source/uibase/wrtsh/wrtsh1.cxx120
16 files changed, 765 insertions, 5 deletions
diff --git a/sw/Library_sw.mk b/sw/Library_sw.mk
index 5f7c204f0e6a..2de7d6b0e4dc 100644
--- a/sw/Library_sw.mk
+++ b/sw/Library_sw.mk
@@ -622,6 +622,7 @@ $(eval $(call gb_Library_add_exception_objects,sw,\
sw/source/uibase/docvw/SidebarTxtControlAcc \
sw/source/uibase/docvw/SidebarWinAcc \
sw/source/uibase/docvw/HeaderFooterWin \
+ sw/source/uibase/docvw/OutlineContentVisibilityWin \
sw/source/uibase/docvw/edtdd \
sw/source/uibase/docvw/edtwin \
sw/source/uibase/docvw/edtwin2 \
diff --git a/sw/inc/ndtxt.hxx b/sw/inc/ndtxt.hxx
index 9edf16dab96e..9dd3a5abe78a 100644
--- a/sw/inc/ndtxt.hxx
+++ b/sw/inc/ndtxt.hxx
@@ -596,6 +596,14 @@ public:
*/
void SetAttrOutlineLevel(int nLevel);
+ /**
+ * @brief GetAttrOutlineContentVisible
+ * @param bOutlineContentVisibleAttr the value stored in RES_PARATR_GRABBAG for 'OutlineContentVisibleAttr'
+ * @return true if 'OutlineContentVisibleAttr' is found in RES_PARATR_GRABBAG
+ */
+ bool GetAttrOutlineContentVisible(bool& bOutlineContentVisibleAttr);
+ void SetAttrOutlineContentVisible(bool bVisible);
+
bool IsEmptyListStyleDueToSetOutlineLevelAttr() const { return mbEmptyListStyleSetDueToSetOutlineLevelAttr;}
void SetEmptyListStyleDueToSetOutlineLevelAttr();
void ResetEmptyListStyleDueToResetOutlineLevelAttr();
diff --git a/sw/inc/strings.hrc b/sw/inc/strings.hrc
index 46a4ec21f64a..86733bf6bb3a 100644
--- a/sw/inc/strings.hrc
+++ b/sw/inc/strings.hrc
@@ -643,6 +643,8 @@
#define STR_OUTLINE_TRACKING_DEFAULT NC_("STR_OUTLINE_TRACKING_DEFAULT", "Default")
#define STR_OUTLINE_TRACKING_FOCUS NC_("STR_OUTLINE_TRACKING_FOCUS", "Focus")
#define STR_OUTLINE_TRACKING_OFF NC_("STR_OUTLINE_TRACKING_OFF", "Off")
+#define STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY NC_("STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY", "Toggle Outline Content Visibility")
+#define STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT NC_("STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT", "hold Ctrl or right-click to include sub levels")
#define STR_EXPANDALL NC_("STR_EXPANDALL", "Expand All")
#define STR_COLLAPSEALL NC_("STR_COLLAPSEALL", "Collapse All")
diff --git a/sw/inc/swtypes.hxx b/sw/inc/swtypes.hxx
index 119ef21d7997..0f7d3af3e962 100644
--- a/sw/inc/swtypes.hxx
+++ b/sw/inc/swtypes.hxx
@@ -242,7 +242,8 @@ enum class FrameControlType
PageBreak,
Header,
Footer,
- FloatingTable
+ FloatingTable,
+ Outline
};
#endif
diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx
index 5ee44842b56f..5bea3f176289 100644
--- a/sw/source/core/crsr/crstrvl.cxx
+++ b/sw/source/core/crsr/crstrvl.cxx
@@ -1278,11 +1278,13 @@ bool SwCursorShell::GetContentAtPos( const Point& rPt,
&& IsAttrAtPos::Outline & rContentAtPos.eContentAtPos
&& !rNds.GetOutLineNds().empty() )
{
- const SwTextNode* pONd = pTextNd->FindOutlineNodeOfLevel(MAXLEVEL-1, GetLayout());
- if( pONd )
+ // only for nodes in outline nodes
+ SwOutlineNodes::size_type nPos;
+ if(rNds.GetOutLineNds().Seek_Entry(pTextNd, &nPos))
{
rContentAtPos.eContentAtPos = IsAttrAtPos::Outline;
- rContentAtPos.sStr = sw::GetExpandTextMerged(GetLayout(), *pONd, true, false, ExpandMode::ExpandFootnote);
+ rContentAtPos.sStr = sw::GetExpandTextMerged(GetLayout(), *pTextNd, true, false, ExpandMode::ExpandFootnote);
+ rContentAtPos.aFnd.pNode = pTextNd;
bRet = true;
}
}
diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx
index 6200eb040abd..56fa589eaef5 100644
--- a/sw/source/core/txtnode/ndtxt.cxx
+++ b/sw/source/core/txtnode/ndtxt.cxx
@@ -71,6 +71,7 @@
#include <numrule.hxx>
#include <docsh.hxx>
#include <SwNodeNum.hxx>
+#include <svl/grabbagitem.hxx>
#include <svl/intitem.hxx>
#include <list.hxx>
#include <sortedobjs.hxx>
@@ -4036,6 +4037,25 @@ void SwTextNode::SetAttrOutlineLevel(int nLevel)
}
}
+bool SwTextNode::GetAttrOutlineContentVisible(bool& bOutlineContentVisibleAttr)
+{
+ SfxGrabBagItem aGrabBagItem(dynamic_cast<const SfxGrabBagItem&>(GetAttr(RES_PARATR_GRABBAG)));
+ auto it = aGrabBagItem.GetGrabBag().find("OutlineContentVisibleAttr");
+ if (it != aGrabBagItem.GetGrabBag().end())
+ {
+ it->second >>= bOutlineContentVisibleAttr;
+ return true;
+ }
+ return false;
+}
+
+void SwTextNode::SetAttrOutlineContentVisible(bool bVisible)
+{
+ SfxGrabBagItem aGrabBagItem(RES_PARATR_GRABBAG);
+ aGrabBagItem.GetGrabBag()["OutlineContentVisibleAttr"] <<= bVisible;
+ GetTextNode()->SetAttr(aGrabBagItem);
+}
+
// #i70748#
void SwTextNode::SetEmptyListStyleDueToSetOutlineLevelAttr()
diff --git a/sw/source/uibase/docvw/FrameControlsManager.cxx b/sw/source/uibase/docvw/FrameControlsManager.cxx
index 9d68bc950435..63bca779d473 100644
--- a/sw/source/uibase/docvw/FrameControlsManager.cxx
+++ b/sw/source/uibase/docvw/FrameControlsManager.cxx
@@ -17,6 +17,10 @@
#include <viewopt.hxx>
#include <view.hxx>
#include <wrtsh.hxx>
+#include <txtfrm.hxx>
+#include <OutlineContentVisibilityWin.hxx>
+#include <ndtxt.hxx>
+#include <IDocumentOutlineNodes.hxx>
using namespace std;
@@ -33,6 +37,7 @@ SwFrameControlsManager::~SwFrameControlsManager()
void SwFrameControlsManager::dispose()
{
m_aControls.clear();
+ m_aTextNodeContentFrameMap.clear();
}
SwFrameControlPtr SwFrameControlsManager::GetControl( FrameControlType eType, const SwFrame* pFrame )
@@ -179,6 +184,109 @@ SwFrameMenuButtonBase::SwFrameMenuButtonBase( SwEditWin* pEditWin, const SwFrame
{
}
+void SwFrameControlsManager::SetOutlineContentVisibilityButtons()
+{
+ // remove entries with outline node keys that are not in the outline nodes list
+ IDocumentOutlineNodes::tSortedOutlineNodeList aOutlineNodes;
+ m_pEditWin->GetView().GetWrtShell().getIDocumentOutlineNodesAccess()->getOutlineNodes(aOutlineNodes);
+ std::map<const SwTextNode*, const SwContentFrame*>::iterator it = m_aTextNodeContentFrameMap.begin();
+ while(it != m_aTextNodeContentFrameMap.end())
+ {
+ const SwNode* pNd = it->first;
+ IDocumentOutlineNodes::tSortedOutlineNodeList::iterator i = std::find(aOutlineNodes.begin(), aOutlineNodes.end(), pNd);
+ if (i == aOutlineNodes.end())
+ {
+ RemoveControlsByType(FrameControlType::Outline, it->second);
+ it = m_aTextNodeContentFrameMap.erase(it);
+ }
+ else
+ it++;
+ }
+ for (SwNode* pNd : m_pEditWin->GetView().GetWrtShell().GetNodes().GetOutLineNds())
+ {
+ bool bOutlineContentVisibleAttr = true;
+ pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ SetOutlineContentVisibilityButton(pNd->GetTextNode());
+ }
+}
+
+void SwFrameControlsManager::SetOutlineContentVisibilityButton(const SwTextNode* pTextNd)
+{
+ const SwContentFrame* pContentFrame = pTextNd->getLayoutFrame(nullptr);
+
+ // has node frame changed or been deleted
+ std::map<const SwTextNode*, const SwContentFrame*>::iterator iter = m_aTextNodeContentFrameMap.find(pTextNd);
+ if (iter != m_aTextNodeContentFrameMap.end())
+ {
+ const SwContentFrame* pFrameWas = iter->second;
+ if (pContentFrame != pFrameWas)
+ {
+ // frame does not match frame in map for node
+ RemoveControlsByType(FrameControlType::Outline, pFrameWas);
+ m_aTextNodeContentFrameMap.erase(iter);
+ }
+ }
+ if (pContentFrame && !pContentFrame->IsInDtor())
+ {
+ // frame is not being destroyed and isn't in map
+ m_aTextNodeContentFrameMap.insert(make_pair(pTextNd, pContentFrame));
+ }
+ else
+ {
+ if (pContentFrame)
+ {
+ // frame is being destroyed
+ RemoveControlsByType(FrameControlType::Outline, pContentFrame);
+ }
+ return;
+ }
+
+ // Check if we already have the control
+ SwFrameControlPtr pControl;
+
+ SwFrameControlPtrMap& rControls = m_aControls[FrameControlType::Outline];
+
+ SwFrameControlPtrMap::iterator lb = rControls.lower_bound(pContentFrame);
+ if (lb != rControls.end() && !(rControls.key_comp()(pContentFrame, lb->first)))
+ {
+ pControl = lb->second;
+ }
+ else
+ {
+ SwFrameControlPtr pNewControl =
+ std::make_shared<SwFrameControl>(VclPtr<SwOutlineContentVisibilityWin>::Create(
+ m_pEditWin, pContentFrame).get());
+ rControls.insert(lb, make_pair(pContentFrame, pNewControl));
+ pControl.swap(pNewControl);
+ }
+
+ SwOutlineContentVisibilityWin* pWin = dynamic_cast<SwOutlineContentVisibilityWin *>(pControl->GetWindow());
+ assert(pWin != nullptr) ;
+ pWin->Set();
+
+ if (pWin->GetSymbol() == SymbolType::ARROW_RIGHT)
+ {
+ // show expand button immediatly
+ pWin->Show();
+ // outline content might not be folded, this happens on undo, outline moves, and folded outline content reveals
+ SwOutlineNodes::size_type nPos;
+ SwOutlineNodes rOutlineNds = m_pEditWin->GetView().GetWrtShell().GetNodes().GetOutLineNds();
+ if (rOutlineNds.Seek_Entry(const_cast<SwTextNode*>(pTextNd), &nPos))
+ {
+ // don't toggle if next node is an outline node or end node
+ SwNodeIndex aIdx(*pTextNd, 1);
+ if (!(aIdx.GetNode().IsEndNode() || ((nPos + 1 < rOutlineNds.size()) && &aIdx.GetNode() == rOutlineNds[nPos +1]))
+ && aIdx.GetNode().IsContentNode() && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr))
+ {
+ m_pEditWin->GetView().GetWrtShell().ToggleOutlineContentVisibility(nPos, true); // force fold
+ }
+ }
+ }
+ else if (!pWin->IsVisible() && pWin->GetSymbol() == SymbolType::ARROW_DOWN)
+ pWin->ShowAll(true);
+}
+
const SwPageFrame* SwFrameMenuButtonBase::GetPageFrame() const
{
if (m_pFrame->IsPageFrame())
diff --git a/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
new file mode 100644
index 000000000000..44772f367813
--- /dev/null
+++ b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
@@ -0,0 +1,237 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+
+#include <edtwin.hxx>
+#include <OutlineContentVisibilityWin.hxx>
+#include <view.hxx>
+#include <viewopt.hxx>
+#include <wrtsh.hxx>
+
+#include <memory>
+
+#include <IDocumentOutlineNodes.hxx>
+#include <txtfrm.hxx>
+#include <ndtxt.hxx>
+#include <vcl/button.hxx>
+#include <vcl/event.hxx>
+#include <strings.hrc>
+#include <svx/svdview.hxx>
+
+#define BUTTON_WIDTH 18
+#define BUTTON_HEIGHT 20
+
+SwOutlineContentVisibilityWin::SwOutlineContentVisibilityWin(SwEditWin* pEditWin,
+ const SwFrame* pFrame)
+ : PushButton(pEditWin, 0)
+ , m_pEditWin(pEditWin)
+ , m_pFrame(pFrame)
+ , m_nDelayAppearing(0)
+ , m_bDestroyed(false)
+{
+ SetSizePixel(Size(BUTTON_WIDTH, BUTTON_HEIGHT));
+
+ m_aDelayTimer.SetTimeout(50);
+ m_aDelayTimer.SetInvokeHandler(LINK(this, SwOutlineContentVisibilityWin, DelayHandler));
+}
+
+void SwOutlineContentVisibilityWin::dispose()
+{
+ m_bDestroyed = true;
+ m_aDelayTimer.Stop();
+
+ m_pEditWin.clear();
+ m_pFrame = nullptr;
+
+ PushButton::dispose();
+}
+
+void SwOutlineContentVisibilityWin::Set()
+{
+ const SwTextFrame* pTextFrame = static_cast<const SwTextFrame*>(GetFrame());
+
+ // outline node frame containing folded outline node content might be folded so need to hide it
+ if (!pTextFrame || pTextFrame->IsInDtor())
+ {
+ SetSymbol(SymbolType::DONTKNOW);
+ Hide();
+ return;
+ }
+ const SwTextNode* pTextNode = pTextFrame->GetTextNodeFirst();
+ SwWrtShell& rSh = GetEditWin()->GetView().GetWrtShell();
+ const SwOutlineNodes& rOutlineNodes = rSh.GetNodes().GetOutLineNds();
+ rOutlineNodes.Seek_Entry(static_cast<SwNode*>(const_cast<SwTextNode*>(pTextNode)),
+ &m_nOutlinePos);
+ assert(m_nOutlinePos != SwOutlineNodes::npos);
+
+ // don't set if no content and no subs with content
+ auto nPos = m_nOutlinePos;
+ SwNode* pSttNd = rOutlineNodes[nPos];
+ SwNode* pEndNd;
+ SwNodeIndex aIdx(*pSttNd);
+ while (true)
+ {
+ if (rOutlineNodes.size() > ++nPos)
+ pEndNd = rOutlineNodes[nPos];
+ else
+ pEndNd = &rSh.GetNodes().GetEndOfContent();
+ if (!pSttNd->IsEndNode())
+ aIdx.Assign(*pSttNd, +1);
+ if (pSttNd->IsEndNode()
+ || ((&aIdx.GetNode() == pEndNd && pEndNd->IsEndNode())
+ || (&aIdx.GetNode() == pEndNd && pSttNd->IsTextNode() && pEndNd->IsTextNode()
+ && pSttNd->GetTextNode()->GetAttrOutlineLevel()
+ >= pEndNd->GetTextNode()->GetAttrOutlineLevel())))
+ {
+ SetSymbol(SymbolType::DONTKNOW);
+ Hide();
+ return;
+ }
+ if (&aIdx.GetNode() != pEndNd)
+ break;
+ pSttNd = pEndNd;
+ }
+
+ // set symbol displayed on button
+ SetSymbol(rSh.IsOutlineContentFolded(m_nOutlinePos) ? SymbolType::ARROW_RIGHT
+ : SymbolType::ARROW_DOWN);
+
+ // set quick help
+ SwOutlineNodes::size_type nOutlineNodesCount
+ = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
+ int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos);
+ OUString sQuickHelp(SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY));
+ if (m_nOutlinePos + 1 < nOutlineNodesCount
+ && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos + 1) > nLevel)
+ sQuickHelp += " (" + SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")";
+ SetQuickHelpText(sQuickHelp);
+
+ // Set the position of the window
+ SwRect aSwRect = GetFrame()->getFrameArea(); // not far in margin
+ //SwRect aSwRect = GetFrame()->GetPaintArea(); // far in margin
+ aSwRect.AddTop(GetFrame()->GetTopMargin());
+ Point aPxPt(GetEditWin()->GetOutDev()->LogicToPixel(
+ aSwRect.TopLeft() - (aSwRect.TopLeft() - aSwRect.BottomLeft()) / 2));
+ aPxPt.AdjustX(-GetSizePixel().getWidth() + 1);
+ aPxPt.AdjustY(-GetSizePixel().getHeight() / 2);
+ SetPosPixel(aPxPt);
+}
+
+void SwOutlineContentVisibilityWin::ShowAll(bool bShow)
+{
+ if (bShow)
+ {
+ m_nDelayAppearing = 0;
+ if (!m_bDestroyed && m_aDelayTimer.IsActive())
+ m_aDelayTimer.Stop();
+ if (!m_bDestroyed)
+ m_aDelayTimer.Start();
+ }
+ else
+ Hide();
+}
+
+bool SwOutlineContentVisibilityWin::Contains(const Point& rDocPt) const
+{
+ ::tools::Rectangle aRect(GetPosPixel(), GetSizePixel());
+ if (aRect.IsInside(rDocPt))
+ return true;
+ return false;
+}
+
+void SwOutlineContentVisibilityWin::ToggleOutlineContentVisibility(const bool bSubs)
+{
+ SwWrtShell& rSh = GetEditWin()->GetView().GetWrtShell();
+ rSh.LockView(true);
+ if (GetEditWin()->GetView().GetDrawView()->IsTextEdit())
+ rSh.EndTextEdit();
+ if (GetEditWin()->GetView().IsDrawMode())
+ GetEditWin()->GetView().LeaveDrawCreate();
+ rSh.EnterStdMode();
+ if (bSubs)
+ {
+ // toggle including sub levels
+ SwOutlineNodes::size_type nPos = m_nOutlinePos;
+ SwOutlineNodes::size_type nOutlineNodesCount
+ = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount();
+ int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos);
+ bool bFold = rSh.IsOutlineContentFolded(m_nOutlinePos);
+ do
+ {
+ if (rSh.IsOutlineContentFolded(nPos) == bFold)
+ rSh.ToggleOutlineContentVisibility(nPos);
+ } while (++nPos < nOutlineNodesCount
+ && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel);
+ }
+ else
+ rSh.ToggleOutlineContentVisibility(m_nOutlinePos);
+ SetSymbol(rSh.IsOutlineContentFolded(m_nOutlinePos) ? SymbolType::ARROW_RIGHT
+ : SymbolType::ARROW_DOWN);
+ rSh.GotoOutline(m_nOutlinePos); // sets cursor position
+ rSh.LockView(false);
+}
+
+void SwOutlineContentVisibilityWin::KeyInput(const KeyEvent& rKEvt)
+{
+ vcl::KeyCode aKeyCode = rKEvt.GetKeyCode();
+ if (!aKeyCode.GetModifier()
+ && (aKeyCode.GetCode() == KEY_RETURN || aKeyCode.GetCode() == KEY_SPACE))
+ {
+ ToggleOutlineContentVisibility(aKeyCode.GetCode() == KEY_RETURN);
+ }
+ else if (aKeyCode.GetCode() == KEY_ESCAPE)
+ {
+ Hide();
+ GrabFocusToDocument();
+ }
+}
+
+void SwOutlineContentVisibilityWin::MouseMove(const MouseEvent& rMEvt)
+{
+ if (rMEvt.IsLeaveWindow())
+ {
+ // MouseMove event may not be seen by edit window
+ // hide collapse button and grab focus to document
+ if (GetSymbol() != SymbolType::ARROW_RIGHT)
+ Hide();
+ GrabFocusToDocument();
+ }
+ else if (rMEvt.IsEnterWindow())
+ {
+ if (!m_bDestroyed && m_aDelayTimer.IsActive())
+ m_aDelayTimer.Stop();
+ // bring button to top and grab focus
+ SetZOrder(this, ZOrderFlags::First);
+ GrabFocus();
+ }
+ GetEditWin()->SetSavedOutlineFrame(const_cast<SwFrame*>(GetFrame()));
+}
+
+void SwOutlineContentVisibilityWin::MouseButtonDown(const MouseEvent& rMEvt)
+{
+ ToggleOutlineContentVisibility(rMEvt.IsRight() || rMEvt.IsMod1());
+}
+
+IMPL_LINK_NOARG(SwOutlineContentVisibilityWin, DelayHandler, Timer*, void)
+{
+ const int TICKS_BEFORE_WE_APPEAR = 5;
+ if (m_nDelayAppearing < TICKS_BEFORE_WE_APPEAR)
+ {
+ ++m_nDelayAppearing;
+ m_aDelayTimer.Start();
+ return;
+ }
+ if (GetEditWin()->GetSavedOutlineFrame() == GetFrame())
+ {
+ Show();
+ GrabFocus();
+ }
+ m_aDelayTimer.Stop();
+}
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx
index 2a2d6634a0ea..8f0751024e2d 100644
--- a/sw/source/uibase/docvw/edtwin.cxx
+++ b/sw/source/uibase/docvw/edtwin.cxx
@@ -139,6 +139,11 @@
#include <sfx2/event.hxx>
#include <memory>
+#include <IDocumentOutlineNodes.hxx>
+#include <ndtxt.hxx>
+#include <cntfrm.hxx>
+#include <txtfrm.hxx>
+
using namespace sw::mark;
using namespace ::com::sun::star;
@@ -1330,6 +1335,32 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt)
}
}
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // not allowed if outline content is folded
+ sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
+ if ((rSh.IsSttPara() && (nKey == KEY_BACKSPACE || nKey == KEY_LEFT))
+ || (rSh.IsEndOfPara() && (nKey == KEY_DELETE || nKey == KEY_RETURN || nKey == KEY_RIGHT)))
+ {
+ SwContentNode* pContentNode = rSh.GetCurrentShellCursor().GetContentNode();
+ SwOutlineNodes::size_type nPos;
+ if (rSh.GetDoc()->GetNodes().GetOutLineNds().Seek_Entry(pContentNode, &nPos))
+ {
+ bool bOutlineContentVisibleAttr = true;
+ pContentNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ return; // outline node is folded
+ if (rSh.IsSttPara() && (nKey == KEY_BACKSPACE || nKey == KEY_LEFT) && (nPos-1 != SwOutlineNodes::npos))
+ {
+ bOutlineContentVisibleAttr = true;
+ rSh.GetDoc()->GetNodes().GetOutLineNds()[nPos-1]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ return; // previous outline node is folded
+ }
+ }
+ }
+ }
+
if( rKEvt.GetKeyCode().GetCode() == KEY_ESCAPE &&
m_pApplyTempl && m_pApplyTempl->m_pFormatClipboard )
{
@@ -2628,6 +2659,10 @@ KEYINPUT_CHECKTABLE_INSDEL:
}
}
+ // x11 backend doesn't like not having this
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ GetFrameControlsManager().SetOutlineContentVisibilityButtons();
+
// update the page number in the statusbar
sal_uInt16 nKey = rKEvt.GetKeyCode().GetCode();
if( KEY_UP == nKey || KEY_DOWN == nKey || KEY_PAGEUP == nKey || KEY_PAGEDOWN == nKey )
@@ -3813,6 +3848,52 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
if( rSh.ActionPend() )
return ;
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // add/remove outline collapse button
+ SwContentAtPos aSwContentAtPos(IsAttrAtPos::Outline);
+ if (rSh.GetContentAtPos(PixelToLogic(rMEvt.GetPosPixel()), aSwContentAtPos))
+ {
+ if(aSwContentAtPos.aFnd.pNode && aSwContentAtPos.aFnd.pNode->IsTextNode())
+ {
+ const SwNodes& rNds = rSh.GetDoc()->GetNodes();
+ SwOutlineNodes::size_type nPos;
+ SwContentFrame* pContentFrame = aSwContentAtPos.aFnd.pNode->GetTextNode()->getLayoutFrame(nullptr);
+ if (pContentFrame != m_pSavedOutlineFrame)
+ {
+ // remove collapse button when saved frame is not frame at mouse position
+ if (m_pSavedOutlineFrame && /* is it possible that m_pSavedOutlineFrame is removed? */ !m_pSavedOutlineFrame->IsInDtor() &&
+ rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos) &&
+ !rSh.IsOutlineContentFolded(nPos))
+ {
+ GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
+ }
+ m_pSavedOutlineFrame = pContentFrame;
+ }
+ // show collapse button
+ if (rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), &nPos) &&
+ !rSh.IsOutlineContentFolded(nPos))
+ {
+ GetFrameControlsManager().SetOutlineContentVisibilityButton(aSwContentAtPos.aFnd.pNode->GetTextNode());
+ }
+ }
+ }
+ else if (m_pSavedOutlineFrame && !m_pSavedOutlineFrame->IsInDtor())
+ {
+ // current pointer pos is not over an outline frame
+ // previous frame was an outline frame
+ // remove collapse button if showing
+ const SwNodes& rNds = rSh.GetDoc()->GetNodes();
+ SwOutlineNodes::size_type nPos;
+ if (rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos) &&
+ !rSh.IsOutlineContentFolded(nPos))
+ {
+ GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
+ }
+ m_pSavedOutlineFrame = nullptr;
+ }
+ }
+
if( m_pShadCursor && 0 != (rMEvt.GetModifier() + rMEvt.GetButtons() ) )
{
m_pShadCursor.reset();
@@ -3847,6 +3928,21 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt)
const Point aOldPt( rSh.VisArea().Pos() );
const bool bInsWin = rSh.VisArea().IsInside( aDocPt ) || comphelper::LibreOfficeKit::isActive();
+ if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ if (m_pSavedOutlineFrame && !bInsWin)
+ {
+ // the mouse pointer has left the building
+ // 86 the collapse button if showing
+ const SwNodes& rNds = rSh.GetDoc()->GetNodes();
+ SwOutlineNodes::size_type nPos;
+ rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)->GetTextNodeFirst(), &nPos);
+ if (!rSh.IsOutlineContentFolded(nPos))
+ GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
+ m_pSavedOutlineFrame = nullptr;
+ }
+ }
+
if( m_pShadCursor && !bInsWin )
{
m_pShadCursor.reset();
@@ -5275,6 +5371,11 @@ void SwEditWin::Command( const CommandEvent& rCEvt )
case CommandEventId::Wheel:
case CommandEventId::StartAutoScroll:
case CommandEventId::AutoScroll:
+ if (m_pSavedOutlineFrame && rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame);
+ m_pSavedOutlineFrame = nullptr;
+ }
m_pShadCursor.reset();
bCallBase = !m_rView.HandleWheelCommands( rCEvt );
break;
@@ -6421,6 +6522,38 @@ void SwEditWin::SetGraphicTwipPosition(bool bStart, const Point& rPosition)
}
}
+void SwEditWin::SetOutlineContentVisiblityButtons()
+{
+ SwWrtShell& rSh = m_rView.GetWrtShell();
+ const SwOutlineNodes& rOutlineNodes = rSh.GetDoc()->GetNodes().GetOutLineNds();
+ if (!rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNodes.size(); ++nPos)
+ {
+ bool bOutlineContentVisibleAttr = true;
+ rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ {
+ // unfold and then set outline content visible attr to false for persistence
+ rSh.ToggleOutlineContentVisibility(nPos);
+ rOutlineNodes[nPos]->GetTextNode()->SetAttrOutlineContentVisible(false);
+ }
+ }
+ GetFrameControlsManager().HideControls(FrameControlType::Outline);
+ }
+ else
+ {
+ for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNodes.size(); ++nPos)
+ {
+ bool bOutlineContentVisibleAttr = true;
+ rOutlineNodes[nPos]->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ rSh.ToggleOutlineContentVisibility(nPos, true);
+ }
+ }
+ GetView().Invalidate(); // set state of dependent slots (FN_TOGGLE_OUTLINE_CONTENT_VISIBILITY)
+}
+
SwFrameControlsManager& SwEditWin::GetFrameControlsManager()
{
return *m_pFrameControlsManager;
diff --git a/sw/source/uibase/docvw/edtwin2.cxx b/sw/source/uibase/docvw/edtwin2.cxx
index da67d799008f..064ddee8de01 100644
--- a/sw/source/uibase/docvw/edtwin2.cxx
+++ b/sw/source/uibase/docvw/edtwin2.cxx
@@ -49,6 +49,7 @@
#include <IDocumentMarkAccess.hxx>
#include <txtfrm.hxx>
#include <ndtxt.hxx>
+#include <FrameControlsManager.hxx>
static OUString lcl_GetRedlineHelp( const SwRangeRedline& rRedl, bool bBalloon )
{
@@ -429,6 +430,9 @@ void SwEditWin::Paint(vcl::RenderContext& rRenderContext, const tools::Rectangle
if( bPaintShadowCursor )
m_pShadCursor->Paint();
+
+ if (pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ GetFrameControlsManager().SetOutlineContentVisibilityButtons();
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/FrameControlsManager.hxx b/sw/source/uibase/inc/FrameControlsManager.hxx
index 66685bd8b174..cb51be62f860 100644
--- a/sw/source/uibase/inc/FrameControlsManager.hxx
+++ b/sw/source/uibase/inc/FrameControlsManager.hxx
@@ -18,6 +18,8 @@
class SwPageFrame;
class SwEditWin;
+class SwContentFrame;
+class SwTextNode;
typedef std::shared_ptr< SwFrameControl > SwFrameControlPtr;
@@ -30,6 +32,7 @@ class SwFrameControlsManager
private:
VclPtr<SwEditWin> m_pEditWin;
std::map< FrameControlType, SwFrameControlPtrMap > m_aControls;
+ std::map<const SwTextNode*, const SwContentFrame*> m_aTextNodeContentFrameMap;
public:
SwFrameControlsManager( SwEditWin* pEditWin );
@@ -46,6 +49,8 @@ class SwFrameControlsManager
void SetHeaderFooterControl( const SwPageFrame* pPageFrame, FrameControlType eType, Point aOffset );
void SetPageBreakControl( const SwPageFrame* pPageFrame );
void SetUnfloatTableButton( const SwFlyFrame* pFlyFrame, bool bShow, Point aTopRightPixel = Point() );
+ void SetOutlineContentVisibilityButton(const SwTextNode* pTextNd);
+ void SetOutlineContentVisibilityButtons();
};
#endif
diff --git a/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx b/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx
new file mode 100644
index 000000000000..13f29fd0f2eb
--- /dev/null
+++ b/sw/source/uibase/inc/OutlineContentVisibilityWin.hxx
@@ -0,0 +1,49 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/*
+ * This file is part of the LibreOffice project.
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/.
+ */
+#ifndef INCLUDED_SW_SOURCE_UIBASE_INC_OUTLINECONTENTVISIBILITYWIN_HXX
+#define INCLUDED_SW_SOURCE_UIBASE_INC_OUTLINECONTENTVISIBILITYWIN_HXX
+
+#include "edtwin.hxx"
+#include "FrameControl.hxx"
+
+class SwOutlineContentVisibilityWin : public PushButton, public ISwFrameControl
+{
+private:
+ VclPtr<SwEditWin> m_pEditWin;
+ const SwFrame* m_pFrame;
+ int m_nDelayAppearing; ///< Before we show the control, wait a few timer ticks to avoid appearing with every mouse over.
+ Timer m_aDelayTimer;
+ bool m_bDestroyed;
+ size_t m_nOutlinePos;
+
+ void ToggleOutlineContentVisibility(const bool bSubs);
+
+public:
+ SwOutlineContentVisibilityWin(SwEditWin* pEditWin, const SwFrame* pFrame);
+ virtual ~SwOutlineContentVisibilityWin() override { disposeOnce(); }
+ virtual void dispose() override;
+
+ virtual void KeyInput(const KeyEvent& rKEvt) override;
+ virtual void MouseButtonDown(const MouseEvent& rMEvt) override;
+ virtual void MouseMove(const MouseEvent& rMEvt) override;
+ virtual void ShowAll(bool bShow) override;
+ virtual bool Contains(const Point& rDocPt) const override;
+ virtual void SetReadonly(bool /*bReadonly*/) override {}
+ virtual const SwFrame* GetFrame() override { return m_pFrame; }
+ virtual SwEditWin* GetEditWin() override { return m_pEditWin; }
+
+ void Set();
+
+private:
+ DECL_LINK(DelayHandler, Timer*, void);
+};
+
+#endif
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx
index 855a2ff4158c..49f09827dd9c 100644
--- a/sw/source/uibase/inc/edtwin.hxx
+++ b/sw/source/uibase/inc/edtwin.hxx
@@ -127,6 +127,8 @@ class SW_DLLPUBLIC SwEditWin final : public vcl::Window,
std::unique_ptr<SwFrameControlsManager> m_pFrameControlsManager;
+ SwFrame* m_pSavedOutlineFrame = nullptr;
+
void LeaveArea(const Point &);
void JustifyAreaTimer();
inline void EnterArea();
@@ -288,7 +290,10 @@ public:
/// Allows starting or ending a graphic move or resize action.
void SetGraphicTwipPosition(bool bStart, const Point& rPosition);
- void SetOutlineContentVisiblityButtons() {(void)this;}
+ const SwFrame* GetSavedOutlineFrame() { return m_pSavedOutlineFrame; }
+ void SetSavedOutlineFrame(SwFrame* pFrame) { m_pSavedOutlineFrame = pFrame; }
+
+ void SetOutlineContentVisiblityButtons();
virtual FactoryFunction GetUITestFactory() const override;
};
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 4c02e5e465b5..8cb74403c795 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -489,6 +489,10 @@ typedef bool (SwWrtShell:: *FNSimpleMove)();
/// Inserts a new annotation/comment at the current cursor position / selection.
void InsertPostIt(SwFieldMgr& rFieldMgr, const SfxRequest& rReq);
+ bool IsOutlineContentFolded(const size_t nPos);
+ void ToggleOutlineContentVisibility(SwNode* pNd, bool bForceFold = false);
+ void ToggleOutlineContentVisibility(const size_t nPos, bool bForceFold = false);
+
private:
SAL_DLLPRIVATE void OpenMark();
diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx
index e9d498d2b426..1fcd1873d8f3 100644
--- a/sw/source/uibase/utlui/content.cxx
+++ b/sw/source/uibase/utlui/content.cxx
@@ -89,6 +89,8 @@
#include <fmtcntnt.hxx>
#include <docstat.hxx>
+#include <viewopt.hxx>
+
#define CTYPE_CNT 0
#define CTYPE_CTT 1
@@ -2639,6 +2641,7 @@ void SwContentTree::ExecCommand(const OString& rCmd, bool bOutlineWithChildren)
SwOutlineNodes::difference_type nDirLast = bUp ? -1 : 1;
bool bStartedAction = false;
+ std::vector<SwNode*> aFoldedOutlineNdsArray;
for (auto const& pCurrentEntry : selected)
{
assert(pCurrentEntry && lcl_IsContent(*pCurrentEntry, *m_xTreeView));
@@ -2660,6 +2663,28 @@ void SwContentTree::ExecCommand(const OString& rCmd, bool bOutlineWithChildren)
if (!bStartedAction)
{
pShell->StartAllAction();
+ if (bUpDown)
+ {
+ if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // unfold all folded outline content
+ SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds();
+ for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos)
+ {
+ SwNode* pNd = rOutlineNds[nPos];
+ if (pNd->IsTextNode()) // should aways be true
+ {
+ bool bOutlineContentVisibleAttr = true;
+ pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ {
+ aFoldedOutlineNdsArray.push_back(pNd);
+ pShell->ToggleOutlineContentVisibility(nPos);
+ }
+ }
+ }
+ }
+ }
pShell->StartUndo(bLeftRight ? SwUndoId::OUTLINE_LR : SwUndoId::OUTLINE_UD);
bStartedAction = true;
}
@@ -2831,6 +2856,15 @@ void SwContentTree::ExecCommand(const OString& rCmd, bool bOutlineWithChildren)
if (bStartedAction)
{
pShell->EndUndo();
+ if (bUpDown)
+ {
+ if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // fold all outlines that were folded before chapter promote/demote
+ for (SwNode* pNd : aFoldedOutlineNdsArray)
+ pShell->ToggleOutlineContentVisibility(pNd, true);
+ }
+ }
pShell->EndAllAction();
if (m_aActiveContentArr[ContentTypeId::OUTLINE])
m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate();
@@ -3006,6 +3040,27 @@ void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos)
{
SwWrtShell *const pShell = GetWrtShell();
pShell->StartAllAction();
+ std::vector<SwNode*> aFoldedOutlineNdsArray;
+
+ if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // unfold all folded outline content
+ SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds();
+ for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos)
+ {
+ SwNode* pNd = rOutlineNds[nPos];
+ if (pNd->IsTextNode()) // should aways be true
+ {
+ bool bOutlineContentVisibleAttr = true;
+ pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr);
+ if (!bOutlineContentVisibleAttr)
+ {
+ aFoldedOutlineNdsArray.push_back(pNd);
+ pShell->ToggleOutlineContentVisibility(nPos);
+ }
+ }
+ }
+ }
pShell->StartUndo(SwUndoId::OUTLINE_UD);
SwOutlineNodes::size_type nPrevSourcePos = SwOutlineNodes::npos;
@@ -3056,6 +3111,12 @@ void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos)
}
pShell->EndUndo();
+ if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // fold all outlines that were folded before chapter promote/demote
+ for (SwNode* pNd : aFoldedOutlineNdsArray)
+ pShell->ToggleOutlineContentVisibility(pNd, true);
+ }
pShell->EndAllAction();
m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate();
Display(true);
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx
index 444db135021d..2c208eb2d592 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -100,6 +100,9 @@
#include <comphelper/lok.hxx>
#include <memory>
+#include <frmtool.hxx>
+#include <viewopt.hxx>
+
using namespace sw::mark;
using namespace com::sun::star;
namespace {
@@ -1989,5 +1992,122 @@ void SwWrtShell::InsertPostIt(SwFieldMgr& rFieldMgr, const SfxRequest& rReq)
pFormat->Broadcast( SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::FOCUS, &GetView() ) );
}
}
+bool SwWrtShell::IsOutlineContentFolded(const size_t nPos)
+{
+ const SwNodes& rNodes = GetDoc()->GetNodes();
+ const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
+
+ assert(nPos < rOutlineNodes.size());
+
+ SwNode* pOutlineNode = rOutlineNodes[nPos];
+ if (pOutlineNode->IsEndNode())
+ return false;
+
+ bool bOutlineContentVisibleAttr = false;
+ if (pOutlineNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr))
+ return !bOutlineContentVisibleAttr;
+
+ return false;
+}
+
+void SwWrtShell::ToggleOutlineContentVisibility(SwNode* pNd, bool bForceFold)
+{
+ SwOutlineNodes::size_type nPos;
+ if (GetNodes().GetOutLineNds().Seek_Entry(pNd, &nPos))
+ ToggleOutlineContentVisibility(nPos, bForceFold);
+}
+
+void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold)
+{
+ const SwNodes& rNodes = GetNodes();
+ const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds();
+
+ assert(nPos < rOutlineNodes.size());
+
+ SwNode* pSttNd = rOutlineNodes[nPos];
+ if (pSttNd->IsEndNode())
+ return;
+
+ SwNode* pEndNd = &rNodes.GetEndOfContent();
+ if (rOutlineNodes.size() > nPos + 1)
+ pEndNd = rOutlineNodes[nPos + 1];
+
+ if (pSttNd->GetTableBox() || pSttNd->GetIndex() < rNodes.GetEndOfExtras().GetIndex())
+ {
+ // limit folding to within table box
+ if (pSttNd->EndOfSectionIndex() < pEndNd->GetIndex() )
+ pEndNd = pSttNd->EndOfSectionNode();
+ }
+ // if pSttNd isn't in table but pEndNd is, skip over all outline nodes in table
+ else if (pEndNd->GetTableBox())
+ {
+ pEndNd = &rNodes.GetEndOfContent();
+ for (size_t nOutlinePos = nPos + 2; nOutlinePos < rOutlineNodes.size(); nOutlinePos++)
+ {
+ if (!(rOutlineNodes[nOutlinePos]->GetTableBox()))
+ {
+ pEndNd = rOutlineNodes[nOutlinePos];
+ break;
+ }
+ }
+ }
+
+ if (IsOutlineContentFolded(nPos) && !bForceFold)
+ {
+ // unfold
+ SwNodeIndex aIdx(*pSttNd, +1);
+ MakeFrames(GetDoc(), aIdx, *pEndNd);
+
+ pSttNd->GetTextNode()->SetAttrOutlineContentVisible(true);
+
+ if (GetViewOptions()->IsShowOutlineContentVisibilityButton())
+ {
+ // remove fold button if focus is not on outline frame control window
+ SwContentFrame* pFrame = pSttNd->GetTextNode()->getLayoutFrame(nullptr);
+ if (pFrame && !pFrame->IsInDtor())
+ {
+ SwFrameControlPtr pOutlineFrameControl = GetView().GetEditWin().GetFrameControlsManager().GetControl(FrameControlType::Outline, pFrame);
+ if (pOutlineFrameControl && pOutlineFrameControl->GetWindow() && !pOutlineFrameControl->GetWindow()->HasFocus())
+ GetView().GetEditWin().GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, pFrame);
+ }
+
+ // fold revealed outline nodes that have collapsed content
+ while (aIdx != *pEndNd)
+ {
+ SwNode* pTmpNd = &aIdx.GetNode();
+ if (pTmpNd->IsTextNode() && pTmpNd->GetTextNode()->IsOutline())
+ {
+ SwTextNode* pTmpTextNd = pTmpNd->GetTextNode();
+ bool bOutlineContentVisibleAttr = true;
+ if (pTmpTextNd->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr) &&
+ !bOutlineContentVisibleAttr)
+ {
+ SwOutlineNodes::size_type iPos;
+ if (rOutlineNodes.Seek_Entry(pTmpTextNd, &iPos))
+ {
+ if (pTmpTextNd->getLayoutFrame(nullptr))
+ ToggleOutlineContentVisibility(iPos, true);
+ }
+ }
+ }
+ aIdx++;
+ }
+ }
+ }
+ else
+ {
+ // fold
+ for (SwNodeIndex aIdx(*pSttNd, +1); &aIdx.GetNode() != pEndNd; aIdx++)
+ {
+ SwNode* pNd = &aIdx.GetNode();
+ if (pNd->IsContentNode())
+ pNd->GetContentNode()->DelFrames(nullptr);
+ else if (pNd->IsTableNode())
+ pNd->GetTableNode()->DelFrames(nullptr);
+ }
+ pSttNd->GetTextNode()->SetAttrOutlineContentVisible(false);
+ }
+ GetView().GetEditWin().Invalidate();
+}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */