sw/qa/core/unocore/unocore.cxx    |   12 ++++++++++++
 sw/source/core/inc/swfont.hxx     |    3 +++
 sw/source/core/inc/txttypes.hxx   |    1 +
 sw/source/core/text/atrhndl.hxx   |    2 +-
 sw/source/core/text/atrstck.cxx   |   15 +++++++++++++++
 sw/source/core/text/inftxt.cxx    |    1 +
 sw/source/core/text/itratr.cxx    |    2 ++
 sw/source/core/text/itrform2.cxx  |   20 ++++++++++++++++++++
 sw/source/core/text/xmldump.cxx   |    2 ++
 sw/source/core/txtnode/swfont.cxx |    3 +++
 10 files changed, 60 insertions(+), 1 deletion(-)

New commits:
commit 8c632d8a837cc722c6e7b3b400f6d97edf9f9800
Author:     Miklos Vajna <vmik...@collabora.com>
AuthorDate: Tue Apr 5 10:53:22 2022 +0200
Commit:     Miklos Vajna <vmik...@collabora.com>
CommitDate: Tue Apr 5 15:41:28 2022 +0200

    sw content controls: add initial layout support
    
    - portions inside content controls are not text portions but content
      control portions
    
    - teach SwTextPaintInfo::DrawViewOpt() to paint field shadings for
      content control portions
    
    - teach the attribute stack code about RES_TXTATR_CONTENTCONTROL, so if
      the whole document is just a content control, then adding text
      before/after the content control is properly text portions, not content
      control portions
    
    Change-Id: Ia9f955a5f7c7a4fd633899fafa8fc723e7c0d050
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/132556
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    Tested-by: Jenkins

diff --git a/sw/qa/core/unocore/unocore.cxx b/sw/qa/core/unocore/unocore.cxx
index c9bca82ae2f8..19ad5d5fd48b 100644
--- a/sw/qa/core/unocore/unocore.cxx
+++ b/sw/qa/core/unocore/unocore.cxx
@@ -404,6 +404,18 @@ CPPUNIT_TEST_FIXTURE(SwCoreUnocoreTest, 
testContentControlTextPortionEnum)
     uno::Reference<container::XEnumeration> xContentEnum = 
xContentEnumAccess->createEnumeration();
     uno::Reference<text::XTextRange> xContent(xContentEnum->nextElement(), 
uno::UNO_QUERY);
     CPPUNIT_ASSERT_EQUAL(OUString("test"), xContent->getString());
+
+    // Also test the generated layout:
+    xmlDocUniquePtr pXmlDoc = parseLayoutDump();
+    assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout/SwFieldPortion", 
"expand", "");
+    // Without the accompanying fix in place, this test would have failed with:
+    // - Expected: PortionType::ContentControl
+    // - Actual  : PortionType::Text
+    // i.e. SwContentControl generated a plain text portion, not a dedicated 
content control
+    // portion.
+    assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout/SwLinePortion", "type",
+                "PortionType::ContentControl");
+    assertXPath(pXmlDoc, "//SwParaPortion/SwLineLayout/SwLinePortion", 
"portion", "test");
 }
 
 CPPUNIT_PLUGIN_IMPLEMENT();
diff --git a/sw/source/core/inc/swfont.hxx b/sw/source/core/inc/swfont.hxx
index a2eedaca5f64..40a4c2e8d66c 100644
--- a/sw/source/core/inc/swfont.hxx
+++ b/sw/source/core/inc/swfont.hxx
@@ -158,6 +158,7 @@ class SwFont
     sal_uInt8   m_nToxCount;        // counts the nesting depth of the Tox
     sal_uInt8   m_nRefCount;        // counts the nesting depth of the Refs
     sal_uInt8   m_nMetaCount;   // count META/METAFIELD
+    sal_uInt8 m_nContentControlCount; // count CONTENTCONTROL
     sal_uInt8   m_nInputFieldCount; // count INPUTFIELD
 
     SwFontScript m_nActual;        // actual font (Latin, CJK or CTL)
@@ -250,6 +251,8 @@ public:
     bool IsRef() const { return ( 0 != m_nRefCount ); }
     sal_uInt8 &GetMeta() { return m_nMetaCount; }
     bool IsMeta() const { return (0 != m_nMetaCount); }
+    sal_uInt8& GetContentControl() { return m_nContentControlCount; }
+    bool IsContentControl() const { return m_nContentControlCount != 0; }
     sal_uInt8 &GetInputField() { return m_nInputFieldCount; }
     bool IsInputField() const { return (0 != m_nInputFieldCount); }
     inline void SetGreyWave( const bool bNew );
diff --git a/sw/source/core/inc/txttypes.hxx b/sw/source/core/inc/txttypes.hxx
index e65ed26dc128..d876b0f8e037 100644
--- a/sw/source/core/inc/txttypes.hxx
+++ b/sw/source/core/inc/txttypes.hxx
@@ -49,6 +49,7 @@ enum class PortionType
     Ref         = 0x808b,
     IsoRef      = 0x808c,
     Meta        = 0x808d,
+    ContentControl = 0x808e,
 
     Expand      = 0xc080,
     Blank       = 0xc081,
diff --git a/sw/source/core/text/atrhndl.hxx b/sw/source/core/text/atrhndl.hxx
index 8bb7845f2760..851615325a06 100644
--- a/sw/source/core/text/atrhndl.hxx
+++ b/sw/source/core/text/atrhndl.hxx
@@ -18,7 +18,7 @@
  */
 
 #pragma once
-#define NUM_ATTRIBUTE_STACKS 44
+#define NUM_ATTRIBUTE_STACKS 45
 
 #include <vector>
 #include <swfntcch.hxx>
diff --git a/sw/source/core/text/atrstck.cxx b/sw/source/core/text/atrstck.cxx
index f5cb36cb03f6..7fab6da10c5e 100644
--- a/sw/source/core/text/atrstck.cxx
+++ b/sw/source/core/text/atrstck.cxx
@@ -123,6 +123,7 @@ const sal_uInt8 StackPos[ RES_TXTATR_WITHEND_END - 
RES_CHRATR_BEGIN + 1 ] =
     42, // RES_TXTATR_CJK_RUBY,                  // 53
      0, // RES_TXTATR_UNKNOWN_CONTAINER,         // 54
     43, // RES_TXTATR_INPUTFIELD                 // 55
+    44, // RES_TXTATR_CONTENTCONTROL             // 56
 };
 
 namespace CharFormat
@@ -516,6 +517,10 @@ void SwAttrHandler::ActivateTop( SwFont& rFnt, const 
sal_uInt16 nAttr )
     {
         rFnt.GetMeta()--;
     }
+    else if (nAttr == RES_TXTATR_CONTENTCONTROL)
+    {
+        rFnt.GetContentControl()--;
+    }
     else if ( RES_TXTATR_CJK_RUBY == nAttr )
     {
         // ruby stack has no more attributes
@@ -810,6 +815,16 @@ void SwAttrHandler::FontChg(const SfxPoolItem& rItem, 
SwFont& rFnt, bool bPush )
             else
                 rFnt.GetMeta()--;
             break;
+        case RES_TXTATR_CONTENTCONTROL:
+            if (bPush)
+            {
+                rFnt.GetContentControl()++;
+            }
+            else
+            {
+                rFnt.GetContentControl()--;
+            }
+            break;
         case RES_TXTATR_INPUTFIELD :
             if ( bPush )
                 rFnt.GetInputField()++;
diff --git a/sw/source/core/text/inftxt.cxx b/sw/source/core/text/inftxt.cxx
index 32219500921a..5f4cbb95b6fc 100644
--- a/sw/source/core/text/inftxt.cxx
+++ b/sw/source/core/text/inftxt.cxx
@@ -1318,6 +1318,7 @@ void SwTextPaintInfo::DrawViewOpt( const SwLinePortion 
&rPor,
     case PortionType::Tox:
     case PortionType::Ref:
     case PortionType::Meta:
+    case PortionType::ContentControl:
     case PortionType::ControlChar:
         if ( !GetOpt().IsPagePreview()
              && !GetOpt().IsReadonly()
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index 95f7929a0e14..4f4a840a564f 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -510,6 +510,7 @@ static bool CanSkipOverRedline(
                 case RES_TXTATR_INETFMT:
                 case RES_TXTATR_CJK_RUBY:
                 case RES_TXTATR_INPUTFIELD:
+                case RES_TXTATR_CONTENTCONTROL:
                     {
                         if (!isTheAnswerYes) return false; // always break
                     }
@@ -600,6 +601,7 @@ static bool CanSkipOverRedline(
                 case RES_TXTATR_INETFMT:
                 case RES_TXTATR_CJK_RUBY:
                 case RES_TXTATR_INPUTFIELD:
+                case RES_TXTATR_CONTENTCONTROL:
                     {
                         if (!isTheAnswerYes) return false;
                     }
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 2f978289a267..f9e6f45a4433 100644
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -863,6 +863,13 @@ public:
     void SetShadowColor(const Color& rCol ) { m_aShadowColor = rCol; }
 };
 
+/// A content control portion is a text portion that is inside 
RES_TXTATR_CONTENTCONTROL.
+class SwContentControlPortion : public SwTextPortion
+{
+public:
+    SwContentControlPortion() { SetWhichPor(PortionType::ContentControl); }
+    virtual void Paint(const SwTextPaintInfo& rInf) const override;
+};
 }
 
 void SwMetaPortion::Paint( const SwTextPaintInfo &rInf ) const
@@ -879,6 +886,15 @@ void SwMetaPortion::Paint( const SwTextPaintInfo &rInf ) 
const
     }
 }
 
+void SwContentControlPortion::Paint(const SwTextPaintInfo& rInf) const
+{
+    if (Width())
+    {
+        rInf.DrawViewOpt(*this, PortionType::ContentControl);
+        SwTextPortion::Paint(rInf);
+    }
+}
+
 namespace sw::mark {
     OUString ExpandFieldmark(IFieldmark* pBM)
     {
@@ -995,6 +1011,10 @@ SwTextPortion *SwTextFormatter::WhichTextPor( 
SwTextFormatInfo &rInf ) const
             }
             pPor = pMetaPor;
         }
+        else if (GetFnt()->IsContentControl())
+        {
+            pPor = new SwContentControlPortion;
+        }
         else
         {
             // Only at the End!
diff --git a/sw/source/core/text/xmldump.cxx b/sw/source/core/text/xmldump.cxx
index 13215bca13c9..fb45c0920f17 100644
--- a/sw/source/core/text/xmldump.cxx
+++ b/sw/source/core/text/xmldump.cxx
@@ -79,6 +79,8 @@ const char* sw::PortionTypeToString(PortionType nType)
             return "PortionType::IsoRef";
         case PortionType::Meta:
             return "PortionType::Meta";
+        case PortionType::ContentControl:
+            return "PortionType::ContentControl";
         case PortionType::FieldMark:
             return "PortionType::FieldMark";
         case PortionType::FieldFormCheckbox:
diff --git a/sw/source/core/txtnode/swfont.cxx 
b/sw/source/core/txtnode/swfont.cxx
index 67028f766761..eb08f33696cc 100644
--- a/sw/source/core/txtnode/swfont.cxx
+++ b/sw/source/core/txtnode/swfont.cxx
@@ -662,6 +662,7 @@ SwFont::SwFont( const SwFont &rFont )
     m_nToxCount = 0;
     m_nRefCount = 0;
     m_nMetaCount = 0;
+    m_nContentControlCount = 0;
     m_nInputFieldCount = 0;
     m_bFontChg = rFont.m_bFontChg;
     m_bOrgChg = rFont.m_bOrgChg;
@@ -677,6 +678,7 @@ SwFont::SwFont( const SwAttrSet* pAttrSet,
     m_nToxCount = 0;
     m_nRefCount = 0;
     m_nMetaCount = 0;
+    m_nContentControlCount = 0;
     m_nInputFieldCount = 0;
     m_bPaintBlank = false;
     m_bGreyWave = false;
@@ -849,6 +851,7 @@ SwFont& SwFont::operator=( const SwFont &rFont )
         m_nToxCount = 0;
         m_nRefCount = 0;
         m_nMetaCount = 0;
+        m_nContentControlCount = 0;
         m_nInputFieldCount = 0;
         m_bFontChg = rFont.m_bFontChg;
         m_bOrgChg = rFont.m_bOrgChg;

Reply via email to