sw/Module_sw.mk                       |    1 
 sw/UITest_sw_ui_frmdlg.mk             |   16 +++++++++
 sw/qa/uitest/ui/frmdlg/frmdlg.py      |   48 +++++++++++++++++++++++++++++
 sw/source/ui/frmdlg/frmpage.cxx       |   56 ++++++++++++++++++++++++++++++++++
 sw/source/uibase/inc/frmpage.hxx      |    1 
 sw/uiconfig/swriter/ui/frmtypepage.ui |   18 ++++++++++
 6 files changed, 139 insertions(+), 1 deletion(-)

New commits:
commit e32dfaf15563372ffae6e0da53998e20068ebf81
Author:     Miklos Vajna <[email protected]>
AuthorDate: Wed Mar 1 09:22:16 2023 +0100
Commit:     Miklos Vajna <[email protected]>
CommitDate: Wed Mar 1 09:52:53 2023 +0000

    sw floattable: teach the UI about SwFormatFlySplit
    
    - in SwFramePage, add a new m_xFlySplitCB and bind it to the flysplit
      from the UI description
    
    - map RES_FLY_SPLIT from the doc model to this new weld::CheckButton
    
    - disable the widget for anchor types other than to-para, also
      completely hide it, unless a frame contains a single table, which
      simplifies Word filters
    
    - add UITest for this
    
    Change-Id: I9ef44b5c66679b04c4818dc343870b92f1b6386d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/148030
    Reviewed-by: Miklos Vajna <[email protected]>
    Tested-by: Jenkins

diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index 2b99d0bff22a..5babd8264e03 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -216,6 +216,7 @@ $(eval $(call gb_Module_add_uicheck_targets,sw,\
        UITest_sw_sidebar \
        UITest_sw_styleInspector \
        UITest_sw_ui_fmtui \
+       UITest_sw_ui_frmdlg \
        UITest_sw_ui_index \
        UITest_sw_ui_misc \
        UITest_sw_uibase_docvw \
diff --git a/sw/UITest_sw_ui_frmdlg.mk b/sw/UITest_sw_ui_frmdlg.mk
new file mode 100644
index 000000000000..9f3c05c4dc42
--- /dev/null
+++ b/sw/UITest_sw_ui_frmdlg.mk
@@ -0,0 +1,16 @@
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+$(eval $(call  gb_UITest_UITest,sw_ui_frmdlg))
+
+$(eval $(call gb_UITest_add_modules,sw_ui_frmdlg,$(SRCDIR)/sw/qa/uitest,\
+       ui/frmdlg/ \
+))
+
+$(eval $(call gb_UITest_set_defs,sw_ui_frmdlg, \
+    TDOC="$(SRCDIR)/sw/qa/uitest/data" \
+))
diff --git a/sw/qa/uitest/ui/frmdlg/frmdlg.py b/sw/qa/uitest/ui/frmdlg/frmdlg.py
new file mode 100644
index 000000000000..cfa2dd8ba954
--- /dev/null
+++ b/sw/qa/uitest/ui/frmdlg/frmdlg.py
@@ -0,0 +1,48 @@
+# -*- tab-width: 4; indent-tabs-mode: nil; py-indent-offset: 4 -*-
+#
+# This file is part of the LibreOffice project.
+#
+# This Source Code Form is subject to the terms of the Mozilla Public
+# License, v. 2.0. If a copy of the MPL was not distributed with this
+# file, You can obtain one at http://mozilla.org/MPL/2.0/.
+#
+
+"""Covers sw/source/ui/frmdlg/ fixes."""
+
+import time
+from libreoffice.uno.propertyvalue import mkPropertyValues
+from uitest.framework import UITestCase
+from uitest.uihelper.common import get_state_as_dict
+
+
+class Test(UITestCase):
+    def test_content_control_dialog(self):
+        with self.ui_test.create_doc_in_start_center("writer") as xComponent:
+            # Given a document with a floating table:
+            args = {
+                "Columns": 1,
+                "Rows": 1,
+            }
+            self.xUITest.executeCommandWithParameters(".uno:InsertTable", 
mkPropertyValues(args))
+            self.xUITest.executeCommand(".uno:SelectAll")
+            args = {
+                "AnchorType": 0,
+            }
+            self.xUITest.executeCommandWithParameters(".uno:InsertFrame", 
mkPropertyValues(args))
+            # Wait until SwTextShell is replaced with SwDrawShell after 120 
ms, as set in the SwView
+            # ctor.
+            time.sleep(0.2)
+            self.assertEqual(xComponent.TextFrames.Frame1.IsSplitAllowed, 
False)
+
+            # When allowing it to split on the UI:
+            with 
self.ui_test.execute_dialog_through_command(".uno:FrameDialog") as xDialog:
+                xFlysplit = xDialog.getChild("flysplit")
+                self.assertEqual(get_state_as_dict(xFlysplit)['Visible'], 
"true")
+                self.assertEqual(get_state_as_dict(xFlysplit)['Selected'], 
"false")
+                xFlysplit.executeAction("CLICK", tuple())
+
+            # Then make sure the doc model is updated correctly:
+            self.assertEqual(xComponent.TextFrames.Frame1.IsSplitAllowed, True)
+
+
+# vim: set shiftwidth=4 softtabstop=4 expandtab:
diff --git a/sw/source/ui/frmdlg/frmpage.cxx b/sw/source/ui/frmdlg/frmpage.cxx
index 8dff4cd41e59..e9cf9974d0ed 100644
--- a/sw/source/ui/frmdlg/frmpage.cxx
+++ b/sw/source/ui/frmdlg/frmpage.cxx
@@ -61,6 +61,8 @@
 #include <osl/diagnose.h>
 
 #include <strings.hrc>
+#include <formatflysplit.hxx>
+#include <fmtcntnt.hxx>
 #include <svx/strings.hrc>
 #include <svx/dialmgr.hxx>
 #include <svx/graphichelper.hxx>
@@ -673,6 +675,7 @@ SwFramePage::SwFramePage(weld::Container* pPage, 
weld::DialogController* pContro
     , m_xVertRelationFT(m_xBuilder->weld_label("verttoft"))
     , m_xVertRelationLB(m_xBuilder->weld_combo_box("vertanchor"))
     , m_xFollowTextFlowCB(m_xBuilder->weld_check_button("followtextflow"))
+    , m_xFlySplitCB(m_xBuilder->weld_check_button("flysplit"))
     , m_xExampleWN(new weld::CustomWeld(*m_xBuilder, "preview", m_aExampleWN))
     , m_xWidthED(new 
SwPercentField(m_xBuilder->weld_metric_spin_button("width", FieldUnit::CM)))
     , m_xHeightED(new 
SwPercentField(m_xBuilder->weld_metric_spin_button("height", FieldUnit::CM)))
@@ -793,6 +796,40 @@ namespace
         RelationMap const * pMap;
         size_t nCount;
     };
+
+/// Checks if the current fly frame contains exactly one table.
+bool ContainsSingleTable(SwWrtShell* pWrtShell)
+{
+    const SwFrameFormat* pFlyFormat = pWrtShell->GetFlyFrameFormat();
+    if (!pFlyFormat)
+    {
+        return false;
+    }
+
+    const SwNodeIndex* pStartNode = pFlyFormat->GetContent().GetContentIdx();
+    if (!pStartNode)
+    {
+        return false;
+    }
+
+    // Check if the frame content starts with a table.
+    SwNodeIndex aNodeIndex(*pStartNode);
+    ++aNodeIndex;
+    if (!aNodeIndex.GetNode().IsTableNode())
+    {
+        return false;
+    }
+
+    // Check if the frame content ends with the same table.
+    SwNodeIndex aEndIndex(*aNodeIndex.GetNode().EndOfSectionNode());
+    ++aEndIndex;
+    if (&aEndIndex.GetNode() != pStartNode->GetNode().EndOfSectionNode())
+    {
+        return false;
+    }
+
+    return true;
+}
 }
 
 void SwFramePage::setOptimalRelWidth()
@@ -981,6 +1018,10 @@ void SwFramePage::Reset( const SfxItemSet *rSet )
             rSet->Get(RES_FOLLOW_TEXT_FLOW).GetValue();
         m_xFollowTextFlowCB->set_active(bFollowTextFlow);
     }
+    {
+        const bool bFlySplit = rSet->Get(RES_FLY_SPLIT).GetValue();
+        m_xFlySplitCB->set_active(bFlySplit);
+    }
 
     if(m_bHtmlMode)
     {
@@ -1003,12 +1044,21 @@ void SwFramePage::Reset( const SfxItemSet *rSet )
         m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
                                            m_xAnchorAtCharRB->get_active() ||
                                            m_xAnchorAtFrameRB->get_active());
+        m_xFlySplitCB->set_sensitive(m_xAnchorAtParaRB->get_active());
+    }
+
+    if (!ContainsSingleTable(pSh))
+    {
+        // Only allow fly split if the frame contains a single table, 
otherwise it would be hard the
+        // resulting model to Word formats.
+        m_xFlySplitCB->hide();
     }
 
     Init(*rSet);
     m_xAtVertPosED->save_value();
     m_xAtHorzPosED->save_value();
     m_xFollowTextFlowCB->save_state();
+    m_xFlySplitCB->save_state();
 
     m_xWidthED->save_value();
     m_xHeightED->save_value();
@@ -1227,6 +1277,10 @@ bool SwFramePage::FillItemSet(SfxItemSet *rSet)
     {
         bRet |= nullptr != 
rSet->Put(SwFormatFollowTextFlow(m_xFollowTextFlowCB->get_active()));
     }
+    if (m_xFlySplitCB->get_state_changed_from_saved())
+    {
+        bRet |= rSet->Put(SwFormatFlySplit(m_xFlySplitCB->get_active())) != 
nullptr;
+    }
     return bRet;
 }
 
@@ -1695,6 +1749,7 @@ void SwFramePage::ActivatePage(const SfxItemSet& rSet)
     m_xHeightED->LockAutoCalculation(false);
     m_xWidthED->LockAutoCalculation(false);
     m_xFollowTextFlowCB->save_state();
+    m_xFlySplitCB->save_state();
 }
 
 DeactivateRC SwFramePage::DeactivatePage(SfxItemSet * _pSet)
@@ -1893,6 +1948,7 @@ IMPL_LINK_NOARG(SwFramePage, AnchorTypeHdl, 
weld::Toggleable&, void)
     m_xFollowTextFlowCB->set_sensitive(m_xAnchorAtParaRB->get_active() ||
                                        m_xAnchorAtCharRB->get_active() ||
                                        m_xAnchorAtFrameRB->get_active());
+    m_xFlySplitCB->set_sensitive(m_xAnchorAtParaRB->get_active());
 
     RndStdIds eId = GetAnchor();
 
diff --git a/sw/source/uibase/inc/frmpage.hxx b/sw/source/uibase/inc/frmpage.hxx
index 8aca87d35293..8270004838e2 100644
--- a/sw/source/uibase/inc/frmpage.hxx
+++ b/sw/source/uibase/inc/frmpage.hxx
@@ -116,6 +116,7 @@ class SwFramePage final : public SfxTabPage
     std::unique_ptr<weld::ComboBox> m_xVertRelationLB;
     // #i18732# - check box for new option 'FollowTextFlow'
     std::unique_ptr<weld::CheckButton> m_xFollowTextFlowCB;
+    std::unique_ptr<weld::CheckButton> m_xFlySplitCB;
 
     // example
     std::unique_ptr<weld::CustomWeld> m_xExampleWN;
diff --git a/sw/uiconfig/swriter/ui/frmtypepage.ui 
b/sw/uiconfig/swriter/ui/frmtypepage.ui
index 07cbf8aea09a..b1e7561b054a 100644
--- a/sw/uiconfig/swriter/ui/frmtypepage.ui
+++ b/sw/uiconfig/swriter/ui/frmtypepage.ui
@@ -524,7 +524,7 @@
         <property name="label-xalign">0</property>
         <property name="shadow-type">none</property>
         <child>
-          <!-- n-columns=6 n-rows=4 -->
+          <!-- n-columns=6 n-rows=5 -->
           <object class="GtkGrid" id="grid10">
             <property name="visible">True</property>
             <property name="can-focus">False</property>
@@ -756,6 +756,22 @@
                 <property name="width">6</property>
               </packing>
             </child>
+            <child>
+              <object class="GtkCheckButton" id="flysplit">
+                <property name="label" translatable="yes" 
context="frmtypepage|flysplit">Allow frame to split across pages</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>
+              </object>
+              <packing>
+                <property name="left-attach">0</property>
+                <property name="top-attach">4</property>
+                <property name="width">6</property>
+              </packing>
+            </child>
           </object>
         </child>
         <child type="label">

Reply via email to