sc/source/filter/inc/orcusinterface.hxx       |   15 ++++
 sc/source/filter/orcus/interface.cxx          |   82 ++++++++++++++++++++------
 sc/source/ui/dataprovider/xmldataprovider.cxx |    2 
 3 files changed, 79 insertions(+), 20 deletions(-)

New commits:
commit 695ae365dcab7c7dd59b39411299c5c200081885
Author:     Kohei Yoshida <ko...@libreoffice.org>
AuthorDate: Tue Aug 29 22:13:32 2023 -0400
Commit:     Kohei Yoshida <ko...@libreoffice.org>
CommitDate: Thu Aug 31 03:03:29 2023 +0200

    Add support for rich-text string import via orcus interface
    
    It was previously imported only as non-formatted strings.  Font names
    and sizes are to be imported later.
    
    Change-Id: I93a313851e87f1d6d9ccc409ca9a9f1abff3de0d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/156271
    Tested-by: Jenkins
    Reviewed-by: Kohei Yoshida <ko...@libreoffice.org>

diff --git a/sc/source/filter/inc/orcusinterface.hxx 
b/sc/source/filter/inc/orcusinterface.hxx
index ed3966a2e136..2fd1d5ed40f3 100644
--- a/sc/source/filter/inc/orcusinterface.hxx
+++ b/sc/source/filter/inc/orcusinterface.hxx
@@ -11,10 +11,12 @@
 
 #include <address.hxx>
 #include <documentimport.hxx>
+#include <editutil.hxx>
 
 #include <tools/color.hxx>
 #include <tools/fontenum.hxx>
 #include <editeng/svxenum.hxx>
+#include <editeng/editobj.hxx>
 
 #include "sharedformulagroups.hxx"
 
@@ -30,6 +32,7 @@
 #include <map>
 #include <unordered_map>
 #include <vector>
+#include <variant>
 
 class ScOrcusSheet;
 class ScOrcusStyles;
@@ -103,8 +106,13 @@ public:
 class ScOrcusSharedStrings : public 
orcus::spreadsheet::iface::import_shared_strings
 {
     ScOrcusFactory& mrFactory;
+    ScFieldEditEngine& mrEditEngine;
+
+    SfxItemSet maCurFormat;
+    std::vector<std::pair<ESelection, SfxItemSet>> maFormatSegments;
+
+    OUString toOUString(std::string_view s);
 
-    OStringBuffer maCurSegment;
 public:
     ScOrcusSharedStrings(ScOrcusFactory& rFactory);
 
@@ -696,12 +704,13 @@ class ScOrcusFactory : public 
orcus::spreadsheet::iface::import_factory
         CellStoreToken( const ScAddress& rPos, OUString aFormula, 
formula::FormulaGrammar::Grammar eGrammar );
     };
 
+    using StringValueType = std::variant<OUString, 
std::unique_ptr<EditTextObject>>;
     typedef std::unordered_map<OUString, size_t> StringHashType;
     typedef std::vector<CellStoreToken> CellStoreTokensType;
 
     ScDocumentImport maDoc;
 
-    std::vector<OUString> maStrings;
+    std::vector<StringValueType> maStrings;
     StringHashType maStringHash;
 
     CellStoreTokensType maCellStoreTokens;
@@ -735,6 +744,8 @@ public:
 
     size_t appendString(const OUString& rStr);
     size_t addString(const OUString& rStr);
+    std::size_t appendFormattedString(std::unique_ptr<EditTextObject> 
pEditText);
+
     const OUString* getString(size_t nIndex) const;
 
     void pushCellStoreAutoToken( const ScAddress& rPos, const OUString& rVal );
diff --git a/sc/source/filter/orcus/interface.cxx 
b/sc/source/filter/orcus/interface.cxx
index a61d545d9151..c2c784a5a016 100644
--- a/sc/source/filter/orcus/interface.cxx
+++ b/sc/source/filter/orcus/interface.cxx
@@ -37,6 +37,7 @@
 #include <editeng/lineitem.hxx>
 #include <editeng/crossedoutitem.hxx>
 #include <editeng/justifyitem.hxx>
+#include <editeng/eeitem.hxx>
 
 #include <svl/sharedstringpool.hxx>
 #include <svl/numformat.hxx>
@@ -455,7 +456,16 @@ void ScOrcusFactory::finalize()
                     // String index out-of-bound!  Something is up.
                     break;
 
-                maDoc.setStringCell(rToken.maPos, maStrings[rToken.mnIndex1]);
+                const auto& s = maStrings[rToken.mnIndex1];
+                switch (s.index())
+                {
+                    case 0: // OUString
+                        maDoc.setStringCell(rToken.maPos, std::get<0>(s));
+                        break;
+                    case 1: // std::unique_ptr<EditTextObject>
+                        maDoc.setEditCell(rToken.maPos, 
std::get<1>(s)->Clone());
+                        break;
+                }
                 ++nCellCount;
                 break;
             }
@@ -577,9 +587,23 @@ size_t ScOrcusFactory::addString(const OUString& rStr)
     return appendString(rStr);
 }
 
+std::size_t 
ScOrcusFactory::appendFormattedString(std::unique_ptr<EditTextObject> pEditText)
+{
+    std::size_t nPos = maStrings.size();
+    maStrings.push_back(std::move(pEditText));
+    return nPos;
+}
+
 const OUString* ScOrcusFactory::getString(size_t nIndex) const
 {
-    return nIndex < maStrings.size() ? &maStrings[nIndex] : nullptr;
+    if (nIndex >= maStrings.size())
+        return nullptr;
+
+    const StringValueType& rStr = maStrings[nIndex];
+    if (rStr.index() != 0)
+        return nullptr;
+
+    return &std::get<OUString>(rStr);
 }
 
 void ScOrcusFactory::pushCellStoreAutoToken( const ScAddress& rPos, const 
OUString& rVal )
@@ -1294,31 +1318,43 @@ ScOrcusFactory& ScOrcusSheet::getFactory()
     return mrFactory;
 }
 
+OUString ScOrcusSharedStrings::toOUString(std::string_view s)
+{
+    return {s.data(), sal_Int32(s.size()), 
mrFactory.getGlobalSettings().getTextEncoding()};
+}
+
 ScOrcusSharedStrings::ScOrcusSharedStrings(ScOrcusFactory& rFactory) :
-    mrFactory(rFactory) {}
+    mrFactory(rFactory),
+    mrEditEngine(rFactory.getDoc().getDoc().GetEditEngine()),
+    maCurFormat(mrEditEngine.GetEmptyItemSet())
+{
+    mrEditEngine.Clear();
+}
 
 size_t ScOrcusSharedStrings::append(std::string_view s)
 {
-    OUString aNewString(s.data(), s.size(), 
mrFactory.getGlobalSettings().getTextEncoding());
-    return mrFactory.appendString(aNewString);
+    return mrFactory.appendString(toOUString(s));
 }
 
 size_t ScOrcusSharedStrings::add(std::string_view s)
 {
-    OUString aNewString(s.data(), s.size(), 
mrFactory.getGlobalSettings().getTextEncoding());
-    return mrFactory.addString(aNewString);
+    return mrFactory.addString(toOUString(s));
 }
 
 void ScOrcusSharedStrings::set_segment_font(size_t /*font_index*/)
 {
 }
 
-void ScOrcusSharedStrings::set_segment_bold(bool /*b*/)
+void ScOrcusSharedStrings::set_segment_bold(bool b)
 {
+    FontWeight eWeight = b ? WEIGHT_BOLD : WEIGHT_NORMAL;
+    maCurFormat.Put(SvxWeightItem(eWeight, EE_CHAR_WEIGHT));
 }
 
-void ScOrcusSharedStrings::set_segment_italic(bool /*b*/)
+void ScOrcusSharedStrings::set_segment_italic(bool b)
 {
+    FontItalic eItalic = b ? ITALIC_NORMAL : ITALIC_NONE;
+    maCurFormat.Put(SvxPostureItem(eItalic, EE_CHAR_ITALIC));
 }
 
 void ScOrcusSharedStrings::set_segment_font_name(std::string_view /*s*/)
@@ -1329,23 +1365,35 @@ void ScOrcusSharedStrings::set_segment_font_size(double 
/*point*/)
 {
 }
 
-void 
ScOrcusSharedStrings::set_segment_font_color(orcus::spreadsheet::color_elem_t,
-            orcus::spreadsheet::color_elem_t,
-            orcus::spreadsheet::color_elem_t,
-            orcus::spreadsheet::color_elem_t)
+void ScOrcusSharedStrings::set_segment_font_color(
+    os::color_elem_t alpha, os::color_elem_t red, os::color_elem_t green, 
os::color_elem_t blue)
 {
+    Color aColor(ColorAlpha, alpha, red, green, blue);
+    maCurFormat.Put(SvxColorItem(aColor, EE_CHAR_COLOR));
 }
 
 void ScOrcusSharedStrings::append_segment(std::string_view s)
 {
-    maCurSegment.append(s.data(), s.size());
+    sal_Int32 nPos = mrEditEngine.GetText().getLength();
+    ESelection aSel{0, nPos, 0, nPos}; // end of current text
+
+    OUString aStr = toOUString(s);
+    mrEditEngine.QuickInsertText(aStr, aSel);
+
+    aSel.nEndPos += aStr.getLength(); // expand the selection over the current 
segment
+    maFormatSegments.emplace_back(aSel, maCurFormat);
+    maCurFormat.ClearItem();
 }
 
 size_t ScOrcusSharedStrings::commit_segments()
 {
-    OString aStr = maCurSegment.makeStringAndClear();
-    return mrFactory.addString(
-        OStringToOUString(aStr, 
mrFactory.getGlobalSettings().getTextEncoding()));
+    for (const auto& [rSel, rFormat] : maFormatSegments)
+        mrEditEngine.QuickSetAttribs(rFormat, rSel);
+
+    auto nPos = 
mrFactory.appendFormattedString(mrEditEngine.CreateTextObject());
+    mrEditEngine.Clear();
+    maFormatSegments.clear();
+    return nPos;
 }
 
 void ScOrcusFont::applyToItemSet( SfxItemSet& rSet ) const
diff --git a/sc/source/ui/dataprovider/xmldataprovider.cxx 
b/sc/source/ui/dataprovider/xmldataprovider.cxx
index fc5c4f07e5e9..464382ecef12 100644
--- a/sc/source/ui/dataprovider/xmldataprovider.cxx
+++ b/sc/source/ui/dataprovider/xmldataprovider.cxx
@@ -71,6 +71,7 @@ void XMLFetchThread::execute()
         maParam.maRangeLinks.push_back(aRangeLink);
     }
     // Do the import.
+    SolarMutexGuard aGuard;
     mpXMLContext->importXML(maParam);
 
     for (auto& itr : maDataTransformations)
@@ -78,7 +79,6 @@ void XMLFetchThread::execute()
         itr->Transform(mrDocument);
     }
 
-    SolarMutexGuard aGuard;
     maImportFinishedHdl();
 }
 

Reply via email to