tdf#114799 Char highlight: skip convert if highlight exists

Don't create two w:highlight entries. This can easily
occur on the endParagraph properties when the user
has replaced the background color. A "none" highlight
is added, the charShadingMarker is removed, and a new
background color is added. So the new background tries
to export as a highlight, even though the none-highlight
overrides it.

This depends on this bug's earlier commit, which added the
context so that HasItem can even find the highlight.

Change-Id: Ibfd6a3b9b94bdeb1fd9ec46fbb71ec825b09a680
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/111297
Tested-by: Jenkins
Reviewed-by: Justin Luth <justin_luth@sil.org>
Reviewed-by: Miklos Vajna <vmiklos@collabora.com>
diff --git a/sw/qa/extras/ooxmlexport/data/tdf135774_numberingCRProps.docx b/sw/qa/extras/ooxmlexport/data/tdf135774_numberingCRProps.docx
new file mode 100644
index 0000000..697db30
--- /dev/null
+++ b/sw/qa/extras/ooxmlexport/data/tdf135774_numberingCRProps.docx
Binary files differ
diff --git a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
index 01fc4eb..77fcb3f 100644
--- a/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
+++ b/sw/qa/extras/ooxmlexport/ooxmlexport14.cxx
@@ -11,6 +11,7 @@

#include <com/sun/star/awt/FontUnderline.hpp>
#include <com/sun/star/awt/FontWeight.hpp>
#include <com/sun/star/beans/NamedValue.hpp>
#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/frame/XStorable.hpp>
#include <com/sun/star/style/LineSpacing.hpp>
@@ -34,6 +35,7 @@
#include <comphelper/sequenceashashmap.hxx>
#include <oox/drawingml/drawingmltypes.hxx>
#include <tools/lineend.hxx>
#include <unotools/fltrcfg.hxx>
#include <unotools/mediadescriptor.hxx>

using namespace com::sun::star;
@@ -857,6 +859,58 @@
    assertXPath(pXmlDoc, "//w:docVars/w:docVar", "val", "bar");
}

CPPUNIT_TEST_FIXTURE(SwModelTestBase, testHighlightEdit_numbering)
{
    // Create the doc model.
    OUString aURL = m_directories.getURLFromSrc(DATA_DIRECTORY) + "tdf135774_numberingCRProps.docx";
    loadURL(aURL, nullptr);

    // This only affects when saving as w:highlight - which is not the default since 7.0.
    SvtFilterOptions& rOpt = SvtFilterOptions::Get();
    bool bWasExportToShade = rOpt.IsCharBackground2Shading();
    rOpt.SetCharBackground2Highlighting();

    //Simulate a user editing the char background color of the paragraph 2 marker (CR)
    uno::Reference<beans::XPropertySet> properties(getParagraph(2), uno::UNO_QUERY);
    uno::Sequence<beans::NamedValue> aListAutoFormat;
    CPPUNIT_ASSERT(properties->getPropertyValue("ListAutoFormat") >>= aListAutoFormat);
    comphelper::SequenceAsHashMap aMap(properties->getPropertyValue("ListAutoFormat"));
    // change the background color to RES_CHRATR_BACKGROUND.
    aMap["CharBackColor"] <<= static_cast<sal_Int32>(0xff00ff);
    // Two attributes can affect character background. Highlight has priority, and is only there for MS compatibility,
    // so clear any potential highlight set earlier, or override any coming via a style.
    aMap["CharHighlight"] <<= static_cast<sal_Int32>(COL_TRANSPARENT);

    uno::Sequence<beans::PropertyValue> aGrabBag;
    aMap["CharInteropGrabBag"] >>= aGrabBag;
    for (beans::PropertyValue& rProp : aGrabBag)
    {
        // The shading is no longer defined from import, so clear that flag.
        // BackColor 0xff00ff will now attempt to export as highlight, since we set that in SvtFilterOptions.
        if (rProp.Name == "CharShadingMarker")
            rProp.Value <<= false;
    }
    aMap["CharInteropGrabBag"] <<= aGrabBag;

    aMap >> aListAutoFormat;
    properties->setPropertyValue("ListAutoFormat", uno::makeAny(aListAutoFormat));

    // Export to docx.
    uno::Reference<frame::XStorable> xStorable(mxComponent, uno::UNO_QUERY);
    utl::MediaDescriptor aMediaDescriptor;
    aMediaDescriptor["FilterName"] <<= OUString("Office Open XML Text");
    xStorable->storeToURL(maTempFile.GetURL(), aMediaDescriptor.getAsConstPropertyValueList());
    mbExported = true;

    // Paragraph 2 should have only one w:highlight written per w:rPr. Without the fix, there were two.
    xmlDocUniquePtr pXmlDoc = parseExport("word/document.xml");
    assertXPath(pXmlDoc, "//w:body/w:p[2]/w:pPr/w:rPr/w:highlight", "val", "none");
    // Visually, the "none" highlight means the bullet point should not have a character background.

    if (bWasExportToShade)
        rOpt.SetCharBackground2Shading();
}

DECLARE_OOXMLEXPORT_EXPORTONLY_TEST(testTdf132766, "tdf132766.docx")
{
    xmlDocUniquePtr pXmlDoc = parseExport("word/numbering.xml");
diff --git a/sw/source/filter/ww8/ww8atr.cxx b/sw/source/filter/ww8/ww8atr.cxx
index f8c0ee8..5d3f4b8 100644
--- a/sw/source/filter/ww8/ww8atr.cxx
+++ b/sw/source/filter/ww8/ww8atr.cxx
@@ -5628,7 +5628,10 @@
    }
    else
    {
        CharHighlight(rBrush);
        // Don't create a duplicate entry when converting to highlight. An existing one has priority.
        // Character runs seem to need a different method to detect duplicates? Just continue to ignore that situation.
        if (GetExport().m_aCurrentCharPropStarts.size() || !GetExport().HasItem(RES_CHRATR_HIGHLIGHT))
            CharHighlight(rBrush);
    }
}