offapi/com/sun/star/text/ViewSettings.idl                  |    6 +
 officecfg/registry/schema/org/openoffice/Office/Writer.xcs |    8 ++
 sw/inc/viewopt.hxx                                         |   17 +++-
 sw/qa/extras/layout/data/abi11870-2.odt                    |binary
 sw/qa/extras/layout/layout.cxx                             |    6 +
 sw/qa/extras/ooxmlexport/ooxmlexport13.cxx                 |    2 
 sw/source/core/crsr/bookmrk.cxx                            |   18 ++++
 sw/source/core/doc/docbm.cxx                               |    5 -
 sw/source/core/inc/bookmrk.hxx                             |    6 -
 sw/source/core/inc/scriptinfo.hxx                          |    1 
 sw/source/core/text/itrform2.cxx                           |    6 +
 sw/source/core/text/porlay.cxx                             |   35 +++++++++
 sw/source/core/text/pormulti.cxx                           |    8 +-
 sw/source/core/text/porrst.cxx                             |   11 ---
 sw/source/core/text/porrst.hxx                             |    7 -
 sw/source/ui/config/optpage.cxx                            |    8 ++
 sw/source/uibase/app/appopt.cxx                            |    1 
 sw/source/uibase/config/cfgitems.cxx                       |    4 +
 sw/source/uibase/config/usrpref.cxx                        |   47 +++++++------
 sw/source/uibase/inc/cfgitems.hxx                          |    1 
 sw/source/uibase/inc/optpage.hxx                           |    3 
 sw/source/uibase/uiview/pview.cxx                          |    1 
 sw/source/uibase/uiview/view0.cxx                          |    2 
 sw/source/uibase/uno/unomod.cxx                            |    4 +
 sw/source/uibase/uno/unotxdoc.cxx                          |    1 
 sw/uiconfig/swriter/ui/optformataidspage.ui                |   32 ++++++++
 26 files changed, 187 insertions(+), 53 deletions(-)

New commits:
commit da1f030eec952dcd6d78ecd80a311b7b33320674
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Tue Jun 2 18:16:15 2020 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 15:37:06 2022 +0200

    crashtesting: fix abi11870-2.odt assert in SwBookmarkPortion::Unchain()
    
    This m_pPrevious pointer is a bad idea, should just use
    FindPrevPortion() to find it, which shouldn't take that long to iterate
    all the portions in the current line.
    
    (regression from 4ce8120f1e53f7b81e653b01d141643013bc69ab)
    
    Change-Id: Ibb5f2bb28d959958547ed27c51e5084cc746d642
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/91622
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caol...@redhat.com>
    (cherry picked from commit f68749054f36f070310e70e2dbf0a11c496539c0)

diff --git a/sw/qa/extras/layout/data/abi11870-2.odt 
b/sw/qa/extras/layout/data/abi11870-2.odt
new file mode 100644
index 000000000000..b02bb85646aa
Binary files /dev/null and b/sw/qa/extras/layout/data/abi11870-2.odt differ
diff --git a/sw/qa/extras/layout/layout.cxx b/sw/qa/extras/layout/layout.cxx
index ea4619f9c1bc..a6015fedaac3 100644
--- a/sw/qa/extras/layout/layout.cxx
+++ b/sw/qa/extras/layout/layout.cxx
@@ -3482,6 +3482,12 @@ CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf116501)
     createDoc("tdf116501.odt");
 }
 
+CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testAbi11870)
+{
+    //just care it doesn't assert
+    createDoc("abi11870-2.odt");
+}
+
 CPPUNIT_TEST_FIXTURE(SwLayoutWriter, testTdf118719)
 {
     // Insert a page break.
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 8a906b4bf2e3..7901c10ccadd 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -1209,7 +1209,7 @@ SwLinePortion 
*SwTextFormatter::WhichFirstPortion(SwTextFormatInfo &rInf)
                 assert(bookmark & SwScriptInfo::MarkKind::Point);
                 mark = '|';
             }
-            pPor = new SwBookmarkPortion(rInf.GetLast(), mark);
+            pPor = new SwBookmarkPortion(mark);
         }
     }
 
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 650198e8a458..3bd45fee2180 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -2037,7 +2037,13 @@ bool SwTextFormatter::BuildMultiPortion( 
SwTextFormatInfo &rInf,
         if (rInf.GetLast()->GetWhichPor() == PortionType::Bookmark)
         {
             auto const 
pBookmark(static_cast<SwBookmarkPortion*>(rInf.GetLast()));
-            rInf.SetLast(pBookmark->Unchain());
+            auto *const pPrevious = pBookmark->FindPrevPortion(rInf.GetRoot());
+            assert(!pPrevious || pPrevious->GetNextPortion() == pBookmark);
+            if (pPrevious)
+            {
+                pPrevious->SetNextPortion(nullptr);
+            }
+            rInf.SetLast(pPrevious);
             assert(m_pCurr->GetNextPortion() == nullptr);
             m_pCurr->SetNextPortion(pBookmark);
         }
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 47d980183c3c..797725e298f6 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -639,13 +639,4 @@ sal_uInt16 SwControlCharPortion::GetViewWidth( const 
SwTextSizeInfo& rInf ) cons
     return mnViewWidth;
 }
 
-SwLinePortion * SwBookmarkPortion::Unchain()
-{
-    assert(!m_pPrevious || m_pPrevious->GetNextPortion() == this);
-    m_pPrevious->SetNextPortion(nullptr);
-    auto const pTmp(m_pPrevious);
-    m_pPrevious = nullptr;
-    return pTmp;
-}
-
 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/core/text/porrst.hxx b/sw/source/core/text/porrst.hxx
index dcb2cfcae7e9..0619c6babe16 100644
--- a/sw/source/core/text/porrst.hxx
+++ b/sw/source/core/text/porrst.hxx
@@ -156,13 +156,9 @@ public:
 /// SwControlCharPortion these do not have a character in the text.
 class SwBookmarkPortion : public SwControlCharPortion
 {
-private:
-    SwLinePortion * m_pPrevious;
-
 public:
-    explicit SwBookmarkPortion(SwLinePortion *const pPrevious, sal_Unicode 
const cChar)
+    explicit SwBookmarkPortion(sal_Unicode const cChar)
         : SwControlCharPortion(cChar)
-        , m_pPrevious(pPrevious)
     {
         SetWhichPor(PortionType::Bookmark);
         SetLen(TextFrameIndex(0));
@@ -171,7 +167,6 @@ public:
     virtual bool DoPaint(SwTextPaintInfo const& rInf,
         OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const 
override;
     virtual SwLinePortion * Compress() override { return this; }
-    SwLinePortion * Unchain();
 };
 
 #endif
commit b17a6f6b083e56b23a3a4e3e647c512f4044154a
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Wed Feb 12 16:15:43 2020 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 15:25:22 2022 +0200

    tdf#45589 sw: add tooltip to Formatting Aids dialog Bookmark label
    
    Thanks to sdc.blanco for the suggestion.
    
    Change-Id: Ib9a1874eeba1e9e1bf594e725be6883e79ed9a67
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88541
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit da164e43779029dbb4795adf60c02179d12cdd7c)

diff --git a/sw/uiconfig/swriter/ui/optformataidspage.ui 
b/sw/uiconfig/swriter/ui/optformataidspage.ui
index 05083b8dcb08..5f86a7e064ec 100644
--- a/sw/uiconfig/swriter/ui/optformataidspage.ui
+++ b/sw/uiconfig/swriter/ui/optformataidspage.ui
@@ -219,6 +219,8 @@
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="label">| [ ]</property>
+                        <property name="tooltip_text" translatable="yes" 
context="optformataidspage|bookmarks_label|tooltip_text">| indicates a point 
bookmark
+[ ] indicate the start and end of a bookmark on a text range</property>
                       </object>
                       <packing>
                         <property name="left_attach">1</property>
commit 611f666fb6b4f7efbe5abc3fc835e3ff566fb8a5
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Wed Feb 12 14:22:18 2020 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 15:24:39 2022 +0200

    tdf#45589 sw: fix Formatting Aids options page for Writer/Web
    
    The pre-existing problem of the lone "tab" label was compounded by the
    new bookmark label.
    
    There is no Insert->Bookmark in Writer/Web so i guess the Bookmark
    checkbox shouldn't be shown.
    
    Change-Id: I5a2348599562bb20d7a8de916d0268a133771a0c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/88535
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit 8daffb60dd2863878bb04317ca2849d76df01f4b)

diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx
index fe41aa6dae33..88b6740e8a9a 100644
--- a/sw/source/ui/config/optpage.cxx
+++ b/sw/source/ui/config/optpage.cxx
@@ -1204,9 +1204,11 @@ 
SwShdwCursorOptionsTabPage::SwShdwCursorOptionsTabPage(weld::Container* pPage, w
     , m_xSpacesCB(m_xBuilder->weld_check_button("spaces"))
     , m_xHSpacesCB(m_xBuilder->weld_check_button("nonbreak"))
     , m_xTabCB(m_xBuilder->weld_check_button("tabs"))
+    , m_xTabLabel(m_xBuilder->weld_label("tabs_label"))
     , m_xBreakCB(m_xBuilder->weld_check_button("break"))
     , m_xCharHiddenCB(m_xBuilder->weld_check_button("hiddentext"))
     , m_xBookmarkCB(m_xBuilder->weld_check_button("bookmarks"))
+    , m_xBookmarkLabel(m_xBuilder->weld_label("bookmarks_label"))
     , m_xDirectCursorFrame(m_xBuilder->weld_frame("directcrsrframe"))
     , m_xOnOffCB(m_xBuilder->weld_check_button("cursoronoff"))
     , m_xFillMarginRB(m_xBuilder->weld_radio_button("fillmargin"))
@@ -1241,8 +1243,10 @@ 
SwShdwCursorOptionsTabPage::SwShdwCursorOptionsTabPage(weld::Container* pPage, w
         return;
 
     m_xTabCB->hide();
+    m_xTabLabel->hide();
     m_xCharHiddenCB->hide();
     m_xBookmarkCB->hide();
+    m_xBookmarkLabel->hide();
 
     m_xDirectCursorFrame->hide();
     m_xOnOffCB->hide();
diff --git a/sw/source/uibase/inc/optpage.hxx b/sw/source/uibase/inc/optpage.hxx
index 955e44c249a5..8de1394b633e 100644
--- a/sw/source/uibase/inc/optpage.hxx
+++ b/sw/source/uibase/inc/optpage.hxx
@@ -226,9 +226,11 @@ class SwShdwCursorOptionsTabPage : public SfxTabPage
     std::unique_ptr<weld::CheckButton> m_xSpacesCB;
     std::unique_ptr<weld::CheckButton> m_xHSpacesCB;
     std::unique_ptr<weld::CheckButton> m_xTabCB;
+    std::unique_ptr<weld::Label> m_xTabLabel;
     std::unique_ptr<weld::CheckButton> m_xBreakCB;
     std::unique_ptr<weld::CheckButton> m_xCharHiddenCB;
     std::unique_ptr<weld::CheckButton> m_xBookmarkCB;
+    std::unique_ptr<weld::Label> m_xBookmarkLabel;
 
     std::unique_ptr<weld::Frame> m_xDirectCursorFrame;
     std::unique_ptr<weld::CheckButton> m_xOnOffCB;
diff --git a/sw/uiconfig/swriter/ui/optformataidspage.ui 
b/sw/uiconfig/swriter/ui/optformataidspage.ui
index fb2fa378c4e2..05083b8dcb08 100644
--- a/sw/uiconfig/swriter/ui/optformataidspage.ui
+++ b/sw/uiconfig/swriter/ui/optformataidspage.ui
@@ -193,7 +193,7 @@
                           </packing>
                         </child>
                         <child>
-                          <object class="GtkLabel">
+                          <object class="GtkLabel" id="tabs_label">
                             <property name="visible">True</property>
                             <property name="can_focus">False</property>
                             <property name="label">→</property>
@@ -215,7 +215,7 @@
                           </packing>
                         </child>
                     <child>
-                      <object class="GtkLabel">
+                      <object class="GtkLabel" id="bookmarks_label">
                         <property name="visible">True</property>
                         <property name="can_focus">False</property>
                         <property name="label">| [ ]</property>
commit 4ec2c9816b8f4012bb7a760a85a46d8a1e530089
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Fri Jan 31 16:19:21 2020 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 15:10:07 2022 +0200

    tdf#45589 offapi,officecfg,sw: add option to toggle bookmark display
    
    Create specific option to toggle display of the bookmark positions
    instead of relying on generic IsViewMetaChars().
    
    Add a Bookmarks checkbox to Writer->Formatting Aids page in Options.
    
    Add property ShowBookmarks to com::sun::star::text::ViewSettings.
    
    Add config setting:
    org/openoffice/Office/Writer/Content/NonprintingCharacter/Bookmarks
    
    Change-Id: I998ecdc16d8e4a5baeeb1bbcff0bf5f1f5636692
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87774
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit 04405edc3fac32938b8940bc767656ea6c7820f9)

diff --git a/offapi/com/sun/star/text/ViewSettings.idl 
b/offapi/com/sun/star/text/ViewSettings.idl
index 5de3bf8d6dd5..b0afa27c46e8 100644
--- a/offapi/com/sun/star/text/ViewSettings.idl
+++ b/offapi/com/sun/star/text/ViewSettings.idl
@@ -278,6 +278,12 @@ published service ViewSettings
     */
     [optional, property] boolean UseHeaderFooterMenu;
 
+    /** If this property is `TRUE`, bookmark positions are displayed.
+
+        @since LibreOffice 7.0
+     */
+    [optional, property] boolean ShowBookmarks;
+
 };
 
 }; }; }; };
diff --git a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
index 6ba34c5338ff..470d9f81ba8e 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
@@ -1172,6 +1172,14 @@
           </info>
           <value>false</value>
         </prop>
+        <prop oor:name="Bookmarks" oor:type="xs:boolean" oor:nillable="false">
+          <!-- UIHints: Tools - Options - Text document  Formatting aids - 
[Section] Display formatting -->
+          <info>
+            <desc>Specifies whether bookmark positions are displayed on the 
screen.</desc>
+            <label>Bookmarks</label>
+          </info>
+          <value>true</value>
+        </prop>
       </group>
       <group oor:name="Update">
         <info>
diff --git a/sw/inc/viewopt.hxx b/sw/inc/viewopt.hxx
index c727452685c7..11d2914ed028 100644
--- a/sw/inc/viewopt.hxx
+++ b/sw/inc/viewopt.hxx
@@ -34,7 +34,7 @@ class OutputDevice;
 class SwDocShell;
 namespace svtools{ class ColorConfig;}
 
-enum class ViewOptFlags1 {
+enum class ViewOptFlags1 : sal_uInt32 {
     UseHeaderFooterMenu = 0x00000001,
     Tab           = 0x00000002,
     Blank         = 0x00000004,
@@ -44,6 +44,7 @@ enum class ViewOptFlags1 {
     Pagebreak     = 0x00000040,
     Columnbreak   = 0x00000080,
     SoftHyph      = 0x00000100,
+    Bookmarks     = 0x00000200,
     Ref           = 0x00000400,
     FieldName     = 0x00000800,
     Postits       = 0x00004000,
@@ -60,10 +61,10 @@ enum class ViewOptFlags1 {
     OnlineSpell   = 0x04000000,
     ShowInlineTooltips = 0x10000000, //tooltips on tracked changes
     ViewMetachars = 0x20000000,
-    Pageback      = 0x40000000
+    Pageback      = 0x40000000,
 };
 namespace o3tl {
-    template<> struct typed_flags<ViewOptFlags1> : 
is_typed_flags<ViewOptFlags1, 0x77dfcdff> {};
+    template<> struct typed_flags<ViewOptFlags1> : 
is_typed_flags<ViewOptFlags1, 0x77dfcfff> {};
 }
 
 enum class ViewOptCoreFlags2 {
@@ -232,6 +233,16 @@ public:
     void SetParagraph( bool b )
         { SetCoreOption(b, ViewOptFlags1::Paragraph); }
 
+    void SetShowBookmarks(bool const b)
+    {
+        SetCoreOption(b, ViewOptFlags1::Bookmarks);
+    }
+    bool IsShowBookmarks(bool const bHard = false) const
+    {
+        return !m_bReadonly && (m_nCoreOptions & ViewOptFlags1::Bookmarks)
+                && (bHard || (m_nCoreOptions & ViewOptFlags1::ViewMetachars));
+    }
+
     bool IsLineBreak(bool bHard = false) const
                     {   return !m_bReadonly && (m_nCoreOptions & 
ViewOptFlags1::Linebreak) &&
                             ((m_nCoreOptions & 
ViewOptFlags1::ViewMetachars)||bHard); }
diff --git a/sw/source/core/text/porrst.cxx b/sw/source/core/text/porrst.cxx
index 8a7b47b04f68..47d980183c3c 100644
--- a/sw/source/core/text/porrst.cxx
+++ b/sw/source/core/text/porrst.cxx
@@ -533,7 +533,7 @@ bool SwControlCharPortion::DoPaint(SwTextPaintInfo const&,
 bool SwBookmarkPortion::DoPaint(SwTextPaintInfo const& rInf,
         OUString & rOutString, SwFont & rTmpFont, int & rDeltaY) const
 {
-    if (!rInf.GetOpt().IsViewMetaChars())
+    if (!rInf.GetOpt().IsShowBookmarks())
     {
         return false;
     }
diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx
index 7e49ff3dc2a9..fe41aa6dae33 100644
--- a/sw/source/ui/config/optpage.cxx
+++ b/sw/source/ui/config/optpage.cxx
@@ -1206,6 +1206,7 @@ 
SwShdwCursorOptionsTabPage::SwShdwCursorOptionsTabPage(weld::Container* pPage, w
     , m_xTabCB(m_xBuilder->weld_check_button("tabs"))
     , m_xBreakCB(m_xBuilder->weld_check_button("break"))
     , m_xCharHiddenCB(m_xBuilder->weld_check_button("hiddentext"))
+    , m_xBookmarkCB(m_xBuilder->weld_check_button("bookmarks"))
     , m_xDirectCursorFrame(m_xBuilder->weld_frame("directcrsrframe"))
     , m_xOnOffCB(m_xBuilder->weld_check_button("cursoronoff"))
     , m_xFillMarginRB(m_xBuilder->weld_radio_button("fillmargin"))
@@ -1241,6 +1242,7 @@ 
SwShdwCursorOptionsTabPage::SwShdwCursorOptionsTabPage(weld::Container* pPage, w
 
     m_xTabCB->hide();
     m_xCharHiddenCB->hide();
+    m_xBookmarkCB->hide();
 
     m_xDirectCursorFrame->hide();
     m_xOnOffCB->hide();
@@ -1320,6 +1322,7 @@ bool SwShdwCursorOptionsTabPage::FillItemSet( SfxItemSet* 
rSet )
     aDisp.bNonbreakingSpace     = m_xHSpacesCB->get_active();
     aDisp.bSoftHyphen           = m_xSHyphCB->get_active();
     aDisp.bCharHiddenText       = m_xCharHiddenCB->get_active();
+    aDisp.bBookmarks            = m_xBookmarkCB->get_active();
     aDisp.bManualBreak          = m_xBreakCB->get_active();
 
     bRet |= (!pOldAttr || aDisp != *pOldAttr);
@@ -1372,6 +1375,7 @@ void SwShdwCursorOptionsTabPage::Reset( const SfxItemSet* 
rSet )
         m_xHSpacesCB->set_active( pDocDisplayAttr->bNonbreakingSpace );
         m_xSHyphCB->set_active( pDocDisplayAttr->bSoftHyphen );
         m_xCharHiddenCB->set_active( pDocDisplayAttr->bCharHiddenText );
+        m_xBookmarkCB->set_active(pDocDisplayAttr->bBookmarks);
         m_xBreakCB->set_active( pDocDisplayAttr->bManualBreak );
     }
 }
diff --git a/sw/source/uibase/app/appopt.cxx b/sw/source/uibase/app/appopt.cxx
index f071b85997fe..941d15e4302c 100644
--- a/sw/source/uibase/app/appopt.cxx
+++ b/sw/source/uibase/app/appopt.cxx
@@ -253,6 +253,7 @@ void SwModule::ApplyItemSet( sal_uInt16 nId, const 
SfxItemSet& rSet )
         {
             if(     (!aViewOpt.IsTab( true ) &&  pDocDispItem->bTab) ||
                     (!aViewOpt.IsBlank( true ) && pDocDispItem->bSpace) ||
+                    (!aViewOpt.IsShowBookmarks(true) && 
pDocDispItem->bBookmarks) ||
                     (!aViewOpt.IsParagraph( true ) && 
pDocDispItem->bParagraphEnd) ||
                     (!aViewOpt.IsLineBreak( true ) && 
pDocDispItem->bManualBreak) )
             {
diff --git a/sw/source/uibase/config/cfgitems.cxx 
b/sw/source/uibase/config/cfgitems.cxx
index 3c6114c9a9a6..efbbdf4154b4 100644
--- a/sw/source/uibase/config/cfgitems.cxx
+++ b/sw/source/uibase/config/cfgitems.cxx
@@ -39,6 +39,7 @@ SwDocDisplayItem::SwDocDisplayItem() :
     bNonbreakingSpace   =
     bSoftHyphen         =
     bCharHiddenText     =
+    bBookmarks          =
     bManualBreak        = true;
 };
 
@@ -52,6 +53,7 @@ SwDocDisplayItem::SwDocDisplayItem(const SwViewOption& rVOpt 
) :
     bNonbreakingSpace   = rVOpt.IsHardBlank();
     bSoftHyphen         = rVOpt.IsSoftHyph();
     bCharHiddenText     = rVOpt.IsShowHiddenChar(true);
+    bBookmarks          = rVOpt.IsShowBookmarks(true);
     bManualBreak        = rVOpt.IsLineBreak(true);
 }
 
@@ -72,6 +74,7 @@ bool SwDocDisplayItem::operator==( const SfxPoolItem& rAttr ) 
const
               bNonbreakingSpace     == rItem.bNonbreakingSpace   &&
               bSoftHyphen           == rItem.bSoftHyphen         &&
               bCharHiddenText       == rItem.bCharHiddenText         &&
+              bBookmarks            == rItem.bBookmarks          &&
               bManualBreak          == rItem.bManualBreak );
 }
 
@@ -83,6 +86,7 @@ void SwDocDisplayItem::FillViewOptions( SwViewOption& rVOpt) 
const
     rVOpt.SetHardBlank  (bNonbreakingSpace  );
     rVOpt.SetSoftHyph   (bSoftHyphen        );
     rVOpt.SetShowHiddenChar(bCharHiddenText );
+    rVOpt.SetShowBookmarks(bBookmarks       );
     rVOpt.SetLineBreak  (bManualBreak       );
 }
 
diff --git a/sw/source/uibase/config/usrpref.cxx 
b/sw/source/uibase/config/usrpref.cxx
index 0246b6f039d6..cfc6142314c6 100644
--- a/sw/source/uibase/config/usrpref.cxx
+++ b/sw/source/uibase/config/usrpref.cxx
@@ -82,9 +82,11 @@ SwMasterUsrPref::~SwMasterUsrPref()
 {
 }
 
+static const auto g_UpdateLinkIndex = 17;
+
 Sequence<OUString> SwContentViewConfig::GetPropertyNames() const
 {
-    static const char* aPropNames[] =
+    static constexpr const char*const aPropNames[] =
     {
         "Display/GraphicObject",                    //  0
         "Display/Table",                            //  1
@@ -102,13 +104,18 @@ Sequence<OUString> 
SwContentViewConfig::GetPropertyNames() const
         "NonprintingCharacter/HiddenText",      // 13
         "NonprintingCharacter/HiddenParagraph", // 14
         "NonprintingCharacter/HiddenCharacter",      // 15
-        "Update/Link",                          // 16
-        "Update/Field",                         // 17
-        "Update/Chart",                         // 18
-        "Display/ShowInlineTooltips",           // 19
-        "Display/UseHeaderFooterMenu"           // 20
+        "NonprintingCharacter/Bookmarks",       // 16
+        "Update/Link",                          // 17
+        "Update/Field",                         // 18
+        "Update/Chart",                         // 19
+        "Display/ShowInlineTooltips",           // 20
+        "Display/UseHeaderFooterMenu"           // 21
     };
-    const int nCount = bWeb ? 12 : 21;
+#if defined(__GNUC__) && !defined(__clang__)
+    // clang 8.0.0 says strcmp isn't constexpr
+    static_assert(std::strcmp("Update/Link", aPropNames[g_UpdateLinkIndex]) == 
0);
+#endif
+    const int nCount = bWeb ? 12 : SAL_N_ELEMENTS(aPropNames);
     Sequence<OUString> aNames(nCount);
     OUString* pNames = aNames.getArray();
     for(int i = 0; i < nCount; i++)
@@ -164,13 +171,14 @@ void SwContentViewConfig::ImplCommit()
             case 13: bVal = rParent.IsShowHiddenField(); break;// 
"NonprintingCharacter/Fields: HiddenText",
             case 14: bVal = rParent.IsShowHiddenPara(); break;// 
"NonprintingCharacter/Fields: HiddenParagraph",
             case 15: bVal = rParent.IsShowHiddenChar(true);    break;// 
"NonprintingCharacter/HiddenCharacter",
-            case 16: pValues[nProp] <<= rParent.GetUpdateLinkMode();    
break;// "Update/Link",
-            case 17: bVal = rParent.IsUpdateFields(); break;// "Update/Field",
-            case 18: bVal = rParent.IsUpdateCharts(); break;// "Update/Chart"
-            case 19: bVal = rParent.IsShowInlineTooltips(); break;// 
"Display/ShowInlineTooltips"
-            case 20: bVal = rParent.IsUseHeaderFooterMenu(); break;// 
"Display/UseHeaderFooterMenu"
+            case 16: bVal = rParent.IsShowBookmarks(true);    break;// 
"NonprintingCharacter/Bookmarks",
+            case 17: pValues[nProp] <<= rParent.GetUpdateLinkMode();    
break;// "Update/Link",
+            case 18: bVal = rParent.IsUpdateFields(); break;// "Update/Field",
+            case 19: bVal = rParent.IsUpdateCharts(); break;// "Update/Chart"
+            case 20: bVal = rParent.IsShowInlineTooltips(); break;// 
"Display/ShowInlineTooltips"
+            case 21: bVal = rParent.IsUseHeaderFooterMenu(); break;// 
"Display/UseHeaderFooterMenu"
         }
-        if(nProp != 16)
+        if (nProp != g_UpdateLinkIndex)
             pValues[nProp] <<= bVal;
     }
     PutProperties(aNames, aValues);
@@ -188,7 +196,7 @@ void SwContentViewConfig::Load()
         {
             if(pValues[nProp].hasValue())
             {
-                bool bSet = nProp != 16 && 
*o3tl::doAccess<bool>(pValues[nProp]);
+                bool bSet = nProp != g_UpdateLinkIndex && 
*o3tl::doAccess<bool>(pValues[nProp]);
                 switch(nProp)
                 {
                     case  0: rParent.SetGraphic(bSet);  break;// 
"Display/GraphicObject",
@@ -207,17 +215,18 @@ void SwContentViewConfig::Load()
                     case 13: rParent.SetShowHiddenField(bSet);   break;// 
"NonprintingCharacter/Fields: HiddenText",
                     case 14: rParent.SetShowHiddenPara(bSet); break;// 
"NonprintingCharacter/Fields: HiddenParagraph",
                     case 15: rParent.SetShowHiddenChar(bSet); break;// 
"NonprintingCharacter/HiddenCharacter",
-                    case 16:
+                    case 16: rParent.SetShowBookmarks(bSet); break;// 
"NonprintingCharacter/Bookmarks",
+                    case 17:
                     {
                         sal_Int32 nSet = 0;
                         pValues[nProp] >>= nSet;
                         rParent.SetUpdateLinkMode(nSet, true);
                     }
                     break;// "Update/Link",
-                    case 17: rParent.SetUpdateFields(bSet); break;// 
"Update/Field",
-                    case 18: rParent.SetUpdateCharts(bSet); break;// 
"Update/Chart"
-                    case 19: rParent.SetShowInlineTooltips(bSet); break;// 
"Display/ShowInlineTooltips"
-                    case 20: rParent.SetUseHeaderFooterMenu(bSet); break;// 
"Display/UseHeaderFooterMenu"
+                    case 18: rParent.SetUpdateFields(bSet); break;// 
"Update/Field",
+                    case 19: rParent.SetUpdateCharts(bSet); break;// 
"Update/Chart"
+                    case 20: rParent.SetShowInlineTooltips(bSet); break;// 
"Display/ShowInlineTooltips"
+                    case 21: rParent.SetUseHeaderFooterMenu(bSet); break;// 
"Display/UseHeaderFooterMenu"
                 }
             }
         }
diff --git a/sw/source/uibase/inc/cfgitems.hxx 
b/sw/source/uibase/inc/cfgitems.hxx
index db525151a079..297ac1846faa 100644
--- a/sw/source/uibase/inc/cfgitems.hxx
+++ b/sw/source/uibase/inc/cfgitems.hxx
@@ -49,6 +49,7 @@ class SW_DLLPUBLIC SwDocDisplayItem : public SfxPoolItem
     bool bNonbreakingSpace  :1;
     bool bSoftHyphen        :1;
     bool bCharHiddenText    :1;
+    bool bBookmarks         :1;
     bool bManualBreak       :1;
 
 public:
diff --git a/sw/source/uibase/inc/optpage.hxx b/sw/source/uibase/inc/optpage.hxx
index 13c5d6194aef..955e44c249a5 100644
--- a/sw/source/uibase/inc/optpage.hxx
+++ b/sw/source/uibase/inc/optpage.hxx
@@ -228,6 +228,7 @@ class SwShdwCursorOptionsTabPage : public SfxTabPage
     std::unique_ptr<weld::CheckButton> m_xTabCB;
     std::unique_ptr<weld::CheckButton> m_xBreakCB;
     std::unique_ptr<weld::CheckButton> m_xCharHiddenCB;
+    std::unique_ptr<weld::CheckButton> m_xBookmarkCB;
 
     std::unique_ptr<weld::Frame> m_xDirectCursorFrame;
     std::unique_ptr<weld::CheckButton> m_xOnOffCB;
diff --git a/sw/source/uibase/uiview/pview.cxx 
b/sw/source/uibase/uiview/pview.cxx
index c8a3c398b46b..2a1b16434845 100644
--- a/sw/source/uibase/uiview/pview.cxx
+++ b/sw/source/uibase/uiview/pview.cxx
@@ -1111,6 +1111,7 @@ void SwPagePreview::Init()
     aOpt.SetSoftHyph( false );
     aOpt.SetFieldName( false );
     aOpt.SetPostIts( false );
+    aOpt.SetShowBookmarks( false );
     aOpt.SetShowHiddenChar( false );
     aOpt.SetShowHiddenField( false );
     aOpt.SetShowHiddenPara( false );
diff --git a/sw/source/uibase/uiview/view0.cxx 
b/sw/source/uibase/uiview/view0.cxx
index 56f363cc0285..79783e138496 100644
--- a/sw/source/uibase/uiview/view0.cxx
+++ b/sw/source/uibase/uiview/view0.cxx
@@ -162,6 +162,7 @@ static void lcl_SetViewMetaChars( SwViewOption& rVOpt, bool 
bOn)
             rVOpt.IsTab()       ||
             rVOpt.IsLineBreak() ||
             rVOpt.IsShowHiddenChar() ||
+            rVOpt.IsShowBookmarks() ||
             rVOpt.IsBlank()))
     {
         rVOpt.SetParagraph(bOn);
@@ -169,6 +170,7 @@ static void lcl_SetViewMetaChars( SwViewOption& rVOpt, bool 
bOn)
         rVOpt.SetLineBreak(bOn);
         rVOpt.SetBlank(bOn);
         rVOpt.SetShowHiddenChar(bOn);
+        rVOpt.SetShowBookmarks(bOn);
     }
 }
 
diff --git a/sw/source/uibase/uno/unomod.cxx b/sw/source/uibase/uno/unomod.cxx
index 5df0c5af9d89..93b63a0e7d68 100644
--- a/sw/source/uibase/uno/unomod.cxx
+++ b/sw/source/uibase/uno/unomod.cxx
@@ -95,6 +95,7 @@ enum SwViewSettingsPropertyHandles
     HANDLE_VIEWSET_INLINECHANGES_TIPS,
     HANDLE_VIEWSET_HIDE_WHITESPACE,
     HANDLE_VIEWSET_USE_HEADERFOOTERMENU,
+    HANDLE_VIEWSET_BOOKMARKS,
 };
 
 enum SwPrintSettingsPropertyHandles
@@ -136,6 +137,7 @@ static ChainablePropertySetInfo * 
lcl_createViewSettingsInfo()
         { OUString( "RasterSubdivisionX"),   
HANDLE_VIEWSET_RASTER_SUBDIVISION_X,    cppu::UnoType<sal_Int32>::get(),     
PROPERTY_NONE},
         { OUString( "RasterSubdivisionY"),   
HANDLE_VIEWSET_RASTER_SUBDIVISION_Y,    cppu::UnoType<sal_Int32>::get(),     
PROPERTY_NONE},
         { OUString( "ShowAnnotations" ),     HANDLE_VIEWSET_ANNOTATIONS        
  , cppu::UnoType<bool>::get(), PROPERTY_NONE},
+        { OUString( "ShowBookmarks" ), HANDLE_VIEWSET_BOOKMARKS, 
cppu::UnoType<bool>::get(), PROPERTY_NONE },
         { OUString( "ShowBreaks"),           HANDLE_VIEWSET_BREAKS             
  , cppu::UnoType<bool>::get(), PROPERTY_NONE},
         { OUString( "ShowDrawings"),         HANDLE_VIEWSET_DRAWINGS           
  , cppu::UnoType<bool>::get(), PROPERTY_NONE},
         { OUString( "ShowFieldCommands"),    HANDLE_VIEWSET_FIELD_COMMANDS     
  , cppu::UnoType<bool>::get(), PROPERTY_NONE},
@@ -579,6 +581,7 @@ void SwXViewSettings::_setSingleValue( const 
comphelper::PropertyInfo & rInfo, c
         case  HANDLE_VIEWSET_PROTECTED_SPACES      :   
mpViewOption->SetHardBlank(*o3tl::doAccess<bool>(rValue));    break;
         case  HANDLE_VIEWSET_TABSTOPS              :   
mpViewOption->SetTab(*o3tl::doAccess<bool>(rValue));  break;
         case  HANDLE_VIEWSET_BREAKS                :   
mpViewOption->SetLineBreak(*o3tl::doAccess<bool>(rValue)); break;
+        case  HANDLE_VIEWSET_BOOKMARKS             :   
mpViewOption->SetShowBookmarks(*o3tl::doAccess<bool>(rValue)); break;
         case  HANDLE_VIEWSET_HIDDEN_TEXT           :   
mpViewOption->SetShowHiddenField(*o3tl::doAccess<bool>(rValue));  break;
         case  HANDLE_VIEWSET_HIDDEN_CHARACTERS     :   
mpViewOption->SetShowHiddenChar(*o3tl::doAccess<bool>(rValue)); break;
         case  HANDLE_VIEWSET_HIDDEN_PARAGRAPHS     :   
mpViewOption->SetShowHiddenPara(*o3tl::doAccess<bool>(rValue));   break;
@@ -820,6 +823,7 @@ void SwXViewSettings::_getSingleValue( const 
comphelper::PropertyInfo & rInfo, u
         case  HANDLE_VIEWSET_PROTECTED_SPACES      :   bBoolVal = 
mpConstViewOption->IsHardBlank(); break;
         case  HANDLE_VIEWSET_TABSTOPS              :   bBoolVal = 
mpConstViewOption->IsTab(true);   break;
         case  HANDLE_VIEWSET_BREAKS                :   bBoolVal = 
mpConstViewOption->IsLineBreak(true); break;
+        case  HANDLE_VIEWSET_BOOKMARKS             :   bBoolVal = 
mpConstViewOption->IsShowBookmarks(true); break;
         case  HANDLE_VIEWSET_HIDDEN_TEXT           :   bBoolVal = 
mpConstViewOption->IsShowHiddenField();   break;
         case  HANDLE_VIEWSET_HIDDEN_CHARACTERS     :   bBoolVal = 
mpConstViewOption->IsShowHiddenChar(true); break;
         case  HANDLE_VIEWSET_HIDE_WHITESPACE       :   bBoolVal = 
mpConstViewOption->IsHideWhitespaceMode(); break;
diff --git a/sw/source/uibase/uno/unotxdoc.cxx 
b/sw/source/uibase/uno/unotxdoc.cxx
index e5ce030ddaac..5e221efa47ea 100644
--- a/sw/source/uibase/uno/unotxdoc.cxx
+++ b/sw/source/uibase/uno/unotxdoc.cxx
@@ -4418,6 +4418,7 @@ SwViewOptionAdjust_Impl::AdjustViewOptions(SwPrintData 
const*const pPrtOptions,
     aRenderViewOptions.SetBlank( false );                 // spaces
     aRenderViewOptions.SetHardBlank( false );             // non-breaking 
spaces
     aRenderViewOptions.SetTab( false );                   // tabs
+    aRenderViewOptions.SetShowBookmarks( false );         // bookmarks
     aRenderViewOptions.SetLineBreak( false );             // breaks (type 1)
     aRenderViewOptions.SetPageBreak( false );             // breaks (type 2)
     aRenderViewOptions.SetColumnBreak( false );           // breaks (type 3)
diff --git a/sw/uiconfig/swriter/ui/optformataidspage.ui 
b/sw/uiconfig/swriter/ui/optformataidspage.ui
index 209de810ac5b..fb2fa378c4e2 100644
--- a/sw/uiconfig/swriter/ui/optformataidspage.ui
+++ b/sw/uiconfig/swriter/ui/optformataidspage.ui
@@ -101,7 +101,7 @@
                         </child>
                         <child>
                           <object class="GtkCheckButton" id="tabs">
-                            <property name="label" translatable="yes" 
context="optformataidspage|tabs">Ta_bs</property>
+                            <property name="label" translatable="yes" 
context="optformataidspage|tabs">Tabs</property>
                             <property name="visible">True</property>
                             <property name="can_focus">True</property>
                             <property name="receives_default">False</property>
@@ -144,6 +144,21 @@
                             <property name="top_attach">6</property>
                           </packing>
                         </child>
+                    <child>
+                      <object class="GtkCheckButton" id="bookmarks">
+                        <property name="label" translatable="yes" 
context="optformataidspage|bookmarks">Bookmarks</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">7</property>
+                      </packing>
+                    </child>
                         <child>
                           <object class="GtkLabel">
                             <property name="visible">True</property>
@@ -199,6 +214,17 @@
                             <property name="top_attach">5</property>
                           </packing>
                         </child>
+                    <child>
+                      <object class="GtkLabel">
+                        <property name="visible">True</property>
+                        <property name="can_focus">False</property>
+                        <property name="label">| [ ]</property>
+                      </object>
+                      <packing>
+                        <property name="left_attach">1</property>
+                        <property name="top_attach">7</property>
+                      </packing>
+                    </child>
                         <child>
                           <placeholder/>
                         </child>
commit bf2c6dea101ec9b28a827eac12842b713aeb9633
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Thu Jan 23 18:36:40 2020 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 14:52:05 2022 +0200

    tdf#45589 sw: split text portions at bookmarks
    
    Always create the portion, not just when the IsViewMetaChars is active.
    
    This has the advantage that nothing has to be invalidated when toggling,
    and the disadvantage that kerning at bookmark positions will never
    happen.
    
    Change-Id: I78943f337eef5c64cff33f6df6ff1a10acb1b8bc
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87363
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit 2817f07fdd942cea6574043971534bf089b527ce)
    
    Note, half of this ended up in commit
    2658cf474b0bd4a385f89bada1f80e4ed61854a6 but this was missing.
    
    Change-Id: Ia8081886c840d1ad7630d7cae03d4daf028cbaf3

diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx 
b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
index 5ad0a4ece74c..8f457f89bc16 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport13.cxx
@@ -588,7 +588,7 @@ DECLARE_OOXMLEXPORT_TEST(testTdf124594, "tdf124594.docx")
     // only "Er horte leise Schritte hinter", which means the 1st line of the 
2nd paragraph was
     // split into two by a Special portion, i.e. the top margin of the shape 
was too large.
     assertXPath(pDump, "/root/page/body/txt[2]/Text[1]", "Portion",
-                "Er horte leise Schritte hinter sich. Das bedeutete nichts 
Gutes. Wer wurde ihm ");
+                "Er horte leise Schritte hinter sich. Das bedeutete nichts 
Gutes. Wer wu"); // ... until the bookmark.
 }
 
 DECLARE_OOXMLEXPORT_TEST(testTextInput, "textinput.odt")
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index ceaca5256b5d..8a906b4bf2e3 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -997,6 +997,10 @@ SwTextPortion *SwTextFormatter::NewTextPortion( 
SwTextFormatInfo &rInf )
     const TextFrameIndex nNextHidden = 
m_pScriptInfo->NextHiddenChg(rInf.GetIdx());
     nNextChg = std::min( nNextChg, nNextHidden );
 
+    // bookmarks
+    const TextFrameIndex nNextBookmark = 
m_pScriptInfo->NextBookmark(rInf.GetIdx());
+    nNextChg = std::min(nNextChg, nNextBookmark);
+
     // Turbo boost:
     // We assume that font characters are not larger than twice
     // as wide as height.
commit e0b2dd958badd4b00ae3ad279c63b1bdffc08336
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Jun 22 14:02:51 2022 +0200
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 14:50:24 2022 +0200

    tdf#45589 sw: add bookmarks to SwScriptInfo
    
    Add a list of bookmark positions in the text frame to SwScriptInfo.
    Initialising this turned out to be more complicated than expected.
    
    Change-Id: I1738186b057b0eece80177097a03826365107589
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87202
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit 46e04a712e97f9095ef4da7f0e52f50cf2bfbb32)
    
    Change-Id: Id6f93f4fb06437d5d7762d29e5d92b547fc992a3
    
    Note, this is already picked as commit
    46e04a712e97f9095ef4da7f0e52f50cf2bfbb32 but it's missing some code.
    
    Change-Id: Ia8182d3ccf14ba67d37e2bce903c620222217101

diff --git a/sw/source/core/inc/scriptinfo.hxx 
b/sw/source/core/inc/scriptinfo.hxx
index 67a12bac0d77..e11f3feccd73 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -182,7 +182,6 @@ public:
         return m_HiddenChg[ nCnt ];
     }
     TextFrameIndex NextHiddenChg(TextFrameIndex nPos) const;
-    static void selectHiddenTextProperty(const SwTextNode& rNode, 
MultiSelection &rHiddenMulti);
     TextFrameIndex NextBookmark(TextFrameIndex nPos) const;
     MarkKind GetBookmark(TextFrameIndex nPos) const;
     static void CalcHiddenRanges(const SwTextNode& rNode,
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index d27ab1c059c6..13453253a837 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -2530,6 +2530,41 @@ void SwScriptInfo::selectHiddenTextProperty(const 
SwTextNode& rNode,
                 pBookmarks->emplace_back(pBookmark, MarkKind::End);
             }
         }
+
+        bool bHide = false;
+        if (pBookmark && pBookmark->IsHidden())
+        {
+            // bookmark is marked as hidden
+            bHide = true;
+
+            // bookmark is marked as hidden with conditions
+            if (!pBookmark->GetHideCondition().isEmpty())
+            {
+                SwDoc& rDoc = *const_cast<SwDoc*>(rNode.GetDoc());
+                SwCalc aCalc(rDoc);
+                rDoc.getIDocumentFieldsAccess().FieldsToCalc(aCalc, 
rNode.GetIndex(), USHRT_MAX);
+
+                SwSbxValue aValue = 
aCalc.Calculate(pBookmark->GetHideCondition());
+                if(!aValue.IsVoidValue())
+                {
+                    bHide = aValue.GetBool();
+                }
+            }
+        }
+
+        if (bHide)
+        {
+            // intersect bookmark range with textnode range and add the 
intersection to rHiddenMulti
+
+            const sal_Int32 nSt =  
pBookmark->GetMarkStart().nContent.GetIndex();
+            const sal_Int32 nEnd = pBookmark->GetMarkEnd().nContent.GetIndex();
+
+            if( nEnd > nSt )
+            {
+                Range aTmp( nSt, nEnd - 1 );
+                rHiddenMulti.Select(aTmp, true);
+            }
+        }
     }
 }
 
commit f9d31904c9b5fa802d9abe28f542a2dd7bcff699
Author:     Michael Stahl <michael.st...@cib.de>
AuthorDate: Tue Jan 21 13:15:50 2020 +0100
Commit:     Michael Stahl <michael.st...@allotropia.de>
CommitDate: Wed Jun 22 13:44:49 2022 +0200

    tdf#45589 sw: invalidate on bookmark insertion/deletion
    
    Invalidate the text frames when a bookmark is inserted or deleted; also
    when MarkManager::repositionMark() changes the positions.
    
    The other calls of SetMarkPos()/SetOtherMarkPos() look like they're all
    from code that corrects positions after text insertions or deletions so
    no additional invalidate should be necessary there.
    
    It turns out that one WW8 document in sw_filters_test wants to insert
    a bookmark on a SwGrfNode; check for that in makeMark().
    
    Change-Id: I293e6da9042bea5992cb27091b9cff77e5c7961d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/87157
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@cib.de>
    (cherry picked from commit ef8427d12a63127a2eb867637699343d630545dd)
    
    Note, this was already cherry-picked as commit
    011f7c8a461ff6e0b3e83bf2c90b1d4502406df1 but apparently some parts
    missing.
    
    Change-Id: I5daa88b8adb273c4f8a4a3c46c13f1fd70188554

diff --git a/sw/source/core/crsr/bookmrk.cxx b/sw/source/core/crsr/bookmrk.cxx
index 1c4d4941463a..3de0b8351391 100644
--- a/sw/source/core/crsr/bookmrk.cxx
+++ b/sw/source/core/crsr/bookmrk.cxx
@@ -431,6 +431,24 @@ namespace sw { namespace mark
         }
     }
 
+    void Bookmark::Hide(bool const isHide)
+    {
+        if (isHide != m_bHidden)
+        {
+            m_bHidden = isHide;
+            InvalidateFrames();
+        }
+    }
+
+    void Bookmark::SetHideCondition(OUString const& rHideCondition)
+    {
+        if (m_sHideCondition != rHideCondition)
+        {
+            m_sHideCondition = rHideCondition;
+            InvalidateFrames();
+        }
+    }
+
     ::sfx2::IXmlIdRegistry& Bookmark::GetRegistry()
     {
         SwDoc *const pDoc( GetMarkPos().GetDoc() );
diff --git a/sw/source/core/doc/docbm.cxx b/sw/source/core/doc/docbm.cxx
index 13034ce3a699..7918e5db8dbe 100644
--- a/sw/source/core/doc/docbm.cxx
+++ b/sw/source/core/doc/docbm.cxx
@@ -561,11 +561,6 @@ namespace sw { namespace mark
                 pPos2->nContent.GetIndex());
         }
 #endif
-        // see for example _SaveContentIdx, Shells
-        OSL_PRECOND(m_vAllMarks.size() < USHRT_MAX,
-            "MarkManager::makeMark(..)"
-            " - more than USHRT_MAX marks are not supported correctly");
-
         if (   (!rPaM.GetPoint()->nNode.GetNode().IsTextNode()
                 && (eType != MarkType::UNO_BOOKMARK
                 // SwXTextRange can be on table node or plain start node 
(FLY_AT_FLY)
diff --git a/sw/source/core/inc/bookmrk.hxx b/sw/source/core/inc/bookmrk.hxx
index 45be76199073..fe5bff942568 100644
--- a/sw/source/core/inc/bookmrk.hxx
+++ b/sw/source/core/inc/bookmrk.hxx
@@ -186,10 +186,8 @@ namespace sw {
                 { return m_bHidden; }
             virtual const OUString& GetHideCondition() const override
                 { return m_sHideCondition; }
-            virtual void Hide(bool rHide) override
-                { m_bHidden = rHide; }
-            virtual void SetHideCondition(const OUString& rHideCondition) 
override
-                { m_sHideCondition = rHideCondition; }
+            virtual void Hide(bool rHide) override;
+            virtual void SetHideCondition(const OUString& rHideCondition) 
override;
 
             // ::sfx2::Metadatable
             virtual ::sfx2::IXmlIdRegistry& GetRegistry() override;

Reply via email to