include/oox/vml/vmlshape.hxx            |    8 +-
 oox/source/vml/vmlshape.cxx             |   27 +++----
 sc/inc/postit.hxx                       |   20 +++++
 sc/source/core/data/postit.cxx          |   78 +++++++++++++++------
 sc/source/filter/excel/xeescher.cxx     |    9 +-
 sc/source/filter/inc/richstring.hxx     |    3 
 sc/source/filter/oox/commentsbuffer.cxx |  115 +++++++++++++++++++++++++-------
 sc/source/filter/oox/richstring.cxx     |   14 ++-
 sc/source/ui/docshell/docfunc.cxx       |    9 +-
 sc/source/ui/inc/docfunc.hxx            |   10 ++
 10 files changed, 214 insertions(+), 79 deletions(-)

New commits:
commit f17acc9d26650b051f9c59dc9646c00fd2794456
Author:     Caolán McNamara <caolan.mcnam...@collabora.com>
AuthorDate: Fri Aug 11 10:46:53 2023 +0100
Commit:     Caolán McNamara <caolan.mcnam...@collabora.com>
CommitDate: Tue Aug 15 13:40:21 2023 +0200

    defer turning xlsx notes into SdrCaptions until activated
    
    to improve import performance
    
    Change-Id: I8dd3483372d20cbbb8694bae02a7d8b062324ff0
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155613
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 2bda87fd8758448267c447ba26f1932325a1338d)
    
    fairly unreadable as combined commit, but component commits are:
    
    refactor to return the position to be set by the caller instead
    
    no change in behavior intended
    
    Change-Id: I32043bdf1d29521d8503df315fa786236e272f7d
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155580
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 5aeb15e95d26ce6de28eb5f5933324828d553f41)
    
    split ShapeBase::convertShapeProperties into two parts
    
    Change-Id: I62f42e54c776f15ea83c5fc861bb4f4ff899e891
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155584
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit c88855c45a675cf28e2cfe4fa261c2b0339f5898)
    
    move setting properties into note comments from oox to sc
    
    no change in behavior intended, the SdrCaption doesn't support
    the skipped conditions
    
    Change-Id: Id909ae4ed115c1ad3398d2a62c6432ff1dfde453
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155585
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 6945d031e759823ab52bdf077e43196b67f594a4)
    
    avoid some UNO querying
    
    Change-Id: I5fa793ab979221252f66bdd38e6950c06a66b00a
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/152601
    Tested-by: Jenkins
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    (cherry picked from commit 367f26ebf0f2be0c0c0ebeab1e14ee26960675e3)
    
    rearrange to collect the properties set on the annotation together
    
    and set them in one block. No behavior change intended.
    
    note: type passed as TextFitToSize seems to be wrong
    Change-Id: I349aeba5176ef6c10163069a73d0367469aadd6b
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155588
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit e11a0e646b8eb75e102f878dc70f5196c4efbea2)
    
    split out common ScPostIt insertion piece
    
    Change-Id: Ie9d718293f907e19e29ed6f8aea4a2bf9d88dfe9
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155610
    Tested-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 5ae486eea7a381403a9f81e5aa8ef1a0a57b95b6)
    
    split out a common CreateNoteData
    
    Change-Id: Ieeaf50f3a086d01b5492eb3ab9b211f132f045ac
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155611
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit ac40c3923580e4ec0e738d57ff8b885da93301ef)
    
    add a CreateNoteFromObjectProperties
    
    which an importer can use to insert a note and defer instantiating an
    SdrCaption until the user activates it
    
    Change-Id: I7d4afe7857d4ee9c49e7b43c5f94150b72ce9a95
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155612
    Tested-by: Jenkins
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>
    (cherry picked from commit 3cc72a1880d1fe2507892eabeb979aa0938dadc5)
    
    move GetEditTextObject to after it is potentially generated
    
    Change-Id: Iadd6a2b66e3131b8883cf3812b5f0a8153631abe
    Reviewed-on: https://gerrit.libreoffice.org/c/core/+/155661
    Tested-by: Jenkins CollaboraOffice <jenkinscollaboraoff...@gmail.com>
    Reviewed-by: Noel Grandin <noel.gran...@collabora.co.uk>
    Reviewed-by: Caolán McNamara <caolan.mcnam...@collabora.com>

diff --git a/include/oox/vml/vmlshape.hxx b/include/oox/vml/vmlshape.hxx
index d46c23282324..e95e44053330 100644
--- a/include/oox/vml/vmlshape.hxx
+++ b/include/oox/vml/vmlshape.hxx
@@ -267,9 +267,11 @@ public:
                             const css::uno::Reference< css::drawing::XShapes 
>& rxShapes,
                             const ShapeParentAnchor* pParentAnchor = nullptr ) 
const;
 
-    /** Converts position and formatting into the passed existing XShape. */
-    void                convertFormatting(
-                            const css::uno::Reference< css::drawing::XShape >& 
rxShape ) const;
+    /** Returns bounds of Shape */
+    css::awt::Rectangle getShapeRectangle() const;
+
+    /** Collects common shape properties such as formatting attributes. */
+    oox::drawingml::ShapePropertyMap makeShapePropertyMap() const;
 
     void setContainer(ShapeContainer* pContainer);
     ShapeContainer* getContainer() const;
diff --git a/oox/source/vml/vmlshape.cxx b/oox/source/vml/vmlshape.cxx
index bdbea0c86fc4..f28ca92e1cf9 100644
--- a/oox/source/vml/vmlshape.cxx
+++ b/oox/source/vml/vmlshape.cxx
@@ -484,22 +484,11 @@ Reference< XShape > ShapeBase::convertAndInsert( const 
Reference< XShapes >& rxS
     return xShape;
 }
 
-void ShapeBase::convertFormatting( const Reference< XShape >& rxShape ) const
+awt::Rectangle ShapeBase::getShapeRectangle() const
 {
-    if( !rxShape.is() )
-        return;
-
     /*  Calculate shape rectangle. Applications may do something special
         according to some imported shape client data (e.g. Excel cell anchor). 
*/
-    awt::Rectangle aShapeRect = calcShapeRectangle( nullptr );
-
-    // convert the shape, if the calculated rectangle is not empty
-    if( (aShapeRect.Width > 0) || (aShapeRect.Height > 0) )
-    {
-        rxShape->setPosition( awt::Point( aShapeRect.X, aShapeRect.Y ) );
-        rxShape->setSize( awt::Size( aShapeRect.Width, aShapeRect.Height ) );
-        convertShapeProperties( rxShape );
-    }
+    return calcShapeRectangle(nullptr);
 }
 
 void ShapeBase::setContainer(ShapeContainer* pContainer) { mpContainer = 
pContainer; }
@@ -519,16 +508,23 @@ awt::Rectangle ShapeBase::calcShapeRectangle( const 
ShapeParentAnchor* pParentAn
     return aShapeRect;
 }
 
-void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) 
const
+::oox::drawingml::ShapePropertyMap ShapeBase::makeShapePropertyMap() const
 {
     ::oox::drawingml::ShapePropertyMap aPropMap( 
mrDrawing.getFilter().getModelObjectHelper() );
     const GraphicHelper& rGraphicHelper = 
mrDrawing.getFilter().getGraphicHelper();
     maTypeModel.maStrokeModel.pushToPropMap( aPropMap, rGraphicHelper );
     maTypeModel.maFillModel.pushToPropMap( aPropMap, rGraphicHelper );
+    return aPropMap;
+}
+
+void ShapeBase::convertShapeProperties( const Reference< XShape >& rxShape ) 
const
+{
+    ::oox::drawingml::ShapePropertyMap aPropMap(makeShapePropertyMap());
 
     uno::Reference<lang::XServiceInfo> xSInfo(rxShape, uno::UNO_QUERY_THROW);
     if (xSInfo->supportsService("com.sun.star.text.TextFrame"))
     {
+        const GraphicHelper& rGraphicHelper = 
mrDrawing.getFilter().getGraphicHelper();
         // Any other service supporting the ShadowFormat property?
         maTypeModel.maShadowModel.pushToPropMap(aPropMap, rGraphicHelper);
         // TextFrames have BackColor, not FillColor
@@ -566,7 +562,10 @@ void ShapeBase::convertShapeProperties( const Reference< 
XShape >& rxShape ) con
         }
     }
     else if (xSInfo->supportsService("com.sun.star.drawing.CustomShape"))
+    {
+        const GraphicHelper& rGraphicHelper = 
mrDrawing.getFilter().getGraphicHelper();
         maTypeModel.maTextpathModel.pushToPropMap(aPropMap, rxShape, 
rGraphicHelper);
+    }
 
     PropertySet( rxShape ).setProperties( aPropMap );
 }
diff --git a/sc/inc/postit.hxx b/sc/inc/postit.hxx
index a7bfe873e0ed..2147622e58af 100644
--- a/sc/inc/postit.hxx
+++ b/sc/inc/postit.hxx
@@ -176,8 +176,21 @@ private:
     sal_uInt32          mnPostItId;
 };
 
+class GenerateNoteCaption
+{
+public:
+    virtual void Generate(SdrCaptionObj& rCaptionObj) = 0;
+    virtual OUString GetSimpleText() const = 0;
+    virtual ~GenerateNoteCaption() {};
+};
+
 class SC_DLLPUBLIC ScNoteUtil
 {
+    static ScPostIt* InsertNote(ScDocument& rDoc, const ScAddress& rPos, 
ScNoteData&& rNoteData,
+                                bool bAlwaysCreateCaption, sal_uInt32 
nPostItId);
+
+    static ScNoteData CreateNoteData(ScDocument& rDoc, const ScAddress& rPos,
+                                     const tools::Rectangle& rCaptionRect, 
bool bShown);
 public:
 
     /** Creates and returns a caption object for a temporary caption. */
@@ -235,6 +248,13 @@ public:
                             const OutlinerParaObject& rOutlinerObj,
                             const tools::Rectangle& rCaptionRect, bool bShown 
);
 
+    // similar to above, except xGenerator is a functor to apply import
+    // properties to the caption object to finalize it on demand
+    static ScPostIt*    CreateNoteFromGenerator(
+                            ScDocument& rDoc, const ScAddress& rPos,
+                            std::unique_ptr<GenerateNoteCaption> xGenerator,
+                            const tools::Rectangle& rCaptionRect, bool bShown 
);
+
     /** Creates a cell note based on the passed string and inserts it into the
         document.
 
diff --git a/sc/source/core/data/postit.cxx b/sc/source/core/data/postit.cxx
index f33ed9dd6b68..eac65f3e40c4 100644
--- a/sc/source/core/data/postit.cxx
+++ b/sc/source/core/data/postit.cxx
@@ -23,8 +23,9 @@
 #include <rtl/ustrbuf.hxx>
 #include <sal/log.hxx>
 #include <unotools/useroptions.hxx>
-#include <svx/svdpage.hxx>
 #include <svx/svdocapt.hxx>
+#include <svx/svdpage.hxx>
+#include <svx/unoshape.hxx>
 #include <editeng/outlobj.hxx>
 #include <editeng/editobj.hxx>
 #include <basegfx/polygon/b2dpolygon.hxx>
@@ -453,11 +454,11 @@ ScNoteCaptionCreator::ScNoteCaptionCreator( ScDocument& 
rDoc, const ScAddress& r
 
 } // namespace
 
-
 struct ScCaptionInitData
 {
     std::optional< SfxItemSet > moItemSet;  /// Caption object formatting.
     std::optional< OutlinerParaObject > mxOutlinerObj; /// Text object with 
all text portion formatting.
+    std::unique_ptr< GenerateNoteCaption > mxGenerator; /// Operator to 
generate Caption Object from import data
     OUString            maSimpleText;       /// Simple text without formatting.
     Point               maCaptionOffset;    /// Caption position relative to 
cell corner.
     Size                maCaptionSize;      /// Size of the caption object.
@@ -686,13 +687,18 @@ void ScPostIt::CreateCaptionFromInitData( const 
ScAddress& rPos ) const
     bool bWasLocked = 
maNoteData.mxCaption->getSdrModelFromSdrObject().isLocked();
     maNoteData.mxCaption->getSdrModelFromSdrObject().setLock(true);
 
-    // transfer ownership of outliner object to caption, or set simple text
-    OSL_ENSURE( xInitData->mxOutlinerObj || !xInitData->maSimpleText.isEmpty(),
-        "ScPostIt::CreateCaptionFromInitData - need either outliner para 
object or simple text" );
-    if (xInitData->mxOutlinerObj)
-        maNoteData.mxCaption->SetOutlinerParaObject( 
std::move(xInitData->mxOutlinerObj) );
+    if (xInitData->mxGenerator)
+        xInitData->mxGenerator->Generate(*maNoteData.mxCaption);
     else
-        maNoteData.mxCaption->SetText( xInitData->maSimpleText );
+    {
+        // transfer ownership of outliner object to caption, or set simple text
+        OSL_ENSURE( xInitData->mxOutlinerObj || 
!xInitData->maSimpleText.isEmpty(),
+            "ScPostIt::CreateCaptionFromInitData - need either outliner para 
object or simple text" );
+        if (xInitData->mxOutlinerObj)
+            maNoteData.mxCaption->SetOutlinerParaObject( 
std::move(xInitData->mxOutlinerObj) );
+        else
+            maNoteData.mxCaption->SetText( xInitData->maSimpleText );
+    }
 
     // copy all items or set default items; reset shadow items
     ScCaptionUtil::SetDefaultItems( *maNoteData.mxCaption, mrDoc, 
xInitData->moItemSet ? &*xInitData->moItemSet : nullptr );
@@ -890,16 +896,12 @@ ScPostIt* ScNoteUtil::CreateNoteFromCaption(
     return pNote;
 }
 
-ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
-        ScDocument& rDoc, const ScAddress& rPos, SfxItemSet&& rItemSet,
-        const OutlinerParaObject& rOutlinerObj, const tools::Rectangle& 
rCaptionRect,
-        bool bShown )
+ScNoteData ScNoteUtil::CreateNoteData(ScDocument& rDoc, const ScAddress& rPos,
+                                      const tools::Rectangle& rCaptionRect, 
bool bShown)
 {
     ScNoteData aNoteData( bShown );
     aNoteData.mxInitData = std::make_shared<ScCaptionInitData>();
     ScCaptionInitData& rInitData = *aNoteData.mxInitData;
-    rInitData.moItemSet.emplace(std::move(rItemSet));
-    rInitData.mxOutlinerObj = rOutlinerObj;
 
     // convert absolute caption position to relative position
     rInitData.mbDefaultPosSize = rCaptionRect.IsEmpty();
@@ -912,13 +914,48 @@ ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
         rInitData.maCaptionSize = rCaptionRect.GetSize();
     }
 
+    return aNoteData;
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromObjectData(
+        ScDocument& rDoc, const ScAddress& rPos, SfxItemSet&& rItemSet,
+        const OutlinerParaObject& rOutlinerObj, const tools::Rectangle& 
rCaptionRect,
+        bool bShown )
+{
+    ScNoteData aNoteData(CreateNoteData(rDoc, rPos, rCaptionRect, bShown));
+    ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+    rInitData.mxOutlinerObj = rOutlinerObj;
+    rInitData.moItemSet.emplace(std::move(rItemSet));
+
+    return InsertNote(rDoc, rPos, std::move(aNoteData), 
/*bAlwaysCreateCaption*/false, 0/*nPostItId*/);
+}
+
+ScPostIt* ScNoteUtil::CreateNoteFromGenerator(
+        ScDocument& rDoc, const ScAddress& rPos,
+        std::unique_ptr<GenerateNoteCaption> xGenerator,
+        const tools::Rectangle& rCaptionRect,
+        bool bShown )
+{
+    ScNoteData aNoteData(CreateNoteData(rDoc, rPos, rCaptionRect, bShown));
+    ScCaptionInitData& rInitData = *aNoteData.mxInitData;
+    rInitData.mxGenerator = std::move(xGenerator);
+    // because the Caption is generated on demand, we will need to create the
+    // simple text now to supply any querys for that which don't require
+    // creation of a full Caption
+    rInitData.maSimpleText = rInitData.mxGenerator->GetSimpleText();
+
+    return InsertNote(rDoc, rPos, std::move(aNoteData), 
/*bAlwaysCreateCaption*/false, 0/*nPostItId*/);
+}
+
+ScPostIt* ScNoteUtil::InsertNote(ScDocument& rDoc, const ScAddress& rPos, 
ScNoteData&& rNoteData,
+                                 bool bAlwaysCreateCaption, sal_uInt32 
nPostItId)
+{
     /*  Create the note and insert it into the document. If the note is
         visible, the caption object will be created automatically. */
-    ScPostIt* pNote = new ScPostIt( rDoc, rPos, std::move(aNoteData), 
/*bAlwaysCreateCaption*/false, 0/*nPostItId*/ );
+    ScPostIt* pNote = new ScPostIt( rDoc, rPos, std::move(rNoteData), 
bAlwaysCreateCaption, nPostItId );
     pNote->AutoStamp();
-
+    //insert takes ownership
     rDoc.SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
-
     return pNote;
 }
 
@@ -935,12 +972,7 @@ ScPostIt* ScNoteUtil::CreateNoteFromString(
         rInitData.maSimpleText = rNoteText;
         rInitData.mbDefaultPosSize = true;
 
-        /*  Create the note and insert it into the document. If the note is
-            visible, the caption object will be created automatically. */
-        pNote = new ScPostIt( rDoc, rPos, std::move(aNoteData), 
bAlwaysCreateCaption, nPostItId );
-        pNote->AutoStamp();
-        //insert takes ownership
-        rDoc.SetNote(rPos, std::unique_ptr<ScPostIt>(pNote));
+        pNote = InsertNote(rDoc, rPos, std::move(aNoteData), 
bAlwaysCreateCaption, nPostItId);
     }
     return pNote;
 }
diff --git a/sc/source/filter/excel/xeescher.cxx 
b/sc/source/filter/excel/xeescher.cxx
index 1dbec73cd97e..3d931a258508 100644
--- a/sc/source/filter/excel/xeescher.cxx
+++ b/sc/source/filter/excel/xeescher.cxx
@@ -1622,12 +1622,8 @@ XclExpNote::XclExpNote(const XclExpRoot& rRoot, const 
ScAddress& rScPos,
     // get the main note text
     OUString aNoteText;
     if( pScNote )
-    {
         aNoteText = pScNote->GetText();
-        const EditTextObject *pEditObj = pScNote->GetEditTextObject();
-        if( pEditObj )
-            mpNoteContents = XclExpStringHelper::CreateString( rRoot, 
*pEditObj );
-    }
+
     // append additional text
     aNoteText = ScGlobal::addToken( aNoteText, rAddText, '\n', 2 );
 
@@ -1668,6 +1664,9 @@ XclExpNote::XclExpNote(const XclExpRoot& rRoot, const 
ScAddress& rScPos,
                     maAuthor = XclExpString( " " );
                 else
                     maAuthor = XclExpString( pScNote->GetAuthor(), 
XclStrFlags::NONE, 54 );
+
+                if (const EditTextObject *pEditObj = 
pScNote->GetEditTextObject())
+                    mpNoteContents = XclExpStringHelper::CreateString( rRoot, 
*pEditObj );
             }
 
             SetRecSize( 9 + maAuthor.GetSize() );
diff --git a/sc/source/filter/inc/richstring.hxx 
b/sc/source/filter/inc/richstring.hxx
index b74e3036f473..3969de6b7974 100644
--- a/sc/source/filter/inc/richstring.hxx
+++ b/sc/source/filter/inc/richstring.hxx
@@ -228,6 +228,9 @@ public:
                             OUString& orString,
                             const oox::xls::Font* pFirstPortionFont ) const;
 
+    /** Get the text of all portions as a single string regardless of 
formatted or not */
+    OUString            getStringContent() const;
+
     /** Converts the string and writes it into the passed XText, replace old 
contents of the text object,.
         @param rxText  The XText interface of the target object.
      */
diff --git a/sc/source/filter/oox/commentsbuffer.cxx 
b/sc/source/filter/oox/commentsbuffer.cxx
index 31c067ef295f..1f1f2dd2540c 100644
--- a/sc/source/filter/oox/commentsbuffer.cxx
+++ b/sc/source/filter/oox/commentsbuffer.cxx
@@ -24,12 +24,14 @@
 #include <com/sun/star/beans/XMultiPropertySet.hpp>
 #include <com/sun/star/text/XText.hpp>
 #include <osl/diagnose.h>
+#include <oox/drawingml/shapepropertymap.hxx>
 #include <oox/helper/attributelist.hxx>
 #include <oox/vml/vmlshape.hxx>
 #include <addressconverter.hxx>
 #include <drawingfragment.hxx>
 #include <svx/sdtaitm.hxx>
 #include <svx/svdocapt.hxx>
+#include <svx/unoshape.hxx>
 #include <comphelper/diagnose_ex.hxx>
 #include <document.hxx>
 #include <drwlayer.hxx>
@@ -145,6 +147,44 @@ RichStringRef const & Comment::createText()
     return maModel.mxText;
 }
 
+namespace
+{
+    struct OOXGenerateNoteCaption : public GenerateNoteCaption
+    {
+        css::uno::Sequence<OUString> maPropertyNames;  /// import filter 
Caption object formatting property names
+        css::uno::Sequence<css::uno::Any> maPropertyValues; /// import filter 
Caption object formatting property values
+        std::shared_ptr<RichString> mxText;
+
+        OOXGenerateNoteCaption(std::shared_ptr<RichString>& rText)
+            : mxText(rText)
+        {
+        }
+
+        virtual void Generate(SdrCaptionObj& rCaptionObj) override
+        {
+            rtl::Reference<SvxShapeText> 
xAnnoShape(dynamic_cast<SvxShapeText*>(rCaptionObj.getUnoShape().get())); // 
SvxShapeText
+            assert(xAnnoShape && "will not be null");
+
+            if (maPropertyNames.getLength())
+            {
+                // setting a property triggers expensive process, so set them 
all at once
+                
static_cast<SvxShape*>(xAnnoShape.get())->setPropertyValues(maPropertyNames, 
maPropertyValues);
+            }
+
+            // insert text and convert text formatting
+            Reference< XText > xAnnoText( xAnnoShape );
+            xAnnoShape->addActionLock();
+            mxText->convert( xAnnoText );
+            xAnnoShape->removeActionLock();
+        }
+
+        virtual OUString GetSimpleText() const override
+        {
+            return mxText->getStringContent();
+        }
+    };
+}
+
 void Comment::finalizeImport()
 {
     // BIFF12 stores cell range instead of cell address, use first cell of 
this range
@@ -158,23 +198,22 @@ void Comment::finalizeImport()
         ScTableSheetObj* pAnnosSupp = 
static_cast<ScTableSheetObj*>(getSheet().get());
         rtl::Reference<ScAnnotationsObj> xAnnos = 
static_cast<ScAnnotationsObj*>(pAnnosSupp->getAnnotations().get());
         ScDocShell* pDocShell = xAnnos->GetDocShell();
-        // non-empty string required by note implementation (real text will be 
added below)
-        ScPostIt* pPostIt = pDocShell->GetDocFunc().ImportNote( 
maModel.maRange.aStart, OUString( ' ' ) );
-        SdrCaptionObj* pCaption = pPostIt->GetOrCreateCaption( 
maModel.maRange.aStart );
 
-        Reference< XShape > xAnnoShape( pCaption->getUnoShape() ); // 
SvxShapeText
-        // setting a property triggers expensive process, so set them all at 
once
-        Reference< css::beans::XMultiPropertySet > 
xAnnoShapeMultiPropSet(xAnnoShape, UNO_QUERY_THROW);
+        auto xGenerator = 
std::make_unique<OOXGenerateNoteCaption>(maModel.mxText);
 
         // Add shape formatting properties (autoFill, colHidden and rowHidden 
are dropped)
-        xAnnoShapeMultiPropSet->setPropertyValues(
-            Sequence<OUString> { "TextFitToSize", "MoveProtect", 
"TextHorizontalAdjust", "TextVerticalAdjust" },
-            Sequence<Any> { Any(maModel.mbAutoScale), Any(maModel.mbLocked),
-                Any(lcl_ToHorizAlign( maModel.mnTHA )), Any(lcl_ToVertAlign( 
maModel.mnTVA )) });
+        // vvv TODO vvv TextFitToSize should be a drawing::TextFitToSizeType 
not bool
+        xGenerator->maPropertyNames =
+            css::uno::Sequence<OUString>{ "TextFitToSize", "MoveProtect", 
"TextHorizontalAdjust", "TextVerticalAdjust" };
+        xGenerator->maPropertyValues =
+            css::uno::Sequence<css::uno::Any>{ Any(maModel.mbAutoScale), 
Any(maModel.mbLocked),
+                                               Any(lcl_ToHorizAlign( 
maModel.mnTHA )), Any(lcl_ToVertAlign( maModel.mnTVA )) };
+
+        tools::Rectangle aCaptionRect;
         if( maModel.maAnchor.Width > 0 && maModel.maAnchor.Height > 0 )
         {
-            xAnnoShape->setPosition( css::awt::Point( maModel.maAnchor.X, 
maModel.maAnchor.Y ) );
-            xAnnoShape->setSize( css::awt::Size( maModel.maAnchor.Width, 
maModel.maAnchor.Height ) );
+            aCaptionRect = tools::Rectangle(Point(maModel.maAnchor.X, 
maModel.maAnchor.Y),
+                                            Size(maModel.maAnchor.Width, 
maModel.maAnchor.Height));
         }
 
         // convert shape formatting and visibility
@@ -182,26 +221,54 @@ void Comment::finalizeImport()
         if( const ::oox::vml::ShapeBase* pVmlNoteShape = 
getVmlDrawing().getNoteShape( maModel.maRange.aStart ) )
         {
             // position and formatting
-            pVmlNoteShape->convertFormatting( xAnnoShape );
+            css::awt::Rectangle aShapeRect = 
pVmlNoteShape->getShapeRectangle();
+            if (aShapeRect.Width > 0 || aShapeRect.Height > 0)
+            {
+                aCaptionRect = tools::Rectangle(Point(aShapeRect.X, 
aShapeRect.Y),
+                                                Size(aShapeRect.Width, 
aShapeRect.Height));
+
+                ::oox::drawingml::ShapePropertyMap 
aPropMap(pVmlNoteShape->makeShapePropertyMap());
+
+                Sequence<OUString> aVMLPropNames;
+                Sequence<Any> aVMLPropValues;
+                aPropMap.fillSequences(aVMLPropNames, aVMLPropValues);
+
+                sal_uInt32 nOldPropLen = 
xGenerator->maPropertyNames.getLength();
+                sal_uInt32 nVMLPropLen = aVMLPropNames.getLength();
+                xGenerator->maPropertyNames.realloc(nOldPropLen + nVMLPropLen);
+                xGenerator->maPropertyValues.realloc(nOldPropLen + 
nVMLPropLen);
+                OUString* pNames = xGenerator->maPropertyNames.getArray();
+                Any* pValues = xGenerator->maPropertyValues.getArray();
+                for (sal_uInt32 i = 0; i < nVMLPropLen; ++i)
+                {
+                    pNames[nOldPropLen + i] = aVMLPropNames[i];
+                    pValues[nOldPropLen + i] = aVMLPropValues[i];
+                }
+            }
+
             // visibility
             bVisible = pVmlNoteShape->getTypeModel().mbVisible;
 
             // Setting comment text alignment
             const ::oox::vml::ClientData* xClientData = 
pVmlNoteShape->getClientData();
-            xAnnoShapeMultiPropSet->setPropertyValues(
-                Sequence<OUString> { "TextVerticalAdjust", "ParaAdjust" },
-                Sequence<Any> { Any(lcl_ToVertAlign( xClientData->mnTextVAlign 
)), Any(lcl_ToParaAlign( xClientData->mnTextHAlign )) });
+            sal_uInt32 nOldPropLen = xGenerator->maPropertyNames.getLength();
+            xGenerator->maPropertyNames.realloc(nOldPropLen + 2);
+            xGenerator->maPropertyValues.realloc(nOldPropLen + 2);
+            OUString* pNames = xGenerator->maPropertyNames.getArray();
+            Any* pValues = xGenerator->maPropertyValues.getArray();
+            pNames[nOldPropLen] = "TextVerticalAdjust";
+            pValues[nOldPropLen] <<= 
lcl_ToVertAlign(xClientData->mnTextVAlign);
+            pNames[nOldPropLen + 1] = "ParaAdjust";
+            pValues[nOldPropLen + 1] <<= lcl_ToParaAlign( 
xClientData->mnTextHAlign);
         }
+
+        xGenerator->mxText->finalizeImport(*this);
+
+        pDocShell->GetDocFunc().ImportNote(maModel.maRange.aStart, 
std::move(xGenerator),
+                                           aCaptionRect, bVisible);
+
         if (bVisible)
             pDocShell->GetDocFunc().ShowNote( maModel.maRange.aStart, bVisible 
);
-
-        // insert text and convert text formatting
-        maModel.mxText->finalizeImport(*this);
-        Reference< XText > xAnnoText( xAnnoShape, UNO_QUERY_THROW );
-        Reference< css::document::XActionLockable > xAnnoLock( xAnnoShape, 
UNO_QUERY_THROW );
-        xAnnoLock->addActionLock();
-        maModel.mxText->convert( xAnnoText );
-        xAnnoLock->removeActionLock();
     }
     catch( Exception& )
     {
diff --git a/sc/source/filter/oox/richstring.cxx 
b/sc/source/filter/oox/richstring.cxx
index a1345179c19a..06db87e3c733 100644
--- a/sc/source/filter/oox/richstring.cxx
+++ b/sc/source/filter/oox/richstring.cxx
@@ -398,18 +398,24 @@ void RichString::convert( const Reference< XText >& 
rxText )
     }
 }
 
-std::unique_ptr<EditTextObject> RichString::convert( ScEditEngineDefaulter& 
rEE, const oox::xls::Font* pFirstPortionFont )
+OUString RichString::getStringContent() const
 {
-    ESelection aSelection;
-
     OUStringBuffer sString;
     for( auto& rTextPortion : maTextPortions )
         sString.append(rTextPortion.getText());
+    return sString.makeStringAndClear();
+}
+
+std::unique_ptr<EditTextObject> RichString::convert( ScEditEngineDefaulter& 
rEE, const oox::xls::Font* pFirstPortionFont )
+{
+    ESelection aSelection;
+
+    OUString sString(getStringContent());
 
     // fdo#84370 - diving into editeng is not thread safe.
     SolarMutexGuard aGuard;
 
-    rEE.SetTextCurrentDefaults( sString.makeStringAndClear() );
+    rEE.SetTextCurrentDefaults(sString);
 
     for( auto& rTextPortion : maTextPortions )
     {
diff --git a/sc/source/ui/docshell/docfunc.cxx 
b/sc/source/ui/docshell/docfunc.cxx
index 4d99824fe0a0..0d92cfaf043b 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1405,7 +1405,9 @@ void ScDocFunc::ReplaceNote( const ScAddress& rPos, const 
OUString& rNoteText, c
     }
 }
 
-ScPostIt* ScDocFunc::ImportNote( const ScAddress& rPos, const OUString& 
rNoteText  )
+void ScDocFunc::ImportNote( const ScAddress& rPos,
+                            std::unique_ptr<GenerateNoteCaption> xGenerator,
+                            const tools::Rectangle& rCaptionRect, bool bShown )
 {
     ScDocShellModificator aModificator( rDocShell );
     ScDocument& rDoc = rDocShell.GetDocument();
@@ -1414,13 +1416,12 @@ ScPostIt* ScDocFunc::ImportNote( const ScAddress& rPos, 
const OUString& rNoteTex
     SAL_WARN_IF(pOldNote, "sc.ui", "imported data has >1 notes on same cell? 
at pos " << rPos);
 
     // create new note
-    ScPostIt* pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, 
rNoteText, false, true, /*nNoteId*/0 );
+    ScNoteUtil::CreateNoteFromGenerator(rDoc, rPos, std::move(xGenerator),
+                                        rCaptionRect, bShown);
 
     rDoc.SetStreamValid(rPos.Tab(), false);
 
     aModificator.SetDocumentModified();
-
-    return pNewNote;
 }
 
 bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& 
rPattern,
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index 7779564db716..73bb554dc32f 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -29,6 +29,7 @@
 #include <vector>
 #include <map>
 
+class GenerateNoteCaption;
 class ScEditEngineDefaulter;
 class SdrUndoAction;
 class ScAddress;
@@ -47,7 +48,6 @@ class ScConditionalFormat;
 class ScConditionalFormatList;
 class ScUndoRemoveMerge;
 class ScRangeName;
-class ScPostIt;
 
 enum class TransliterationFlags;
 enum class CreateNameFlags;
@@ -58,6 +58,10 @@ namespace sc
     class SparklineGroup;
     class Sparkline;
 }
+namespace tools
+{
+    class Rectangle;
+}
 
 class ScDocFunc
 {
@@ -124,7 +128,9 @@ public:
 
     void            SetNoteText( const ScAddress& rPos, const OUString& 
rNoteText, bool bApi );
     void            ReplaceNote( const ScAddress& rPos, const OUString& 
rNoteText, const OUString* pAuthor, const OUString* pDate, bool bApi );
-    SC_DLLPUBLIC ScPostIt* ImportNote( const ScAddress& rPos, const OUString& 
rNoteText );
+    SC_DLLPUBLIC void ImportNote( const ScAddress& rPos,
+                                  std::unique_ptr<GenerateNoteCaption> 
xGenerator,
+                                  const tools::Rectangle& rCaptionRect, bool 
bShown );
 
     bool            ApplyAttributes( const ScMarkData& rMark, const 
ScPatternAttr& rPattern,
                                            bool bApi );

Reply via email to