chart2/qa/extras/chart2import.cxx                          |   11 +++
 chart2/qa/extras/data/pptx/tdf146487.pptx                  |binary
 oox/inc/drawingml/chart/plotareaconverter.hxx              |    3 +
 oox/inc/drawingml/chart/typegroupconverter.hxx             |    3 +
 oox/source/drawingml/chart/chartspaceconverter.cxx         |   14 ++++
 oox/source/drawingml/chart/plotareaconverter.cxx           |   10 +++
 oox/source/drawingml/chart/typegroupconverter.cxx          |    9 +++
 sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf |   37 +++++++++++++
 sw/qa/extras/rtfexport/rtfexport6.cxx                      |   21 +++++++
 sw/qa/extras/rtfimport/data/fdo52052.rtf                   |    2 
 sw/source/filter/ww8/rtfattributeoutput.cxx                |    8 ++
 sw/source/filter/ww8/wrtw8nds.cxx                          |    7 ++
 writerfilter/source/dmapper/DomainMapper_Impl.cxx          |   28 +++------
 writerfilter/source/rtftok/rtfdispatchflag.cxx             |    9 ---
 writerfilter/source/rtftok/rtfdispatchsymbol.cxx           |    6 --
 writerfilter/source/rtftok/rtfdocumentimpl.cxx             |   10 +--
 writerfilter/source/rtftok/rtfdocumentimpl.hxx             |    8 --
 17 files changed, 138 insertions(+), 48 deletions(-)

New commits:
commit 9055db461851ec198b13930fa9bdb365911a7bcf
Author:     Michael Stahl <michael.st...@allotropia.de>
AuthorDate: Wed Feb 7 13:04:14 2024 +0100
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 18:28:00 2024 +0100

    tdf#158586 writerfilter: RTF import: fix assert on ooo113308-1.rtf
    
      warn:legacy.osl:::writerfilter/source/dmapper/DomainMapper_Impl.cxx:1278: 
section stack already empty
      DomainMapper_Impl.cxx:9817: void 
writerfilter::dmapper::DomainMapper_Impl::substream(): Assertion 
`m_aContextStack.size() == contextSize' failed.
    
    Before substream(), there is one CONTEXT_SECTION, after there is an
    additional CONTEXT_PARAGRPAH.
    
    The first OSL_ENSURE is because RTFDocumentImpl::tableBreak() calls
    endParagraphGroup() but in the substream, startParagraphGroup() hadn't
    been called; fixing this also makes the assert failure go away.
    
    This worked previously because sectBreak() called endParagraphGroup()
    after reading the header substreams, but it seems dubious that a
    paragraph group started in the body should be used in the substream.
    
    (regression from commit 57abad5cf990111fd7de011809d4421dc0550193)
    
    Change-Id: I98864bca03b59099c17080c0a7582de2b77d41e1
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/163096
    Tested-by: Jenkins
    Reviewed-by: Michael Stahl <michael.st...@allotropia.de>

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 652a910c9869..b9c17c0adc61 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -653,6 +653,7 @@ void RTFDocumentImpl::runBreak()
 
 void RTFDocumentImpl::tableBreak()
 {
+    checkFirstRun(); // ooo113308-1.rtf has a header at offset 151084 that 
doesn't startParagraphGroup() without this
     runBreak();
     Mapper().endParagraphGroup();
     Mapper().startParagraphGroup();
commit cf6fac5e6e226da1e4ae8b77d433f0f961febc44
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Mon Dec 18 12:29:25 2023 -0500
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 18:28:00 2024 +0100

    tdf#158586 RTF writerfilter: substitute hasProperties for inFrame
    
    A proper inFrame() would be identical to hasProperties,
    so just substitute the existing, complete function for inFrame.
    
    This is based on a code read, not a problem document,
    but finding a document that depended on inFrame
    returning true made it trivial to modify it to fail.
    
    Somewhat surprisingly, it made it all the way through
    the rtfexports without failing.
    
    make CppunitTest_sw_rtfimport CPPUNIT_TEST_NAME=testFdo52052
    
    Change-Id: I96f00c9b542dabd3709a896d778569b7681c8f19
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160928
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/rtfimport/data/fdo52052.rtf 
b/sw/qa/extras/rtfimport/data/fdo52052.rtf
index e58a64bd43f6..8ae92383c443 100644
--- a/sw/qa/extras/rtfimport/data/fdo52052.rtf
+++ b/sw/qa/extras/rtfimport/data/fdo52052.rtf
@@ -13,7 +13,7 @@
 {\pard \pvpg\phpg\posx2007\posy597bsw12870bsh-900i0 \ltrpar\qc first
 \par }
 \page\sect 
-{\pard \pvpg\phpg\posx13152\posy612bsw2984bsh-210i0 \ltrpar\qr      x360    
x720    x1080   x1440   x1800   x2160   x2520   x2880
+{\pard \pvpg\phpg \posxc\posyc i0 \ltrpar\qr  x360    x720    x1080   x1440   
x1800   x2160   x2520   x2880
 {\ltrch0 \i0\ul0\strike0s15  \par }
 \page\sect 
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx 
b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index e79143d54a06..6c1c94b944d9 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -124,7 +124,7 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
             }
             // but don't emit properties yet, since they may change till the 
first text token arrives
             m_bNeedPap = true;
-            if (!m_aStates.top().getFrame().inFrame())
+            if (!m_aStates.top().getFrame().hasProperties())
                 m_bNeedPar = false;
             m_bNeedFinalPar = false;
         }
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 0e72b318ed55..652a910c9869 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -1349,8 +1349,6 @@ RTFError RTFDocumentImpl::resolveChars(char ch)
     return RTFError::OK;
 }
 
-bool RTFFrame::inFrame() const { return m_nW > 0 || m_nH > 0 || m_nX > 0 || 
m_nY > 0; }
-
 void RTFDocumentImpl::singleChar(sal_uInt8 nValue, bool bRunProps)
 {
     sal_uInt8 sValue[] = { nValue };
@@ -2966,7 +2964,7 @@ RTFError RTFDocumentImpl::beforePopState(RTFParserState& 
rState)
         case Destination::SHAPE:
             m_bNeedFinalPar = true;
             m_bNeedCr = m_bNeedCrOrig;
-            if (rState.getFrame().inFrame())
+            if (rState.getFrame().hasProperties())
             {
                 // parBreak() modifies m_aStates.top() so we can't apply 
resetFrame() directly on aState
                 resetFrame();
@@ -3629,7 +3627,7 @@ RTFError RTFDocumentImpl::popState()
 
     checkUnicode(/*bUnicode =*/true, /*bHex =*/true);
     RTFParserState aState(m_aStates.top());
-    m_bWasInFrame = aState.getFrame().inFrame();
+    m_bWasInFrame = aState.getFrame().hasProperties();
 
     // dmapper expects some content in header/footer, so if there would be 
nothing, add an empty paragraph.
     if (m_pTokenizer->getGroup() == 1 && m_bFirstRun)
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index 8f415ac101e7..f05f7d321cdd 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -384,9 +384,8 @@ public:
     RTFSprms getSprms();
     /// Store a property
     void setSprm(Id nId, Id nValue);
-    bool hasProperties() const;
     /// If we got tokens indicating we're in a frame.
-    bool inFrame() const;
+    bool hasProperties() const;
 };
 
 /// State of the parser, which gets saved / restored when changing groups.
@@ -969,7 +968,7 @@ private:
     RTFKeyword m_nResetBreakOnSectBreak;
     /// If a section break is needed before the end of the doc (false right 
after a section break).
     bool m_bNeedSect;
-    /// If aFrame.inFrame() was true in the previous state.
+    /// If aFrame.hasProperties() was true in the previous state.
     bool m_bWasInFrame;
     /// A picture was seen in the current paragraph.
     bool m_bHadPicture;
commit a8b71033e73800514728f1da326f9cca97d14158
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Wed Dec 13 22:25:32 2023 -0500
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 18:28:00 2024 +0100

    related tdf#158586 RTF writerfilter: HAnchor's default is text, not margin
    
    \phcol: Use the column as the horizontal reference frame.
    This is the default if no horizontal reference frame is given.
    
    Change-Id: I8ef4a35c578768810edc0a68e3fd3b227c069dfe
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160776
    Reviewed-by: Justin Luth <jl...@mail.com>
    Tested-by: Jenkins

diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 5d6df1ddc80c..0e72b318ed55 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -3981,7 +3981,7 @@ RTFSprms RTFFrame::getSprms()
             case NS_ooxml::LN_CT_FramePr_hAnchor:
             {
                 if (m_nHoriAnchor == 0)
-                    m_nHoriAnchor = NS_ooxml::LN_Value_doc_ST_HAnchor_margin;
+                    m_nHoriAnchor = NS_ooxml::LN_Value_doc_ST_HAnchor_text;
                 pValue = new RTFValue(m_nHoriAnchor);
             }
             break;
commit e857bb6db3b0de0c3acaa148c967fba297f76e02
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Dec 1 14:30:45 2023 -0500
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 18:28:00 2024 +0100

    tdf#148540 Revert "tdf#109790 RTF import: keep remembering...
    
    ... paragraph style between     This reverts 5.4.1 commit 
aaa6a5202a447fb4e86d5f016d8e79fbc34a3ed7,
    and rtfexport7's tdf109790.rtf unit test still passes.
    I also did a visual test, which looks good.
    
    After      ow is completely unexpected most of the time.
    I'm not really sure why that patch was ever thought to be good.
    
    The problem was that \pard was not removing the paragraph style
    that was assigned to an earlier column. The end result seemed
    innocent (no bad formatting noticed),
    but that is probably based on other work
    done in the meantime which allows the unit test to still pass
    even after all of "its code" has been reverted.
    
    [If this causes a regression, perhaps m_pLastCharacterContext
    could be of value?]
    
    Change-Id: Ide9b65f5e5fa39c21bac6d8ed354bb88e0bbefe5
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160233
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>

diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index 569a65069b31..8140e1724e2d 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -172,6 +172,8 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
     CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+
+    CPPUNIT_ASSERT_EQUAL(OUString("Standard"), getProperty<OUString>(xPara, 
"ParaStyleName"));
 }
 
 DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
diff --git a/writerfilter/source/rtftok/rtfdispatchflag.cxx 
b/writerfilter/source/rtftok/rtfdispatchflag.cxx
index 49e82d3b9a88..753f1c3fbba9 100644
--- a/writerfilter/source/rtftok/rtfdispatchflag.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchflag.cxx
@@ -581,8 +581,6 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword nKeyword)
                 dispatchSymbol(RTFKeyword::PAR);
             // \pard is allowed between              // It should not reset 
the paragraph style, either, so remember the old paragraph style.
-            RTFValue::Pointer_t pOldStyle
-                = 
m_aStates.top().getParagraphSprms().find(NS_ooxml::LN_CT_PPrBase_pStyle);
             m_aStates.top().getParagraphSprms() = 
m_aDefaultState.getParagraphSprms();
             m_aStates.top().getParagraphAttributes() = 
m_aDefaultState.getParagraphAttributes();
 
@@ -595,19 +593,14 @@ RTFError RTFDocumentImpl::dispatchFlag(RTFKeyword 
nKeyword)
             {
                 // We are still in a table.
                 m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_inTbl, 
new RTFValue(1));
-                if (m_bAfterCellBeforeRow && pOldStyle)
-                    // And we still have the same paragraph style.
-                    
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_pStyle,
-                                                            pOldStyle);
                 // Ideally getDefaultSPRM() would take care of this, but it 
would not when we're buffering.
                 
m_aStates.top().getParagraphSprms().set(NS_ooxml::LN_CT_PPrBase_tabs,
                                                         new RTFValue());
             }
             resetFrame();
 
-            // Reset currently selected paragraph style as well, unless we are 
in the special "after +            // Reset currently selected paragraph style 
as well.
             // By default the style with index 0 is applied.
-            if (!m_bAfterCellBeforeRow)
             {
                 OUString const aName = getStyleName(0);
                 // But only in case it's not a character style.
diff --git a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx 
b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
index c7eee5b0f4b1..e79143d54a06 100644
--- a/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
+++ b/writerfilter/source/rtftok/rtfdispatchsymbol.cxx
@@ -181,9 +181,6 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
         case RTFKeyword::CELL:
         case RTFKeyword::NESTCELL:
         {
-            if (nKeyword == RTFKeyword::CELL)
-                m_bAfterCellBeforeRow = true;
-
             checkFirstRun();
             if (m_bNeedPap)
             {
@@ -237,7 +234,6 @@ RTFError RTFDocumentImpl::dispatchSymbol(RTFKeyword 
nKeyword)
         break;
         case RTFKeyword::ROW:
         {
-            m_bAfterCellBeforeRow = false;
             if (m_aStates.top().getTableRowWidthAfter() > 0)
             {
                 // Add fake cellx / cell, RTF equivalent of
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.cxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
index 53f414b57524..5d6df1ddc80c 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.cxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.cxx
@@ -330,7 +330,6 @@ 
RTFDocumentImpl::RTFDocumentImpl(uno::Reference<uno::XComponentContext> const& x
     , m_hasFHeader(false)
     , m_hasRFooter(false)
     , m_hasFFooter(false)
-    , m_bAfterCellBeforeRow(false)
 {
     OSL_ASSERT(xInputStream.is());
     m_pInStream = utl::UcbStreamHelper::CreateStream(xInputStream, true);
diff --git a/writerfilter/source/rtftok/rtfdocumentimpl.hxx 
b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
index f96c8ada6453..8f415ac101e7 100644
--- a/writerfilter/source/rtftok/rtfdocumentimpl.hxx
+++ b/writerfilter/source/rtftok/rtfdocumentimpl.hxx
@@ -990,9 +990,6 @@ private:
     bool m_hasFHeader;
     bool m_hasRFooter;
     bool m_hasFFooter;
-
-    /// Are we after a -    bool m_bAfterCellBeforeRow;
 };
 } // namespace writerfilter::rtftok
 
commit 586a07e3f343829928cbdc1b1ca8227d53cdce71
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Tue Dec 5 21:43:16 2023 -0500
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 18:28:00 2024 +0100

    tdf#108505 rtfexport: avoid mis-inheriting field char settings
    
    The field result fully defines its own character properties,
    so it should not inherit any "parent" properties from the field.
    
    My test file didn't show any problems with DOCX or DOC,
    and reading through the code I didn't notice anything
    that looked wrong. Both are very different from RTF syntax,
    and it didn't look like they did anything "special"
    for this situation, so nothing to copy from...
    
    This whole area of field properties looks very hacky,
    but it seems pretty clear that OutputTextNode
    loops through OutAttr's run properties for each of
    start/sep/end for fields. OutAttr picks up all of the
    direct formatting, so nothing should be "missing",
    and therefore a \plain character reset should be appropriate.
    
    The good news is that MS Word 2010 imported both the bad
    and the good export just like we do.
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat2
    
    Change-Id: I713c071dfcd40117bfff03d152718eb5d847327e
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160375
    Tested-by: Jenkins
    Reviewed-by: Justin Luth <jl...@mail.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>
    (cherry picked from commit 5f888fa920c99cce91dfd18244a5c3869807b970)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160580
    Reviewed-by: Xisco Fauli <xiscofa...@libreoffice.org>

diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index f64e3035c529..569a65069b31 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -176,21 +176,19 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
 
 DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
 {
-    // not exported properly. Currrently xyz exports as run 6, red, italic.
-    if (isExported())
-        return;
-
     uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), 
uno::UNO_QUERY);
     uno::Reference<text::XTextRange> xCell(xTable->getCellByName("C1"), 
uno::UNO_QUERY);
     uno::Reference<text::XTextRange> xPara = getParagraphOfText(1, 
xCell->getText());
 
-    // Preemptive test: nothing found wrong/fixed by the accompanying patch
+    const sal_Int32 nRun = isExported() ? 6 : 5;
+    const Color aColor = isExported() ? COL_BLACK : COL_AUTO;
+
     // Character formatting should only be defined by the ldrslt, and not by 
prior formatting.
     // Prior formatting is italic, red, 20pt.
-    uno::Reference<text::XTextRange> xRun = getRun(xPara, 5, u"xyz"_ustr);
+    uno::Reference<text::XTextRange> xRun = getRun(xPara, nRun, u"xyz");
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
-    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xRun, "CharColor"));
+    CPPUNIT_ASSERT_EQUAL(aColor, getProperty<Color>(xRun, "CharColor"));
 }
 
 /** Make sure that the document variable "Unused", which is not referenced in 
the document,
diff --git a/sw/source/filter/ww8/rtfattributeoutput.cxx 
b/sw/source/filter/ww8/rtfattributeoutput.cxx
index c8ac5b4cadf4..2e255d43be02 100644
--- a/sw/source/filter/ww8/rtfattributeoutput.cxx
+++ b/sw/source/filter/ww8/rtfattributeoutput.cxx
@@ -1856,7 +1856,13 @@ void RtfAttributeOutput::WriteField_Impl(const SwField* 
const pField, ww::eField
                 msfilter::rtfutil::OutString(rFieldCmd, 
m_rExport.GetCurrentEncoding()));
         if (nMode & FieldFlags::CmdEnd)
         {
-            m_aRunText->append("}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT " {");
+            m_aRunText->append("}}{" OOO_STRING_SVTOOLS_RTF_FLDRSLT);
+            // The fldrslt contains its own full copy of character formatting,
+            // but if the result is empty (nMode & FieldFlags::End) or field 
export is condensed
+            // in any way (multiple flags) then avoid spamming an unnecessary 
plain character reset.
+            if (nMode == FieldFlags::CmdEnd)
+                m_aRunText->append(OOO_STRING_SVTOOLS_RTF_PLAIN);
+            m_aRunText->append(" {");
         }
         if (nMode & FieldFlags::Close)
         {
diff --git a/sw/source/filter/ww8/wrtw8nds.cxx 
b/sw/source/filter/ww8/wrtw8nds.cxx
index e27137946ef5..1d02b5a6f73d 100644
--- a/sw/source/filter/ww8/wrtw8nds.cxx
+++ b/sw/source/filter/ww8/wrtw8nds.cxx
@@ -2621,7 +2621,12 @@ void MSWordExportBase::OutputTextNode( SwTextNode& rNode 
)
                     // DateFieldmark / ODF_FORMDATE is not a field...
                     if (pFieldmark->GetFieldname() != ODF_FORMDATE)
                     {
-                        OutputField( nullptr, lcl_getFieldId( pFieldmark ), 
OUString(), FieldFlags::CmdEnd );
+                        FieldFlags nFlags = FieldFlags::CmdEnd;
+                        // send hint that fldrslt is empty, to avoid spamming 
RTF CharProp reset.
+                        // ::End does nothing when sending 
rFieldCmd=OUString(), so safe to do.
+                        if (pFieldmark->GetContent().isEmpty())
+                            nFlags |= FieldFlags::End;
+                        OutputField(nullptr, lcl_getFieldId(pFieldmark), 
OUString(), nFlags);
 
                         if (pFieldmark->GetFieldname() == ODF_UNHANDLED)
                         {
commit 366f720c16dad01638faf458ebe615bd7cc7509e
Author:     Justin Luth <justin.l...@collabora.com>
AuthorDate: Fri Dec 1 14:16:14 2023 -0500
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 16:44:25 2024 +0100

    tdf#108505 writerfilter: fix field direct char settings
    
    Instead of adding characters properties one at a time,
    lets take care of everything all at once.
    
    The results seem to be good so far.
    There is even some similarity between
    how MS Word has these properties on the
    "in-between" pseudo end character, where
    placing the cursor after the field gets these properties.
    I don't see it happening in MS Word
    at the pseudo start character, but it does in LO now...
    
    Hopefully that doesn't end up doing bad things.
    
    In the unit test, replacing the content ends up
    in red, italic. However, I see the same thing in MSO
    when testing with my second FORMTEXT example,
    so I think everything is "working as expected".
    
    I tried to see if I could limit doing this
    for only certain types of fields or conditions.
    However, pContext->GetResult() doesn't have a ldrslt
    yet at the time this is happening. Also, TextField.is()
    happens less than I expected. I'm sure I could limit it
    to just certain pContext->GetFieldId(),
    but so far no problems are noticed for all field types.
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat
    
    make CppunitTest_sw_rtfexport6 \
        CPPUNIT_TEST_NAME=testTdf108505_fieldCharFormat2
    
    Change-Id: I3223437fd0d694f5e5733a9f7323f10f03d7802f
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/160232
    Tested-by: Jenkins
    Tested-by: Gabor Kelemen <kelem...@ubuntu.com>
    Reviewed-by: Miklos Vajna <vmik...@collabora.com>

diff --git a/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf 
b/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf
new file mode 100644
index 000000000000..bb45e3052011
--- /dev/null
+++ b/sw/qa/extras/rtfexport/data/tdf108505_fieldCharFormat2.rtf
@@ -0,0 +1,37 @@
+{ 
tf1deflang1025nsinsicpg1252\uc1deff0\deff0\stshfdbch0\stshfloch0\stshfhich0\stshfbi0\deflang2057\deflangfe2057
   hemelang3079    hemelangfe0     hemelangcs0
+
+
oqfpromote {\stylesheet{\ql \li0 i0\widctlpar\wrapdefaultspalphaspnum
aautodjustright in0\lin0\itap0  tlchcs1 
+f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+ qc      x4819   qr      
x9071\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0  tlchcs1 
f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+}
+\paperw16834\paperh11913\margl1134\margr1418\margt1418\margb567\gutter0\ltrsect
 
+\deftab708\widowctrltnbjenddoc\hyphhotz425   rackmoves0      
rackformatting1\donotembedsysfont0 elyonvml0\donotembedlingdata0\grfdocevents0
alidatexml1\showplaceholdtext0\ignoremixedcontent0\saveinvalidxml0
+\showxmlerrors1
oextrasprl\prcolbl+\jexpandiewkind1iewscale70\pgbrdrhead\pgbrdrfoot
olnhtadjtbl
ojkernpunct sidroot3825670 et0
+
+\ltrrow        rowd \irow0\irowband0\lastrow \ltrrow
+       s11     rgaph70 rleft-70        rkeep   rftsWidth3      rwWidth8931     
rftsWidthB3     rftsWidthA3     rpaddl70        rpaddr70        rpaddfl3        
rpaddfr3        blrsid16408416  blind0  blindtype3 +++\pard\plain 
\ltrpar\s17\ql \li72 i0\sb120\sa120\widctlpar\intbl   qr      
x1561\wrapdefaultspalphaspnumaautodjustright in0\lin72\pararsid8918882  
tlchcs1 f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+
+{onttbl{0romanprq2charset0 Times New Roman;}{5nilprq2charset128 Linux 
Biolinum Keyboard O;}}
+
+{+
+{ tlchcs1 f0 \ltrchcs0 5s32+ tlchcs1 f0fs20lang1025 \ltrchcs0 
s26\lang1031\langfe3079+\qc \li0 
i0\sb120\sa120\widctlpar\intbl\wrapdefaultspalphaspnumaautodjustright 
in0\lin0 { tlchcs1 f0 \ltrchcs0 \insrsid5701682+
+{ield{\*ldinst {\ltrchcs0 \is40+{\*ormfield{ftype0ftypetxt0{\*fname 
Text1}
+{\*fdeftext {placeholder}}}}}}
+{ldrslt s48 xyz}}
+
+\sectd \ltrsect
+\lndscpsxninfsxn4insxn4\linex0\headery851\sectlinegrid354\sectdefaultcl\sectrsid1197700\sftnbj
 { tlchcs1 f0 \ltrchcs0 \insrsid5701682+++++}
diff --git a/sw/qa/extras/rtfexport/rtfexport6.cxx 
b/sw/qa/extras/rtfexport/rtfexport6.cxx
index 6baa86e3079a..f64e3035c529 100644
--- a/sw/qa/extras/rtfexport/rtfexport6.cxx
+++ b/sw/qa/extras/rtfexport/rtfexport6.cxx
@@ -171,7 +171,26 @@ DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat, 
"tdf108505_fieldCharFormat
     uno::Reference<text::XTextRange> xRun = getRun(xPara, 3, "MZ");
     CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
     CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
-    // CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+    CPPUNIT_ASSERT_EQUAL(COL_LIGHTGREEN, getProperty<Color>(xRun, 
"CharColor"));
+}
+
+DECLARE_RTFEXPORT_TEST(testTdf108505_fieldCharFormat2, 
"tdf108505_fieldCharFormat2.rtf")
+{
+    // not exported properly. Currrently xyz exports as run 6, red, italic.
+    if (isExported())
+        return;
+
+    uno::Reference<text::XTextTable> xTable(getParagraphOrTable(1), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xCell(xTable->getCellByName("C1"), 
uno::UNO_QUERY);
+    uno::Reference<text::XTextRange> xPara = getParagraphOfText(1, 
xCell->getText());
+
+    // Preemptive test: nothing found wrong/fixed by the accompanying patch
+    // Character formatting should only be defined by the ldrslt, and not by 
prior formatting.
+    // Prior formatting is italic, red, 20pt.
+    uno::Reference<text::XTextRange> xRun = getRun(xPara, 5, u"xyz"_ustr);
+    CPPUNIT_ASSERT_EQUAL(awt::FontWeight::BOLD, getProperty<float>(xRun, 
"CharWeight"));
+    CPPUNIT_ASSERT_EQUAL(awt::FontSlant_NONE, 
getProperty<awt::FontSlant>(xRun, "CharPosture"));
+    CPPUNIT_ASSERT_EQUAL(COL_AUTO, getProperty<Color>(xRun, "CharColor"));
 }
 
 /** Make sure that the document variable "Unused", which is not referenced in 
the document,
diff --git a/writerfilter/source/dmapper/DomainMapper_Impl.cxx 
b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
index 3f417afd6ae0..118bae8dfe6e 100644
--- a/writerfilter/source/dmapper/DomainMapper_Impl.cxx
+++ b/writerfilter/source/dmapper/DomainMapper_Impl.cxx
@@ -7296,11 +7296,8 @@ void DomainMapper_Impl::CloseFieldCommand()
         (void)vSwitches;
         OUString const sFirstParam(vArguments.empty() ? OUString() : 
vArguments.front());
 
-        // apply font size to the form control
-        if (!m_aTextAppendStack.empty() && m_pLastCharacterContext
-            && (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT)
-                || m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME)
-                || m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT)))
+        // apply character properties to the form control
+        if (!m_aTextAppendStack.empty() && m_pLastCharacterContext)
         {
             uno::Reference< text::XTextAppend >  xTextAppend = 
m_aTextAppendStack.top().xTextAppend;
             if (xTextAppend.is())
@@ -7310,20 +7307,17 @@ void DomainMapper_Impl::CloseFieldCommand()
                 {
                     xCrsr->gotoEnd(false);
                     uno::Reference< beans::XPropertySet > xProp( xCrsr, 
uno::UNO_QUERY );
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT))
+                    for (auto& rPropValue : 
m_pLastCharacterContext->GetPropertyValues(false))
                     {
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT), 
m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT)->second);
-                        if 
(m_pLastCharacterContext->isSet(PROP_CHAR_HEIGHT_COMPLEX))
-                            
xProp->setPropertyValue(getPropertyName(PROP_CHAR_HEIGHT_COMPLEX), 
m_pLastCharacterContext->getProperty(PROP_CHAR_HEIGHT_COMPLEX)->second);
-                    }
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT))
-                    {
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT), 
m_pLastCharacterContext->getProperty(PROP_CHAR_WEIGHT)->second);
-                        if 
(m_pLastCharacterContext->isSet(PROP_CHAR_WEIGHT_COMPLEX))
-                            
xProp->setPropertyValue(getPropertyName(PROP_CHAR_WEIGHT_COMPLEX), 
m_pLastCharacterContext->getProperty(PROP_CHAR_WEIGHT_COMPLEX)->second);
+                        try
+                        {
+                            xProp->setPropertyValue(rPropValue.Name, 
rPropValue.Value);
+                        }
+                        catch(uno::Exception&)
+                        {
+                            TOOLS_WARN_EXCEPTION( "writerfilter.dmapper", 
"Unknown Field PropVal");
+                        }
                     }
-                    if (m_pLastCharacterContext->isSet(PROP_CHAR_FONT_NAME))
-                        
xProp->setPropertyValue(getPropertyName(PROP_CHAR_FONT_NAME), 
m_pLastCharacterContext->getProperty(PROP_CHAR_FONT_NAME)->second);
                 }
             }
         }
commit a84df57622b6b35cef17176b4400317b20d66330
Author:     Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
AuthorDate: Mon Aug 14 15:59:18 2023 +0200
Commit:     Thorsten Behrens <thorsten.behr...@allotropia.de>
CommitDate: Fri Feb 9 10:50:18 2024 +0100

    tdf#146487 Don't show generic diagram title when there is an empty title 
given
    
    Bugdoc has autoTitleDeleted set to false (so title should be visible), but 
then an empty title is given.
    In this case no default string should be added to the title, only in case 
of Pie Charts.
    Any other Chart types show the default title in MS-Office.
    
    Co-authored-by: Balazs Varga <balazs.varga.ext...@allotropia.de>
    
    Change-Id: Ib445099a4a3d113cff6b1ffdfd093fe41c34716b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155681
    Tested-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
    Reviewed-by: Samuel Mehrbrodt <samuel.mehrbr...@allotropia.de>
    (cherry picked from commit c205194b8c54011af4b2cd34fbc00f4885883643)
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162270
    Tested-by: Jenkins
    Reviewed-by: Thorsten Behrens <thorsten.behr...@allotropia.de>

diff --git a/chart2/qa/extras/chart2import.cxx 
b/chart2/qa/extras/chart2import.cxx
index d4bae4aa40d5..fc1b5ea34cc7 100644
--- a/chart2/qa/extras/chart2import.cxx
+++ b/chart2/qa/extras/chart2import.cxx
@@ -1979,6 +1979,17 @@ CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testTdf121205)
     CPPUNIT_ASSERT_EQUAL(OUString("Firstline
Secondline
Thirdline"), aTitle);
 }
 
+CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testTdf146487)
+{
+    loadFromFile(u"pptx/tdf146487.pptx");
+    Reference<chart2::XChartDocument> xChartDoc(getChartDocFromDrawImpress(0, 
0), uno::UNO_QUERY);
+    CPPUNIT_ASSERT_MESSAGE("failed to load chart", xChartDoc.is());
+
+    Reference<chart2::XTitled> xTitled(xChartDoc, uno::UNO_QUERY_THROW);
+    uno::Reference<chart2::XTitle> xTitle = xTitled->getTitleObject();
+    CPPUNIT_ASSERT_MESSAGE("chart doc should not have a title", !xTitle.is());
+}
+
 CPPUNIT_TEST_FIXTURE(Chart2ImportTest, testFixedSizeBarChartVeryLongLabel)
 {
     // Bar chart area size is fixed (not automatic) so we can't resize
diff --git a/chart2/qa/extras/data/pptx/tdf146487.pptx 
b/chart2/qa/extras/data/pptx/tdf146487.pptx
new file mode 100644
index 000000000000..2a78ae5d859b
Binary files /dev/null and b/chart2/qa/extras/data/pptx/tdf146487.pptx differ
diff --git a/oox/inc/drawingml/chart/plotareaconverter.hxx 
b/oox/inc/drawingml/chart/plotareaconverter.hxx
index b520c6b4816c..988405b3247c 100644
--- a/oox/inc/drawingml/chart/plotareaconverter.hxx
+++ b/oox/inc/drawingml/chart/plotareaconverter.hxx
@@ -74,6 +74,8 @@ public:
 
     /** Returns the automatic chart title if the chart contains only one 
series. */
     const OUString&     getAutomaticTitle() const { return maAutoTitle; }
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool                isSingleSeriesTitle() const { return 
mbSingleSeriesTitle; }
     /** Returns true, if chart type supports wall and floor format in 3D mode. 
*/
     bool                isWall3dChart() const { return mbWall3dChart; }
 
@@ -82,6 +84,7 @@ private:
     bool                mb3dChart;
     bool                mbWall3dChart;
     bool                mbPieChart;
+    bool                mbSingleSeriesTitle;;
 };
 
 
diff --git a/oox/inc/drawingml/chart/typegroupconverter.hxx 
b/oox/inc/drawingml/chart/typegroupconverter.hxx
index 2e3aae5a2a10..6b780dd0ae15 100644
--- a/oox/inc/drawingml/chart/typegroupconverter.hxx
+++ b/oox/inc/drawingml/chart/typegroupconverter.hxx
@@ -133,6 +133,9 @@ public:
     /** Returns series title, if the chart type group contains only one single 
series. */
     OUString            getSingleSeriesTitle() const;
 
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool                isSingleSeriesTitle() const;
+
     /** Creates a coordinate system according to the contained chart type. */
     css::uno::Reference< css::chart2::XCoordinateSystem >
                         createCoordinateSystem();
diff --git a/oox/source/drawingml/chart/chartspaceconverter.cxx 
b/oox/source/drawingml/chart/chartspaceconverter.cxx
index c83ed37e9c02..f9b370e04d8f 100644
--- a/oox/source/drawingml/chart/chartspaceconverter.cxx
+++ b/oox/source/drawingml/chart/chartspaceconverter.cxx
@@ -38,6 +38,7 @@
 #include <drawingml/chart/titleconverter.hxx>
 #include <ooxresid.hxx>
 #include <strings.hrc>
+#include <drawingml/textbody.hxx>
 
 using namespace ::com::sun::star;
 using ::com::sun::star::uno::Reference;
@@ -183,7 +184,18 @@ void ChartSpaceConverter::convertFromModel( const 
Reference< XShapes >& rxExtern
         OUString aAutoTitle = aPlotAreaConv.getAutomaticTitle();
         if( mrModel.mxTitle.is() || !aAutoTitle.isEmpty() )
         {
-            if( aAutoTitle.isEmpty() )
+            // tdf#146487 In some cases, we need to show the empty title
+            bool bShowEmptyTitle = aAutoTitle.isEmpty() && 
!mrModel.mbAutoTitleDel
+                                   && aPlotAreaConv.isSingleSeriesTitle()
+                                   && mrModel.mxTitle->mxShapeProp.is()
+                                   && mrModel.mxTitle->mxTextProp.is()
+                                   && mrModel.mxTitle->mxTextProp->isEmpty();
+            // Also for tdf#146487
+            bool bEmptyRichText = mrModel.mxTitle->mxText.is()
+                && mrModel.mxTitle->mxText->mxTextBody.is()
+                && mrModel.mxTitle->mxText->mxTextBody->isEmpty();
+
+            if (aAutoTitle.isEmpty() && !bShowEmptyTitle && !bEmptyRichText)
                 aAutoTitle = OoxResId(STR_DIAGRAM_TITLE);
             Reference< XTitled > xTitled( getChartDocument(), UNO_QUERY_THROW 
);
             TitleConverter aTitleConv( *this, mrModel.mxTitle.getOrCreate() );
diff --git a/oox/source/drawingml/chart/plotareaconverter.cxx 
b/oox/source/drawingml/chart/plotareaconverter.cxx
index 96e51c577d43..32e4de7d1ee4 100644
--- a/oox/source/drawingml/chart/plotareaconverter.cxx
+++ b/oox/source/drawingml/chart/plotareaconverter.cxx
@@ -76,6 +76,8 @@ public:
 
     /** Returns the automatic chart title if the axes set contains only one 
series. */
     const OUString& getAutomaticTitle() const { return maAutoTitle; }
+    /** Returns true, if the chart contains only one series and have title 
textbox (even empty). */
+    bool         isSingleSeriesTitle() const { return mbSingleSeriesTitle; }
     /** Returns true, if the chart is three-dimensional. */
     bool         is3dChart() const { return mb3dChart; }
     /** Returns true, if chart type supports wall and floor format in 3D mode. 
*/
@@ -88,13 +90,15 @@ private:
     bool                mb3dChart;
     bool                mbWall3dChart;
     bool                mbPieChart;
+    bool                mbSingleSeriesTitle;
 };
 
 AxesSetConverter::AxesSetConverter( const ConverterRoot& rParent, 
AxesSetModel& rModel ) :
     ConverterBase< AxesSetModel >( rParent, rModel ),
     mb3dChart( false ),
     mbWall3dChart( false ),
-    mbPieChart( false )
+    mbPieChart( false ),
+    mbSingleSeriesTitle( false )
 {
 }
 
@@ -127,7 +131,10 @@ void AxesSetConverter::convertFromModel( const Reference< 
XDiagram >& rxDiagram,
 
         // get automatic chart title, if there is only one type group
         if( aTypeGroups.size() == 1 )
+        {
             maAutoTitle = rFirstTypeGroup.getSingleSeriesTitle();
+            mbSingleSeriesTitle = rFirstTypeGroup.isSingleSeriesTitle();
+        }
 
         /*  Create a coordinate system. For now, all type groups from all axes 
sets
             have to be inserted into one coordinate system. Later, chart2 
should
@@ -422,6 +429,7 @@ void PlotAreaConverter::convertFromModel( View3DModel& 
rView3DModel )
         if(nAxesSetIdx == nStartAxesSetIdx)
         {
             maAutoTitle = aAxesSetConv.getAutomaticTitle();
+            mbSingleSeriesTitle = aAxesSetConv.isSingleSeriesTitle();
             mb3dChart = aAxesSetConv.is3dChart();
             mbWall3dChart = aAxesSetConv.isWall3dChart();
             mbPieChart = aAxesSetConv.isPieChart();
diff --git a/oox/source/drawingml/chart/typegroupconverter.cxx 
b/oox/source/drawingml/chart/typegroupconverter.cxx
index e8d8bb47bc33..327a855f708f 100644
--- a/oox/source/drawingml/chart/typegroupconverter.cxx
+++ b/oox/source/drawingml/chart/typegroupconverter.cxx
@@ -234,6 +234,15 @@ OUString TypeGroupConverter::getSingleSeriesTitle() const
     return aSeriesTitle;
 }
 
+bool TypeGroupConverter::isSingleSeriesTitle() const
+{
+    if (!mrModel.maSeries.empty() && (maTypeInfo.mbSingleSeriesVis || 
(mrModel.maSeries.size() == 1)) &&
+        mrModel.maSeries.front()->mxText.is())
+        return true;
+
+    return false;
+}
+
 Reference< XCoordinateSystem > TypeGroupConverter::createCoordinateSystem()
 {
     // create the coordinate system object

Reply via email to