summaryrefslogtreecommitdiff
path: root/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
diff options
context:
space:
mode:
authorJim Raykowski <raykowj@gmail.com>2020-07-27 17:52:41 -0800
committerMike Kaganski <mike.kaganski@collabora.com>2020-07-30 12:03:56 +0200
commit835cd06a047717dfe5e0f117959f3c042e13b21b (patch)
tree74a334fb89d401370e9dcd51d5a3c4ad93edcc64 /sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx
parentb2686de46250d0c8d14365a2af8428387baa0c24 (diff)
tdf#38093 Writer outline folding - outline visibility and on canvas ui
Patch 2/6 Outline content visibility and on canvas collapse/expand control button implementations. Change-Id: I8481125b102d2f07bfcfce91e1379d8e786a7aa2 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/99653 Tested-by: Jenkins Reviewed-by: Mike Kaganski <mike.kaganski@collabora.com>
Diffstat (limited to 'sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx')
-rw-r--r--sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx237
1 files changed, 237 insertions, 0 deletions
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: */