include/svx/hdft.hxx | 1 sc/qa/uitest/calc_tests8/tdf144940.py | 6 ++-- svx/source/dialog/hdft.cxx | 50 +++++++++++++++++++++++++--------- 3 files changed, 41 insertions(+), 16 deletions(-)
New commits: commit 11cd6b2fbc86e28506d5b26a436df1b4b2b5bf09 Author: Justin Luth <[email protected]> AuthorDate: Thu Sep 4 11:11:42 2025 -0400 Commit: Justin Luth <[email protected]> CommitDate: Sat Sep 6 03:31:33 2025 +0200 tdf#100287 svx dialog: sync "first header" with "first footer" When either the header OR the footer wants different first content, then (by design) the application applies it to both of them. (True for Writer only - not true for Calc!!!) It is also important (for the user experience) that either one is able to stop using first content altogether (for Writer only). This was already working to some extent, but the user experience was not consistent or predictable. Specifically, the improvements with this patch: -provide an appropriate "default" value when turning on a H/F. -always visually match the most recent "first content" choice. -in Calc, simply visiting the H/F no longer turns on first page. The prior situation was very "fickle", and "first content" could be affected without the user even touching that box (for both Writer and Calc). The underlying reason this patch can work is because of SvxHFPage::SvxHFPage SetExchangeSupport(). That causes SfxTabDialogController::DeactivatePage to update the m_xExampleSet which is then passed to SvxHFPage::ActivatePage. Thus the active tab knows about all the dialog's current settings. Since Reset() calls ActivatePage, it was safe to move the initialization out of Reset. make -srj1 UITest_calc_tests8 \ UITEST_TEST_NAME=tdf144940.tdf144940.test_tdf144940 \ SAL_USE_VCLPLUGIN=gen Change-Id: Icd6084ca50d244317c807266f04c85dadbba2bb1 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/190606 Tested-by: Jenkins Reviewed-by: Justin Luth <[email protected]> diff --git a/include/svx/hdft.hxx b/include/svx/hdft.hxx index ec69102f1a91..53d402a0fee5 100644 --- a/include/svx/hdft.hxx +++ b/include/svx/hdft.hxx @@ -90,6 +90,7 @@ protected: private: SVX_DLLPRIVATE void ResetBackground_Impl( const SfxItemSet& rSet ); + bool m_bIsCalc; }; class SVX_DLLPUBLIC SvxHeaderPage final : public SvxHFPage diff --git a/sc/qa/uitest/calc_tests8/tdf144940.py b/sc/qa/uitest/calc_tests8/tdf144940.py index 9e577bf72815..f2628588ac7b 100644 --- a/sc/qa/uitest/calc_tests8/tdf144940.py +++ b/sc/qa/uitest/calc_tests8/tdf144940.py @@ -34,11 +34,11 @@ class tdf144940(UITestCase): self.assertEqual("true", get_state_as_dict(xCheckHeaderOn)["Selected"]) self.assertEqual("true", get_state_as_dict(xCheckSameLR)["Selected"]) - self.assertEqual("false", get_state_as_dict(xCheckSameFP)["Selected"]) + self.assertEqual("true", get_state_as_dict(xCheckSameFP)["Selected"]) xCheckSameFP.executeAction("CLICK", tuple()) - self.assertEqual("true", get_state_as_dict(xCheckSameFP)["Selected"]) + self.assertEqual("false", get_state_as_dict(xCheckSameFP)["Selected"]) with self.ui_test.execute_dialog_through_command(".uno:Save", close_button="open") as xSaveDialog: xFileName = xSaveDialog.getChild("file_name") @@ -55,7 +55,7 @@ class tdf144940(UITestCase): # AssertionError: False is not true self.assertTrue(xDefaultPageStyle.HeaderOn) self.assertTrue(xDefaultPageStyle.FooterOn) - self.assertTrue(xDefaultPageStyle.FirstPageHeaderIsShared) + self.assertFalse(xDefaultPageStyle.FirstPageHeaderIsShared) self.assertTrue(xDefaultPageStyle.FirstPageFooterIsShared) # vim: set shiftwidth=4 softtabstop=4 expandtab: diff --git a/svx/source/dialog/hdft.cxx b/svx/source/dialog/hdft.cxx index d66e22276981..b7dfb6b2cc6b 100644 --- a/svx/source/dialog/hdft.cxx +++ b/svx/source/dialog/hdft.cxx @@ -143,6 +143,10 @@ SvxHFPage::SvxHFPage(weld::Container* pPage, weld::DialogController* pController , m_xFrame(m_xBuilder->weld_frame(u"frame1"_ustr)) , m_xBspWin(new weld::CustomWeld(*m_xBuilder, u"drawingareaPageHF"_ustr, m_aBspWin)) { + const SfxPoolItem* pExt1 = GetItem(rSet, SID_ATTR_PAGE_EXT1); + const SfxPoolItem* pExt2 = GetItem(rSet, SID_ATTR_PAGE_EXT2); + m_bIsCalc = dynamic_cast<const SfxBoolItem*>(pExt1) && dynamic_cast<const SfxBoolItem*>(pExt2); + //swap header <-> footer in UI if (nId == SID_ATTR_PAGE_FOOTERSET) { @@ -349,9 +353,6 @@ void SvxHFPage::Reset( const SfxItemSet* rSet ) rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_DYNAMIC ) ); const SfxBoolItem& rShared = rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SHARED ) ); - const SfxBoolItem* pSharedFirst = nullptr; - if (rHeaderSet.HasItem(GetWhich(SID_ATTR_PAGE_SHARED_FIRST))) - pSharedFirst = static_cast<const SfxBoolItem*>(&rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SHARED_FIRST ) )); const SvxSizeItem& rSize = rHeaderSet.Get( GetWhich( SID_ATTR_PAGE_SIZE ) ); const SvxULSpaceItem& rUL = rHeaderSet.Get( GetWhich( SID_ATTR_ULSPACE ) ); @@ -379,22 +380,14 @@ void SvxHFPage::Reset( const SfxItemSet* rSet ) SetMetricValue(*m_xLMEdit, rLR.ResolveLeft({}), eUnit); SetMetricValue(*m_xRMEdit, rLR.ResolveRight({}), eUnit); m_xCntSharedBox->set_active(rShared.GetValue()); - if (pSharedFirst) - m_xCntSharedFirstBox->set_active(pSharedFirst->GetValue()); } else pSetItem = nullptr; } else { - bool bIsCalc = false; - const SfxPoolItem* pExt1 = GetItem(*rSet, SID_ATTR_PAGE_EXT1); - const SfxPoolItem* pExt2 = GetItem(*rSet, SID_ATTR_PAGE_EXT2); - if (dynamic_cast<const SfxBoolItem*>(pExt1) && dynamic_cast<const SfxBoolItem*>(pExt2) ) - bIsCalc = true; - // defaults for distance and height - tools::Long nDefaultDist = bIsCalc ? DEF_DIST_CALC : DEF_DIST_WRITER; + tools::Long nDefaultDist = m_bIsCalc ? DEF_DIST_CALC : DEF_DIST_WRITER; SetMetricValue( *m_xDistEdit, nDefaultDist, MapUnit::Map100thMM ); SetMetricValue( *m_xHeightEdit, 500, MapUnit::Map100thMM ); } @@ -404,7 +397,6 @@ void SvxHFPage::Reset( const SfxItemSet* rSet ) m_xTurnOnBox->set_active(false); m_xHeightDynBtn->set_active(true); m_xCntSharedBox->set_active(true); - m_xCntSharedFirstBox->set_active(true); } TurnOn(nullptr); @@ -848,6 +840,12 @@ void SvxHFPage::ActivatePage( const SfxItemSet& rSet ) m_aBspWin.SetSize( rSize.GetSize() ); } + // For Writer, either header OR footer can indicate that first H/F will have different contents. + // Prioritize the non-activated tab's setting (in case the value was already changed there). + std::optional<bool> oNonActivatedFirstShared; // only used by Writer + bool bActivatedFirstShared = true; // default value + const sal_uInt16 nSidAttrPageSharedFirst = GetWhich(SID_ATTR_PAGE_SHARED_FIRST); + // Evaluate Header attribute const SvxSetItem* pSetItem = nullptr; @@ -872,6 +870,17 @@ void SvxHFPage::ActivatePage( const SfxItemSet& rSet ) m_aBspWin.SetHdLeft(rLR.ResolveLeft({})); m_aBspWin.SetHdRight(rLR.ResolveRight({})); m_aBspWin.SetHeader( true ); + const SfxBoolItem* pSharedFirst = nullptr; + if (rHeaderSet.HasItem(nSidAttrPageSharedFirst)) + pSharedFirst + = static_cast<const SfxBoolItem*>(&rHeaderSet.Get(nSidAttrPageSharedFirst)); + if (pSharedFirst) + { + if (SID_ATTR_PAGE_HEADERSET == nId || m_bIsCalc) + bActivatedFirstShared = pSharedFirst->GetValue(); + else + oNonActivatedFirstShared = pSharedFirst->GetValue(); + } } else pSetItem = nullptr; @@ -910,6 +919,17 @@ void SvxHFPage::ActivatePage( const SfxItemSet& rSet ) m_aBspWin.SetFtLeft(rLR.ResolveLeft({})); m_aBspWin.SetFtRight(rLR.ResolveRight({})); m_aBspWin.SetFooter( true ); + const SfxBoolItem* pSharedFirst = nullptr; + if (rFooterSet.HasItem(nSidAttrPageSharedFirst)) + pSharedFirst + = static_cast<const SfxBoolItem*>(&rFooterSet.Get(nSidAttrPageSharedFirst)); + if (pSharedFirst) + { + if (SID_ATTR_PAGE_FOOTERSET == nId || m_bIsCalc) + bActivatedFirstShared = pSharedFirst->GetValue(); + else + oNonActivatedFirstShared = pSharedFirst->GetValue(); + } } else pSetItem = nullptr; @@ -926,6 +946,10 @@ void SvxHFPage::ActivatePage( const SfxItemSet& rSet ) } } + // Priority: non-active tab's FirstBox - then this tab's First - otherwise default is shared + m_xCntSharedFirstBox->set_active( + oNonActivatedFirstShared.has_value() ? *oNonActivatedFirstShared : bActivatedFirstShared); + pItem = GetItem( rSet, SID_ATTR_PAGE_EXT1 ); if ( auto pBoolItem = dynamic_cast<const SfxBoolItem*>( pItem) )
