tdf#129228 speedup opening of xlsx file with lots of comments

de-UNOise the Comment::finalizeImport method, so we can build
a better custom import code path, that does not touch all the stuff
that updating a running UI needs.

The primary improvements comes from using setPropertyValues
to set a bunch of props together.

This takes the opening time from 61s to 53s for me.

Change-Id: I5506a5a37a9b4b84b6930f0563a775a8aa0a9e2c
Reviewed-on: https://gerrit.libreoffice.org/c/core/+/85947
Reviewed-by: Noel Grandin <noel.grandin@collabora.co.uk>
Tested-by: Noel Grandin <noel.grandin@collabora.co.uk>
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx
index b809337..f2adcda 100644
--- a/sc/inc/docuno.hxx
+++ b/sc/inc/docuno.hxx
@@ -673,6 +673,8 @@

    virtual void            Notify( SfxBroadcaster& rBC, const SfxHint& rHint ) override;

    ScDocShell*             GetDocShell() const { return pDocShell; }

                            /// XSheetAnnotations
    virtual void SAL_CALL   insertNew( const css::table::CellAddress& aPosition,
                                const OUString& aText ) override;
diff --git a/sc/source/filter/oox/commentsbuffer.cxx b/sc/source/filter/oox/commentsbuffer.cxx
index 43b133a..097e86b 100644
--- a/sc/source/filter/oox/commentsbuffer.cxx
+++ b/sc/source/filter/oox/commentsbuffer.cxx
@@ -23,6 +23,7 @@
#include <commentsbuffer.hxx>

#include <com/sun/star/beans/XPropertySet.hpp>
#include <com/sun/star/beans/XMultiPropertySet.hpp>
#include <com/sun/star/sheet/XSheetAnnotationAnchor.hpp>
#include <com/sun/star/sheet/XSheetAnnotationShapeSupplier.hpp>
#include <com/sun/star/sheet/XSheetAnnotations.hpp>
@@ -34,8 +35,16 @@
#include <addressconverter.hxx>
#include <drawingfragment.hxx>
#include <svx/sdtaitm.hxx>
#include <svx/svdocapt.hxx>
#include <svx/unoshape.hxx>
#include <tools/diagnose_ex.h>
#include <document.hxx>
#include <drwlayer.hxx>
#include <cellsuno.hxx>
#include <docfunc.hxx>
#include <docuno.hxx>
#include <docsh.hxx>
#include <postit.hxx>

namespace oox {
namespace xls {
@@ -149,28 +158,27 @@
    // BIFF12 stores cell range instead of cell address, use first cell of this range
    OSL_ENSURE( maModel.maRange.aStart == maModel.maRange.aEnd,
        "Comment::finalizeImport - comment anchor should be a single cell" );
    if( getAddressConverter().checkCellAddress( maModel.maRange.aStart, true ) && maModel.mxText.get() ) try
    if( !getAddressConverter().checkCellAddress( maModel.maRange.aStart, true ) || !maModel.mxText.get() )
        return;

    try
    {
        CellAddress aNotePos( maModel.maRange.aStart.Tab(), maModel.maRange.aStart.Col(), maModel.maRange.aStart.Row() );
        Reference< XSheetAnnotationsSupplier > xAnnosSupp( getSheet(), UNO_QUERY_THROW );
        Reference< XSheetAnnotations > xAnnos( xAnnosSupp->getAnnotations(), UNO_SET_THROW );
        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)
        xAnnos->insertNew( aNotePos, OUString( ' ' ) );
        ScPostIt* pPostIt = pDocShell->GetDocFunc().ImportNote( maModel.maRange.aStart, OUString( ' ' ), nullptr, nullptr );
        SdrCaptionObj* pCaption = pPostIt->GetOrCreateCaption( maModel.maRange.aStart );

        // receive created note from cell (insertNew does not return the note)
        Reference< XSheetAnnotationAnchor > xAnnoAnchor( getCell( maModel.maRange.aStart ), UNO_QUERY_THROW );
        Reference< XSheetAnnotation > xAnno( xAnnoAnchor->getAnnotation(), UNO_SET_THROW );
        Reference< XSheetAnnotationShapeSupplier > xAnnoShapeSupp( xAnno, UNO_QUERY_THROW );
        Reference< XShape > xAnnoShape( xAnnoShapeSupp->getAnnotationShape(), UNO_SET_THROW );
        Reference< XShape > xAnnoShape( pCaption->getUnoShape(), UNO_QUERY_THROW ); // SvxShapeText
        // setting a property triggers expensive process, so set them all at once
        Reference< css::beans::XMultiPropertySet > xAnnoShapeMultiPropSet(xAnnoShape, UNO_QUERY_THROW);

        // convert shape formatting and visibility
        bool bVisible = true;
        // Add shape formatting properties (autoFill, colHidden and rowHidden are dropped)
        PropertySet aCommentPr( xAnnoShape );
        aCommentPr.setProperty( PROP_TextFitToSize, maModel.mbAutoScale );
        aCommentPr.setProperty( PROP_MoveProtect, maModel.mbLocked );
        aCommentPr.setProperty( PROP_TextHorizontalAdjust, lcl_ToHorizAlign( maModel.mnTHA ) );
        aCommentPr.setProperty( PROP_TextVerticalAdjust, lcl_ToVertAlign( maModel.mnTVA ) );
        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 )) });
        if( maModel.maAnchor.Width > 0 && maModel.maAnchor.Height > 0 )
        {
            xAnnoShape->setPosition( css::awt::Point( maModel.maAnchor.X, maModel.maAnchor.Y ) );
@@ -178,19 +186,22 @@
        }

        // convert shape formatting and visibility
        if( const ::oox::vml::ShapeBase* pNoteShape = getVmlDrawing().getNoteShape( maModel.maRange.aStart ) )
        bool bVisible = true;
        if( const ::oox::vml::ShapeBase* pVmlNoteShape = getVmlDrawing().getNoteShape( maModel.maRange.aStart ) )
        {
            // position and formatting
            pNoteShape->convertFormatting( xAnnoShape );
            pVmlNoteShape->convertFormatting( xAnnoShape );
            // visibility
            bVisible = pNoteShape->getTypeModel().mbVisible;
            bVisible = pVmlNoteShape->getTypeModel().mbVisible;

            // Setting comment text alignment
            const ::oox::vml::ClientData* xClientData = pNoteShape->getClientData();
            aCommentPr.setProperty(PROP_TextVerticalAdjust, lcl_ToVertAlign(xClientData->mnTextVAlign));
            aCommentPr.setProperty(PROP_ParaAdjust, lcl_ToParaAlign(xClientData->mnTextHAlign));
            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 )) });
        }
        xAnno->setIsVisible( bVisible );
        if (bVisible)
            pDocShell->GetDocFunc().ShowNote( maModel.maRange.aStart, bVisible );

        // insert text and convert text formatting
        maModel.mxText->finalizeImport();
@@ -199,6 +210,7 @@
    }
    catch( Exception& )
    {
        DBG_UNHANDLED_EXCEPTION("sc");
    }
}

diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx
index b9598ed..b65edc7 100644
--- a/sc/source/ui/docshell/docfunc.cxx
+++ b/sc/source/ui/docshell/docfunc.cxx
@@ -1363,6 +1363,29 @@
    }
}

ScPostIt* ScDocFunc::ImportNote( const ScAddress& rPos, const OUString& rNoteText, const OUString* pAuthor, const OUString* pDate )
{
    ScDocShellModificator aModificator( rDocShell );
    ScDocument& rDoc = rDocShell.GetDocument();

    std::unique_ptr<ScPostIt> pOldNote = rDoc.ReleaseNote( rPos );
    assert(!pOldNote && "imported data has >1 notes on same cell?");

    // create new note
    ScPostIt* pNewNote = nullptr;
    if( (pNewNote = ScNoteUtil::CreateNoteFromString( rDoc, rPos, rNoteText, false, true, /*nNoteId*/0 )) )
    {
        if( pAuthor ) pNewNote->SetAuthor( *pAuthor );
        if( pDate ) pNewNote->SetDate( *pDate );
    }

    rDoc.SetStreamValid(rPos.Tab(), false);

    aModificator.SetDocumentModified();

    return pNewNote;
}

bool ScDocFunc::ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
                                    bool bApi )
{
diff --git a/sc/source/ui/inc/docfunc.hxx b/sc/source/ui/inc/docfunc.hxx
index bf07e23..ca0f03e 100644
--- a/sc/source/ui/inc/docfunc.hxx
+++ b/sc/source/ui/inc/docfunc.hxx
@@ -46,6 +46,7 @@
class ScConditionalFormatList;
class ScUndoRemoveMerge;
class ScRangeName;
class ScPostIt;

enum class TransliterationFlags;
enum class CreateNameFlags;
@@ -114,10 +115,11 @@
        const ScAddress& rPos, const OUString& rText, bool bInterpret, bool bEnglish, bool bApi,
        const formula::FormulaGrammar::Grammar eGrammar );

    bool            ShowNote( const ScAddress& rPos, bool bShow );
    SC_DLLPUBLIC bool ShowNote( const ScAddress& rPos, bool bShow );

    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, const OUString* pAuthor, const OUString* pDate );

    bool            ApplyAttributes( const ScMarkData& rMark, const ScPatternAttr& rPattern,
                                           bool bApi );