summaryrefslogtreecommitdiff
path: root/sw
diff options
context:
space:
mode:
authorMiklos Vajna <vmiklos@collabora.com>2022-04-05 10:53:22 +0200
committerMiklos Vajna <vmiklos@collabora.com>2022-04-05 15:41:28 +0200
commit8c632d8a837cc722c6e7b3b400f6d97edf9f9800 (patch)
tree5b99a95287744cee5e543b09b841ac86f473631c /sw
parent19d623d54503327e47f6effa3507342ddbea3d73 (diff)
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 <vmiklos@collabora.com> Tested-by: Jenkins
Diffstat (limited to 'sw')
-rw-r--r--sw/qa/core/unocore/unocore.cxx12
-rw-r--r--sw/source/core/inc/swfont.hxx3
-rw-r--r--sw/source/core/inc/txttypes.hxx1
-rw-r--r--sw/source/core/text/atrhndl.hxx2
-rw-r--r--sw/source/core/text/atrstck.cxx15
-rw-r--r--sw/source/core/text/inftxt.cxx1
-rw-r--r--sw/source/core/text/itratr.cxx2
-rw-r--r--sw/source/core/text/itrform2.cxx20
-rw-r--r--sw/source/core/text/xmldump.cxx2
-rw-r--r--sw/source/core/txtnode/swfont.cxx3
10 files changed, 60 insertions, 1 deletions
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;