diff options
author | Noel Grandin <noelgrandin@gmail.com> | 2019-12-29 14:00:14 +0200 |
---|---|---|
committer | Noel Grandin <noel.grandin@collabora.co.uk> | 2020-01-01 09:37:37 +0100 |
commit | 4992d61600536fe14b97b718dbb11f00e936c6a9 (patch) | |
tree | 870274981061d3f16896f1a9ddaea4a807bcb9da /sc | |
parent | 6dfa6d3d53369ef3cce86717fb1923fc9fcb7982 (diff) |
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>
Diffstat (limited to 'sc')
-rw-r--r-- | sc/inc/docuno.hxx | 2 | ||||
-rw-r--r-- | sc/source/filter/oox/commentsbuffer.cxx | 60 | ||||
-rw-r--r-- | sc/source/ui/docshell/docfunc.cxx | 23 | ||||
-rw-r--r-- | sc/source/ui/inc/docfunc.hxx | 4 |
4 files changed, 64 insertions, 25 deletions
diff --git a/sc/inc/docuno.hxx b/sc/inc/docuno.hxx index b80933783761..f2adcda7a80f 100644 --- a/sc/inc/docuno.hxx +++ b/sc/inc/docuno.hxx @@ -673,6 +673,8 @@ public: 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 43b133aad4fe..097e86b176d9 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 @@ void Comment::finalizeImport() // 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 @@ void Comment::finalizeImport() } // 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 @@ void Comment::finalizeImport() } catch( Exception& ) { + DBG_UNHANDLED_EXCEPTION("sc"); } } diff --git a/sc/source/ui/docshell/docfunc.cxx b/sc/source/ui/docshell/docfunc.cxx index b9598ed24c55..b65edc73a8c0 100644 --- a/sc/source/ui/docshell/docfunc.cxx +++ b/sc/source/ui/docshell/docfunc.cxx @@ -1363,6 +1363,29 @@ void ScDocFunc::ReplaceNote( const ScAddress& rPos, const OUString& rNoteText, c } } +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 bf07e230cea8..ca0f03e0318c 100644 --- a/sc/source/ui/inc/docfunc.hxx +++ b/sc/source/ui/inc/docfunc.hxx @@ -46,6 +46,7 @@ class ScConditionalFormat; class ScConditionalFormatList; class ScUndoRemoveMerge; class ScRangeName; +class ScPostIt; enum class TransliterationFlags; enum class CreateNameFlags; @@ -114,10 +115,11 @@ public: 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 ); |