sw/CppunitTest_sw_uibase_wrtsh.mk     |   75 ++++++++++++++++++++++++++++++++++
 sw/Module_sw.mk                       |    1 
 sw/inc/swabstdlg.hxx                  |    2 
 sw/qa/uibase/wrtsh/wrtsh.cxx          |   58 ++++++++++++++++++++++++++
 sw/source/ui/chrdlg/break.cxx         |    8 +++
 sw/source/ui/dialog/swdlgfact.cxx     |   11 ++++
 sw/source/ui/dialog/swdlgfact.hxx     |    1 
 sw/source/uibase/inc/break.hxx        |    5 ++
 sw/source/uibase/inc/wrtsh.hxx        |    3 -
 sw/source/uibase/shells/textsh1.cxx   |   11 +++-
 sw/source/uibase/wrtsh/wrtsh1.cxx     |   22 ++++++++-
 sw/uiconfig/swriter/ui/insertbreak.ui |   47 ++++++++++++++++++---
 12 files changed, 229 insertions(+), 15 deletions(-)

New commits:
commit 8a7d0e8a811da83265c383630cc48af57f96dc49
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Thu Mar 24 08:44:52 2022 +0100
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Thu Mar 24 12:52:42 2022 +0100

    sw clearing breaks: add insert UI
    
    Expose SwLineBreakClear in SwBreakDlg and extend
    SwWrtShell::InsertLineBreak() to be able to insert clearing breaks as
    well.
    
    Change-Id: I17a4c34cb74f1c72d8e208bace25597de0367e17
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132024
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/CppunitTest_sw_uibase_wrtsh.mk 
b/sw/CppunitTest_sw_uibase_wrtsh.mk
new file mode 100644
index 000000000000..7578be915fcb
--- /dev/null
+++ b/sw/CppunitTest_sw_uibase_wrtsh.mk
@@ -0,0 +1,75 @@
+# -*- Mode: makefile-gmake; tab-width: 4; indent-tabs-mode: t -*-
+#*************************************************************************
+#
+# 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_CppunitTest_CppunitTest,sw_uibase_wrtsh))
+
+$(eval $(call gb_CppunitTest_use_common_precompiled_header,sw_uibase_wrtsh))
+
+$(eval $(call gb_CppunitTest_add_exception_objects,sw_uibase_wrtsh, \
+    sw/qa/uibase/wrtsh/wrtsh \
+))
+
+$(eval $(call gb_CppunitTest_use_libraries,sw_uibase_wrtsh, \
+    comphelper \
+    cppu \
+    cppuhelper \
+    editeng \
+    sal \
+    sfx \
+    svl \
+    svx \
+    svxcore \
+    sw \
+       swqahelper \
+    test \
+    unotest \
+    utl \
+    vcl \
+    tl \
+))
+
+$(eval $(call gb_CppunitTest_use_externals,sw_uibase_wrtsh,\
+    boost_headers \
+    libxml2 \
+))
+
+$(eval $(call gb_CppunitTest_set_include,sw_uibase_wrtsh,\
+    -I$(SRCDIR)/sw/inc \
+    -I$(SRCDIR)/sw/source/core/inc \
+    -I$(SRCDIR)/sw/source/uibase/inc \
+    -I$(SRCDIR)/sw/qa/inc \
+    $$(INCLUDE) \
+))
+
+$(eval $(call gb_CppunitTest_use_api,sw_uibase_wrtsh,\
+       udkapi \
+       offapi \
+       oovbaapi \
+))
+
+$(eval $(call gb_CppunitTest_use_ure,sw_uibase_wrtsh))
+$(eval $(call gb_CppunitTest_use_vcl,sw_uibase_wrtsh))
+
+$(eval $(call gb_CppunitTest_use_rdb,sw_uibase_wrtsh,services))
+
+$(eval $(call gb_CppunitTest_use_custom_headers,sw_uibase_wrtsh,\
+    officecfg/registry \
+))
+
+$(eval $(call gb_CppunitTest_use_configuration,sw_uibase_wrtsh))
+
+$(eval $(call gb_CppunitTest_use_uiconfigs,sw_uibase_wrtsh, \
+    modules/swriter \
+))
+
+$(eval $(call gb_CppunitTest_use_more_fonts,sw_uibase_wrtsh))
+
+# vim: set noet sw=4 ts=4:
diff --git a/sw/Module_sw.mk b/sw/Module_sw.mk
index de0affba1bc7..ee4e0798a5b9 100644
--- a/sw/Module_sw.mk
+++ b/sw/Module_sw.mk
@@ -129,6 +129,7 @@ $(eval $(call gb_Module_add_slowcheck_targets,sw,\
     CppunitTest_sw_uibase_dochdl \
     CppunitTest_sw_uibase_frmdlg \
     CppunitTest_sw_uibase_uno \
+    CppunitTest_sw_uibase_wrtsh \
     CppunitTest_sw_core_accessibilitycheck \
     CppunitTest_sw_core_layout \
     CppunitTest_sw_core_fields \
diff --git a/sw/inc/swabstdlg.hxx b/sw/inc/swabstdlg.hxx
index dafbef78c5e6..08c71a2f33d1 100644
--- a/sw/inc/swabstdlg.hxx
+++ b/sw/inc/swabstdlg.hxx
@@ -60,6 +60,7 @@ class SwInsTableDlg;
 enum class SwBorderModes;
 enum class SwCharDlgMode;
 enum class SfxStyleFamily;
+enum class SwLineBreakClear;
 
 namespace com::sun::star{
     namespace frame{
@@ -235,6 +236,7 @@ public:
     virtual OUString                        GetTemplateName() = 0;
     virtual sal_uInt16                      GetKind() = 0;
     virtual ::std::optional<sal_uInt16>   GetPageNumber() = 0;
+    virtual std::optional<SwLineBreakClear> GetClear() = 0;
 
     virtual std::shared_ptr<weld::DialogController> getDialogController() = 0;
 };
diff --git a/sw/qa/uibase/wrtsh/wrtsh.cxx b/sw/qa/uibase/wrtsh/wrtsh.cxx
new file mode 100644
index 000000000000..9f63ed2fc7e6
--- /dev/null
+++ b/sw/qa/uibase/wrtsh/wrtsh.cxx
@@ -0,0 +1,58 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-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/.
+ */
+
+#include <swmodeltestbase.hxx>
+
+#include <optional>
+
+#include <com/sun/star/text/XTextContent.hpp>
+#include <com/sun/star/text/XTextRange.hpp>
+
+#include <rtl/ustring.hxx>
+#include <sal/types.h>
+
+#include <doc.hxx>
+#include <docsh.hxx>
+#include <formatlinebreak.hxx>
+#include <wrtsh.hxx>
+
+namespace
+{
+/// Covers sw/source/uibase/wrtsh/ fixes.
+class Test : public SwModelTestBase
+{
+};
+
+CPPUNIT_TEST_FIXTURE(Test, testInsertLineBreak)
+{
+    // Given an empty document:
+    SwDoc* pDoc = createSwDoc();
+
+    // When inserting a clearing break:
+    SwWrtShell* pWrtShell = pDoc->GetDocShell()->GetWrtShell();
+    std::optional<SwLineBreakClear> oClear = SwLineBreakClear::ALL;
+    pWrtShell->InsertLineBreak(oClear);
+
+    // Then make sure it's not just a plain linebreak:
+    uno::Reference<css::text::XTextRange> xTextPortion = 
getRun(getParagraph(1), 1);
+    auto aPortionType = getProperty<OUString>(xTextPortion, "TextPortionType");
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: LineBreak
+    // - Actual  : Text
+    // i.e. the line break lost its "clear" property.
+    CPPUNIT_ASSERT_EQUAL(OUString("LineBreak"), aPortionType);
+    auto xLineBreak = 
getProperty<uno::Reference<text::XTextContent>>(xTextPortion, "LineBreak");
+    auto eClear = getProperty<sal_Int16>(xLineBreak, "Clear");
+    CPPUNIT_ASSERT_EQUAL(static_cast<sal_Int16>(SwLineBreakClear::ALL), 
eClear);
+}
+}
+
+CPPUNIT_PLUGIN_IMPLEMENT();
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sw/source/ui/chrdlg/break.cxx b/sw/source/ui/chrdlg/break.cxx
index 7bc1210ef34d..8c1c6a0ccbfc 100644
--- a/sw/source/ui/chrdlg/break.cxx
+++ b/sw/source/ui/chrdlg/break.cxx
@@ -36,7 +36,10 @@ void SwBreakDlg::rememberResult()
 {
     nKind = 0;
     if (m_xLineBtn->get_active())
+    {
         nKind = 1;
+        m_eClear = 
static_cast<SwLineBreakClear>(m_xLineClearBox->get_active());
+    }
     else if(m_xColumnBtn->get_active())
         nKind = 2;
     else if(m_xPageBtn->get_active())
@@ -125,6 +128,8 @@ IMPL_LINK_NOARG(SwBreakDlg, OkHdl, weld::Button&, void)
 SwBreakDlg::SwBreakDlg(weld::Window *pParent, SwWrtShell &rS)
     : GenericDialogController(pParent, "modules/swriter/ui/insertbreak.ui", 
"BreakDialog")
     , m_xLineBtn(m_xBuilder->weld_radio_button("linerb"))
+    , m_xLineClearText(m_xBuilder->weld_label("clearft"))
+    , m_xLineClearBox(m_xBuilder->weld_combo_box("clearlb"))
     , m_xColumnBtn(m_xBuilder->weld_radio_button("columnrb"))
     , m_xPageBtn(m_xBuilder->weld_radio_button("pagerb"))
     , m_xPageCollText(m_xBuilder->weld_label("styleft"))
@@ -189,6 +194,9 @@ void SwBreakDlg::CheckEnable()
     const bool bPage = m_xPageBtn->get_active();
     m_xPageCollText->set_sensitive(bPage);
     m_xPageCollBox->set_sensitive(bPage);
+    bool bLine = m_xLineBtn->get_active();
+    m_xLineClearText->set_sensitive(bLine);
+    m_xLineClearBox->set_sensitive(bLine);
 
     bEnable &= bPage;
     if ( bEnable )
diff --git a/sw/source/ui/dialog/swdlgfact.cxx 
b/sw/source/ui/dialog/swdlgfact.cxx
index 2f28ef1b385d..dd5211277832 100644
--- a/sw/source/ui/dialog/swdlgfact.cxx
+++ b/sw/source/ui/dialog/swdlgfact.cxx
@@ -87,7 +87,7 @@
 #include <mailconfigpage.hxx>
 #include <uiborder.hxx>
 #include <mmresultdialogs.hxx>
-
+#include <formatlinebreak.hxx>
 
 using namespace ::com::sun::star;
 using namespace css::frame;
@@ -386,6 +386,15 @@ sal_uInt16 AbstractSwBreakDlg_Impl:: GetKind()
     return 0;
 }
 
+std::optional<SwLineBreakClear> AbstractSwBreakDlg_Impl::GetClear()
+{
+    SwBreakDlg* pDlg = dynamic_cast<SwBreakDlg*>(m_xDlg.get());
+    if (pDlg)
+        return pDlg->GetClear();
+
+    return SwLineBreakClear::NONE;
+}
+
 void AbstractSwConvertTableDlg_Impl::GetValues( sal_Unicode& 
rDelim,SwInsertTableOptions& rInsTableFlags,
                                                 SwTableAutoFormat const*& 
prTAFormat)
 {
diff --git a/sw/source/ui/dialog/swdlgfact.hxx 
b/sw/source/ui/dialog/swdlgfact.hxx
index bd0f8ab392c5..867b37a467f6 100644
--- a/sw/source/ui/dialog/swdlgfact.hxx
+++ b/sw/source/ui/dialog/swdlgfact.hxx
@@ -181,6 +181,7 @@ public:
     virtual OUString                        GetTemplateName() override;
     virtual sal_uInt16                      GetKind() override;
     virtual ::std::optional<sal_uInt16>   GetPageNumber() override;
+    std::optional<SwLineBreakClear> GetClear() override;
 
     virtual std::shared_ptr<weld::DialogController> getDialogController() 
override { return m_xDlg; }
 };
diff --git a/sw/source/uibase/inc/break.hxx b/sw/source/uibase/inc/break.hxx
index 928761305027..3dbb4c681039 100644
--- a/sw/source/uibase/inc/break.hxx
+++ b/sw/source/uibase/inc/break.hxx
@@ -24,10 +24,13 @@
 #include <optional>
 
 class SwWrtShell;
+enum class SwLineBreakClear;
 
 class SwBreakDlg final : public weld::GenericDialogController
 {
     std::unique_ptr<weld::RadioButton> m_xLineBtn;
+    std::unique_ptr<weld::Label> m_xLineClearText;
+    std::unique_ptr<weld::ComboBox> m_xLineClearBox;
     std::unique_ptr<weld::RadioButton> m_xColumnBtn;
     std::unique_ptr<weld::RadioButton> m_xPageBtn;
     std::unique_ptr<weld::Label> m_xPageCollText;
@@ -40,6 +43,7 @@ class SwBreakDlg final : public weld::GenericDialogController
     OUString m_aTemplate;
     sal_uInt16 nKind;
     ::std::optional<sal_uInt16> oPgNum;
+    std::optional<SwLineBreakClear> m_eClear;
 
     bool bHtmlMode;
 
@@ -57,6 +61,7 @@ public:
     const OUString& GetTemplateName() const { return m_aTemplate; }
     sal_uInt16 GetKind() const { return nKind; }
     const ::std::optional<sal_uInt16>& GetPageNumber() const { return oPgNum; }
+    std::optional<SwLineBreakClear> GetClear() const { return m_eClear; }
 };
 
 #endif
diff --git a/sw/source/uibase/inc/wrtsh.hxx b/sw/source/uibase/inc/wrtsh.hxx
index 41ef84d1d00f..1c85873bc249 100644
--- a/sw/source/uibase/inc/wrtsh.hxx
+++ b/sw/source/uibase/inc/wrtsh.hxx
@@ -53,6 +53,7 @@ class SfxStringListItem;
 enum class SvMacroItemId : sal_uInt16;
 class SwFieldMgr;
 class SfxRequest;
+enum class SwLineBreakClear;
 
 namespace i18nutil {
     struct SearchOptions2;
@@ -312,7 +313,7 @@ typedef bool (SwWrtShell::*FNSimpleMove)();
 
     void    InsertByWord( const OUString & );
     void    InsertPageBreak(const OUString *pPageDesc = nullptr, const 
::std::optional<sal_uInt16>& rPgNum = std::nullopt);
-    void    InsertLineBreak();
+    void InsertLineBreak(std::optional<SwLineBreakClear> oClear = 
std::nullopt);
     void    InsertColumnBreak();
     void    InsertFootnote(const OUString &, bool bEndNote = false, bool bEdit 
= true );
     void    SplitNode( bool bAutoFormat = false );
diff --git a/sw/source/uibase/shells/textsh1.cxx 
b/sw/source/uibase/shells/textsh1.cxx
index c7b05a53b4c6..e0f4459f31e9 100644
--- a/sw/source/uibase/shells/textsh1.cxx
+++ b/sw/source/uibase/shells/textsh1.cxx
@@ -331,12 +331,13 @@ namespace {
 void InsertBreak(SwWrtShell& rWrtSh,
                  sal_uInt16 nKind,
                  ::std::optional<sal_uInt16> oPageNumber,
-                 const OUString& rTemplateName)
+                 const OUString& rTemplateName, 
std::optional<SwLineBreakClear> oClear)
 {
     switch ( nKind )
     {
         case 1 :
-            rWrtSh.InsertLineBreak(); break;
+            rWrtSh.InsertLineBreak(oClear);
+            break;
         case 2 :
             rWrtSh.InsertColumnBreak(); break;
         case 3 :
@@ -652,6 +653,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
             if ( pItem )
             {
                 ::std::optional<sal_uInt16> oPageNumber;
+                std::optional<SwLineBreakClear> oClear;
                 OUString aTemplateName;
                 sal_uInt16 nKind = static_cast<const 
SfxInt16Item*>(pItem)->GetValue();
                 const SfxStringItem* pTemplate = 
rReq.GetArg<SfxStringItem>(FN_PARAM_1);
@@ -662,7 +664,7 @@ void SwTextShell::Execute(SfxRequest &rReq)
                 if ( pNumber && pIsNumberFilled && pIsNumberFilled->GetValue() 
)
                     oPageNumber = pNumber->GetValue();
 
-                InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName);
+                InsertBreak(rWrtSh, nKind, oPageNumber, aTemplateName, oClear);
             }
             else
             {
@@ -678,8 +680,9 @@ void SwTextShell::Execute(SfxRequest &rReq)
                             sal_uInt16 nKind = pAbstractDialog->GetKind();
                             OUString aTemplateName = 
pAbstractDialog->GetTemplateName();
                             ::std::optional<sal_uInt16> oPageNumber = 
pAbstractDialog->GetPageNumber();
+                            std::optional<SwLineBreakClear> oClear = 
pAbstractDialog->GetClear();
 
-                            InsertBreak(rWrtSh, nKind, oPageNumber, 
aTemplateName);
+                            InsertBreak(rWrtSh, nKind, oPageNumber, 
aTemplateName, oClear);
                         }
                     });
             }
diff --git a/sw/source/uibase/wrtsh/wrtsh1.cxx 
b/sw/source/uibase/wrtsh/wrtsh1.cxx
index e4e4efb76d2d..a55b5ed7513a 100644
--- a/sw/source/uibase/wrtsh/wrtsh1.cxx
+++ b/sw/source/uibase/wrtsh/wrtsh1.cxx
@@ -111,6 +111,7 @@
 #include <IDocumentUndoRedo.hxx>
 #include <UndoInsert.hxx>
 #include <UndoCore.hxx>
+#include <formatlinebreak.hxx>
 
 using namespace sw::mark;
 using namespace com::sun::star;
@@ -949,7 +950,7 @@ void SwWrtShell::InsertPageBreak(const OUString *pPageDesc, 
const ::std::optiona
 // Insert hard page break;
 // Selections will be overwritten
 
-void SwWrtShell::InsertLineBreak()
+void SwWrtShell::InsertLineBreak(std::optional<SwLineBreakClear> oClear)
 {
     if (!lcl_IsAllowed(this))
         return;
@@ -961,11 +962,26 @@ void SwWrtShell::InsertLineBreak()
             DelRight();
 
         const sal_Unicode cIns = 0x0A;
+        SwLineBreakClear eClear = SwLineBreakClear::NONE;
+        if (oClear.has_value())
+        {
+            eClear = *oClear;
+        }
         SvxAutoCorrect* pACorr = lcl_IsAutoCorr();
-        if( pACorr )
+        if (pACorr && eClear == SwLineBreakClear::NONE)
             AutoCorrect( *pACorr, cIns );
         else
-            SwWrtShell::Insert( OUString( cIns ) );
+        {
+            if (eClear == SwLineBreakClear::NONE)
+            {
+                SwWrtShell::Insert(OUString(cIns));
+            }
+            else
+            {
+                SwFormatLineBreak aLineBreak(eClear);
+                SetAttrItem(aLineBreak);
+            }
+        }
     }
 }
 
diff --git a/sw/uiconfig/swriter/ui/insertbreak.ui 
b/sw/uiconfig/swriter/ui/insertbreak.ui
index 839515671112..b52655b369f4 100644
--- a/sw/uiconfig/swriter/ui/insertbreak.ui
+++ b/sw/uiconfig/swriter/ui/insertbreak.ui
@@ -114,6 +114,41 @@
                     <property name="position">0</property>
                   </packing>
                 </child>
+                <child>
+                  <object class="GtkLabel" id="clearft">
+                    <property name="visible">True</property>
+                    <property name="can_focus">False</property>
+                    <property name="margin_top">6</property>
+                    <property name="label" translatable="yes" 
context="insertbreak|clearft">Restart Location:</property>
+                    <property name="use_underline">True</property>
+                    <property name="mnemonic_widget">clearlb</property>
+                    <property name="xalign">0</property>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">1</property>
+                  </packing>
+                </child>
+                <child>
+                  <object class="GtkComboBoxText" id="clearlb">
+                    <property name="visible">True</property>
+                    <property name="sensitive">False</property>
+                    <property name="can_focus">False</property>
+                    <property name="active">0</property>
+                    <items>
+                      <item id="0" translatable="yes" 
context="insertbreak|clearlb0">[None]</item>
+                      <item id="1" translatable="yes" 
context="insertbreak|clearlb1">Left</item>
+                      <item id="2" translatable="yes" 
context="insertbreak|clearlb2">Right</item>
+                      <item id="3" translatable="yes" 
context="insertbreak|clearlb3">Next Full Line</item>
+                    </items>
+                  </object>
+                  <packing>
+                    <property name="expand">False</property>
+                    <property name="fill">True</property>
+                    <property name="position">2</property>
+                  </packing>
+                </child>
                 <child>
                   <object class="GtkRadioButton" id="columnrb">
                     <property name="label" translatable="yes" 
context="insertbreak|columnrb">Column break</property>
@@ -132,7 +167,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">1</property>
+                    <property name="position">3</property>
                   </packing>
                 </child>
                 <child>
@@ -153,7 +188,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">2</property>
+                    <property name="position">4</property>
                   </packing>
                 </child>
                 <child>
@@ -169,7 +204,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">3</property>
+                    <property name="position">5</property>
                   </packing>
                 </child>
                 <child>
@@ -189,7 +224,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">4</property>
+                    <property name="position">6</property>
                   </packing>
                 </child>
                 <child>
@@ -210,7 +245,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">5</property>
+                    <property name="position">7</property>
                   </packing>
                 </child>
                 <child>
@@ -233,7 +268,7 @@
                   <packing>
                     <property name="expand">False</property>
                     <property name="fill">True</property>
-                    <property name="position">6</property>
+                    <property name="position">8</property>
                   </packing>
                 </child>
               </object>

Reply via email to