officecfg/registry/schema/org/openoffice/Office/Writer.xcs |   53 ++
 sw/qa/uitest/options/optionsDialog.py                      |   30 +
 sw/source/ui/config/optpage.cxx                            |   95 ++++
 sw/source/uibase/app/appopt.cxx                            |   12 
 sw/source/uibase/config/cfgitems.cxx                       |   14 
 sw/source/uibase/config/usrpref.cxx                        |   38 +
 sw/source/uibase/inc/cfgitems.hxx                          |   13 
 sw/source/uibase/inc/optpage.hxx                           |   12 
 sw/source/uibase/inc/usrpref.hxx                           |   28 +
 sw/source/uibase/uiview/view.cxx                           |   10 
 sw/uiconfig/swriter/ui/viewoptionspage.ui                  |  293 +++++++++++--
 11 files changed, 558 insertions(+), 40 deletions(-)

New commits:
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>

Reply via email to