Rebased ref, commits from common ancestor:
commit ca68a98eaa26a76a0f9709070a0522c76131c0c4
Author:     Juergen Funk <[email protected]>
AuthorDate: Mon Oct 7 12:15:06 2024 +0200
Commit:     Juergen Funk <[email protected]>
CommitDate: Mon Oct 7 12:15:06 2024 +0200

    Revert "tdf#158375 Hack to make sure process service factory is set"
    
    This reverts commit 53d6a13635d918367664763437d3fb52ce5fd9c3.

diff --git a/pyuno/source/loader/pyuno_loader.cxx 
b/pyuno/source/loader/pyuno_loader.cxx
index b02ad302fa80..afdb016aa764 100644
--- a/pyuno/source/loader/pyuno_loader.cxx
+++ b/pyuno/source/loader/pyuno_loader.cxx
@@ -34,11 +34,8 @@
 
 #include <cppuhelper/factory.hxx>
 
-#include <com/sun/star/lang/XMultiServiceFactory.hpp>
-#include <com/sun/star/uno/DeploymentException.hpp>
 #include <com/sun/star/uno/XComponentContext.hpp>
 
-#include <comphelper/processfactory.hxx>
 #include <officecfg/Office/Common.hxx>
 
 // apparently PATH_MAX is not standard and not defined by MSVC
@@ -247,17 +244,6 @@ extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface*
 pyuno_Loader_get_implementation(
     css::uno::XComponentContext* ctx , css::uno::Sequence<css::uno::Any> 
const&)
 {
-    //HACK: Reading the configuration via officecfg::... below internally 
needs the
-    // comphelper::getProcessServiceFactory(), which might not be set if this 
code is e.g. executed
-    // in a uno.bin process when installing a LibreOffice extension written in 
Python, so make sure
-    // the process service factory is set:
-    try {
-        comphelper::getProcessServiceFactory();
-    } catch (css::uno::DeploymentException const &) {
-        comphelper::setProcessServiceFactory(
-            css::uno::Reference<css::lang::XMultiServiceFactory>(
-                ctx->getServiceManager(), css::uno::UNO_QUERY_THROW));
-    }
     if 
(officecfg::Office::Common::Security::Scripting::DisablePythonRuntime::get())
         return nullptr;
 
commit 88291a6f47899f36b4359a3d996e046da7401144
Author:     Juergen Funk <[email protected]>
AuthorDate: Mon Oct 7 12:14:22 2024 +0200
Commit:     Juergen Funk <[email protected]>
CommitDate: Mon Oct 7 12:14:22 2024 +0200

    Revert "perf: hard-disable D2DWriteTextRenderer code path"
    
    This reverts commit 52d1d115d6b0482463293a1e6c3030777ab61f52.

diff --git a/vcl/win/gdi/winlayout.cxx b/vcl/win/gdi/winlayout.cxx
index 2e624e58a188..eb5c740580c5 100644
--- a/vcl/win/gdi/winlayout.cxx
+++ b/vcl/win/gdi/winlayout.cxx
@@ -226,7 +226,7 @@ void WinSalGraphics::DrawTextLayout(const GenericSalLayout& 
rLayout)
     const bool bVerticalScreenText
         = !mbPrinter && rLayout.GetFont().GetFontSelectPattern().mbVertical;
     const bool bRenderingModeNatural = rLayout.GetSubpixelPositioning();
-    const bool bUseDWrite = false;
+    const bool bUseDWrite = bVerticalScreenText || bRenderingModeNatural;
     DrawTextLayout(rLayout, hDC, bUseDWrite, bRenderingModeNatural);
 
     ::SelectFont(hDC, hOrigFont);
commit 23735e228767740599e3f00b9371b05bcbf243d2
Author:     Oliver Specht <[email protected]>
AuthorDate: Wed Sep 25 17:01:12 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Thu Sep 26 00:38:07 2024 +0200

    tdf#132274 follow-up fix
    
    Width of zoom radio buttons increased to prevent overwriting
    of zoom value control in e.g. German translation.
    
    Change-Id: I1e78840ede6aa1899ec7b62fdd0ce2bc92edea9e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173908
    Reviewed-by: Thorsten Behrens <[email protected]>
    Tested-by: Thorsten Behrens <[email protected]>

diff --git a/sw/uiconfig/swriter/ui/viewoptionspage.ui 
b/sw/uiconfig/swriter/ui/viewoptionspage.ui
index 2a569341b676..b2cab32d84eb 100644
--- a/sw/uiconfig/swriter/ui/viewoptionspage.ui
+++ b/sw/uiconfig/swriter/ui/viewoptionspage.ui
@@ -906,6 +906,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">0</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
@@ -927,6 +928,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">1</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
@@ -947,6 +949,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">2</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
@@ -968,6 +971,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">3</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
@@ -989,6 +993,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">4</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
@@ -1010,6 +1015,7 @@
                       <packing>
                         <property name="left-attach">0</property>
                         <property name="top-attach">5</property>
+                        <property name="width">2</property>
                       </packing>
                     </child>
                     <child>
commit 2dc905a72cea448203bfcd64c3ed81147a968abe
Author:     Thorsten Behrens <[email protected]>
AuthorDate: Tue Sep 24 10:59:25 2024 +0200
Commit:     Gerrit Code Review <[email protected]>
CommitDate: Tue Sep 24 10:59:25 2024 +0200

    Update git submodules
    
    * Update translations from branch 'feature/cib_contract49c'
      to b7e8a4f314080d6bb04ea3181c881b7dc12d437e
      - Manually add translations for new zoom settings
    
        Change-Id: I5b0683f5c0847b2bdb231ca82857656483706183

diff --git a/translations b/translations
index 977c1be2b7ee..b7e8a4f31408 160000
--- a/translations
+++ b/translations
@@ -1 +1 @@
-Subproject commit 977c1be2b7eecf4f8a42eeb991d6d1a48b626bd5
+Subproject commit b7e8a4f314080d6bb04ea3181c881b7dc12d437e
commit 34ae6c53e1c287cd5cf3664091c40345437846ee
Author:     Oliver Specht <[email protected]>
AuthorDate: Mon Aug 5 13:53:25 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Sep 24 04:28:43 2024 +0200

    tdf#132274 add zoom defaults to Writer options
    
    Zoom value is sometimes stored at documents. But users
    might prefer local zoom settings over stored values.
    Users are now able to set preferred values in Writer's
    option dialog.
    
    Change-Id: Ia1c3926aac3dd236f15f84d8dc535d8aa3758238
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173266
    Reviewed-by: Thorsten Behrens <[email protected]>
    Tested-by: allotropia jenkins <[email protected]>

diff --git a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs 
b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
index e27b53e20bf1..2de3e2ffaedc 100644
--- a/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
+++ b/officecfg/registry/schema/org/openoffice/Office/Writer.xcs
@@ -901,6 +901,59 @@
           <value>1</value>
         </prop>
       </group>
+      <group oor:name="Zoom">
+          <info>
+              <desc>Contains zoom settings of the document view.</desc>
+          </info>
+          <prop oor:name="DefaultZoom" oor:type="xs:boolean" 
oor:nillable="false">
+              <!-- UIHints: Tools - Options - Text document  Contents - 
[Section] ´Zoom-->
+              <info>
+                  <desc>Determines whether zoom settings previously selected 
are applied to new/loaded document view or predefined zoom values are 
applied</desc>
+              </info>
+              <value>true</value>
+          </prop>
+          <prop oor:name="ZoomType" oor:type="xs:int" oor:nillable="false">
+              <!-- UIHints: Tools - Options - Text document  Contents - 
[Section] ´Zoom-->
+              <info>
+                  <desc>Contains predefined zoom type</desc>
+              </info>
+              <constraints>
+                  <enumeration oor:value="0">
+                      <info>
+                          <desc>PERCENT</desc>
+                      </info>
+                  </enumeration>
+                  <enumeration oor:value="1">
+                      <info>
+                          <desc>OPTIMAL</desc>
+                      </info>
+                  </enumeration>
+                  <enumeration oor:value="2">
+                      <info>
+                          <desc>WHOLEPAGE</desc>
+                      </info>
+                  </enumeration>
+                  <enumeration oor:value="3">
+                      <info>
+                          <desc>PAGEWIDTH</desc>
+                      </info>
+                  </enumeration>
+                  <enumeration oor:value="4">
+                      <info>
+                          <desc>PAGEWIDTH_NOBORDER</desc>
+                      </info>
+                  </enumeration>
+              </constraints>
+              <value>0</value>
+          </prop>
+          <prop oor:name="ZoomValue" oor:type="xs:int" oor:nillable="false">
+              <!-- UIHints: Tools - Options - Text document  Contents - 
[Section] ´Zoom-->
+              <info>
+                  <desc>Contains predefined zoom value in percent.</desc>
+              </info>
+              <value>100</value>
+          </prop>
+      </group>
       <group oor:name="NonprintingCharacter">
         <info>
           <desc>Contains settings for the visibility of various non-printing 
characters.</desc>
diff --git a/sw/qa/uitest/options/optionsDialog.py 
b/sw/qa/uitest/options/optionsDialog.py
index 790d30c9b7ed..48c1d5d5bc6c 100644
--- a/sw/qa/uitest/options/optionsDialog.py
+++ b/sw/qa/uitest/options/optionsDialog.py
@@ -7,6 +7,7 @@
 # file, You can obtain one at http://mozilla.org/MPL/2.0/.
 #
 from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
 
 class optionsDialog(UITestCase):
 
@@ -48,5 +49,34 @@ class optionsDialog(UITestCase):
                 xApplyBtn.executeAction("CLICK", tuple())
 
 
+    def test_tdf132274Text(self):
+        with self.ui_test.create_doc_in_start_center("writer"):
+
+            with 
self.ui_test.execute_dialog_through_command(".uno:OptionsTreeDialog") as 
xDialog:
+                xPages = xDialog.getChild("pages")
+                xWriterEntry = xPages.getChild('3')
+                xWriterEntry.executeAction("EXPAND", tuple())
+                xContentEntry = xWriterEntry.getChild('1')
+                xContentEntry.executeAction("SELECT", tuple())
+                xOptimal = xDialog.getChild("zoomoptimal")
+                self.assertEqual(get_state_as_dict(xOptimal)['Visible'], 
"true")
+                xApplyBtn = xDialog.getChild("apply")
+
+    def test_tdf132274Web(self):
+        with self.ui_test.create_doc_in_start_center("writer"):
+
+            with 
self.ui_test.execute_dialog_through_command(".uno:OptionsTreeDialog") as 
xDialog:
+                xPages = xDialog.getChild("pages")
+                xWriterWebEntry = xPages.getChild('4')
+                xWriterWebEntry.executeAction("EXPAND", tuple())
+                xContentWebEntry = xWriterWebEntry.getChild('1')
+                xContentWebEntry.executeAction("SELECT", tuple())
+                try:
+                    xOptimalWeb = xDialog.getChild("zoomoptimal")
+                    raise RuntimeError("Zoom controls visible in Web dialog")
+                except Exception:
+                    xApplyBtn = xDialog.getChild("apply")
+
+
 
 # vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/config/optpage.cxx b/sw/source/ui/config/optpage.cxx
index a2af6912b75a..021bca753955 100644
--- a/sw/source/ui/config/optpage.cxx
+++ b/sw/source/ui/config/optpage.cxx
@@ -122,6 +122,15 @@ SwContentOptPage::SwContentOptPage(weld::Container* pPage, 
weld::DialogControlle
     , m_xFieldHiddenImg(m_xBuilder->weld_widget("lockhiddentextfield"))
     , m_xFieldHiddenParaCB(m_xBuilder->weld_check_button("hiddenparafield"))
     , m_xFieldHiddenParaImg(m_xBuilder->weld_widget("lockhiddenparafield"))
+    , m_xZoomFrame(m_xBuilder->weld_frame("zoomframe"))
+    , m_xZoomLatestRB(m_xBuilder->weld_radio_button("zoomlatest"))
+    , m_xZoomPreferredRB(m_xBuilder->weld_radio_button("zoompreferred"))
+    , m_xZoomOptimalRB(m_xBuilder->weld_radio_button("zoomoptimal"))
+    , m_xZoomWidthAndHeightRB(m_xBuilder->weld_radio_button("zoomfitwandh"))
+    , m_xZoomWidthRB(m_xBuilder->weld_radio_button("zoomfitw"))
+    , m_xZoom100RB(m_xBuilder->weld_radio_button("zoom100pc"))
+    , m_xZoomCustomRB(m_xBuilder->weld_radio_button("zoomcustom"))
+    , m_xZoomValue(m_xBuilder->weld_metric_spin_button("zoomvalue", 
FieldUnit::PERCENT))
 {
     m_xShowOutlineContentVisibilityButton->connect_toggled(LINK(this, 
SwContentOptPage, ShowOutlineContentVisibilityButtonHdl));
 
@@ -133,6 +142,29 @@ SwContentOptPage::SwContentOptPage(weld::Container* pPage, 
weld::DialogControlle
         m_xSettingsLabel->hide();
         m_xMetricLabel->hide();
         m_xMetricLB->hide();
+
+        Link<weld::Toggleable&, void> aZoomLatestLink = LINK(this, 
SwContentOptPage, ZoomLatestHdl);
+        m_xZoomLatestRB->connect_toggled(aZoomLatestLink);
+        m_xZoomPreferredRB->connect_toggled(aZoomLatestLink);
+        Link<weld::Toggleable&, void> aZoomLink = LINK(this, SwContentOptPage, 
ZoomHdl);
+        m_xZoomOptimalRB->connect_toggled(aZoomLink);
+        m_xZoomWidthAndHeightRB->connect_toggled(aZoomLink);
+        m_xZoomWidthRB->connect_toggled(aZoomLink);
+        m_xZoom100RB->connect_toggled(aZoomLink);
+        m_xZoomCustomRB->connect_toggled(aZoomLink);
+        m_xZoomValue->set_range(MINZOOM, MAXZOOM, FieldUnit::PERCENT);
+    }
+    else
+    {
+        m_xZoomFrame->hide();
+        m_xZoomLatestRB->hide();
+        m_xZoomPreferredRB->hide();
+        m_xZoomOptimalRB->hide();
+        m_xZoomWidthAndHeightRB->hide();
+        m_xZoomWidthRB->hide();
+        m_xZoom100RB->hide();
+        m_xZoomCustomRB->hide();
+        m_xZoomValue->hide();
     }
 
     if(!SvtCJKOptions::IsVerticalTextEnabled() )
@@ -285,6 +317,26 @@ void SwContentOptPage::Reset(const SfxItemSet* rSet)
         m_xFieldHiddenParaCB->set_active( pElemAttr->m_bShowHiddenPara );
         m_xFieldHiddenParaCB->set_sensitive(!bReadOnly);
         m_xFieldHiddenParaImg->set_visible(bReadOnly);
+
+        if (!bWebOptionsPage)
+        {
+            m_xZoomLatestRB->set_active(pElemAttr->IsDefaultZoom());
+            m_xZoomPreferredRB->set_active(!pElemAttr->IsDefaultZoom());
+            switch (pElemAttr->GetDefaultZoomType())
+            {
+                case SvxZoomType::OPTIMAL:   
m_xZoomOptimalRB->set_active(true); break;
+                case SvxZoomType::WHOLEPAGE: 
m_xZoomWidthAndHeightRB->set_active(true); break;
+                case SvxZoomType::PAGEWIDTH: m_xZoomWidthRB->set_active(true); 
break;
+                case SvxZoomType::PERCENT:
+                    m_xZoom100RB->set_active(pElemAttr->GetDefaultZoomValue() 
== 100);
+                    
m_xZoomCustomRB->set_active(pElemAttr->GetDefaultZoomValue() != 100);
+                    break;
+                default:
+                    break;
+            }
+            m_xZoomValue->set_value(pElemAttr->GetDefaultZoomValue(), 
FieldUnit::PERCENT);
+            ZoomLatestHdl(*m_xZoomLatestRB);
+        }
     }
 
     bReadOnly = !bWebOptionsPage ? 
officecfg::Office::Writer::Layout::Window::HorizontalRulerUnit::isReadOnly() :
@@ -366,6 +418,25 @@ bool SwContentOptPage::FillItemSet(SfxItemSet* rSet)
     aElem.m_bFieldHiddenText      = m_xFieldHiddenCB->get_active();
     aElem.m_bShowHiddenPara       = m_xFieldHiddenParaCB->get_active();
 
+    if (m_xZoomLatestRB->is_visible())
+    {
+        aElem.SetDefaultZoom(m_xZoomLatestRB->get_active());
+        if (m_xZoomOptimalRB->get_active())
+            aElem.SetDefaultZoomType(SvxZoomType::OPTIMAL);
+        else if (m_xZoomWidthAndHeightRB->get_active())
+            aElem.SetDefaultZoomType(SvxZoomType::WHOLEPAGE);
+        else if (m_xZoomWidthRB->get_active())
+            aElem.SetDefaultZoomType(SvxZoomType::PAGEWIDTH);
+        else if (m_xZoom100RB->get_active())
+        {
+            aElem.SetDefaultZoomType(SvxZoomType::PERCENT);
+            aElem.SetDefaultZoomValue(100);
+        }
+        else
+            aElem.SetDefaultZoomType(SvxZoomType::PERCENT);
+    }
+    aElem.SetDefaultZoomValue(m_xZoomValue->get_value(FieldUnit::PERCENT));
+
     bool bRet = !pOldAttr || aElem != *pOldAttr;
     if(bRet)
         bRet = nullptr != rSet->Put(aElem);
@@ -408,6 +479,30 @@ IMPL_LINK(SwContentOptPage, 
ShowOutlineContentVisibilityButtonHdl, weld::Togglea
     m_xTreatSubOutlineLevelsAsContent->set_sensitive(rBox.get_active());
 }
 
+IMPL_LINK_NOARG(SwContentOptPage, ZoomLatestHdl, weld::Toggleable&, void)
+{
+    bool bZoomPreferred = m_xZoomPreferredRB->get_active();
+    m_xZoomOptimalRB->set_sensitive(bZoomPreferred);
+    m_xZoomWidthAndHeightRB->set_sensitive(bZoomPreferred);
+    m_xZoomWidthRB->set_sensitive(bZoomPreferred);
+    m_xZoom100RB->set_sensitive(bZoomPreferred);
+    m_xZoomCustomRB->set_sensitive(bZoomPreferred);
+    m_xZoomValue->set_sensitive(bZoomPreferred);
+    ZoomHdl(*m_xZoomOptimalRB);
+}
+IMPL_LINK_NOARG(SwContentOptPage, ZoomHdl, weld::Toggleable&, void)
+{
+    if (m_xZoomCustomRB->get_active() && m_xZoomCustomRB->get_sensitive())
+    {
+        m_xZoomValue->set_sensitive(true);
+        m_xZoomValue->grab_focus();
+    }
+    else
+    {
+       m_xZoomValue->set_sensitive(false);
+    }
+}
+
 // 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 7be59a1dab9a..21c7b10c7ea6 100644
--- a/sw/source/uibase/app/appopt.cxx
+++ b/sw/source/uibase/app/appopt.cxx
@@ -106,12 +106,16 @@ std::optional<SfxItemSet> SwModule::CreateItemSet( 
sal_uInt16 nId )
         aRet(GetPool());
 
     aRet.Put( SwDocDisplayItem( aViewOpt ) );
-    aRet.Put( SwElemItem( aViewOpt ) );
+    SwElemItem aElemItem( aViewOpt );
     if( bTextDialog )
     {
         aRet.Put( SwShadowCursorItem( aViewOpt ));
         aRet.Put( SfxBoolItem(FN_PARAM_CRSR_IN_PROTECTED, 
aViewOpt.IsCursorInProtectedArea()));
+        aElemItem.SetDefaultZoom(pPref->IsDefaultZoom());
+        aElemItem.SetDefaultZoomType(pPref->GetDefaultZoomType());
+        aElemItem.SetDefaultZoomValue(pPref->GetDefaultZoomValue());
     }
+    aRet.Put( aElemItem );
 
     if( pAppView )
     {
@@ -261,6 +265,12 @@ void SwModule::ApplyItemSet( sal_uInt16 nId, const 
SfxItemSet& rSet )
     if( const SwElemItem* pElemItem = rSet.GetItemIfSet( FN_PARAM_ELEM, false 
) )
     {
         pElemItem->FillViewOptions( aViewOpt );
+        if (bTextDialog)
+        {
+            pPref->SetDefaultZoom(pElemItem->IsDefaultZoom());
+            pPref->SetDefaultZoomType(pElemItem->GetDefaultZoomType());
+            pPref->SetDefaultZoomValue(pElemItem->GetDefaultZoomValue());
+        }
 
         // Outline-folding options
         if (SwWrtShell* pWrtShell = GetActiveWrtShell())
diff --git a/sw/source/uibase/config/cfgitems.cxx 
b/sw/source/uibase/config/cfgitems.cxx
index 693837d84f10..0d7da3d55018 100644
--- a/sw/source/uibase/config/cfgitems.cxx
+++ b/sw/source/uibase/config/cfgitems.cxx
@@ -104,6 +104,9 @@ SwElemItem::SwElemItem() :
     m_bShowChangesInMargin =
     m_bFieldHiddenText =
     m_bShowHiddenPara  = false;
+    m_bDefaultZoom = true;
+    m_eDefaultZoomType = SvxZoomType::PERCENT;
+    m_nDefaultZoomValue = 100;
 }
 
 SwElemItem::SwElemItem(const SwViewOption& rVOpt) :
@@ -149,7 +152,10 @@ bool SwElemItem::operator==( const SfxPoolItem& rAttr ) 
const
                 m_bTreatSubOutlineLevelsAsContent == 
rItem.m_bTreatSubOutlineLevelsAsContent &&
                 m_bShowChangesInMargin  == rItem.m_bShowChangesInMargin &&
                 m_bFieldHiddenText == rItem.m_bFieldHiddenText &&
-                m_bShowHiddenPara  == rItem.m_bShowHiddenPara);
+                m_bShowHiddenPara  == rItem.m_bShowHiddenPara &&
+                m_bDefaultZoom == rItem.m_bDefaultZoom &&
+                m_eDefaultZoomType == rItem.m_eDefaultZoomType &&
+                m_nDefaultZoomValue == rItem.m_nDefaultZoomValue );
 }
 
 void SwElemItem::FillViewOptions( SwViewOption& rVOpt) const
@@ -169,6 +175,12 @@ void SwElemItem::FillViewOptions( SwViewOption& rVOpt) 
const
     rVOpt.SetShowChangesInMargin( m_bShowChangesInMargin );
     rVOpt.SetShowHiddenField(m_bFieldHiddenText );
     rVOpt.SetShowHiddenPara(m_bShowHiddenPara );
+    if (!m_bDefaultZoom)
+    {
+        rVOpt.SetZoomType(m_eDefaultZoomType);
+        if (m_eDefaultZoomType == SvxZoomType::PERCENT)
+            rVOpt.SetZoom(m_nDefaultZoomValue);
+    }
 }
 
 // CTOR for empty Item
diff --git a/sw/source/uibase/config/usrpref.cxx 
b/sw/source/uibase/config/usrpref.cxx
index c04d775c3ac3..26ba290b1677 100644
--- a/sw/source/uibase/config/usrpref.cxx
+++ b/sw/source/uibase/config/usrpref.cxx
@@ -52,7 +52,10 @@ SwMasterUsrPref::SwMasterUsrPref(bool bWeb) :
     m_aGridConfig(bWeb, *this),
     m_aCursorConfig(*this),
     m_pWebColorConfig(bWeb ? new SwWebColorConfig(*this) : nullptr),
-    m_bApplyCharUnit(false)
+    m_bApplyCharUnit(false),
+    m_bUseDefaultZoom(true),
+    m_nDefaultZoomValue(100),
+    m_eDefaultZoomType(SvxZoomType::PERCENT)
 {
     if (utl::ConfigManager::IsFuzzing())
     {
@@ -81,6 +84,8 @@ SwMasterUsrPref::~SwMasterUsrPref()
 
 const auto g_UpdateLinkIndex = 17;
 const auto g_DefaultAnchor = 25;
+const auto g_ZoomType = 27;
+const auto g_ZoomValue = 28;
 
 Sequence<OUString> SwContentViewConfig::GetPropertyNames() const
 {
@@ -111,12 +116,17 @@ Sequence<OUString> 
SwContentViewConfig::GetPropertyNames() const
         "Display/ShowOutlineContentVisibilityButton", // 22
         "Display/TreatSubOutlineLevelsAsContent",     // 23
         "Display/ShowChangesInMargin",          // 24
-        "Display/DefaultAnchor"                 // 25
+        "Display/DefaultAnchor",                // 25
+        "Zoom/DefaultZoom",                     // 26
+        "Zoom/ZoomType",                        // 27
+        "Zoom/ZoomValue"                        //28
     };
 #if defined(__GNUC__) && !defined(__clang__)
     // clang 8.0.0 says strcmp isn't constexpr
     static_assert(std::strcmp("Update/Link", aPropNames[g_UpdateLinkIndex]) == 
0);
     static_assert(std::strcmp("Display/DefaultAnchor", 
aPropNames[g_DefaultAnchor]) == 0);
+    static_assert(std::strcmp("Zoom/ZoomType", aPropNames[g_ZoomType]) == 0);
+    static_assert(std::strcmp("Zoom/ZoomValue", aPropNames[g_ZoomValue]) == 0);
 #endif
     const int nCount = m_bWeb ? 12 : SAL_N_ELEMENTS(aPropNames);
     Sequence<OUString> aNames(nCount);
@@ -184,8 +194,13 @@ void SwContentViewConfig::ImplCommit()
             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"
+                //TODO: Save zoom preferred, zoom type, zoom value
+            case 26: bVal = m_rParent.IsDefaultZoom(); break;// 
"Zoom/DefaultZoom"
+            case 27:pValues[nProp] <<= 
static_cast<sal_Int32>(m_rParent.GetDefaultZoomType()); break; // 
"Zoom/ZoomType"
+            case 28: pValues[nProp] <<= 
static_cast<sal_Int32>(m_rParent.GetDefaultZoomValue()); break; // 
"Zoom/ZoomValue"
         }
-        if ((nProp != g_UpdateLinkIndex) && (nProp != g_DefaultAnchor))
+        if ((nProp != g_UpdateLinkIndex) && (nProp != g_DefaultAnchor) &&
+            (nProp != g_ZoomType) && (nProp != g_ZoomValue))
             pValues[nProp] <<= bVal;
     }
     PutProperties(aNames, aValues);
@@ -203,7 +218,7 @@ void SwContentViewConfig::Load()
     {
         if(pValues[nProp].hasValue())
         {
-            bool bSet = ((nProp != g_UpdateLinkIndex) && (nProp != 
g_DefaultAnchor))
+            bool bSet = ((nProp != g_UpdateLinkIndex) && (nProp != 
g_DefaultAnchor) && (nProp != g_ZoomType)&& (nProp != g_ZoomValue))
                         && *o3tl::doAccess<bool>(pValues[nProp]);
             switch(nProp)
             {
@@ -245,6 +260,21 @@ void SwContentViewConfig::Load()
                     m_rParent.SetDefaultAnchor(nSet);
                 }
                 break; // "Display/DefaultAnchor"
+                case 26:  m_rParent.SetDefaultZoom(bSet); break; // 
"Zoom/DefaultZoom"
+                case 27:
+                {
+                    sal_Int32 nSet = 0;
+                    pValues[nProp] >>= nSet;
+                    
m_rParent.SetDefaultZoomType(static_cast<SvxZoomType>(nSet), true);
+                }
+                break; //"Zoom/ZoomType", // 27
+                case 28:
+                {
+                    sal_Int32 nSet = 0;
+                    pValues[nProp] >>= nSet;
+                    
m_rParent.SetDefaultZoomValue(static_cast<sal_uInt16>(nSet), true);
+                }
+                break; //"Zoom/ZoomValue"
             }
         }
     }
diff --git a/sw/source/uibase/inc/cfgitems.hxx 
b/sw/source/uibase/inc/cfgitems.hxx
index 8f7dc0bd3b72..b7535e1b9db0 100644
--- a/sw/source/uibase/inc/cfgitems.hxx
+++ b/sw/source/uibase/inc/cfgitems.hxx
@@ -24,6 +24,7 @@
 #include <printdata.hxx>
 
 #include <cmdid.h>
+#include <sfx2/zoomitem.hxx>
 
 class SwModule;
 #ifdef DBG_UTIL
@@ -83,6 +84,9 @@ class SW_DLLPUBLIC SwElemItem final : public SfxPoolItem
     bool m_bShowChangesInMargin :1;
     bool m_bFieldHiddenText   :1;
     bool m_bShowHiddenPara    :1;
+    bool m_bDefaultZoom       :1;
+    SvxZoomType m_eDefaultZoomType;
+    sal_uInt16  m_nDefaultZoomValue;
 
     friend class SwContentOptPage;
 
@@ -95,6 +99,15 @@ public:
 
     void                    FillViewOptions( SwViewOption& rVOpt) const;
 
+    bool IsDefaultZoom() const {return m_bDefaultZoom; }
+    void SetDefaultZoom(bool bSet) { m_bDefaultZoom = bSet; }
+
+    SvxZoomType GetDefaultZoomType() const { return m_eDefaultZoomType; }
+    void SetDefaultZoomType(SvxZoomType eType) { m_eDefaultZoomType = eType; }
+
+    sal_uInt16  GetDefaultZoomValue() const { return m_nDefaultZoomValue;}
+    void SetDefaultZoomValue(sal_Int16 nValue){ m_nDefaultZoomValue = nValue; }
+
 };
 
 // OS 12.01.95
diff --git a/sw/source/uibase/inc/optpage.hxx b/sw/source/uibase/inc/optpage.hxx
index e2641fd7fc2b..4829eac56700 100644
--- a/sw/source/uibase/inc/optpage.hxx
+++ b/sw/source/uibase/inc/optpage.hxx
@@ -75,8 +75,20 @@ class SwContentOptPage final : public SfxTabPage
     std::unique_ptr<weld::CheckButton> m_xFieldHiddenParaCB;
     std::unique_ptr<weld::Widget> m_xFieldHiddenParaImg;
 
+    std::unique_ptr<weld::Frame> m_xZoomFrame;
+    std::unique_ptr<weld::RadioButton> m_xZoomLatestRB;
+    std::unique_ptr<weld::RadioButton> m_xZoomPreferredRB;
+    std::unique_ptr<weld::RadioButton> m_xZoomOptimalRB;
+    std::unique_ptr<weld::RadioButton> m_xZoomWidthAndHeightRB;
+    std::unique_ptr<weld::RadioButton> m_xZoomWidthRB;
+    std::unique_ptr<weld::RadioButton> m_xZoom100RB;
+    std::unique_ptr<weld::RadioButton> m_xZoomCustomRB;
+    std::unique_ptr<weld::MetricSpinButton> m_xZoomValue;
+
     DECL_LINK(VertRulerHdl, weld::Toggleable&, void);
     DECL_LINK(ShowOutlineContentVisibilityButtonHdl, weld::Toggleable&, void);
+    DECL_LINK(ZoomHdl, weld::Toggleable&, void);
+    DECL_LINK(ZoomLatestHdl, weld::Toggleable&, void);
 public:
     SwContentOptPage(weld::Container* pPage, weld::DialogController* 
pController, const SfxItemSet& rSet);
     virtual ~SwContentOptPage() override;
diff --git a/sw/source/uibase/inc/usrpref.hxx b/sw/source/uibase/inc/usrpref.hxx
index 1464c90bce3c..c9e4aa0d7cf3 100644
--- a/sw/source/uibase/inc/usrpref.hxx
+++ b/sw/source/uibase/inc/usrpref.hxx
@@ -148,6 +148,12 @@ class SwMasterUsrPref : public SwViewOption
     std::unique_ptr<SwWebColorConfig>   m_pWebColorConfig;
 
     bool m_bApplyCharUnit; // apply_char_unit
+
+    // Scale
+    bool              m_bUseDefaultZoom;
+    sal_uInt16        m_nDefaultZoomValue;  // percent.
+    SvxZoomType       m_eDefaultZoomType;
+
 public:
     SwMasterUsrPref(bool bWeb);
     ~SwMasterUsrPref();
@@ -241,6 +247,28 @@ public:
         }
     }
 
+    bool IsDefaultZoom() const { return m_bUseDefaultZoom;}
+    void SetDefaultZoom( bool bSet, bool bNoModify = false )
+    {
+        m_bUseDefaultZoom = bSet;
+        if(!bNoModify)
+            m_aContentConfig.SetModified();
+    }
+    sal_uInt16 GetDefaultZoomValue() const { return m_nDefaultZoomValue; }
+    void SetDefaultZoomValue ( sal_uInt16 nValue, bool bNoModify = false )
+    {
+        m_nDefaultZoomValue = nValue;
+        if(!bNoModify)
+          m_aContentConfig.SetModified();
+    }
+    SvxZoomType GetDefaultZoomType() const { return m_eDefaultZoomType;}
+    void SetDefaultZoomType( SvxZoomType eType, bool bNoModify = false )
+    {
+        m_eDefaultZoomType = eType;
+        if(!bNoModify)
+            m_aContentConfig.SetModified();
+    }
+
     sal_Int32   GetDefTabInMm100() const { return m_nDefTabInMm100;}
     void        SetDefTabInMm100( sal_Int32  nSet, bool bNoModify = false )
                 {
diff --git a/sw/source/uibase/uiview/view.cxx b/sw/source/uibase/uiview/view.cxx
index 2d46cd04f260..956386840389 100644
--- a/sw/source/uibase/uiview/view.cxx
+++ b/sw/source/uibase/uiview/view.cxx
@@ -903,12 +903,17 @@ SwView::SwView(SfxViewFrame& _rFrame, SfxViewShell* 
pOldSh)
             aUsrPref.SetZoomType( SvxZoomType::PERCENT );
             aUsrPref.SetZoom( 100 );
         }
-        if (rDocSh.IsPreview())
+        else if (rDocSh.IsPreview())
         {
             aUsrPref.SetZoomType( SvxZoomType::WHOLEPAGE );
             aUsrPref.SetViewLayoutBookMode( false );
             aUsrPref.SetViewLayoutColumns( 1 );
         }
+        else if (!pUsrPref->IsDefaultZoom())
+        {
+            aUsrPref.SetZoomType(pUsrPref->GetDefaultZoomType());
+            aUsrPref.SetZoom(pUsrPref->GetDefaultZoomValue());
+        }
         m_pWrtShell.reset(new SwWrtShell(rDoc, m_pEditWin, *this, &aUsrPref));
         // creating an SwView from a SwPagePreview needs to
         // add the SwViewShell to the ring of the other SwViewShell(s)
@@ -1566,7 +1571,8 @@ void SwView::ReadUserDataSequence ( const uno::Sequence < 
beans::PropertyValue >
                                         ( pVOpt->GetViewLayoutColumns() != 
nViewLayoutColumns || pVOpt->IsViewLayoutBookMode() != bViewLayoutBookMode );
 
     const bool bSetViewSettings = bGotZoomType && bGotZoomFactor &&
-                                  ( pVOpt->GetZoom() != nZoomFactor || 
pVOpt->GetZoomType() != eZoom );
+                                  ( pVOpt->GetZoom() != nZoomFactor || 
pVOpt->GetZoomType() != eZoom ) &&
+                                   
SW_MOD()->GetUsrPref(pVOpt->getBrowseMode())->IsDefaultZoom();
 
     // In case we have a 'fixed' view layout of 2 or more columns,
     // we have to apply the view options *before* starting the action.
diff --git a/sw/uiconfig/swriter/ui/viewoptionspage.ui 
b/sw/uiconfig/swriter/ui/viewoptionspage.ui
index 7d1ba0354c27..2a569341b676 100644
--- a/sw/uiconfig/swriter/ui/viewoptionspage.ui
+++ b/sw/uiconfig/swriter/ui/viewoptionspage.ui
@@ -1,7 +1,12 @@
 <?xml version="1.0" encoding="UTF-8"?>
-<!-- Generated with glade 3.38.2 -->
+<!-- Generated with glade 3.40.0 -->
 <interface domain="sw">
   <requires lib="gtk+" version="3.20"/>
+  <object class="GtkAdjustment" id="adjustment2">
+    <property name="upper">100</property>
+    <property name="step-increment">1</property>
+    <property name="page-increment">10</property>
+  </object>
   <object class="GtkBox" id="ViewOptionsPage">
     <property name="visible">True</property>
     <property name="can-focus">False</property>
@@ -459,6 +464,105 @@
                 <property name="position">3</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>
+                  <!-- n-columns=2 n-rows=2 -->
+                  <object class="GtkGrid">
+                    <property name="visible">True</property>
+                    <property name="can-focus">False</property>
+                    <property name="margin-start">12</property>
+                    <property name="margin-top">6</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-folding 
buttons</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="draw-indicator">True</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="outlinecontentvisibilitybutton-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" 
context="viewoptionspage|extended_tip|outlinecontentvisibilitybutton">Displays 
outline folding buttons on the left of the outline headings.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</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="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="suboutlinelevelsascontent-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" 
context="viewoptionspage|extended_tip|suboutlinelevelsascontent">Displays the 
folding buttons of the outline sub levels.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">1</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkImage" 
id="lockoutlinecontentvisibility">
+                        <property name="can-focus">False</property>
+                        <property name="no-show-all">True</property>
+                        <property name="halign">center</property>
+                        <property name="valign">center</property>
+                        <property name="icon-name">res/lock.png</property>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">0</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkImage" id="locksuboutlinelevels">
+                        <property name="can-focus">False</property>
+                        <property name="no-show-all">True</property>
+                        <property name="halign">center</property>
+                        <property name="valign">center</property>
+                        <property name="icon-name">res/lock.png</property>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">1</property>
+                      </packing>
+                    </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 Folding</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>
@@ -766,92 +870,217 @@
               </packing>
             </child>
             <child>
-              <object class="GtkFrame" id="outlineframe">
+              <placeholder/>
+            </child>
+            <child>
+              <object class="GtkFrame" id="zoomframe">
                 <property name="visible">True</property>
                 <property name="can-focus">False</property>
                 <property name="label-xalign">0</property>
                 <property name="shadow-type">none</property>
                 <child>
-                  <!-- n-columns=2 n-rows=2 -->
+                  <!-- n-columns=2 n-rows=7 -->
                   <object class="GtkGrid">
                     <property name="visible">True</property>
                     <property name="can-focus">False</property>
                     <property name="margin-start">12</property>
                     <property name="margin-top">6</property>
-                    <property name="row-spacing">6</property>
+                    <property name="margin-bottom">43</property>
+                    <property name="row-spacing">7</property>
                     <property name="column-spacing">6</property>
                     <child>
-                      <object class="GtkCheckButton" 
id="outlinecontentvisibilitybutton">
-                        <property name="label" translatable="yes" 
context="viewoptionspage|outlinecontentvisibilitybutton">_Show outline-folding 
buttons</property>
+                      <object class="GtkRadioButton" id="zoomlatest">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoomlatest">Use latest setting</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="active">True</property>
                         <property name="draw-indicator">True</property>
                         <child internal-child="accessible">
-                          <object class="AtkObject" 
id="outlinecontentvisibilitybutton-atkobject">
-                            <property name="AtkObject::accessible-description" 
translatable="yes" 
context="viewoptionspage|extended_tip|outlinecontentvisibilitybutton">Displays 
outline folding buttons on the left of the outline headings.</property>
+                          <object class="AtkObject" id="zoomlatest-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoomlatest">Uses the zoom 
setting that has been applied manually.</property>
                           </object>
                         </child>
                       </object>
                       <packing>
-                        <property name="left-attach">1</property>
+                        <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>
+                      <object class="GtkRadioButton" id="zoompreferred">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoompreferred">Use preferred values</property>
                         <property name="visible">True</property>
                         <property name="can-focus">True</property>
                         <property name="receives-default">False</property>
-                        <property name="margin-start">12</property>
                         <property name="use-underline">True</property>
+                        <property name="active">True</property>
                         <property name="draw-indicator">True</property>
+                        <property name="group">zoomlatest</property>
                         <child internal-child="accessible">
-                          <object class="AtkObject" 
id="suboutlinelevelsascontent-atkobject">
-                            <property name="AtkObject::accessible-description" 
translatable="yes" 
context="viewoptionspage|extended_tip|suboutlinelevelsascontent">Displays the 
folding buttons of the outline sub levels.</property>
+                          <object class="AtkObject" 
id="zoompreferred-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoompreferred">Applies 
preferred zoom settings to documents.</property>
                           </object>
                         </child>
                       </object>
                       <packing>
-                        <property name="left-attach">1</property>
+                        <property name="left-attach">0</property>
                         <property name="top-attach">1</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkImage" 
id="lockoutlinecontentvisibility">
-                        <property name="can-focus">False</property>
-                        <property name="no-show-all">True</property>
-                        <property name="halign">center</property>
-                        <property name="valign">center</property>
-                        <property name="icon-name">res/lock.png</property>
+                      <object class="GtkRadioButton" id="zoomoptimal">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoomoptimal">Optimal</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="zoomoptimal-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoomoptimal">Resizes the 
display to fit the width of the text in the document at the moment the command 
is started.</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>
-                        <property name="top-attach">0</property>
+                        <property name="top-attach">2</property>
                       </packing>
                     </child>
                     <child>
-                      <object class="GtkImage" id="locksuboutlinelevels">
-                        <property name="can-focus">False</property>
-                        <property name="no-show-all">True</property>
-                        <property name="halign">center</property>
-                        <property name="valign">center</property>
-                        <property name="icon-name">res/lock.png</property>
+                      <object class="GtkRadioButton" id="zoomfitwandh">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoomfitwandh">Fit width and height</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <property name="group">zoomoptimal</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" 
id="zoomfitwandh-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoomfitwandh">Displays the 
entire page on your screen.</property>
+                          </object>
+                        </child>
                       </object>
                       <packing>
                         <property name="left-attach">0</property>
-                        <property name="top-attach">1</property>
+                        <property name="top-attach">3</property>
                       </packing>
                     </child>
+                    <child>
+                      <object class="GtkRadioButton" id="zoomfitw">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoomfitw">Fit width</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <property name="group">zoomoptimal</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="zoomfitw-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoomfitw">Displays the 
complete width of the document page. The top and bottom edges of the page may 
not be visible.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">4</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="zoom100pc">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zomm100pc">100%</property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <property name="group">zoomoptimal</property>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="zomm100pc-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zomm100pc">Displays the 
document at its actual size.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">5</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkRadioButton" id="zoomcustom">
+                        <property name="label" translatable="yes" 
context="zoomdialog|zoomcustom">Custom: </property>
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="receives-default">False</property>
+                        <property name="margin-start">12</property>
+                        <property name="use-underline">True</property>
+                        <property name="draw-indicator">True</property>
+                        <property name="group">zoomoptimal</property>
+                        <accessibility>
+                          <relation type="label-for" target="zoomvalue"/>
+                        </accessibility>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="zoomcustom-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="zoomdialog|extended_tip|zoomcustom">Enter the zoom 
factor at which you want to display the document. Enter a percentage in the 
box.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">0</property>
+                        <property name="top-attach">6</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <object class="GtkSpinButton" id="zoomvalue">
+                        <property name="visible">True</property>
+                        <property name="can-focus">True</property>
+                        <property name="hexpand">True</property>
+                        <property name="adjustment">adjustment2</property>
+                        <accessibility>
+                          <relation type="labelled-by" target="zoomcustom"/>
+                        </accessibility>
+                        <child internal-child="accessible">
+                          <object class="AtkObject" id="zoomvalue-atkobject">
+                            <property name="AtkObject::accessible-description" 
translatable="yes" context="extended_tip|zoomvalue">Enter the zoom factor at 
which you want to display the document. Enter a percentage in the 
box.</property>
+                          </object>
+                        </child>
+                      </object>
+                      <packing>
+                        <property name="left-attach">1</property>
+                        <property name="top-attach">6</property>
+                      </packing>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
+                    <child>
+                      <placeholder/>
+                    </child>
                   </object>
                 </child>
                 <child type="label">
-                  <object class="GtkLabel" id="outlinelabel">
+                  <object class="GtkLabel" id="zoomlabel">
                     <property name="visible">True</property>
                     <property name="can-focus">False</property>
-                    <property name="label" translatable="yes" 
context="viewoptionspage|outlinelabel">Outline Folding</property>
+                    <property name="label" translatable="yes" 
context="viewoptionspage|outlinelabel">Zoom</property>
                     <attributes>
                       <attribute name="weight" value="bold"/>
                     </attributes>
@@ -861,7 +1090,7 @@
               <packing>
                 <property name="expand">False</property>
                 <property name="fill">True</property>
-                <property name="position">2</property>
+                <property name="position">3</property>
               </packing>
             </child>
           </object>
commit b7a49b42d612e2bd65c38f5a3da4c67f7ceca20e
Author:     Balazs Varga <[email protected]>
AuthorDate: Tue Sep 17 14:32:20 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Sep 17 18:04:38 2024 +0200

    tdf#162988 - A11Y sidebar: fix hyperlinks false warning
    
    Better to check the SwpHints of the textnodes then iterate
    through on the xParagraph's xTextRanges to search for a11y
    hyperlink warnings.
    
    Change-Id: I19a3eddd53f122bd4290e5b93e4784b89f65427d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173563
    Reviewed-by: Thorsten Behrens <[email protected]>
    Tested-by: allotropia jenkins <[email protected]>

diff --git a/sw/qa/core/accessibilitycheck/data/HyperlinkTest.odt 
b/sw/qa/core/accessibilitycheck/data/HyperlinkTest.odt
index 1eba1932ce21..92240fb1d67f 100644
Binary files a/sw/qa/core/accessibilitycheck/data/HyperlinkTest.odt and 
b/sw/qa/core/accessibilitycheck/data/HyperlinkTest.odt differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx 
b/sw/source/core/access/AccessibilityCheck.cxx
index 83ff5de88ff1..96260cc19a95 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -370,42 +370,48 @@ public:
 class HyperlinkCheck : public NodeCheck
 {
 private:
-    void checkTextRange(uno::Reference<text::XTextRange> const& xTextRange, 
SwTextNode* pTextNode,
-                        sal_Int32 nStart)
+    void checkHyperLinks(SwTextNode* pTextNode)
     {
-        uno::Reference<beans::XPropertySet> xProperties(xTextRange, 
uno::UNO_QUERY);
-        if 
(!xProperties->getPropertySetInfo()->hasPropertyByName("HyperLinkURL"))
-            return;
-
-        OUString sHyperlink;
-        xProperties->getPropertyValue("HyperLinkURL") >>= sHyperlink;
-        if (!sHyperlink.isEmpty())
+        const OUString& sParagraphText = pTextNode->GetText();
+        SwpHints& rHints = pTextNode->GetSwpHints();
+        for (size_t i = 0; i < rHints.Count(); ++i)
         {
-            OUString sText = xTextRange->getString();
-            INetURLObject aHyperlink(sHyperlink);
-            std::shared_ptr<sw::AccessibilityIssue> pIssue;
-            if (aHyperlink.GetProtocol() != INetProtocol::NotValid
-                && INetURLObject(sText) == aHyperlink)
+            const SwTextAttr* pTextAttr = rHints.Get(i);
+            if (pTextAttr->Which() == RES_TXTATR_INETFMT)
             {
-                OUString sIssueText
-                    = 
SwResId(STR_HYPERLINK_TEXT_IS_LINK).replaceFirst("%LINK%", sHyperlink);
-                pIssue = lclAddIssue(m_rIssueCollection, sIssueText,
-                                     
sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT);
-            }
-            else if (sText.getLength() <= 5)
-            {
-                pIssue = lclAddIssue(m_rIssueCollection, 
SwResId(STR_HYPERLINK_TEXT_IS_SHORT),
-                                     
sfx::AccessibilityIssueID::HYPERLINK_SHORT);
-            }
+                OUString sHyperlink = pTextAttr->GetINetFormat().GetValue();
+                if (!sHyperlink.isEmpty())
+                {
+                    INetURLObject aHyperlink(sHyperlink);
+                    std::shared_ptr<sw::AccessibilityIssue> pIssue;
+                    sal_Int32 nStart = pTextAttr->GetStart();
+                    OUString sRunText = sParagraphText.copy(nStart, 
*pTextAttr->GetEnd() - nStart);
 
-            if (pIssue)
-            {
-                pIssue->setIssueObject(IssueObject::TEXT);
-                pIssue->setNode(pTextNode);
-                SwDoc& rDocument = pTextNode->GetDoc();
-                pIssue->setDoc(rDocument);
-                pIssue->setStart(nStart);
-                pIssue->setEnd(nStart + sText.getLength());
+                    if (aHyperlink.GetProtocol() != INetProtocol::NotValid
+                        && INetURLObject(sRunText) == aHyperlink)
+                    {
+                        OUString sIssueText = 
SwResId(STR_HYPERLINK_TEXT_IS_LINK)
+                                                  .replaceFirst("%LINK%", 
sHyperlink);
+                        pIssue = lclAddIssue(m_rIssueCollection, sIssueText,
+                                             
sfx::AccessibilityIssueID::HYPERLINK_IS_TEXT);
+                    }
+                    else if (sRunText.getLength() <= 5)
+                    {
+                        pIssue
+                            = lclAddIssue(m_rIssueCollection, 
SwResId(STR_HYPERLINK_TEXT_IS_SHORT),
+                                          
sfx::AccessibilityIssueID::HYPERLINK_SHORT);
+                    }
+
+                    if (pIssue)
+                    {
+                        pIssue->setIssueObject(IssueObject::TEXT);
+                        pIssue->setNode(pTextNode);
+                        SwDoc& rDocument = pTextNode->GetDoc();
+                        pIssue->setDoc(rDocument);
+                        pIssue->setStart(nStart);
+                        pIssue->setEnd(nStart + sRunText.getLength());
+                    }
+                }
             }
         }
     }
@@ -422,21 +428,9 @@ public:
             return;
 
         SwTextNode* pTextNode = pCurrent->GetTextNode();
-        rtl::Reference<SwXParagraph> xParagraph
-            = SwXParagraph::CreateXParagraph(pTextNode->GetDoc(), pTextNode, 
nullptr);
-        if (!xParagraph.is())
-            return;
-
-        uno::Reference<container::XEnumeration> xRunEnum = 
xParagraph->createEnumeration();
-        sal_Int32 nStart = 0;
-        while (xRunEnum->hasMoreElements())
+        if (pTextNode->HasHints())
         {
-            uno::Reference<text::XTextRange> xRun(xRunEnum->nextElement(), 
uno::UNO_QUERY);
-            if (xRun.is())
-            {
-                checkTextRange(xRun, pTextNode, nStart);
-                nStart += xRun->getString().getLength();
-            }
+            checkHyperLinks(pTextNode);
         }
     }
 };
commit 85d7d20444b0eee9a542846f06eff8813811e3a6
Author:     Balazs Varga <[email protected]>
AuthorDate: Fri Sep 13 10:24:38 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Sep 17 14:51:07 2024 +0200

    tdf#162890 - A11Y sidebar: fix unecceserry warning in case if we have
    
    no any direct format or we have a style which are not applied to the page.
    (In that case no need to show the warning since the 'goto' can lead us 
nowhere.)
    
    Also check the direct formats by comparing them to the character styles,
    paragraph styles or to the default character properties.
    
    Change-Id: I154379dc6deaa3af3fe17e51367cc229067216dd
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173317
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx 
b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
index 621a811def50..f45d4356be3b 100644
--- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -269,6 +269,24 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, 
testDeleteHeader)
     CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aResultIssues[2]->m_eIssueID);
 }
 
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testStylesWithHeader)
+{
+    // Check direct formats, char/para styles and not allowed page styles
+    createSwDoc("PageCharParaStyles.odt");
+    SwDoc* pDoc = getSwDoc();
+    CPPUNIT_ASSERT(pDoc);
+
+    sw::AccessibilityCheck aCheck(pDoc);
+    auto& aIssues = aCheck.getIssueCollection().getIssues();
+    aCheck.check();
+    CPPUNIT_ASSERT_EQUAL(size_t(5), aIssues.size());
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, 
aIssues[0]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[1]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[2]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[3]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[4]->m_eIssueID);
+}
+
 namespace
 {
 std::vector<std::shared_ptr<sfx::AccessibilityIssue>>
diff --git a/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt 
b/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt
new file mode 100644
index 000000000000..2f073a4a4afb
Binary files /dev/null and 
b/sw/qa/core/accessibilitycheck/data/PageCharParaStyles.odt differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx 
b/sw/source/core/access/AccessibilityCheck.cxx
index 362279f219ae..83ff5de88ff1 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -639,11 +639,22 @@ public:
     {
     }
 
-    void checkAutoFormat(SwTextNode* pTextNode, const SwTextAttr* pTextAttr)
+    void checkAutoFormat(SwTextNode* pTextNode, const SwTextAttr* pTextAttr,
+                         const std::map<sal_Int32, const SwTextAttr*>& 
rCharFormats)
     {
         const SwFormatAutoFormat& rAutoFormat = pTextAttr->GetAutoFormat();
         SfxItemIter aItemIter(*rAutoFormat.GetStyleHandle());
         const SfxPoolItem* pItem = aItemIter.GetCurItem();
+
+        const SwTextAttr* pCharAttr = nullptr;
+        auto itr = rCharFormats.find(pTextAttr->GetStart());
+        if (itr != rCharFormats.end())
+            pCharAttr = itr->second;
+
+        const SwCharFormat* pCharformat = nullptr;
+        if (pCharAttr && (*pTextAttr->GetEnd() == *pCharAttr->GetEnd()))
+            pCharformat = pCharAttr->GetCharFormat().GetCharFormat();
+
         std::vector<OUString> aFormattings;
         while (pItem)
         {
@@ -653,57 +664,367 @@ public:
                 case RES_CHRATR_WEIGHT:
                 case RES_CHRATR_CJK_WEIGHT:
                 case RES_CHRATR_CTL_WEIGHT:
-                    sFormattingType = "Weight";
-                    break;
+                {
+                    const SvxWeightItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                    {
+                        pStyleItem = pCharformat->GetItemIfSet(
+                            TypedWhichId<SvxWeightItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                            TypedWhichId<SvxWeightItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            TypedWhichId<SvxWeightItem>(pItem->Which()));
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxWeightItem*>(pItem), pStyleItem))
+                        sFormattingType = "Weight";
+                }
+                break;
+
                 case RES_CHRATR_POSTURE:
                 case RES_CHRATR_CJK_POSTURE:
                 case RES_CHRATR_CTL_POSTURE:
-                    sFormattingType = "Posture";
-                    break;
+                {
+                    const SvxPostureItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                    {
+                        pStyleItem = pCharformat->GetItemIfSet(
+                            TypedWhichId<SvxPostureItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                            TypedWhichId<SvxPostureItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            TypedWhichId<SvxPostureItem>(pItem->Which()));
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxPostureItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Posture";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_SHADOWED:
-                    sFormattingType = "Shadowed";
-                    break;
+                {
+                    const SvxShadowedItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_SHADOWED, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_SHADOWED, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_SHADOWED);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxShadowedItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Shadowed";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_COLOR:
-                    sFormattingType = "Font Color";
-                    break;
+                {
+                    const SvxColorItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_COLOR, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_COLOR, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_COLOR);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxColorItem*>(pItem), pStyleItem))
+                        sFormattingType = "Font Color";
+                }
+                break;
 
                 case RES_CHRATR_FONTSIZE:
-                case RES_CHRATR_CJK_FONTSIZE:
-                case RES_CHRATR_CTL_FONTSIZE:
-                    sFormattingType = "Font Size";
-                    break;
+                {
+                    // case RES_CHRATR_CJK_FONTSIZE:
+                    // case RES_CHRATR_CTL_FONTSIZE:
+                    // TODO: check depending on which lang is used Western, 
Complex, Asia
+                    const SvxFontHeightItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                    {
+                        pStyleItem = pCharformat->GetItemIfSet(
+                            TypedWhichId<SvxFontHeightItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                            TypedWhichId<SvxFontHeightItem>(pItem->Which()), 
false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            TypedWhichId<SvxFontHeightItem>(pItem->Which()));
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxFontHeightItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Font Size";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_FONT:
                 case RES_CHRATR_CJK_FONT:
                 case RES_CHRATR_CTL_FONT:
-                    sFormattingType = "Font";
-                    break;
+                {
+                    // 3. direct formatting
+                    const SvxFontItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                    {
+                        pStyleItem = pCharformat->GetItemIfSet(
+                            TypedWhichId<SvxFontItem>(pItem->Which()), false);
+                    }
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                            TypedWhichId<SvxFontItem>(pItem->Which()), false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            TypedWhichId<SvxFontItem>(pItem->Which()));
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxFontItem*>(pItem), pStyleItem))
+                        sFormattingType = "Font";
+                }
+                break;
 
                 case RES_CHRATR_EMPHASIS_MARK:
-                    sFormattingType = "Emphasis Mark";
-                    break;
+                {
+                    const SvxEmphasisMarkItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_EMPHASIS_MARK, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                            RES_CHRATR_EMPHASIS_MARK, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_EMPHASIS_MARK);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxEmphasisMarkItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Emphasis Mark";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_UNDERLINE:
-                    sFormattingType = "Underline";
-                    break;
+                {
+                    const SvxUnderlineItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_UNDERLINE, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_UNDERLINE, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_UNDERLINE);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxUnderlineItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Underline";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_OVERLINE:
-                    sFormattingType = "Overline";
-                    break;
+                {
+                    const SvxOverlineItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_OVERLINE, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_OVERLINE, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_OVERLINE);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxOverlineItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Overline";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_CROSSEDOUT:
-                    sFormattingType = "Strikethrough";
-                    break;
+                {
+                    const SvxCrossedOutItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_CROSSEDOUT);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxCrossedOutItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Strikethrough";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_RELIEF:
-                    sFormattingType = "Relief";
-                    break;
+                {
+                    const SvxCharReliefItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_RELIEF, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_RELIEF, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_RELIEF);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxCharReliefItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Relief";
+                    }
+                }
+                break;
 
                 case RES_CHRATR_CONTOUR:
-                    sFormattingType = "Outline";
-                    break;
+                {
+                    const SvxContourItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_CONTOUR, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CONTOUR, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_CONTOUR);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxContourItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "Outline";
+                    }
+                }
+                break;
+
+                case RES_CHRATR_NOHYPHEN:
+                {
+                    const SvxNoHyphenItem* pStyleItem = nullptr;
+
+                    if (pCharformat)
+                        pStyleItem = 
pCharformat->GetItemIfSet(RES_CHRATR_NOHYPHEN, false);
+
+                    if (!pStyleItem && pTextNode->GetTextColl())
+                    {
+                        pStyleItem
+                            = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_NOHYPHEN, false);
+                    }
+
+                    if (!pStyleItem)
+                    {
+                        pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                            RES_CHRATR_NOHYPHEN);
+                    }
+
+                    if (!SfxPoolItem::areSame(static_cast<const 
SvxNoHyphenItem*>(pItem),
+                                              pStyleItem))
+                    {
+                        sFormattingType = "No Hyphenation";
+                    }
+                }
+                break;
+
                 default:
                     break;
             }
@@ -725,45 +1046,328 @@ public:
         pIssue->setEnd(pTextAttr->GetAnyEnd());
     }
 
+    static bool isDirectFormat(const SwTextNode* pTextNode, const SwAttrSet& 
rSwAttrSet)
+    {
+        const SfxPoolItem* pItem = nullptr;
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_WEIGHT, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_WEIGHT, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_WEIGHT, false)))
+        {
+            // 3. direct formatting
+            const SvxWeightItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+            {
+                // 1. paragraph format
+                pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                    TypedWhichId<SvxWeightItem>(pItem->Which()), false);
+            }
+
+            if (!pStyleItem)
+            {
+                // 0. document default
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                    TypedWhichId<SvxWeightItem>(pItem->Which()));
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxWeightItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_POSTURE, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_POSTURE, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_POSTURE, false)))
+        {
+            const SvxPostureItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+            {
+                pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                    TypedWhichId<SvxPostureItem>(pItem->Which()), false);
+            }
+
+            if (!pStyleItem)
+            {
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                    TypedWhichId<SvxPostureItem>(pItem->Which()));
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxPostureItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_SHADOWED, false)))
+        {
+            const SvxShadowedItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_SHADOWED, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_SHADOWED);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxShadowedItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_COLOR, false)))
+        {
+            const SvxColorItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_COLOR, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_COLOR);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const SvxColorItem*>(pItem), 
pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        // TODO: check depending on which lang is used Western, Complex, Asia
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_FONTSIZE, false))
+            /*|| (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_FONTSIZE, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_FONTSIZE, false))*/)
+        {
+            const SvxFontHeightItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+            {
+                pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                    TypedWhichId<SvxFontHeightItem>(pItem->Which()), false);
+            }
+
+            if (!pStyleItem)
+            {
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                    TypedWhichId<SvxFontHeightItem>(pItem->Which()));
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxFontHeightItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_FONT, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CJK_FONT, false))
+            || (pItem = rSwAttrSet.GetItem(RES_CHRATR_CTL_FONT, false)))
+        {
+            const SvxFontItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+            {
+                pStyleItem = pTextNode->GetTextColl()->GetItemIfSet(
+                    TypedWhichId<SvxFontItem>(pItem->Which()), false);
+            }
+
+            if (!pStyleItem)
+            {
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                    TypedWhichId<SvxFontItem>(pItem->Which()));
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const SvxFontItem*>(pItem), 
pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_EMPHASIS_MARK, false)))
+        {
+            const SvxEmphasisMarkItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+            {
+                pStyleItem
+                    = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_EMPHASIS_MARK, false);
+            }
+
+            if (!pStyleItem)
+            {
+                pStyleItem = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(
+                    RES_CHRATR_EMPHASIS_MARK);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxEmphasisMarkItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_UNDERLINE, false)))
+        {
+            const SvxUnderlineItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_UNDERLINE, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_UNDERLINE);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxUnderlineItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_OVERLINE, false)))
+        {
+            const SvxOverlineItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_OVERLINE, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_OVERLINE);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxOverlineItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_CROSSEDOUT, false)))
+        {
+            const SvxCrossedOutItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CROSSEDOUT, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_CROSSEDOUT);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxCrossedOutItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_RELIEF, false)))
+        {
+            const SvxCharReliefItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_RELIEF, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_RELIEF);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxCharReliefItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_NOHYPHEN, false)))
+        {
+            const SvxNoHyphenItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_NOHYPHEN, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_NOHYPHEN);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxNoHyphenItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        if ((pItem = rSwAttrSet.GetItem(RES_CHRATR_CONTOUR, false)))
+        {
+            const SvxContourItem* pStyleItem = nullptr;
+
+            if (pTextNode->GetTextColl())
+                pStyleItem = 
pTextNode->GetTextColl()->GetItemIfSet(RES_CHRATR_CONTOUR, false);
+
+            if (!pStyleItem)
+            {
+                pStyleItem
+                    = 
pTextNode->GetDoc().GetAttrPool().GetPoolDefaultItem(RES_CHRATR_CONTOUR);
+            }
+
+            if (!SfxPoolItem::areSame(static_cast<const 
SvxContourItem*>(pItem), pStyleItem))
+                return true;
+            else
+                pItem = nullptr;
+        }
+
+        return false;
+    }
+
     void check(SwNode* pCurrent) override
     {
         if (!pCurrent->IsTextNode())
             return;
 
         SwTextNode* pTextNode = pCurrent->GetTextNode();
+        SwWrtShell* pWrtShell = 
pTextNode->GetDoc().GetDocShell()->GetWrtShell();
+        if (pWrtShell && !pTextNode->getLayoutFrame(pWrtShell->GetLayout()))
+            return;
+
         if (pTextNode->HasHints())
         {
+            // collect character style formats (if have)
             SwpHints& rHints = pTextNode->GetSwpHints();
+            std::map<sal_Int32, const SwTextAttr*> aCharFormats;
+            for (size_t i = 0; i < rHints.Count(); ++i)
+            {
+                const SwTextAttr* pTextAttr = rHints.Get(i);
+
+                if (pTextAttr->Which() == RES_TXTATR_CHARFMT)
+                {
+                    aCharFormats.insert({ pTextAttr->GetStart(), pTextAttr });
+                }
+            }
+
+            // direct formatting
             for (size_t i = 0; i < rHints.Count(); ++i)
             {
                 const SwTextAttr* pTextAttr = rHints.Get(i);
                 if (pTextAttr->Which() == RES_TXTATR_AUTOFMT)
                 {
-                    checkAutoFormat(pTextNode, pTextAttr);
+                    checkAutoFormat(pTextNode, pTextAttr, aCharFormats);
                 }
             }
         }
-        else if (pTextNode->HasSwAttrSet())
+        if (pTextNode->HasSwAttrSet())
         {
             // Paragraph doesn't have hints but the entire paragraph might 
have char attributes
-            auto& aSwAttrSet = pTextNode->GetSwAttrSet();
             auto nParagraphLength = pTextNode->GetText().getLength();
             if (nParagraphLength == 0)
                 return;
-            if (aSwAttrSet.GetItem(RES_CHRATR_WEIGHT, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CJK_WEIGHT, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CTL_WEIGHT, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_POSTURE, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CJK_POSTURE, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CTL_POSTURE, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_SHADOWED, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_COLOR, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_EMPHASIS_MARK, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_UNDERLINE, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_OVERLINE, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CROSSEDOUT, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_RELIEF, false)
-                || aSwAttrSet.GetItem(RES_CHRATR_CONTOUR, false))
+
+            if (isDirectFormat(pTextNode, pTextNode->GetSwAttrSet()))
             {
                 auto pIssue
                     = lclAddIssue(m_rIssueCollection, 
SwResId(STR_TEXT_FORMATTING_CONVEYS_MEANING),
commit 8da940e0be4c6da5633b34ea70ba13f3ac048aa0
Author:     Balazs Varga <[email protected]>
AuthorDate: Wed Sep 11 15:56:36 2024 +0200
Commit:     Thorsten Behrens <[email protected]>
CommitDate: Tue Sep 17 12:08:55 2024 +0200

    tdf#162889 - A11Y sidebar: fix warning does not disappear when
    
    page header is deleted. Check if nodes have contentframe.
    
    Change-Id: Ie7f79cedb577b856d518d23326e9d7ceba2b825c
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173215
    Reviewed-by: Michael Stahl <[email protected]>
    Tested-by: Gabor Kelemen <[email protected]>
    Reviewed-by: Balazs Varga <[email protected]>
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/173511
    Tested-by: allotropia jenkins <[email protected]>
    Reviewed-by: Thorsten Behrens <[email protected]>

diff --git a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx 
b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
index bfe2e08d8543..621a811def50 100644
--- a/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
+++ b/sw/qa/core/accessibilitycheck/AccessibilityCheckTest.cxx
@@ -229,6 +229,46 @@ CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, 
testCheckTOCHyperlink)
     CPPUNIT_ASSERT_EQUAL(size_t(0), aIssues.size());
 }
 
+CPPUNIT_TEST_FIXTURE(AccessibilityCheckTest, testDeleteHeader)
+{
+    // Delete Header from doc and check if we have less Direct format warning
+    createSwDoc("DeleteHeader.odt");
+    SwDoc* pDoc = getSwDoc();
+    CPPUNIT_ASSERT(pDoc);
+
+    sw::AccessibilityCheck aCheck(pDoc);
+    auto& aIssues = aCheck.getIssueCollection().getIssues();
+    aCheck.check();
+    CPPUNIT_ASSERT_EQUAL(size_t(8), aIssues.size());
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, 
aIssues[0]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[1]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[2]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[3]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[4]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[5]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[6]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aIssues[7]->m_eIssueID);
+
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    CPPUNIT_ASSERT(pWrtShell);
+
+    // modify header
+    pWrtShell->ChangeHeaderOrFooter(u"Default Page Style", true, false, false);
+    pWrtShell->GetWin()->GrabFocusToDocument();
+
+    // re-check A11Y issues
+    sw::AccessibilityCheck aReCheck(pDoc);
+    auto& aResultIssues = aReCheck.getIssueCollection().getIssues();
+    aReCheck.check();
+
+    // Check the result
+    aResultIssues = aReCheck.getIssueCollection().getIssues();
+    CPPUNIT_ASSERT_EQUAL(size_t(3), aResultIssues.size());
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::DOCUMENT_TITLE, 
aResultIssues[0]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aResultIssues[1]->m_eIssueID);
+    CPPUNIT_ASSERT_EQUAL(sfx::AccessibilityIssueID::TEXT_FORMATTING, 
aResultIssues[2]->m_eIssueID);
+}
+
 namespace
 {
 std::vector<std::shared_ptr<sfx::AccessibilityIssue>>
diff --git a/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt 
b/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt
new file mode 100644
index 000000000000..6503699c132b
Binary files /dev/null and 
b/sw/qa/core/accessibilitycheck/data/DeleteHeader.odt differ
diff --git a/sw/source/core/access/AccessibilityCheck.cxx 
b/sw/source/core/access/AccessibilityCheck.cxx
index dfa94c3ed9ab..362279f219ae 100644
--- a/sw/source/core/access/AccessibilityCheck.cxx
+++ b/sw/source/core/access/AccessibilityCheck.cxx
@@ -15,6 +15,7 @@
 #include <ndnotxt.hxx>
 #include <ndtxt.hxx>
 #include <docsh.hxx>
+#include <wrtsh.hxx>
 #include <IDocumentDrawModelAccess.hxx>
 #include <drawdoc.hxx>
 #include <svx/svdpage.hxx>
@@ -814,52 +815,60 @@ public:
             return;
 
         SwTextNode* pTextNode = pCurrent->GetTextNode();
+        SwDoc& rDocument = pTextNode->GetDoc();
         auto nParagraphLength = pTextNode->GetText().getLength();
         if (nParagraphLength == 0)
         {
             SwTextNode* pPrevTextNode = getPrevTextNode(pCurrent);
             if (!pPrevTextNode)
                 return;
-            if (pPrevTextNode->GetText().getLength() == 0)
+
+            SwWrtShell* pWrtShell = rDocument.GetDocShell()->GetWrtShell();
+            if (pWrtShell && 
pPrevTextNode->getLayoutFrame(pWrtShell->GetLayout()))
             {
-                auto pIssue = lclAddIssue(m_rIssueCollection, 
SwResId(STR_AVOID_NEWLINES_SPACE),
-                                          
sfx::AccessibilityIssueID::TEXT_FORMATTING);
-                pIssue->setIssueObject(IssueObject::TEXT);
-                pIssue->setNode(pTextNode);
-                SwDoc& rDocument = pTextNode->GetDoc();
-                pIssue->setDoc(rDocument);
+                if (pPrevTextNode->GetText().getLength() == 0)
+                {
+                    auto pIssue = lclAddIssue(m_rIssueCollection, 
SwResId(STR_AVOID_NEWLINES_SPACE),
+                                              
sfx::AccessibilityIssueID::TEXT_FORMATTING);
+                    pIssue->setIssueObject(IssueObject::TEXT);
+                    pIssue->setNode(pTextNode);
+                    pIssue->setDoc(rDocument);
+                }
             }
         }
         else
         {
-            // Check for excess lines inside this paragraph
-            const OUString& sParagraphText = pTextNode->GetText();
-            int nLineCount = 0;
-            for (sal_Int32 i = 0; i < nParagraphLength; i++)
+            SwWrtShell* pWrtShell = rDocument.GetDocShell()->GetWrtShell();
+            if (pWrtShell && pTextNode->getLayoutFrame(pWrtShell->GetLayout()))
             {
-                auto aChar = sParagraphText[i];
-                if (aChar == '
')
+                // Check for excess lines inside this paragraph
-e 
... etc. - the rest is truncated

Reply via email to