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-900i0 \ltrpar\qc first \par } \page\sect -{\pard \pvpg\phpg\posx13152\posy612bsw2984bsh-210i0 \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 {\ltrch0 \i0\ul0\strike0s15 \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 tlchcs1 +f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+ qc x4819 qr x9071\wrapdefaultspalphaspnumaautodjustright in0\lin0\itap0 tlchcs1 f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+} +\paperw16834\paperh11913\margl1134\margr1418\margt1418\margb567\gutter0\ltrsect +\deftab708\widowctrltnbjenddoc\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\wrapdefaultspalphaspnumaautodjustright in0\lin72\pararsid8918882 tlchcs1 f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+ +{onttbl{0romanprq2charset0 Times New Roman;}{5nilprq2charset128 Linux Biolinum Keyboard O;}} + +{+ +{ tlchcs1 f0 \ltrchcs0 5s32+ tlchcs1 f0fs20lang1025 \ltrchcs0 s26\lang1031\langfe3079+\qc \li0 i0\sb120\sa120\widctlpar\intbl\wrapdefaultspalphaspnumaautodjustright in0\lin0 { tlchcs1 f0 \ltrchcs0 \insrsid5701682+ +{ield{\*ldinst {\ltrchcs0 \is40+{\*ormfield{ftype0ftypetxt0{\*fname Text1} +{\*fdeftext {placeholder}}}}}} +{ldrslt s48 xyz}} + +\sectd \ltrsect +\lndscpsxninfsxn4insxn4\linex0\headery851\sectlinegrid354\sectdefaultcl\sectrsid1197700\sftnbj { tlchcs1 f0 \ltrchcs0 \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