offapi/com/sun/star/text/ViewSettings.idl | 6 officecfg/registry/schema/org/openoffice/Office/Writer.xcs | 8 sw/inc/viewopt.hxx | 8 sw/source/core/doc/DocumentContentOperationsManager.cxx | 32 --- sw/source/core/edit/ednumber.cxx | 48 ++++ sw/source/core/txtnode/ndtxt.cxx | 2 sw/source/ui/config/optpage.cxx | 24 +- sw/source/uibase/app/appopt.cxx | 63 ++++++ sw/source/uibase/config/cfgitems.cxx | 4 sw/source/uibase/config/usrpref.cxx | 17 + sw/source/uibase/config/viewopt.cxx | 5 sw/source/uibase/docvw/FrameControlsManager.cxx | 35 ++- sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx | 53 +---- sw/source/uibase/docvw/edtwin.cxx | 80 ++------ sw/source/uibase/inc/cfgitems.hxx | 1 sw/source/uibase/inc/edtwin.hxx | 2 sw/source/uibase/inc/optpage.hxx | 3 sw/source/uibase/inc/wrtsh.hxx | 6 sw/source/uibase/uiview/view0.cxx | 37 +++ sw/source/uibase/uno/unomod.cxx | 3 sw/source/uibase/utlui/content.cxx | 77 +++++++- sw/source/uibase/wrtsh/wrtsh1.cxx | 67 ++++-- sw/uiconfig/swriter/ui/viewoptionspage.ui | 125 +++++++------ 23 files changed, 470 insertions(+), 236 deletions(-)
New commits: commit c405bae468d887ec77dd3830b7678fcedc2debfd Author: Jim Raykowski <rayk...@gmail.com> AuthorDate: Sat Dec 5 20:57:15 2020 -0900 Commit: Jim Raykowski <rayk...@gmail.com> CommitDate: Thu Dec 24 07:12:59 2020 +0100 tdf#138136 tdf#38093 add option to treat sub outline levels as content Also included in this patch: - Modifications to make all outline content visible during move operations. - Removal of code intended to redraw buttons when layout is changed that seems not to work as intended. - Function IsOutlineContentFolded changed to IsOutlineContentVisible - Change of delay before button is shown to half of what it was. Change-Id: I0dde555ccd0693ca382c1f15326edfdc2fc44a93 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/107815 Tested-by: Jenkins Reviewed-by: Jim Raykowski <rayk...@gmail.com> diff --git a/offapi/com/sun/star/text/ViewSettings.idl b/offapi/com/sun/star/text/ViewSettings.idl index 8261ca1dc50f..4439b7fc9709 100644 --- a/offapi/com/sun/star/text/ViewSettings.idl +++ b/offapi/com/sun/star/text/ViewSettings.idl @@ -296,6 +296,12 @@ published service ViewSettings */ [optional, property] boolean ShowChangesInMargin; + /** If this property is `TRUE`, sub outline levels are treated as content in + outline content visibility actions. + + @since LibreOffice 7.2 + */ + [optional, property] boolean TreatSubOutlineLevelsAsContent; }; }; }; }; }; diff --git a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs index c99841d3cbde..1d54ace2d950 100644 --- a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs +++ b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs @@ -1079,6 +1079,14 @@ </info> <value>false</value> </prop> + <prop oor:name="TreatSubOutlineLevelsAsContent" oor:type="xs:boolean" oor:nillable="false"> + <!-- UIHints: Tools - Options - Writer - View - [Section] Outline mode --> + <info> + <desc>Enables the writer outline content visibility feature to treat sub outline levels as content.</desc> + <label>Treat sub outline levels as content</label> + </info> + <value>false</value> + </prop> <prop oor:name="ShowChangesInMargin" oor:type="xs:boolean" oor:nillable="false"> <!-- UIHints: Tools - Options - Writer - View - [Section] Display tracked changes --> <info> diff --git a/sw/inc/viewopt.hxx b/sw/inc/viewopt.hxx index ebfab960d226..996aec4848c2 100644 --- a/sw/inc/viewopt.hxx +++ b/sw/inc/viewopt.hxx @@ -61,6 +61,7 @@ enum class ViewOptFlags1 : sal_uInt64 { Synchronize = 0x01000000, GridVisible = 0x02000000, OnlineSpell = 0x04000000, + TreatSubOutlineLevelsAsContent = 0x08000000, ShowInlineTooltips = 0x10000000, //tooltips on tracked changes ViewMetachars = 0x20000000, Pageback = 0x40000000, @@ -68,7 +69,7 @@ enum class ViewOptFlags1 : sal_uInt64 { ShowChangesInMargin = 0x100000000 //tracked deletions in margin }; namespace o3tl { - template<> struct typed_flags<ViewOptFlags1> : is_typed_flags<ViewOptFlags1, 0x1F7dfcfff> {}; + template<> struct typed_flags<ViewOptFlags1> : is_typed_flags<ViewOptFlags1, 0x1ffdfcfff> {}; } enum class ViewOptCoreFlags2 { @@ -306,6 +307,11 @@ public: void SetShowOutlineContentVisibilityButton(bool b) { SetCoreOption(b, ViewOptFlags1::ShowOutlineContentVisibilityButton); } + bool IsTreatSubOutlineLevelsAsContent() const; + void SetTreatSubOutlineLevelsAsContent(bool b) + { SetCoreOption(b, ViewOptFlags1::TreatSubOutlineLevelsAsContent); } + + bool IsShowHiddenChar(bool bHard = false) const { return !m_bReadonly && (m_nCoreOptions & ViewOptFlags1::CharHidden) && ((m_nCoreOptions & ViewOptFlags1::ViewMetachars)||bHard); } diff --git a/sw/source/core/doc/DocumentContentOperationsManager.cxx b/sw/source/core/doc/DocumentContentOperationsManager.cxx index 19701083ba38..1b160fe2deec 100644 --- a/sw/source/core/doc/DocumentContentOperationsManager.cxx +++ b/sw/source/core/doc/DocumentContentOperationsManager.cxx @@ -90,10 +90,6 @@ #include <tuple> #include <memory> -#include <editsh.hxx> -#include <viewopt.hxx> -#include <wrtsh.hxx> - using namespace ::com::sun::star::i18n; namespace @@ -2425,27 +2421,6 @@ bool DocumentContentOperationsManager::MoveRange( SwPaM& rPaM, SwPosition& rPos, bool DocumentContentOperationsManager::MoveNodeRange( SwNodeRange& rRange, SwNodeIndex& rPos, SwMoveFlags eMvFlags ) { - std::vector<SwNode*> aFoldedOutlineNdsArray; - SwWrtShell* pWrtShell = dynamic_cast<SwWrtShell*>(m_rDoc.GetEditShell()); - if (pWrtShell && pWrtShell->GetViewOptions() && pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) - { - // unfold all folded outline content - SwOutlineNodes rOutlineNds = m_rDoc.GetNodes().GetOutLineNds(); - for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) - { - SwNode* pNd = rOutlineNds[nPos]; - if (pNd->IsTextNode()) // should always be true - { - bool bOutlineContentVisibleAttr = true; - pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); - if (!bOutlineContentVisibleAttr) - { - aFoldedOutlineNdsArray.push_back(pNd); - pWrtShell->ToggleOutlineContentVisibility(nPos); - } - } - } - } // Moves all Nodes to the new position. // Bookmarks are moved too (currently without Undo support). @@ -2571,13 +2546,6 @@ bool DocumentContentOperationsManager::MoveNodeRange( SwNodeRange& rRange, SwNod m_rDoc.GetFootnoteIdxs().UpdateAllFootnote(); } - if (pWrtShell && pWrtShell->GetViewOptions() && pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) - { - // fold all outlines that were folded before move - for (SwNode* pNd : aFoldedOutlineNdsArray) - pWrtShell->ToggleOutlineContentVisibility(pNd, true); - } - m_rDoc.getIDocumentState().SetModified(); return true; } diff --git a/sw/source/core/edit/ednumber.cxx b/sw/source/core/edit/ednumber.cxx index 58b587e11dcb..b806edc599e9 100644 --- a/sw/source/core/edit/ednumber.cxx +++ b/sw/source/core/edit/ednumber.cxx @@ -28,6 +28,9 @@ #include <numrule.hxx> #include <osl/diagnose.h> +#include <viewopt.hxx> +#include <wrtsh.hxx> + SwPamRanges::SwPamRanges( const SwPaM& rRing ) { for(SwPaM& rTmp : const_cast<SwPaM*>(&rRing)->GetRingContainer()) @@ -391,8 +394,53 @@ void SwEditShell::SetIndent(short nIndent, const SwPosition & rPos) EndAllAction(); } +namespace +{ +class MakeAllOutlineContentTemporarilyVisibile +{ +private: + SwWrtShell* pWrtShell; + std::vector<SwNode*> aOutlineNdsArray; +public: + MakeAllOutlineContentTemporarilyVisibile(SwWrtShell* pShell) + { + pWrtShell = pShell; + if (pWrtShell && pWrtShell->GetViewOptions() && pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // make all outlines content visible and store outline nodes having + // content visible attribute value false + SwOutlineNodes rOutlineNds = pWrtShell->GetNodes().GetOutLineNds(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) + { + SwNode* pNd = rOutlineNds[nPos]; + if (pNd->IsTextNode()) // should always be true + { + bool bOutlineContentVisibleAttr = true; + pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); + if (!bOutlineContentVisibleAttr) + { + aOutlineNdsArray.push_back(pNd); + pWrtShell->ToggleOutlineContentVisibility(nPos); + } + } + } + } + } + + ~MakeAllOutlineContentTemporarilyVisibile() + { + // restore outlines content visibility + for (SwNode* pNd : aOutlineNdsArray) + pWrtShell->ToggleOutlineContentVisibility(pNd, true); + } +}; +} + bool SwEditShell::MoveParagraph( tools::Long nOffset ) { + // make all outline nodes content temporarily visibile for paragraph move + MakeAllOutlineContentTemporarilyVisibile a(dynamic_cast<SwWrtShell*>(this)); + StartAllAction(); SwPaM *pCursor = GetCursor(); diff --git a/sw/source/core/txtnode/ndtxt.cxx b/sw/source/core/txtnode/ndtxt.cxx index a41c9bc19b7e..e71ea4b76119 100644 --- a/sw/source/core/txtnode/ndtxt.cxx +++ b/sw/source/core/txtnode/ndtxt.cxx @@ -4020,7 +4020,7 @@ void SwTextNode::SetAttrOutlineContentVisible(bool bVisible) { SfxGrabBagItem aGrabBagItem(RES_PARATR_GRABBAG); aGrabBagItem.GetGrabBag()["OutlineContentVisibleAttr"] <<= bVisible; - GetTextNode()->SetAttr(aGrabBagItem); + SetAttr(aGrabBagItem); } // #i70748# diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx index 5820f260886e..b6f0b696a91b 100644 --- a/sw/source/ui/config/optpage.cxx +++ b/sw/source/ui/config/optpage.cxx @@ -53,7 +53,6 @@ #include <officecfg/Office/Common.hxx> #include <sal/macros.h> #include <sfx2/dialoghelper.hxx> -#include <sfx2/dispatch.hxx> #include <sfx2/printer.hxx> #include <sfx2/bindings.hxx> #include <sfx2/viewfrm.hxx> @@ -101,13 +100,23 @@ SwContentOptPage::SwContentOptPage(weld::Container* pPage, weld::DialogControlle , m_xMetricLabel(m_xBuilder->weld_label("measureunitlabel")) , m_xMetricLB(m_xBuilder->weld_combo_box("measureunit")) , m_xShowInlineTooltips(m_xBuilder->weld_check_button("changestooltip")) + , m_xOutlineLabel(m_xBuilder->weld_label("outlinelabel")) , m_xShowOutlineContentVisibilityButton(m_xBuilder->weld_check_button("outlinecontentvisibilitybutton")) + , m_xTreatSubOutlineLevelsAsContent(m_xBuilder->weld_check_button("suboutlinelevelsascontent")) , m_xShowChangesInMargin(m_xBuilder->weld_check_button("changesinmargin")) , m_xFieldHiddenCB(m_xBuilder->weld_check_button("hiddentextfield")) , m_xFieldHiddenParaCB(m_xBuilder->weld_check_button("hiddenparafield")) { if (!officecfg::Office::Common::Misc::ExperimentalMode::get()) + { + m_xOutlineLabel->hide(); m_xShowOutlineContentVisibilityButton->hide(); + m_xTreatSubOutlineLevelsAsContent->hide(); + } + else + { + m_xShowOutlineContentVisibilityButton->connect_toggled(LINK(this, SwContentOptPage, ShowOutlineContentVisibilityButtonHdl)); + } /* This part is visible only with Writer/Web->View dialogue. */ const SfxPoolItem* pItem; @@ -206,11 +215,11 @@ void SwContentOptPage::Reset(const SfxItemSet* rSet) m_xSmoothCBox->set_active(pElemAttr->m_bSmoothScroll); m_xShowInlineTooltips->set_active(pElemAttr->m_bShowInlineTooltips); m_xShowOutlineContentVisibilityButton->set_active(pElemAttr->m_bShowOutlineContentVisibilityButton); + m_xTreatSubOutlineLevelsAsContent->set_active(pElemAttr->m_bTreatSubOutlineLevelsAsContent); + m_xTreatSubOutlineLevelsAsContent->set_sensitive(pElemAttr->m_bShowOutlineContentVisibilityButton); m_xShowChangesInMargin->set_active(pElemAttr->m_bShowChangesInMargin); m_xFieldHiddenCB->set_active( pElemAttr->m_bFieldHiddenText ); m_xFieldHiddenParaCB->set_active( pElemAttr->m_bShowHiddenPara ); - if (GetActiveWrtShell()->GetViewOptions()->IsShowOutlineContentVisibilityButton() != pElemAttr->m_bShowOutlineContentVisibilityButton) - GetActiveWrtShell()->GetView().GetDocShell()->GetDispatcher()->Execute(FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON); } m_xMetricLB->set_active(-1); lcl_SelectMetricLB(*m_xMetricLB, SID_ATTR_METRIC, *rSet); @@ -234,13 +243,11 @@ bool SwContentOptPage::FillItemSet(SfxItemSet* rSet) aElem.m_bSmoothScroll = m_xSmoothCBox->get_active(); aElem.m_bShowInlineTooltips = m_xShowInlineTooltips->get_active(); aElem.m_bShowOutlineContentVisibilityButton = m_xShowOutlineContentVisibilityButton->get_active(); + aElem.m_bTreatSubOutlineLevelsAsContent = m_xTreatSubOutlineLevelsAsContent->get_active(); aElem.m_bShowChangesInMargin = m_xShowChangesInMargin->get_active(); aElem.m_bFieldHiddenText = m_xFieldHiddenCB->get_active(); aElem.m_bShowHiddenPara = m_xFieldHiddenParaCB->get_active(); - if (GetActiveWrtShell()->GetViewOptions()->IsShowOutlineContentVisibilityButton() != aElem.m_bShowOutlineContentVisibilityButton) - GetActiveWrtShell()->GetView().GetDocShell()->GetDispatcher()->Execute(FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON); - bool bRet = !pOldAttr || aElem != *pOldAttr; if(bRet) bRet = nullptr != rSet->Put(aElem); @@ -277,6 +284,11 @@ IMPL_LINK(SwContentOptPage, VertRulerHdl, weld::ToggleButton&, rBox, void) m_xVRulerRightCBox->set_sensitive(rBox.get_sensitive() && rBox.get_active()); } +IMPL_LINK(SwContentOptPage, ShowOutlineContentVisibilityButtonHdl, weld::ToggleButton&, rBox, void) +{ + m_xTreatSubOutlineLevelsAsContent->set_sensitive(rBox.get_active()); +} + // TabPage Printer additional settings SwAddPrinterTabPage::SwAddPrinterTabPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rCoreSet) diff --git a/sw/source/uibase/app/appopt.cxx b/sw/source/uibase/app/appopt.cxx index 263017fb4604..1d813793cff6 100644 --- a/sw/source/uibase/app/appopt.cxx +++ b/sw/source/uibase/app/appopt.cxx @@ -56,6 +56,8 @@ #include <swabstdlg.hxx> #include <swwrtshitem.hxx> +#include <ndtxt.hxx> + using namespace ::com::sun::star::uno; using namespace ::com::sun::star::lang; @@ -259,11 +261,52 @@ void SwModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet ) } // Elements - interpret Item + std::vector<SwNode*> aFoldedOutlineNdsArray; + bool bShow = false; if( SfxItemState::SET == rSet.GetItemState( FN_PARAM_ELEM, false, &pItem ) ) { const SwElemItem* pElemItem = static_cast<const SwElemItem*>(pItem); pElemItem->FillViewOptions( aViewOpt ); + SwWrtShell* pWrtShell = GetActiveWrtShell(); + bShow = pWrtShell->GetViewOptions()->IsShowOutlineContentVisibilityButton(); + bool bTreatSubsChanged = aViewOpt.IsTreatSubOutlineLevelsAsContent() + != pWrtShell->GetViewOptions()->IsTreatSubOutlineLevelsAsContent(); + + // move cursor to top if something with the outline mode changed + if ((bShow != aViewOpt.IsShowOutlineContentVisibilityButton()) || + (pWrtShell->GetViewOptions()->IsTreatSubOutlineLevelsAsContent() != + aViewOpt.IsTreatSubOutlineLevelsAsContent())) + { + // move cursor to top of document + if (pWrtShell->IsSelFrameMode()) + { + pWrtShell->UnSelectFrame(); + pWrtShell->LeaveSelFrameMode(); + } + pWrtShell->EnterStdMode(); + pWrtShell->SttEndDoc(true); + } + + if (bShow && (!aViewOpt.IsShowOutlineContentVisibilityButton() || bTreatSubsChanged)) + { + // outline mode options have change which require to show all content + const SwOutlineNodes& rOutlineNds = pWrtShell->GetNodes().GetOutLineNds(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) + { + SwNode* pNd = rOutlineNds[nPos]; + if (pNd->IsTextNode()) // should always be true + { + bool bOutlineContentVisibleAttr = true; + pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); + if (!bOutlineContentVisibleAttr) + { + aFoldedOutlineNdsArray.push_back(pNd); + pWrtShell->ToggleOutlineContentVisibility(nPos); + } + } + } + } } if( SfxItemState::SET == rSet.GetItemState(SID_ATTR_METRIC, false, &pItem ) ) @@ -381,6 +424,26 @@ void SwModule::ApplyItemSet( sal_uInt16 nId, const SfxItemSet& rSet ) // set elements for the current view and shell ApplyUsrPref( aViewOpt, pAppView, bTextDialog? SvViewOpt::DestText : SvViewOpt::DestWeb); + + // must be done after ApplyUsrPref + if (SfxItemState::SET == rSet.GetItemState(FN_PARAM_ELEM, false)) + { + if (!GetActiveWrtShell()->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // outline mode is no longer active + // set outline content visible attribute to false for nodes in the array + for (SwNode* pNd : aFoldedOutlineNdsArray) + pNd->GetTextNode()->SetAttrOutlineContentVisible(false); + } + else if (bShow) + { + // outline mode remained active + // sub level treatment might have changed + // ToggleOutlineContentVisiblity only knows sub level treatment after ApplyUserPref + for (SwNode* pNd : aFoldedOutlineNdsArray) + GetActiveWrtShell()->ToggleOutlineContentVisibility(pNd, true); + } + } } std::unique_ptr<SfxTabPage> SwModule::CreateTabPage( sal_uInt16 nId, weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet ) diff --git a/sw/source/uibase/config/cfgitems.cxx b/sw/source/uibase/config/cfgitems.cxx index e7d1fc2a9a11..e32c86e14c52 100644 --- a/sw/source/uibase/config/cfgitems.cxx +++ b/sw/source/uibase/config/cfgitems.cxx @@ -100,6 +100,7 @@ SwElemItem::SwElemItem() : m_bNotes = false; m_bShowInlineTooltips = true; m_bShowOutlineContentVisibilityButton = + m_bTreatSubOutlineLevelsAsContent = m_bShowChangesInMargin = m_bFieldHiddenText = m_bShowHiddenPara = false; @@ -118,6 +119,7 @@ SwElemItem::SwElemItem(const SwViewOption& rVOpt) : m_bNotes = rVOpt.IsPostIts(); m_bShowInlineTooltips = rVOpt.IsShowInlineTooltips(); m_bShowOutlineContentVisibilityButton = rVOpt.IsShowOutlineContentVisibilityButton(); + m_bTreatSubOutlineLevelsAsContent = rVOpt.IsTreatSubOutlineLevelsAsContent(); m_bShowChangesInMargin = rVOpt.IsShowChangesInMargin(); m_bFieldHiddenText = rVOpt.IsShowHiddenField(); m_bShowHiddenPara = rVOpt.IsShowHiddenPara(); @@ -144,6 +146,7 @@ bool SwElemItem::operator==( const SfxPoolItem& rAttr ) const m_bNotes == rItem.m_bNotes && m_bShowInlineTooltips == rItem.m_bShowInlineTooltips && m_bShowOutlineContentVisibilityButton == rItem.m_bShowOutlineContentVisibilityButton && + m_bTreatSubOutlineLevelsAsContent == rItem.m_bTreatSubOutlineLevelsAsContent && m_bShowChangesInMargin == rItem.m_bShowChangesInMargin && m_bFieldHiddenText == rItem.m_bFieldHiddenText && m_bShowHiddenPara == rItem.m_bShowHiddenPara); @@ -162,6 +165,7 @@ void SwElemItem::FillViewOptions( SwViewOption& rVOpt) const rVOpt.SetPostIts (m_bNotes ); rVOpt.SetShowInlineTooltips( m_bShowInlineTooltips ); rVOpt.SetShowOutlineContentVisibilityButton(m_bShowOutlineContentVisibilityButton); + rVOpt.SetTreatSubOutlineLevelsAsContent(m_bTreatSubOutlineLevelsAsContent); rVOpt.SetShowChangesInMargin( m_bShowChangesInMargin ); rVOpt.SetShowHiddenField(m_bFieldHiddenText ); rVOpt.SetShowHiddenPara(m_bShowHiddenPara ); diff --git a/sw/source/uibase/config/usrpref.cxx b/sw/source/uibase/config/usrpref.cxx index e2d2336d76ac..e08b4dfd3699 100644 --- a/sw/source/uibase/config/usrpref.cxx +++ b/sw/source/uibase/config/usrpref.cxx @@ -76,7 +76,7 @@ SwMasterUsrPref::~SwMasterUsrPref() } const auto g_UpdateLinkIndex = 17; -const auto g_DefaultAnchor = 24; +const auto g_DefaultAnchor = 25; Sequence<OUString> SwContentViewConfig::GetPropertyNames() const { @@ -105,8 +105,9 @@ Sequence<OUString> SwContentViewConfig::GetPropertyNames() const "Display/ShowInlineTooltips", // 20 "Display/UseHeaderFooterMenu", // 21 "Display/ShowOutlineContentVisibilityButton", // 22 - "Display/ShowChangesInMargin", // 23 - "Display/DefaultAnchor" // 24 + "Display/TreatSubOutlineLevelsAsContent", // 23 + "Display/ShowChangesInMargin", // 24 + "Display/DefaultAnchor" // 25 }; #if defined(__GNUC__) && !defined(__clang__) // clang 8.0.0 says strcmp isn't constexpr @@ -175,8 +176,9 @@ void SwContentViewConfig::ImplCommit() case 20: bVal = m_rParent.IsShowInlineTooltips(); break;// "Display/ShowInlineTooltips" case 21: bVal = m_rParent.IsUseHeaderFooterMenu(); break;// "Display/UseHeaderFooterMenu" case 22: bVal = m_rParent.IsShowOutlineContentVisibilityButton(); break;// "Display/ShowOutlineContentVisibilityButton" - case 23: bVal = m_rParent.IsShowChangesInMargin(); break;// "Display/ShowChangesInMargin" - case 24: pValues[nProp] <<= m_rParent.GetDefaultAnchor(); break;// "Display/DefaultAnchor" + case 23: bVal = m_rParent.IsTreatSubOutlineLevelsAsContent(); break;// "Display/TreatSubOutlineLevelsAsContent" + case 24: bVal = m_rParent.IsShowChangesInMargin(); break;// "Display/ShowChangesInMargin" + case 25: pValues[nProp] <<= m_rParent.GetDefaultAnchor(); break;// "Display/DefaultAnchor" } if ((nProp != g_UpdateLinkIndex) && (nProp != g_DefaultAnchor)) pValues[nProp] <<= bVal; @@ -229,8 +231,9 @@ void SwContentViewConfig::Load() case 20: m_rParent.SetShowInlineTooltips(bSet); break;// "Display/ShowInlineTooltips" case 21: m_rParent.SetUseHeaderFooterMenu(bSet); break;// "Display/UseHeaderFooterMenu" case 22: m_rParent.SetShowOutlineContentVisibilityButton(bSet); break;// "Display/ShowOutlineContententVisibilityButton" - case 23: m_rParent.SetShowChangesInMargin(bSet); break;// "Display/ShowChangesInMargin" - case 24: + case 23: m_rParent.SetTreatSubOutlineLevelsAsContent(bSet); break;// "Display/TreatSubOutlineLevelsAsContent" + case 24: m_rParent.SetShowChangesInMargin(bSet); break;// "Display/ShowChangesInMargin" + case 25: { sal_Int32 nSet; pValues[nProp] >>= nSet; diff --git a/sw/source/uibase/config/viewopt.cxx b/sw/source/uibase/config/viewopt.cxx index 3e534f1126d9..458621846514 100644 --- a/sw/source/uibase/config/viewopt.cxx +++ b/sw/source/uibase/config/viewopt.cxx @@ -103,6 +103,11 @@ bool SwViewOption::IsShowOutlineContentVisibilityButton() const (m_nCoreOptions & ViewOptFlags1::ShowOutlineContentVisibilityButton); } +bool SwViewOption::IsTreatSubOutlineLevelsAsContent() const +{ + return officecfg::Office::Common::Misc::ExperimentalMode::get() && + (m_nCoreOptions & ViewOptFlags1::TreatSubOutlineLevelsAsContent); +} void SwViewOption::DrawRect( OutputDevice *pOut, const SwRect &rRect, ::Color nCol ) diff --git a/sw/source/uibase/docvw/FrameControlsManager.cxx b/sw/source/uibase/docvw/FrameControlsManager.cxx index 2232ca7ed869..886021ee89f8 100644 --- a/sw/source/uibase/docvw/FrameControlsManager.cxx +++ b/sw/source/uibase/docvw/FrameControlsManager.cxx @@ -218,7 +218,7 @@ void SwFrameControlsManager::SetOutlineContentVisibilityButton(const SwTextNode* { const SwContentFrame* pContentFrame = pTextNd->getLayoutFrame(nullptr); - // has node frame changed or been deleted + // has node frame changed or been deleted? std::map<const SwTextNode*, const SwContentFrame*>::iterator iter = m_aTextNodeContentFrameMap.find(pTextNd); if (iter != m_aTextNodeContentFrameMap.end()) { @@ -272,17 +272,38 @@ void SwFrameControlsManager::SetOutlineContentVisibilityButton(const SwTextNode* { // show expand button immediately pWin->Show(); - // outline content might not be folded, this happens on undo, outline moves, and folded outline content reveals + /* + The outline content might be visible here. This happens on document load, + undo outline moves, and show of outline content that itself has outline nodes + having outline content visibility attribute false, for example tables and text + frames containing outline nodes. + */ 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)) + SwNodeIndex aIdx(*pTextNd, +1); + // there shouldn't be a layout frame + // if there is then force visiblity false + if (!m_pEditWin->GetView().GetWrtShell().GetViewOptions()->IsTreatSubOutlineLevelsAsContent()) { - m_pEditWin->GetView().GetWrtShell().ToggleOutlineContentVisibility(nPos, true); // force fold + if (!(aIdx.GetNode().IsEndNode() || + (nPos + 1 < rOutlineNds.size() && &aIdx.GetNode() == rOutlineNds[nPos +1])) + && aIdx.GetNode().IsContentNode() + // this determines if the content is really visible + && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr)) + { + // force outline content visibility false + m_pEditWin->GetView().GetWrtShell().ToggleOutlineContentVisibility(nPos, true); + } + } + else if (!aIdx.GetNode().IsEndNode() + && aIdx.GetNode().IsContentNode() + // this determines if the content is really visible + && aIdx.GetNode().GetContentNode()->getLayoutFrame(nullptr)) + { + // force outline content visibility false + m_pEditWin->GetView().GetWrtShell().ToggleOutlineContentVisibility(nPos, true); } } } diff --git a/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx index b696709d6042..864c2b604bd0 100644 --- a/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx +++ b/sw/source/uibase/docvw/OutlineContentVisibilityWin.cxx @@ -21,6 +21,8 @@ #include <strings.hrc> #include <svx/svdview.hxx> +#include <viewopt.hxx> + SwOutlineContentVisibilityWin::SwOutlineContentVisibilityWin(SwEditWin* pEditWin, const SwFrame* pFrame) : InterimItemWindow(pEditWin, "modules/swriter/ui/outlinebutton.ui", "OutlineButton") @@ -50,7 +52,7 @@ SwOutlineContentVisibilityWin::SwOutlineContentVisibilityWin(SwEditWin* pEditWin m_xRightBtn->connect_key_press(LINK(this, SwOutlineContentVisibilityWin, KeyInputHdl)); m_xDownBtn->connect_key_press(LINK(this, SwOutlineContentVisibilityWin, KeyInputHdl)); - m_aDelayTimer.SetTimeout(50); + m_aDelayTimer.SetTimeout(25); m_aDelayTimer.SetInvokeHandler(LINK(this, SwOutlineContentVisibilityWin, DelayAppearHandler)); } @@ -132,44 +134,17 @@ void SwOutlineContentVisibilityWin::Set() return; } - // 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); + SetSymbol(rSh.IsOutlineContentVisible(m_nOutlinePos) ? SymbolType::ARROW_DOWN + : SymbolType::ARROW_RIGHT); // 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 + if (!rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent() + && m_nOutlinePos + 1 < nOutlineNodesCount && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(m_nOutlinePos + 1) > nLevel) sQuickHelp += " (" + SwResId(STR_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")"; SetQuickHelpText(sQuickHelp); @@ -219,30 +194,30 @@ void SwOutlineContentVisibilityWin::ToggleOutlineContentVisibility(const bool bS // set cursor position here so Navigator tracks outline // when doc changed broadcast message is sent in toggle function rSh.GotoOutline(m_nOutlinePos); - if (bSubs) + if (rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent()) + rSh.ToggleOutlineContentVisibility(m_nOutlinePos); + else 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); + bool bVisible = rSh.IsOutlineContentVisible(m_nOutlinePos); do { - if (rSh.IsOutlineContentFolded(nPos) == bFold) + if (rSh.IsOutlineContentVisible(nPos) == bVisible) rSh.ToggleOutlineContentVisibility(nPos); } while (++nPos < nOutlineNodesCount && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel); } else rSh.ToggleOutlineContentVisibility(m_nOutlinePos); - if (!m_bDestroyed) { - SetSymbol(rSh.IsOutlineContentFolded(m_nOutlinePos) ? SymbolType::ARROW_RIGHT - : SymbolType::ARROW_DOWN); + SetSymbol(rSh.IsOutlineContentVisible(m_nOutlinePos) ? SymbolType::ARROW_DOWN + : SymbolType::ARROW_RIGHT); } - rSh.LockView(false); } diff --git a/sw/source/uibase/docvw/edtwin.cxx b/sw/source/uibase/docvw/edtwin.cxx index 32ca8139fdc5..303bb7b7aa8f 100644 --- a/sw/source/uibase/docvw/edtwin.cxx +++ b/sw/source/uibase/docvw/edtwin.cxx @@ -577,7 +577,8 @@ void SwEditWin::UpdatePointer(const Point &rLPt, sal_uInt16 nModifier ) = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos); OUString sQuickHelp(SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY)); - if (nPos + 1 < nOutlineNodesCount + if (!rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent() + && nPos + 1 < nOutlineNodesCount && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos + 1) > nLevel) sQuickHelp += " (" + SwResId(STR_CLICK_OUTLINE_CONTENT_TOGGLE_VISIBILITY_EXT) + ")"; SetQuickHelpText(sQuickHelp); @@ -1362,7 +1363,7 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) if (rSh.GetViewOptions()->IsShowOutlineContentVisibilityButton()) { - // not allowed if outline content is folded + // not allowed if outline content visibility is false 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))) @@ -1374,13 +1375,13 @@ void SwEditWin::KeyInput(const KeyEvent &rKEvt) bool bOutlineContentVisibleAttr = true; pContentNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); if (!bOutlineContentVisibleAttr) - return; // outline node is folded + return; // outline content visibility is false 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 + return; // previous outline node has content visibility false } } } @@ -3538,7 +3539,7 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) MoveCursor(rSh, aDocPos, bOnlyText, bLockView); SwPaM aPam(*rSh.GetCurrentShellCursor().GetPoint()); SwOutlineNodes::size_type nPos; - if (rSh.GetNodes().GetOutLineNds().Seek_Entry( &aPam.GetPoint()->nNode.GetNode(), &nPos)) + if (rSh.GetNodes().GetOutLineNds().Seek_Entry(&aPam.GetPoint()->nNode.GetNode(), &nPos)) rSh.ToggleOutlineContentVisibility(nPos); return; } @@ -3787,15 +3788,20 @@ void SwEditWin::MouseButtonDown(const MouseEvent& _rMEvt) SwOutlineNodes::size_type nPos; if (rSh.GetNodes().GetOutLineNds().Seek_Entry(&aPam.GetPoint()->nNode.GetNode(), &nPos)) { - SwOutlineNodes::size_type nOutlineNodesCount = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); - int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos); - bool bFold = rSh.IsOutlineContentFolded(nPos); - do + if (rSh.GetViewOptions()->IsTreatSubOutlineLevelsAsContent()) + rSh.ToggleOutlineContentVisibility(nPos); + else { - if (rSh.IsOutlineContentFolded(nPos) == bFold) - rSh.ToggleOutlineContentVisibility(nPos); - } while (++nPos < nOutlineNodesCount - && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel); + SwOutlineNodes::size_type nOutlineNodesCount = rSh.getIDocumentOutlineNodesAccess()->getOutlineNodesCount(); + int nLevel = rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos); + bool bVisible = rSh.IsOutlineContentVisible(nPos); + do + { + if (rSh.IsOutlineContentVisible(nPos) == bVisible) + rSh.ToggleOutlineContentVisibility(nPos); + } while (++nPos < nOutlineNodesCount + && rSh.getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel); + } return; } } @@ -3944,15 +3950,15 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) // 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)) + rSh.IsOutlineContentVisible(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)) + if (rNds.GetOutLineNds().Seek_Entry(aSwContentAtPos.aFnd.pNode->GetTextNode(), + &nPos) && rSh.IsOutlineContentVisible(nPos)) { GetFrameControlsManager().SetOutlineContentVisibilityButton(aSwContentAtPos.aFnd.pNode->GetTextNode()); } @@ -3965,10 +3971,12 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) // 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)) + if (rNds.GetOutLineNds().Seek_Entry(static_cast<SwTextFrame*>(m_pSavedOutlineFrame)-> + GetTextNodeFirst(), &nPos) && + rSh.IsOutlineContentVisible(nPos)) { - GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); + GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, + m_pSavedOutlineFrame); } m_pSavedOutlineFrame = nullptr; } @@ -4017,7 +4025,7 @@ void SwEditWin::MouseMove(const MouseEvent& _rMEvt) 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)) + if (rSh.IsOutlineContentVisible(nPos)) GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, m_pSavedOutlineFrame); m_pSavedOutlineFrame = nullptr; } @@ -6631,38 +6639,6 @@ void SwEditWin::SetGraphicTwipPosition(bool bStart, const Point& rPosition) } } -void SwEditWin::SetOutlineContentVisibilityButtons() -{ - 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/inc/cfgitems.hxx b/sw/source/uibase/inc/cfgitems.hxx index a647c01f0925..0aa6c2c8d135 100644 --- a/sw/source/uibase/inc/cfgitems.hxx +++ b/sw/source/uibase/inc/cfgitems.hxx @@ -79,6 +79,7 @@ class SW_DLLPUBLIC SwElemItem : public SfxPoolItem bool m_bNotes :1; bool m_bShowInlineTooltips :1; bool m_bShowOutlineContentVisibilityButton :1; + bool m_bTreatSubOutlineLevelsAsContent :1; bool m_bShowChangesInMargin :1; bool m_bFieldHiddenText :1; bool m_bShowHiddenPara :1; diff --git a/sw/source/uibase/inc/edtwin.hxx b/sw/source/uibase/inc/edtwin.hxx index a74afc85d085..cb736bdf562f 100644 --- a/sw/source/uibase/inc/edtwin.hxx +++ b/sw/source/uibase/inc/edtwin.hxx @@ -294,8 +294,6 @@ public: const SwFrame* GetSavedOutlineFrame() const { return m_pSavedOutlineFrame; } void SetSavedOutlineFrame(SwFrame* pFrame) { m_pSavedOutlineFrame = pFrame; } - void SetOutlineContentVisibilityButtons(); - virtual FactoryFunction GetUITestFactory() const override; }; diff --git a/sw/source/uibase/inc/optpage.hxx b/sw/source/uibase/inc/optpage.hxx index 2a35c1d843a8..18f2d1ee4c04 100644 --- a/sw/source/uibase/inc/optpage.hxx +++ b/sw/source/uibase/inc/optpage.hxx @@ -54,12 +54,15 @@ class SwContentOptPage : public SfxTabPage std::unique_ptr<weld::ComboBox> m_xMetricLB; std::unique_ptr<weld::CheckButton> m_xShowInlineTooltips; + std::unique_ptr<weld::Label> m_xOutlineLabel; std::unique_ptr<weld::CheckButton> m_xShowOutlineContentVisibilityButton; + std::unique_ptr<weld::CheckButton> m_xTreatSubOutlineLevelsAsContent; std::unique_ptr<weld::CheckButton> m_xShowChangesInMargin; std::unique_ptr<weld::CheckButton> m_xFieldHiddenCB; std::unique_ptr<weld::CheckButton> m_xFieldHiddenParaCB; DECL_LINK(VertRulerHdl, weld::ToggleButton&, void); + DECL_LINK(ShowOutlineContentVisibilityButtonHdl, weld::ToggleButton&, void); public: SwContentOptPage(weld::Container* pPage, weld::DialogController* pController, const SfxItemSet& rSet); virtual ~SwContentOptPage() override; diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx index d4c9a6be9d64..1bf0ce26db8a 100644 --- a/sw/source/uibase/inc/wrtsh.hxx +++ b/sw/source/uibase/inc/wrtsh.hxx @@ -490,9 +490,9 @@ 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); + bool IsOutlineContentVisible(const size_t nPos); + void ToggleOutlineContentVisibility(SwNode* pNd, const bool bForceNotVisible = false); + void ToggleOutlineContentVisibility(const size_t nPos, const bool bForceNotVisible = false); private: diff --git a/sw/source/uibase/uiview/view0.cxx b/sw/source/uibase/uiview/view0.cxx index 5dc5bc316110..ad2756b8fdd8 100644 --- a/sw/source/uibase/uiview/view0.cxx +++ b/sw/source/uibase/uiview/view0.cxx @@ -57,6 +57,8 @@ #include <swslots.hxx> #include <PostItMgr.hxx> +#include <ndtxt.hxx> + using namespace ::com::sun::star; #include <unotools/moduleoptions.hxx> @@ -594,11 +596,41 @@ void SwView::ExecViewOptions(SfxRequest &rReq) break; case FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON: + { if( STATE_TOGGLE == eState ) bFlag = !pOpt->IsShowOutlineContentVisibilityButton(); - pOpt->SetShowOutlineContentVisibilityButton( bFlag ); + SwWrtShell &rSh = GetWrtShell(); + + // move cursor to top of document + if (rSh.IsSelFrameMode()) + { + rSh.UnSelectFrame(); + rSh.LeaveSelFrameMode(); + } + rSh.EnterStdMode(); + rSh.SttEndDoc(true); + + if (!bFlag) + { + // make all content visible + const SwOutlineNodes& rOutlineNds = rSh.GetNodes().GetOutLineNds(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) + { + SwNode* pNd = rOutlineNds[nPos]; + bool bOutlineContentVisibleAttr = true; + pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); + if (!bOutlineContentVisibleAttr) + { + rSh.ToggleOutlineContentVisibility(nPos); + pNd->GetTextNode()->SetAttrOutlineContentVisible(false); + } + } + } + + pOpt->SetShowOutlineContentVisibilityButton(bFlag); break; + } case FN_SHOW_CHANGES_IN_MARGIN: if( STATE_TOGGLE == eState ) @@ -640,9 +672,6 @@ void SwView::ExecViewOptions(SfxRequest &rReq) if ( nSlot == SID_AUTOSPELL_CHECK ) GetPostItMgr()->SetSpellChecking(); - if (nSlot == FN_SHOW_OUTLINECONTENTVISIBILITYBUTTON) - GetEditWin().SetOutlineContentVisibilityButtons(); - const bool bLockedView = rSh.IsViewLocked(); rSh.LockView( true ); //lock visible section GetWrtShell().EndAction(); diff --git a/sw/source/uibase/uno/unomod.cxx b/sw/source/uibase/uno/unomod.cxx index c17356610646..7138f5b6af01 100644 --- a/sw/source/uibase/uno/unomod.cxx +++ b/sw/source/uibase/uno/unomod.cxx @@ -96,6 +96,7 @@ enum SwViewSettingsPropertyHandles HANDLE_VIEWSET_USE_HEADERFOOTERMENU, HANDLE_VIEWSET_BOOKMARKS, HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON, + HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT, HANDLE_VIEWSET_CHANGES_IN_MARGIN }; @@ -136,6 +137,7 @@ static ChainablePropertySetInfo * lcl_createViewSettingsInfo() { OUString( "ShowInlineTooltips" ), HANDLE_VIEWSET_INLINECHANGES_TIPS , cppu::UnoType<bool>::get(), PROPERTY_NONE}, { OUString( "UseHeaderFooterMenu" ), HANDLE_VIEWSET_USE_HEADERFOOTERMENU , cppu::UnoType<bool>::get(), PROPERTY_NONE}, { OUString( "ShowOutlineContentVisibilityButton" ), HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON , cppu::UnoType<bool>::get(), PROPERTY_NONE}, + { OUString( "TreatSubOutlineLevelsAsContent" ), HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT , cppu::UnoType<bool>::get(), PROPERTY_NONE}, { OUString( "ShowChangesInMargin" ), HANDLE_VIEWSET_CHANGES_IN_MARGIN, cppu::UnoType<bool>::get(), PROPERTY_NONE}, { OUString( "RasterResolutionX"), HANDLE_VIEWSET_RASTER_RESOLUTION_X, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE}, { OUString( "RasterResolutionY"), HANDLE_VIEWSET_RASTER_RESOLUTION_Y, cppu::UnoType<sal_Int32>::get(), PROPERTY_NONE}, @@ -600,6 +602,7 @@ void SwXViewSettings::_setSingleValue( const comphelper::PropertyInfo & rInfo, c case HANDLE_VIEWSET_INLINECHANGES_TIPS : mpViewOption->SetShowInlineTooltips(*o3tl::doAccess<bool>(rValue)); break; case HANDLE_VIEWSET_USE_HEADERFOOTERMENU : mpViewOption->SetUseHeaderFooterMenu(*o3tl::doAccess<bool>(rValue)); break; case HANDLE_VIEWSET_SHOW_OUTLINECONTENTVISIBILITYBUTTON : mpViewOption->SetShowOutlineContentVisibilityButton(*o3tl::doAccess<bool>(rValue)); break; + case HANDLE_VIEWSET_TREAT_SUB_OUTLINE_LEVELS_AS_CONTENT : mpViewOption->SetTreatSubOutlineLevelsAsContent(*o3tl::doAccess<bool>(rValue)); break; case HANDLE_VIEWSET_CHANGES_IN_MARGIN : mpViewOption->SetShowChangesInMargin(*o3tl::doAccess<bool>(rValue)); break; case HANDLE_VIEWSET_RASTER_RESOLUTION_X : { diff --git a/sw/source/uibase/utlui/content.cxx b/sw/source/uibase/utlui/content.cxx index 54b84ee935d9..378a6675e861 100644 --- a/sw/source/uibase/utlui/content.cxx +++ b/sw/source/uibase/utlui/content.cxx @@ -1262,7 +1262,7 @@ static void lcl_SetOutlineContentEntriesSensitivities(SwContentTree* pThis, cons nPos++; } - bool bHasFolded(pThis->GetWrtShell()->IsOutlineContentFolded(nPos)); + bool bHasFolded(!pThis->GetWrtShell()->IsOutlineContentVisible(nPos)); bool bHasUnfolded(!bHasFolded); while ((++nPos < pThis->GetWrtShell()->getIDocumentOutlineNodesAccess()->getOutlineNodesCount()) && @@ -1278,7 +1278,7 @@ static void lcl_SetOutlineContentEntriesSensitivities(SwContentTree* pThis, cons if (rNodes.GoNext(&aIdx) == pEndNd) continue; // skip if no content - if (pThis->GetWrtShell()->IsOutlineContentFolded(nPos)) + if (!pThis->GetWrtShell()->IsOutlineContentVisible(nPos)) bHasFolded = true; else bHasUnfolded = true; @@ -2840,6 +2840,7 @@ void SwContentTree::ExecCommand(std::string_view rCmd, bool bOutlineWithChildren SwOutlineNodes::difference_type nDirLast = bUp ? -1 : 1; bool bStartedAction = false; + std::vector<SwNode*> aOutlineNdsArray; for (auto const& pCurrentEntry : selected) { assert(pCurrentEntry && lcl_IsContent(*pCurrentEntry, *m_xTreeView)); @@ -2861,6 +2862,29 @@ void SwContentTree::ExecCommand(std::string_view rCmd, bool bOutlineWithChildren if (!bStartedAction) { pShell->StartAllAction(); + if (bUpDown) + { + if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // make all outline nodes content visible before move + // restore outline nodes content visibile state after move + SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) + { + SwNode* pNd = rOutlineNds[nPos]; + if (pNd->IsTextNode()) // should always be true + { + bool bOutlineContentVisibleAttr = true; + pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); + if (!bOutlineContentVisibleAttr) + { + aOutlineNdsArray.push_back(pNd); + pShell->ToggleOutlineContentVisibility(nPos); + } + } + } + } + } pShell->StartUndo(bLeftRight ? SwUndoId::OUTLINE_LR : SwUndoId::OUTLINE_UD); bStartedAction = true; } @@ -3032,6 +3056,15 @@ void SwContentTree::ExecCommand(std::string_view rCmd, bool bOutlineWithChildren if (bStartedAction) { pShell->EndUndo(); + if (bUpDown) + { + if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // restore state of outline content visibility to before move + for (SwNode* pNd : aOutlineNdsArray) + pShell->ToggleOutlineContentVisibility(pNd, true); + } + } pShell->EndAllAction(); if (m_aActiveContentArr[ContentTypeId::OUTLINE]) m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); @@ -3365,6 +3398,28 @@ void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos) { SwWrtShell *const pShell = GetWrtShell(); pShell->StartAllAction(); + std::vector<SwNode*> aOutlineNdsArray; + + if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // make all outline nodes content visible before move + // restore outline nodes content visibile state after move + SwOutlineNodes rOutlineNds = pShell->GetDoc()->GetNodes().GetOutLineNds(); + for (SwOutlineNodes::size_type nPos = 0; nPos < rOutlineNds.size(); ++nPos) + { + SwNode* pNd = rOutlineNds[nPos]; + if (pNd->IsTextNode()) // should always be true + { + bool bOutlineContentVisibleAttr = true; + pNd->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr); + if (!bOutlineContentVisibleAttr) + { + aOutlineNdsArray.push_back(pNd); + pShell->ToggleOutlineContentVisibility(nPos); + } + } + } + } pShell->StartUndo(SwUndoId::OUTLINE_UD); SwOutlineNodes::size_type nPrevSourcePos = SwOutlineNodes::npos; @@ -3415,6 +3470,12 @@ void SwContentTree::MoveOutline(SwOutlineNodes::size_type nTargetPos) } pShell->EndUndo(); + if (pShell->GetViewOptions()->IsShowOutlineContentVisibilityButton()) + { + // restore state of outline content visibility to before move + for (SwNode* pNd : aOutlineNdsArray) + pShell->ToggleOutlineContentVisibility(pNd, true); + } pShell->EndAllAction(); m_aActiveContentArr[ContentTypeId::OUTLINE]->Invalidate(); Display(true); @@ -3726,6 +3787,11 @@ void SwContentTree::ExecuteContextMenuAction(const OString& rSelectedPopupEntry) m_pActiveShell->EnterStdMode(); m_bIgnoreViewChange = true; SwOutlineContent* pCntFirst = reinterpret_cast<SwOutlineContent*>(m_xTreeView->get_id(*xFirst).toInt64()); + if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry + m_pActiveShell->GotoPage(1, true); + else + GotoContent(pCntFirst); + grab_focus(); if (nSelectedPopupEntry == 1512) { m_pActiveShell->ToggleOutlineContentVisibility(pCntFirst->GetOutlinePos()); @@ -3745,16 +3811,11 @@ void SwContentTree::ExecuteContextMenuAction(const OString& rSelectedPopupEntry) bool bFold(nSelectedPopupEntry == 1514); do { - if (m_pActiveShell->IsOutlineContentFolded(nPos) == bFold) + if (!m_pActiveShell->IsOutlineContentVisible(nPos) == bFold) m_pActiveShell->ToggleOutlineContentVisibility(nPos); } while (++nPos < nOutlineNodesCount && (nLevel == -1 || m_pActiveShell->getIDocumentOutlineNodesAccess()->getOutlineLevel(nPos) > nLevel)); } - if (lcl_IsContentType(*xFirst, *m_xTreeView)) // Headings root entry - m_pActiveShell->GotoPage(1, true); - else - GotoContent(pCntFirst); - grab_focus(); m_bIgnoreViewChange = false; } break; diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx b/sw/source/uibase/wrtsh/wrtsh1.cxx index 0019de241a1f..496a302a1d1e 100644 --- a/sw/source/uibase/wrtsh/wrtsh1.cxx +++ b/sw/source/uibase/wrtsh/wrtsh1.cxx @@ -1989,32 +1989,30 @@ void SwWrtShell::InsertPostIt(SwFieldMgr& rFieldMgr, const SfxRequest& rReq) pFormat->Broadcast( SwFormatFieldHint( nullptr, SwFormatFieldHintWhich::FOCUS, &GetView() ) ); } } -bool SwWrtShell::IsOutlineContentFolded(const size_t nPos) +bool SwWrtShell::IsOutlineContentVisible(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; + return true; bool bOutlineContentVisibleAttr = false; if (pOutlineNode->GetTextNode()->GetAttrOutlineContentVisible(bOutlineContentVisibleAttr)) - return !bOutlineContentVisibleAttr; + return bOutlineContentVisibleAttr; - return false; + return true; } -void SwWrtShell::ToggleOutlineContentVisibility(SwNode* pNd, bool bForceFold) +void SwWrtShell::ToggleOutlineContentVisibility(SwNode* pNd, const bool bForceNotVisible) { SwOutlineNodes::size_type nPos; if (GetNodes().GetOutLineNds().Seek_Entry(pNd, &nPos)) - ToggleOutlineContentVisibility(nPos, bForceFold); + ToggleOutlineContentVisibility(nPos, bForceNotVisible); } -void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) +void SwWrtShell::ToggleOutlineContentVisibility(const size_t nPos, const bool bForceNotVisible) { const SwNodes& rNodes = GetNodes(); const SwOutlineNodes& rOutlineNodes = rNodes.GetOutLineNds(); @@ -2031,7 +2029,7 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) if (pSttNd->GetTableBox() || pSttNd->GetIndex() < rNodes.GetEndOfExtras().GetIndex()) { - // limit folding to within table box + // limit toggle to within table box if (pSttNd->EndOfSectionIndex() < pEndNd->GetIndex() ) pEndNd = pSttNd->EndOfSectionNode(); } @@ -2049,17 +2047,47 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) } } - if (IsOutlineContentFolded(nPos) && !bForceFold) + if (GetViewOptions()->IsTreatSubOutlineLevelsAsContent()) { - // unfold - SwNodeIndex aIdx(*pSttNd, +1); + 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]; + } + } + + SwNodeIndex aIdx(*pSttNd, +1); // the next node after pSttdNd in the doc model SwNodes + if (!IsOutlineContentVisible(nPos) && !bForceNotVisible) + { + // make visible MakeFrames(GetDoc(), aIdx, *pEndNd); pSttNd->GetTextNode()->SetAttrOutlineContentVisible(true); if (GetViewOptions()->IsShowOutlineContentVisibilityButton()) { - // remove fold button if focus is not on outline frame control window + // remove button if focus is not on outline frame control window SwContentFrame* pFrame = pSttNd->GetTextNode()->getLayoutFrame(nullptr); if (pFrame && !pFrame->IsInDtor()) { @@ -2068,7 +2096,7 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) GetView().GetEditWin().GetFrameControlsManager().RemoveControlsByType(FrameControlType::Outline, pFrame); } - // fold revealed outline nodes that have collapsed content + // toggle outline content made visible that have outline visible attribute false while (aIdx != *pEndNd) { SwNode* pTmpNd = &aIdx.GetNode(); @@ -2083,7 +2111,7 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) if (rOutlineNodes.Seek_Entry(pTmpTextNd, &iPos)) { if (pTmpTextNd->getLayoutFrame(nullptr)) - ToggleOutlineContentVisibility(iPos, true); + ToggleOutlineContentVisibility(iPos, true); // force not visible } } } @@ -2093,18 +2121,19 @@ void SwWrtShell::ToggleOutlineContentVisibility(size_t nPos, bool bForceFold) } else { - // fold - for (SwNodeIndex aIdx(*pSttNd, +1); &aIdx.GetNode() != pEndNd; aIdx++) + // remove content frames + while (aIdx != *pEndNd) { SwNode* pNd = &aIdx.GetNode(); if (pNd->IsContentNode()) pNd->GetContentNode()->DelFrames(nullptr); else if (pNd->IsTableNode()) pNd->GetTableNode()->DelFrames(nullptr); + aIdx++; } pSttNd->GetTextNode()->SetAttrOutlineContentVisible(false); } - GetView().GetEditWin().Invalidate(InvalidateFlags::Update); + GetDoc()->GetDocShell()->Broadcast(SfxHint(SfxHintId::DocChanged)); } diff --git a/sw/uiconfig/swriter/ui/viewoptionspage.ui b/sw/uiconfig/swriter/ui/viewoptionspage.ui index 82204b0f3d83..b1ef4247bc3c 100644 --- a/sw/uiconfig/swriter/ui/viewoptionspage.ui +++ b/sw/uiconfig/swriter/ui/viewoptionspage.ui @@ -371,61 +371,6 @@ <property name="position">3</property> </packing> </child> - <child> - <object class="GtkFrame" id="changesframe1"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label_xalign">0</property> - <property name="shadow_type">none</property> - <child> - <object class="GtkAlignment" id="fieldsalignment2"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="top_padding">6</property> - <property name="left_padding">12</property> - <child> - <!-- n-columns=1 n-rows=1 --> - <object class="GtkGrid"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="row_spacing">6</property> - <property name="column_spacing">6</property> - <child> - <object class="GtkCheckButton" id="outlinecontentvisibilitybutton"> - <property name="label" translatable="yes" context="viewoptionspage|outlinecontentvisibilitybutton">_Show outline content visibility button</property> - <property name="visible">True</property> - <property name="can_focus">True</property> - <property name="receives_default">False</property> - <property name="use_underline">True</property> - <property name="xalign">0</property> - <property name="draw_indicator">True</property> - </object> - <packing> - <property name="left_attach">0</property> - <property name="top_attach">0</property> - </packing> - </child> - </object> - </child> - </object> - </child> - <child type="label"> - <object class="GtkLabel" id="outlinelabel"> - <property name="visible">True</property> - <property name="can_focus">False</property> - <property name="label" translatable="yes" context="viewoptionspage|outlinelabel">Outline mode</property> - <attributes> - <attribute name="weight" value="bold"/> - </attributes> - </object> - </child> - </object> - <packing> - <property name="expand">False</property> - <property name="fill">True</property> - <property name="position">4</property> - </packing> - </child> </object> <packing> <property name="left_attach">0</property> @@ -671,6 +616,76 @@ <property name="position">1</property> </packing> </child> + <child> + <object class="GtkFrame" id="outlineframe"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label_xalign">0</property> + <property name="shadow_type">none</property> + <child> + <object class="GtkAlignment" id="outlinealignment"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="top_padding">6</property> + <property name="left_padding">12</property> + <child> + <object class="GtkGrid"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="row_spacing">6</property> + <property name="column_spacing">6</property> + <child> + <object class="GtkCheckButton" id="outlinecontentvisibilitybutton"> + <property name="label" translatable="yes" context="viewoptionspage|outlinecontentvisibilitybutton">_Show outline content visibility button</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">0</property> + </packing> + </child> + <child> + <object class="GtkCheckButton" id="suboutlinelevelsascontent"> + <property name="label" translatable="yes" context="viewoptionspage|suboutlinelevelscontent">Include sub _levels</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="margin_left">12</property> + <property name="receives_default">False</property> + <property name="use_underline">True</property> + <property name="xalign">0</property> + <property name="draw_indicator">True</property> + </object> + <packing> + <property name="left_attach">0</property> + <property name="top_attach">1</property> + </packing> + </child> + </object> + </child> + </object> + </child> + <child type="label"> + <object class="GtkLabel" id="outlinelabel"> + <property name="visible">True</property> + <property name="can_focus">False</property> + <property name="label" translatable="yes" context="viewoptionspage|outlinelabel">Outline mode</property> + <attributes> + <attribute name="weight" value="bold"/> + </attributes> + </object> + </child> + </object> + <packing> + <property name="expand">False</property> + <property name="fill">True</property> + <property name="position">2</property> + </packing> + </child> </object> <packing> <property name="left_attach">1</property> _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits