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 );