diff options
Diffstat (limited to 'sd/source/ui')
-rw-r--r-- | sd/source/ui/animations/SlideTransitionPane.cxx | 9 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationmanager.cxx | 50 | ||||
-rw-r--r-- | sd/source/ui/annotations/annotationwindow.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/app/optsitem.cxx | 8 | ||||
-rw-r--r-- | sd/source/ui/func/fuconrec.cxx | 1 | ||||
-rw-r--r-- | sd/source/ui/func/fusel.cxx | 5 | ||||
-rw-r--r-- | sd/source/ui/inc/SlideshowLayerRenderer.hxx | 71 | ||||
-rw-r--r-- | sd/source/ui/inc/annotationmanager.hxx | 3 | ||||
-rw-r--r-- | sd/source/ui/inc/optsitem.hxx | 3 | ||||
-rw-r--r-- | sd/source/ui/inc/unomodel.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/sidebar/MasterPageContainer.hxx | 2 | ||||
-rw-r--r-- | sd/source/ui/slideshow/slideshowimpl.hxx | 1 | ||||
-rw-r--r-- | sd/source/ui/tools/SlideshowLayerRenderer.cxx | 430 | ||||
-rw-r--r-- | sd/source/ui/unoidl/unomodel.cxx | 4 | ||||
-rw-r--r-- | sd/source/ui/unoidl/unopage.cxx | 7 | ||||
-rw-r--r-- | sd/source/ui/view/drviewsb.cxx | 3 | ||||
-rw-r--r-- | sd/source/ui/view/drviewse.cxx | 31 |
17 files changed, 470 insertions, 162 deletions
diff --git a/sd/source/ui/animations/SlideTransitionPane.cxx b/sd/source/ui/animations/SlideTransitionPane.cxx index 1ab9ca44ab0c..91a053b0db44 100644 --- a/sd/source/ui/animations/SlideTransitionPane.cxx +++ b/sd/source/ui/animations/SlideTransitionPane.cxx @@ -544,10 +544,15 @@ void SlideTransitionPane::updateControls() { // ToDo: That 0 is "no transition" is documented nowhere except in the // CTOR of sdpage + OUString sSelectedId = mxTransitionsIconView->get_selected_id(); + auto* pTransitionEntry = weld::fromId<TransitionEntry*>(sSelectedId); + if( aEffect.mnType == 0 ) mxTransitionsIconView->select(0); - else + else if(!pTransitionEntry) updateVariants(getPreset(aEffect)); + else + updateVariants(pTransitionEntry->mpPreset); } if( aEffect.mbDurationAmbiguous ) @@ -877,6 +882,8 @@ impl::TransitionEffect SlideTransitionPane::getTransitionEffectFromControls() co aResult.mbLoopSoundAmbiguous = false; } + mpDrawDoc->Broadcast(SdrHint(SdrHintKind::ObjectChange)); + return aResult; } diff --git a/sd/source/ui/annotations/annotationmanager.cxx b/sd/source/ui/annotations/annotationmanager.cxx index e3743c97ca42..cfcfa52ef971 100644 --- a/sd/source/ui/annotations/annotationmanager.cxx +++ b/sd/source/ui/annotations/annotationmanager.cxx @@ -25,6 +25,7 @@ #include <com/sun/star/office/XAnnotationAccess.hpp> #include <comphelper/lok.hxx> #include <svx/svxids.hrc> +#include <svx/svditer.hxx> #include <vcl/settings.hxx> #include <vcl/svapp.hxx> @@ -208,6 +209,22 @@ void AnnotationManagerImpl::init() // WeakComponentImplHelper void AnnotationManagerImpl::disposing (std::unique_lock<std::mutex>&) { + for (sal_uInt16 i = 0; i < mpDoc->GetPageCount(); i++) + { + SdrPage* pPage = mpDoc->GetPage(i); + SdrObjListIter aIterator(pPage, SdrIterMode::DeepWithGroups); + while (aIterator.IsMore()) + { + SdrObject* pObject = aIterator.Next(); + if (pObject) + { + auto& xAnnotationData = pObject->getAnnotationData(); + if (xAnnotationData) + xAnnotationData->closePopup(); + } + } + } + try { uno::Reference<document::XEventBroadcaster> xModel (mrBase.GetDocShell()->GetModel(), uno::UNO_QUERY_THROW); @@ -875,9 +892,19 @@ void AnnotationManagerImpl::SelectNextAnnotation(bool bForward) while( true ); } -void AnnotationManagerImpl::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, bool /*bEdit*/) +void AnnotationManagerImpl::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, bool bEdit) { mxSelectedAnnotation = xAnnotation; + if (bEdit) + { + SdrObject* pObject = xAnnotation->findAnnotationObject(); + if (pObject) + { + auto& pAnnotationData = pObject->getAnnotationData(); + if (pAnnotationData) + pAnnotationData->openPopup(); + } + } } void AnnotationManagerImpl::GetSelectedAnnotation( rtl::Reference<sdr::annotation::Annotation>& xAnnotation ) @@ -949,7 +976,7 @@ namespace void applyAnnotationCommon(SdrObject& rObject, rtl::Reference<sdr::annotation::Annotation> const& xAnnotation) { - rObject.setAsAnnotationObject(true); + rObject.setAsAnnotationObject(); auto& xAnnotationData = rObject.getAnnotationData(); xAnnotationData->mpAnnotationPopup.reset(new AnnotationPopup(xAnnotation)); xAnnotationData->mxAnnotation = xAnnotation; @@ -983,17 +1010,12 @@ void AnnotationManagerImpl::SyncAnnotationObjects() if (!mxCurrentPage.is() || !mpDoc) return; - sd::DrawDocShell* pDocShell = dynamic_cast<sd::DrawDocShell*>(SfxObjectShell::Current()); - sd::ViewShell* pViewShell = pDocShell ? pDocShell->GetViewShell() : nullptr; + std::shared_ptr<DrawViewShell> pDrawViewShell = std::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell()); - if (!pViewShell) - { - pViewShell = mrBase.GetMainViewShell().get(); - if (!pViewShell) - return; - } + if (!pDrawViewShell) + return; - auto* pView = pViewShell->GetView(); + auto* pView = pDrawViewShell->GetView(); if (!pView) return; @@ -1011,6 +1033,7 @@ void AnnotationManagerImpl::SyncAnnotationObjects() if (pObject) { nIndex++; + pObject->SetVisible(mbShowAnnotations); continue; } @@ -1116,6 +1139,7 @@ void AnnotationManagerImpl::SyncAnnotationObjects() } pNewObject->SetRelativePos(aRectangle.TopLeft()); + pNewObject->SetVisible(mbShowAnnotations); pView->InsertObjectAtView(pNewObject.get(), *pView->GetSdrPageView()); @@ -1290,9 +1314,9 @@ void AnnotationManager::GetAnnotationState(SfxItemSet& rItemSet) mxImpl->GetAnnotationState(rItemSet); } -void AnnotationManager::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation) +void AnnotationManager::SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, bool bEdit) { - mxImpl->SelectAnnotation(xAnnotation); + mxImpl->SelectAnnotation(xAnnotation, bEdit); } } // end sd diff --git a/sd/source/ui/annotations/annotationwindow.hxx b/sd/source/ui/annotations/annotationwindow.hxx index 31f82348b371..d7f3d98e10b0 100644 --- a/sd/source/ui/annotations/annotationwindow.hxx +++ b/sd/source/ui/annotations/annotationwindow.hxx @@ -105,6 +105,7 @@ private: public: AnnotationWindow(weld::Window* pParent, const ::tools::Rectangle& rRect, DrawDocShell* pDocShell, const rtl::Reference<sdr::annotation::Annotation>& xAnnotation); + ~AnnotationWindow(); void connect_closed(const Link<weld::Popover&, void>& rLink) { mxPopover->connect_closed(rLink); } @@ -131,7 +132,6 @@ public: OutlinerView* GetOutlinerView() { return mpOutlinerView.get();} ::Outliner* GetOutliner() { return mpOutliner.get();} - ~AnnotationWindow(); void SetColor(); }; diff --git a/sd/source/ui/app/optsitem.cxx b/sd/source/ui/app/optsitem.cxx index f9695b39ab10..454e2171baf6 100644 --- a/sd/source/ui/app/optsitem.cxx +++ b/sd/source/ui/app/optsitem.cxx @@ -404,13 +404,13 @@ bool SdOptionsMisc::WriteData( Any* pValues ) const \************************************************************************/ SdOptionsMiscItem::SdOptionsMiscItem() -: SfxPoolItem ( ATTR_OPTIONS_MISC, SfxItemType::SdOptionsMiscItemType ) +: SfxPoolItem ( ATTR_OPTIONS_MISC ) , maOptionsMisc ( false, false ) { } SdOptionsMiscItem::SdOptionsMiscItem( SdOptions const * pOpts, ::sd::FrameView const * pView ) -: SfxPoolItem ( ATTR_OPTIONS_MISC, SfxItemType::SdOptionsMiscItemType ) +: SfxPoolItem ( ATTR_OPTIONS_MISC ) , maOptionsMisc ( false, false ) { if( pOpts ) @@ -839,13 +839,13 @@ bool SdOptionsPrint::WriteData( Any* pValues ) const \************************************************************************/ SdOptionsPrintItem::SdOptionsPrintItem() -: SfxPoolItem ( ATTR_OPTIONS_PRINT, SfxItemType::SdOptionsPrintItemType ) +: SfxPoolItem ( ATTR_OPTIONS_PRINT ) , maOptionsPrint ( false, false ) { } SdOptionsPrintItem::SdOptionsPrintItem( SdOptions const * pOpts ) -: SfxPoolItem ( ATTR_OPTIONS_PRINT, SfxItemType::SdOptionsPrintItemType ) +: SfxPoolItem ( ATTR_OPTIONS_PRINT ) , maOptionsPrint ( false, false ) { if( !pOpts ) diff --git a/sd/source/ui/func/fuconrec.cxx b/sd/source/ui/func/fuconrec.cxx index 45abc8058d82..5cbdb1e82596 100644 --- a/sd/source/ui/func/fuconrec.cxx +++ b/sd/source/ui/func/fuconrec.cxx @@ -514,6 +514,7 @@ void FuConstructRectangle::Deactivate() uno::Reference<security::XCertificate> xCertificate = svx::SignatureLineHelper::getSignatureCertificate(mpViewShell->GetObjectShell(), + mpViewShell->GetViewShell(), mpViewShell->GetFrameWeld()); if (!xCertificate.is()) { diff --git a/sd/source/ui/func/fusel.cxx b/sd/source/ui/func/fusel.cxx index bc2da0ced224..aa43a76ee91b 100644 --- a/sd/source/ui/func/fusel.cxx +++ b/sd/source/ui/func/fusel.cxx @@ -869,10 +869,7 @@ bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) { auto* pDrawViewShell = dynamic_cast<DrawViewShell*>(mpViewShell); if (pDrawViewShell && pDrawViewShell->getAnnotationManagerPtr()) - { - pDrawViewShell->getAnnotationManagerPtr()->SelectAnnotation(pAnnotationData->mxAnnotation); - } - pAnnotationData->openPopup(); + pDrawViewShell->getAnnotationManagerPtr()->SelectAnnotation(pAnnotationData->mxAnnotation, true); } return true; } diff --git a/sd/source/ui/inc/SlideshowLayerRenderer.hxx b/sd/source/ui/inc/SlideshowLayerRenderer.hxx index 5cd590e920e7..48490c981512 100644 --- a/sd/source/ui/inc/SlideshowLayerRenderer.hxx +++ b/sd/source/ui/inc/SlideshowLayerRenderer.hxx @@ -16,16 +16,24 @@ #include <tools/gen.hxx> #include <tools/helpers.hxx> +#include <CustomAnimationEffect.hxx> + #include <deque> -#include <map> +#include <vector> +#include <optional> +#include <unordered_map> #include <unordered_set> class SdrPage; class SdrModel; class SdrObject; - class Size; +namespace com::sun::star::animations +{ +class XAnimate; +} + namespace sd { struct RenderContext; @@ -39,6 +47,19 @@ enum class RenderStage Count }; +struct AnimationLayerInfo +{ + OString msHash; + std::optional<bool> moInitiallyVisible; +}; + +struct AnimationRenderInfo +{ + std::optional<AnimationLayerInfo> moObjectInfo; + std::vector<sal_Int32> maParagraphs; + std::unordered_map<sal_Int32, AnimationLayerInfo> maParagraphInfos; +}; + /** Holds rendering state, properties and switches through all rendering passes */ struct RenderState { @@ -47,18 +68,21 @@ struct RenderState bool mbStopRenderingWhenField = true; std::unordered_set<SdrObject*> maObjectsDone; - std::unordered_set<SdrObject*> maInAnimation; - std::map<SdrObject*, OString> maAnimationTargetHash; - std::map<SdrObject*, bool> maInitiallyVisible; + + std::unordered_map<SdrObject*, AnimationRenderInfo> maAnimationRenderInfoList; + sal_Int32 mnIndex[static_cast<unsigned>(RenderStage::Count)] = { 0, 0, 0, 0 }; SdrObject* mpCurrentTarget = nullptr; + sal_Int32 mnCurrentTargetParagraph = -1; + + sal_Int32 mnRenderedObjectsInPass = 0; - bool mbFirstObjectInPass = true; - bool mbPassHasOutput = false; bool mbSkipAllInThisPass = false; sal_Int32 mnCurrentPass = 0; + std::deque<sal_Int32> maParagraphsToRender; + /// increments index depending on the current render stage void incrementIndex() { mnIndex[static_cast<unsigned>(meStage)]++; } @@ -80,20 +104,28 @@ struct RenderState /// returns the current target element for which layer is created if any SdrObject* currentTarget() const { return mpCurrentTarget; } + /// returns the current target paragraph index or -1 if paragraph is not relevant + sal_Int32 currentTargetParagraph() const { return mnCurrentTargetParagraph; } + /// resets properties that are valid for one pass void resetPass() { - mbFirstObjectInPass = true; - mbPassHasOutput = false; + mnRenderedObjectsInPass = 0; mbSkipAllInThisPass = false; mpCurrentTarget = nullptr; + mnCurrentTargetParagraph = -1; } + bool hasPassAnyRenderedOutput() const { return mnRenderedObjectsInPass > 0; } + + /// is first rendered object in pass + bool isFirstObjectInPass() const { return mnRenderedObjectsInPass == 0; } + /// return if there was no rendering output in the pass bool noMoreOutput() const { - // no output and we don't skip anything - return !mbPassHasOutput && !mbSkipAllInThisPass; + // no output and we didn't skip anything and nothing was rendered + return !hasPassAnyRenderedOutput() && !mbSkipAllInThisPass; } /// should include background in rendering @@ -104,19 +136,6 @@ struct RenderState return maObjectsDone.find(pObject) != maObjectsDone.end(); } - bool isObjectInAnimation(SdrObject* pObject) const - { - return maInAnimation.find(pObject) != maInAnimation.end(); - } - - bool isObjectInitiallyVisible(SdrObject* pObject) const - { - bool bInitiallyVisible = true; - if (maInitiallyVisible.contains(pObject)) - bInitiallyVisible = maInitiallyVisible.at(pObject); - return bInitiallyVisible; - } - static std::string getObjectHash(SdrObject* pObject) { css::uno::Reference<css::drawing::XShape> xShape = GetXShapeForSdrObject(pObject); @@ -144,7 +163,9 @@ private: void createViewAndDraw(RenderContext& rRenderContext); void writeJSON(OString& rJsonMsg); + void setupAnimations(); + void resolveEffect(CustomAnimationEffectPtr const& rEffect); public: SlideshowLayerRenderer(SdrPage& rPage); @@ -164,7 +185,7 @@ public: * The properties of the layer are written to the input string in JSON format. * * @returns false, if nothing was rendered and rendering is done */ - bool render(unsigned char* pBuffer, OString& rJsonMsg); + bool render(unsigned char* pBuffer, double& scale, OString& rJsonMsg); }; } // end of namespace sd diff --git a/sd/source/ui/inc/annotationmanager.hxx b/sd/source/ui/inc/annotationmanager.hxx index 25bf5503384e..b9af2ecca1b3 100644 --- a/sd/source/ui/inc/annotationmanager.hxx +++ b/sd/source/ui/inc/annotationmanager.hxx @@ -42,7 +42,8 @@ public: void ExecuteAnnotation(SfxRequest const& rRequest); void GetAnnotationState(SfxItemSet& rItemSet); - void SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation); + void SelectAnnotation(rtl::Reference<sdr::annotation::Annotation> const& xAnnotation, + bool bEdit = false); private: ::rtl::Reference<AnnotationManagerImpl> mxImpl; diff --git a/sd/source/ui/inc/optsitem.hxx b/sd/source/ui/inc/optsitem.hxx index 65bca1991090..21ad5153b528 100644 --- a/sd/source/ui/inc/optsitem.hxx +++ b/sd/source/ui/inc/optsitem.hxx @@ -240,6 +240,7 @@ class SD_DLLPUBLIC SdOptionsMiscItem final : public SfxPoolItem { public: + DECLARE_ITEM_TYPE_FUNCTION(SdOptionsMiscItem) explicit SdOptionsMiscItem(); SdOptionsMiscItem( SdOptions const * pOpts, ::sd::FrameView const * pView ); @@ -292,6 +293,7 @@ class SdOptionsGridItem final : public SvxGridItem { public: + DECLARE_ITEM_TYPE_FUNCTION(SdOptionsGridItem) explicit SdOptionsGridItem( SdOptions const * pOpts ); void SetOptions( SdOptions* pOpts ) const; @@ -384,6 +386,7 @@ class SD_DLLPUBLIC SdOptionsPrintItem final : public SfxPoolItem { public: + DECLARE_ITEM_TYPE_FUNCTION(SdOptionsPrintItem) explicit SdOptionsPrintItem(); explicit SdOptionsPrintItem( SdOptions const * pOpts ); diff --git a/sd/source/ui/inc/unomodel.hxx b/sd/source/ui/inc/unomodel.hxx index 4e4019db3147..7a299c54c280 100644 --- a/sd/source/ui/inc/unomodel.hxx +++ b/sd/source/ui/inc/unomodel.hxx @@ -308,7 +308,7 @@ public: /// @see vcl::ITiledRenderable::postSlideshowCleanup(). SD_DLLPUBLIC void postSlideshowCleanup() override; /// @see vcl::ITiledRenderable::renderNextSlideLayer(). - SD_DLLPUBLIC bool renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, OUString& rJsonMsg) override; + SD_DLLPUBLIC bool renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg) override; rtl::Reference< SdDrawPagesAccess > getSdDrawPages(); diff --git a/sd/source/ui/sidebar/MasterPageContainer.hxx b/sd/source/ui/sidebar/MasterPageContainer.hxx index 9de4eb6bc8cc..d9d3cc2311a7 100644 --- a/sd/source/ui/sidebar/MasterPageContainer.hxx +++ b/sd/source/ui/sidebar/MasterPageContainer.hxx @@ -25,6 +25,8 @@ class SdPage; +template <typename Arg, typename Ret> class Link; + namespace sd::sidebar { class MasterPageDescriptor; diff --git a/sd/source/ui/slideshow/slideshowimpl.hxx b/sd/source/ui/slideshow/slideshowimpl.hxx index 00f9c80003b7..c86c6e9b192f 100644 --- a/sd/source/ui/slideshow/slideshowimpl.hxx +++ b/sd/source/ui/slideshow/slideshowimpl.hxx @@ -44,6 +44,7 @@ class SfxBindings; class SfxDispatcher; class SfxViewFrame; class StarBASIC; +class VclSimpleEvent; namespace sd { diff --git a/sd/source/ui/tools/SlideshowLayerRenderer.cxx b/sd/source/ui/tools/SlideshowLayerRenderer.cxx index bf5e34a65a6a..43b0e0455f7d 100644 --- a/sd/source/ui/tools/SlideshowLayerRenderer.cxx +++ b/sd/source/ui/tools/SlideshowLayerRenderer.cxx @@ -8,7 +8,6 @@ */ #include <SlideshowLayerRenderer.hxx> -#include <CustomAnimationEffect.hxx> #include <svx/svdpage.hxx> #include <svx/svdmodel.hxx> #include <svx/svdview.hxx> @@ -17,9 +16,15 @@ #include <svx/sdr/contact/objectcontact.hxx> #include <svx/svdoutl.hxx> #include <svx/svdpagv.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/unoshape.hxx> + #include <vcl/virdev.hxx> #include <tools/json_writer.hxx> #include <editeng/editeng.hxx> +#include <animations/animationnodehelper.hxx> +#include <sdpage.hxx> +#include <comphelper/servicehelper.hxx> #include <com/sun/star/animations/XAnimate.hpp> #include <com/sun/star/animations/XAnimationNode.hpp> @@ -27,10 +32,13 @@ #include <com/sun/star/drawing/XShape.hpp> #include <com/sun/star/presentation/ParagraphTarget.hpp> -#include <animations/animationnodehelper.hxx> -#include <sdpage.hxx> -#include <comphelper/servicehelper.hxx> -#include <svx/unoshape.hxx> +#include <drawinglayer/primitive2d/Primitive2DContainer.hxx> +#include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> +#include <drawinglayer/primitive2d/BufferedDecompositionPrimitive2D.hxx> +#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> +#include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx> + +#include <drawinglayer/tools/primitive2dxmldump.hxx> using namespace ::com::sun::star; @@ -41,10 +49,13 @@ struct RenderContext SdrModel& mrModel; EEControlBits mnSavedControlBits; + Fraction maScale; ScopedVclPtrInstance<VirtualDevice> maVirtualDevice; - RenderContext(unsigned char* pBuffer, SdrModel& rModel, SdrPage& rPage, Size const& rSlideSize) + RenderContext(unsigned char* pBuffer, SdrModel& rModel, SdrPage& rPage, Size const& rSlideSize, + const Fraction& rScale) : mrModel(rModel) + , maScale(rScale) , maVirtualDevice(DeviceFormat::WITHOUT_ALPHA) { // Turn off spelling @@ -54,8 +65,8 @@ struct RenderContext maVirtualDevice->SetBackground(Wallpaper(COL_TRANSPARENT)); - maVirtualDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(rSlideSize, Fraction(1.0), - Point(), pBuffer); + maVirtualDevice->SetOutputSizePixelScaleOffsetAndLOKBuffer(rSlideSize, maScale, Point(), + pBuffer); Size aPageSize(rPage.GetSize()); MapMode aMapMode(MapUnit::Map100thMM); @@ -96,6 +107,115 @@ bool hasFields(SdrObject* pObject) return false; } +void changePolyPolys(drawinglayer::primitive2d::Primitive2DContainer& rContainer, + bool bRenderObject) +{ + for (auto& pBasePrimitive : rContainer) + { + if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONCOLORPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRADIENTPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONGRAPHICPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHATCHPRIMITIVE2D + || pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_POLYPOLYGONHAIRLINEPRIMITIVE2D) + { + pBasePrimitive->setVisible(bRenderObject); + } + } +} + +void changeBackground(drawinglayer::primitive2d::Primitive2DContainer const& rContainer, + bool bRenderObject) +{ + for (size_t i = 0; i < rContainer.size(); i++) + { + drawinglayer::primitive2d::BasePrimitive2D* pBasePrimitive = rContainer[i].get(); + if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D) + { + drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; + pBasePrimitive->get2DDecomposition(aPrimitiveContainer, + drawinglayer::geometry::ViewInformation2D()); + changePolyPolys(aPrimitiveContainer, bRenderObject); + } + } +} + +drawinglayer::primitive2d::TextHierarchyBlockPrimitive2D* +findTextBlock(drawinglayer::primitive2d::Primitive2DContainer const& rContainer) +{ + for (size_t i = 0; i < rContainer.size(); i++) + { + drawinglayer::primitive2d::BasePrimitive2D* pBasePrimitive = rContainer[i].get(); + if (pBasePrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_TEXTHIERARCHYBLOCKPRIMITIVE2D) + { + auto* pPrimitive + = dynamic_cast<drawinglayer::primitive2d::TextHierarchyBlockPrimitive2D*>( + pBasePrimitive); + if (pPrimitive) + return pPrimitive; + } + else + { + auto* pGroupPrimitive + = dynamic_cast<drawinglayer::primitive2d::GroupPrimitive2D*>(pBasePrimitive); + if (pGroupPrimitive) + { + auto* pTextBlock = findTextBlock(pGroupPrimitive->getChildren()); + if (pTextBlock) + return pTextBlock; + } + + auto* pBufferedPrimitive + = dynamic_cast<drawinglayer::primitive2d::BufferedDecompositionPrimitive2D*>( + pBasePrimitive); + if (pBufferedPrimitive) + { + // try to decompose + drawinglayer::primitive2d::Primitive2DContainer aPrimitiveContainer; + pBasePrimitive->get2DDecomposition(aPrimitiveContainer, + drawinglayer::geometry::ViewInformation2D()); + auto* pTextBlock = findTextBlock(aPrimitiveContainer); + if (pTextBlock) + return pTextBlock; + } + } + } + return nullptr; +} + +void modifyParagraphs(drawinglayer::primitive2d::Primitive2DContainer& rContainer, + std::deque<sal_Int32> const& rPreserveIndices, bool bRenderObject) +{ + auto* pTextBlock = findTextBlock(rContainer); + + if (pTextBlock) + { + auto& rPrimitives = const_cast<drawinglayer::primitive2d::Primitive2DContainer&>( + pTextBlock->getChildren()); + sal_Int32 nIndex = 0; + for (auto& pPrimitive : rPrimitives) + { + if (pPrimitive->getPrimitive2DID() == PRIMITIVE2D_ID_TEXTHIERARCHYPARAGRAPHPRIMITIVE2D) + { + auto& pParagraphPrimitive2d + = static_cast<drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D&>( + *pPrimitive); + + // find the index + auto aIterator + = std::find(rPreserveIndices.begin(), rPreserveIndices.end(), nIndex); + + // is index in preserve list - if false, hide the primitive + bool bHideIndex = aIterator == rPreserveIndices.end(); + + pParagraphPrimitive2d.setVisible(!bHideIndex); + } + nIndex++; + } + + changeBackground(rContainer, bRenderObject); + } +} + /** VOC redirector to control which object should be rendered and which not */ class ObjectRedirector : public sdr::contact::ViewObjectContactRedirector { @@ -116,7 +236,7 @@ public: // Generate single pass for background layer if (mrRenderState.meStage == RenderStage::Background) { - mrRenderState.mbPassHasOutput = true; + mrRenderState.mnRenderedObjectsInPass++; mrRenderState.mbSkipAllInThisPass = true; return; } @@ -148,7 +268,7 @@ public: // Check if we are in correct stage if (mrRenderState.meStage == RenderStage::Master && !pPage->IsMasterPage()) { - if (mrRenderState.mbFirstObjectInPass) + if (mrRenderState.isFirstObjectInPass()) { // if this is the first object - change from master to slide // means we are done with rendering of master layers @@ -162,18 +282,45 @@ public: } } - if (mrRenderState.isObjectInAnimation(pObject)) + // Paragraph rendering switches + bool bRenderOtherParagraphs = false; + std::deque<sal_Int32> nOtherParagraphs; + + // check if object is in animation + auto aIterator = mrRenderState.maAnimationRenderInfoList.find(pObject); + if (aIterator != mrRenderState.maAnimationRenderInfoList.end()) { // Animated object has to be only one in the render - mrRenderState.mbSkipAllInThisPass = true; + mrRenderState.mbSkipAllInThisPass = true; // skip all next objects - // Animated object cannot be attached to the previous object - if (!mrRenderState.mbFirstObjectInPass) + // Force a new layer + if (!mrRenderState.isFirstObjectInPass()) return; - } - if (mrRenderState.meStage == RenderStage::Master && hasFields(pObject) - && mrRenderState.mbStopRenderingWhenField && !mrRenderState.mbFirstObjectInPass) + AnimationRenderInfo aInfo = aIterator->second; + + if (mrRenderState.maParagraphsToRender.empty() + && !aInfo.maParagraphs.empty()) // we need to render paragraphs + { + auto* pTextObject = dynamic_cast<SdrTextObj*>(pObject); + if (pTextObject) + { + sal_Int32 nNumberOfParagraphs = pTextObject->GetOutlinerParaObject()->Count(); + + for (sal_Int32 nParagraph = 0; nParagraph < nNumberOfParagraphs; ++nParagraph) + nOtherParagraphs.push_back(nParagraph); + + for (sal_Int32 nParagraph : aInfo.maParagraphs) + { + mrRenderState.maParagraphsToRender.push_back(nParagraph); + std::erase(nOtherParagraphs, nParagraph); + } + bRenderOtherParagraphs = true; + } + } + } + else if (mrRenderState.meStage == RenderStage::Master && hasFields(pObject) + && mrRenderState.mbStopRenderingWhenField && !mrRenderState.isFirstObjectInPass()) { mrRenderState.mbStopRenderingWhenField = false; mrRenderState.mbSkipAllInThisPass = true; @@ -186,9 +333,33 @@ public: sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( rOriginal, rDisplayInfo, rVisitor); - mrRenderState.mbFirstObjectInPass = false; - mrRenderState.maObjectsDone.insert(pObject); - mrRenderState.mbPassHasOutput = true; + if (!mrRenderState.maParagraphsToRender.empty()) + { + auto rContainer + = static_cast<drawinglayer::primitive2d::Primitive2DContainer&>(rVisitor); + + if (bRenderOtherParagraphs) + { + modifyParagraphs(rContainer, nOtherParagraphs, true); // render the object + mrRenderState.mnCurrentTargetParagraph = -1; + } + else + { + sal_Int32 nParagraph = mrRenderState.maParagraphsToRender.front(); + mrRenderState.maParagraphsToRender.pop_front(); + + std::deque<sal_Int32> aPreserveParagraphs{ nParagraph }; + mrRenderState.mnCurrentTargetParagraph = nParagraph; + modifyParagraphs(rContainer, aPreserveParagraphs, + false); // render only the paragraphs + } + } + + if (mrRenderState.maParagraphsToRender.empty()) + { + mrRenderState.mnRenderedObjectsInPass++; + mrRenderState.maObjectsDone.insert(pObject); + } } }; @@ -207,6 +378,16 @@ bool hasEmptyMaster(SdrPage const& rPage) return true; } +SdrObject* getObjectForShape(uno::Reference<drawing::XShape> const& xShape) +{ + if (!xShape.is()) + return nullptr; + SvxShape* pShape = comphelper::getFromUnoTunnel<SvxShape>(xShape); + if (pShape) + return pShape->GetSdrObject(); + return nullptr; +} + } // end anonymous namespace SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage) @@ -217,92 +398,90 @@ SlideshowLayerRenderer::SlideshowLayerRenderer(SdrPage& rPage) setupAnimations(); } -void SlideshowLayerRenderer::setupAnimations() +void SlideshowLayerRenderer::resolveEffect(CustomAnimationEffectPtr const& rEffect) { - auto* pSdPage = dynamic_cast<SdPage*>(&mrPage); + SdrObject* pObject = nullptr; + sal_Int32 nParagraph = -1; + uno::Reference<drawing::XShape> xShape; - if (!pSdPage) + uno::Any aTargetAny(rEffect->getTarget()); + + if ((aTargetAny >>= xShape) && xShape.is()) + { + pObject = getObjectForShape(xShape); + } + else // if target is not a shape - could be paragraph target containing a shape + { + presentation::ParagraphTarget aParagraphTarget; + if ((aTargetAny >>= aParagraphTarget) && aParagraphTarget.Shape.is()) + { + nParagraph = aParagraphTarget.Paragraph; + pObject = getObjectForShape(aParagraphTarget.Shape); + } + } + + if (!pObject) return; - std::vector<uno::Reference<animations::XAnimationNode>> aAnimationVector; - anim::create_deep_vector(pSdPage->getAnimationNode(), aAnimationVector); + AnimationRenderInfo aAnimationInfo; + auto aIterator = maRenderState.maAnimationRenderInfoList.find(pObject); + if (aIterator != maRenderState.maAnimationRenderInfoList.end()) + aAnimationInfo = aIterator->second; + + AnimationLayerInfo aLayerInfo; - for (uno::Reference<animations::XAnimationNode> const& rNode : aAnimationVector) + std::optional<bool> bVisible; + uno::Any aAny + = rEffect->getProperty(animations::AnimationNodeType::SET, u"Visibility", EValue::To); + if (aAny.hasValue()) { - switch (rNode->getType()) - { - // filter out the most obvious - case animations::AnimationNodeType::CUSTOM: - case animations::AnimationNodeType::ANIMATE: - case animations::AnimationNodeType::SET: - case animations::AnimationNodeType::ANIMATEMOTION: - case animations::AnimationNodeType::ANIMATECOLOR: - case animations::AnimationNodeType::ANIMATETRANSFORM: - case animations::AnimationNodeType::TRANSITIONFILTER: - case animations::AnimationNodeType::ANIMATEPHYSICS: - { - uno::Reference<animations::XAnimate> xAnimate(rNode, uno::UNO_QUERY); - if (xAnimate.is()) - { - uno::Any aAny = xAnimate->getTarget(); + // if initial anim sets shape visible, set it + // to invisible. If we're asked for the final + // state, don't do anything obviously + bVisible = !anim::getVisibilityPropertyForAny(aAny); + } + aLayerInfo.moInitiallyVisible = bVisible; - uno::Reference<drawing::XShape> xShape; - SvxShape* pShape = nullptr; - SdrObject* pObject = nullptr; + OStringBuffer aStringBuffer; + anim::convertTarget(aStringBuffer, aTargetAny); + aLayerInfo.msHash = aStringBuffer.makeStringAndClear(); - if ((aAny >>= xShape) && xShape.is()) - { - pShape = comphelper::getFromUnoTunnel<SvxShape>(xShape); - if (pShape) - { - pObject = pShape->GetSdrObject(); - maRenderState.maInAnimation.insert(pObject); - } - } - else // if target is not a shape - { - presentation::ParagraphTarget aParagraphTarget; - if ((aAny >>= aParagraphTarget) && aParagraphTarget.Shape.is()) - { - //sal_Int32 nParagraph = aParagraphTarget.Paragraph; - - xShape = aParagraphTarget.Shape; - - pShape = comphelper::getFromUnoTunnel<SvxShape>(xShape); - if (pShape) - { - pObject = pShape->GetSdrObject(); - maRenderState.maInAnimation.insert(pObject); - } - } - } + // We have paragraphs + if (nParagraph >= 0) + { + auto aParagraphIterator = std::find(aAnimationInfo.maParagraphs.begin(), + aAnimationInfo.maParagraphs.end(), nParagraph); - if (pObject) - { - bool bVisible; - - if (anim::getVisibilityProperty(xAnimate, bVisible)) - { - // if initial anim sets shape visible, set it - // to invisible. If we're asked for the final - // state, don't do anything obviously - bVisible = !bVisible; - - maRenderState.maInitiallyVisible[pObject] = bVisible; - } - - if (aAny.hasValue()) - { - OStringBuffer sTmp; - anim::convertTarget(sTmp, aAny); - maRenderState.maAnimationTargetHash[pObject] - = static_cast<OString>(sTmp); - } - } - } - } + // Check if paragraph already exists + if (aParagraphIterator == aAnimationInfo.maParagraphs.end()) + { + // We have a paragraph, so write the hash for the paragraph + aAnimationInfo.maParagraphs.push_back(nParagraph); + aAnimationInfo.maParagraphInfos.emplace(nParagraph, aLayerInfo); } } + else + { + if (!aAnimationInfo.moObjectInfo) + aAnimationInfo.moObjectInfo = aLayerInfo; + } + + maRenderState.maAnimationRenderInfoList[pObject] = std::move(aAnimationInfo); +} + +void SlideshowLayerRenderer::setupAnimations() +{ + auto* pSdPage = dynamic_cast<SdPage*>(&mrPage); + + if (!pSdPage) + return; + + auto const& rMain = pSdPage->getMainSequence(); + + for (auto const& rEffect : rMain->getSequence()) + { + resolveEffect(rEffect); + } } Size SlideshowLayerRenderer::calculateAndSetSizePixel(Size const& rDesiredSizePixel) @@ -335,14 +514,16 @@ void SlideshowLayerRenderer::createViewAndDraw(RenderContext& rRenderContext) aView.CompleteRedraw(rRenderContext.maVirtualDevice, aRegion, &aRedirector); } -static void writeContentNode(::tools::JsonWriter& aJsonWriter) +namespace +{ +void writeContentNode(::tools::JsonWriter& aJsonWriter) { auto aContentNode = aJsonWriter.startNode("content"); aJsonWriter.put("type", "%IMAGETYPE%"); aJsonWriter.put("checksum", "%IMAGECHECKSUM%"); } -static void writeBoundingBox(::tools::JsonWriter& aJsonWriter, SdrObject* pObject) +void writeBoundingBox(::tools::JsonWriter& aJsonWriter, SdrObject* pObject) { auto aContentNode = aJsonWriter.startNode("bounds"); ::tools::Rectangle aRectmm100 = pObject->GetCurrentBoundRect(); @@ -353,6 +534,26 @@ static void writeBoundingBox(::tools::JsonWriter& aJsonWriter, SdrObject* pObjec aJsonWriter.put("height", aRect.GetHeight()); } +void writeAnimated(::tools::JsonWriter& aJsonWriter, AnimationLayerInfo const& rLayerInfo, + SdrObject* pObject) +{ + aJsonWriter.put("type", "animated"); + { + bool bInitiallyVisible = true; + if (rLayerInfo.moInitiallyVisible.has_value()) + bInitiallyVisible = *rLayerInfo.moInitiallyVisible; + + auto aContentNode = aJsonWriter.startNode("content"); + aJsonWriter.put("hash", rLayerInfo.msHash); + aJsonWriter.put("initVisible", bInitiallyVisible); + aJsonWriter.put("type", "bitmap"); + writeContentNode(aJsonWriter); + writeBoundingBox(aJsonWriter, pObject); + } +} + +} // end anonymous namespace + void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg) { ::tools::JsonWriter aJsonWriter; @@ -361,19 +562,30 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg) aJsonWriter.put("slideHash", GetInterfaceHash(GetXDrawPageForSdrPage(&mrPage))); SdrObject* pObject = maRenderState.currentTarget(); + sal_Int32 nParagraph = maRenderState.currentTargetParagraph(); - bool bIsAnimated = maRenderState.isObjectInAnimation(pObject); - if (bIsAnimated) + auto aIterator = maRenderState.maAnimationRenderInfoList.find(pObject); + if (aIterator != maRenderState.maAnimationRenderInfoList.end()) { + AnimationRenderInfo& rInfo = aIterator->second; assert(pObject); - aJsonWriter.put("type", "animated"); + + if (nParagraph >= 0) + { + auto aParagraphInfoIterator = rInfo.maParagraphInfos.find(nParagraph); + if (aParagraphInfoIterator != rInfo.maParagraphInfos.end()) + { + writeAnimated(aJsonWriter, aParagraphInfoIterator->second, pObject); + } + } + else if (rInfo.moObjectInfo) + { + writeAnimated(aJsonWriter, *rInfo.moObjectInfo, pObject); + } + else // No object hash and paragraph hash -> Non-animated part of the object (non-animated paragraphs) { - auto aContentNode = aJsonWriter.startNode("content"); - aJsonWriter.put("hash", maRenderState.maAnimationTargetHash.at(pObject)); - aJsonWriter.put("initVisible", maRenderState.isObjectInitiallyVisible(pObject)); aJsonWriter.put("type", "bitmap"); writeContentNode(aJsonWriter); - writeBoundingBox(aJsonWriter, pObject); } } else @@ -389,15 +601,17 @@ void SlideshowLayerRenderer::writeJSON(OString& rJsonMsg) maRenderState.incrementIndex(); } -bool SlideshowLayerRenderer::render(unsigned char* pBuffer, OString& rJsonMsg) +bool SlideshowLayerRenderer::render(unsigned char* pBuffer, double& rScale, OString& rJsonMsg) { - // Reset state + // We want to render one pass (one iteration through objects) + + // Reset state for this pass maRenderState.resetPass(); - RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize); + RenderContext aRenderContext(pBuffer, mrModel, mrPage, maSlideSize, Fraction(rScale)); createViewAndDraw(aRenderContext); - // Check if we are done rendering all passes + // Check if we are done rendering all passes and there is no more output if (maRenderState.noMoreOutput()) return false; diff --git a/sd/source/ui/unoidl/unomodel.cxx b/sd/source/ui/unoidl/unomodel.cxx index 809c2a982db1..b5fb118a2957 100644 --- a/sd/source/ui/unoidl/unomodel.cxx +++ b/sd/source/ui/unoidl/unomodel.cxx @@ -4587,7 +4587,7 @@ void SdXImpressDocument::postSlideshowCleanup() pViewSh->destroyXSlideShowInstance(); } -bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, OUString& rJsonMsg) +bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsBitmapLayer, double& rScale, OUString& rJsonMsg) { bool bDone = true; @@ -4595,7 +4595,7 @@ bool SdXImpressDocument::renderNextSlideLayer(unsigned char* pBuffer, bool& bIsB return bDone; OString sMsg; - bool bOK = mpSlideshowLayerRenderer->render(pBuffer, sMsg); + bool bOK = mpSlideshowLayerRenderer->render(pBuffer, rScale, sMsg); if (bOK) { diff --git a/sd/source/ui/unoidl/unopage.cxx b/sd/source/ui/unoidl/unopage.cxx index 8183d6cfbfe6..a5899460e754 100644 --- a/sd/source/ui/unoidl/unopage.cxx +++ b/sd/source/ui/unoidl/unopage.cxx @@ -2984,7 +2984,12 @@ void SAL_CALL SdMasterPage::setName( const OUString& rName ) GetPage()->SetName( rName ); if( pDoc ) - pDoc->RenameLayoutTemplate( GetPage()->GetLayoutName(), rName ); + { + // tdf#164463 we need to pass a copy of the LayoutName here, a + // reference means it can get updated to rName during the function. + OUString aOldPageLayoutName = GetPage()->GetLayoutName(); + pDoc->RenameLayoutTemplate(aOldPageLayoutName, rName); + } // fake a mode change to repaint the page tab bar ::sd::DrawDocShell* pDocSh = GetModel()->GetDocShell(); diff --git a/sd/source/ui/view/drviewsb.cxx b/sd/source/ui/view/drviewsb.cxx index b585185c09d0..0f6d46460153 100644 --- a/sd/source/ui/view/drviewsb.cxx +++ b/sd/source/ui/view/drviewsb.cxx @@ -83,7 +83,8 @@ bool DrawViewShell::RenameSlide( sal_uInt16 nPageId, const OUString & rName ) { // rename MasterPage -> rename LayoutTemplate pPageToRename = GetDoc()->GetMasterSdPage( maTabControl->GetPagePos(nPageId), ePageKind ); - GetDoc()->RenameLayoutTemplate( pPageToRename->GetLayoutName(), rName ); + OUString aOldPageLayoutName = pPageToRename->GetLayoutName(); + GetDoc()->RenameLayoutTemplate(aOldPageLayoutName, rName); } bool bSuccess = (rName == pPageToRename->GetName()); diff --git a/sd/source/ui/view/drviewse.cxx b/sd/source/ui/view/drviewse.cxx index 9a7c8df31f7a..ea2f65a01c00 100644 --- a/sd/source/ui/view/drviewse.cxx +++ b/sd/source/ui/view/drviewse.cxx @@ -98,6 +98,7 @@ #include <basegfx/utils/zoomtools.hxx> #include <officecfg/Office/Draw.hxx> #include <officecfg/Office/Impress.hxx> +#include <sfx2/lokhelper.hxx> using namespace ::com::sun::star; using namespace ::com::sun::star::uno; @@ -455,6 +456,36 @@ void DrawViewShell::FuPermanent(SfxRequest& rReq) case SID_CONNECTOR_LINES_CIRCLES: case SID_INSERT_SIGNATURELINE: { + if (nSId == SID_INSERT_SIGNATURELINE) + { + // See if a signing cert is passed as a parameter: if so, parse that. + std::string aSignatureCert; + std::string aSignatureKey; + const SfxStringItem* pSignatureCert = rReq.GetArg<SfxStringItem>(FN_PARAM_1); + if (pSignatureCert) + { + aSignatureCert = pSignatureCert->GetValue().toUtf8(); + } + const SfxStringItem* pSignatureKey = rReq.GetArg<SfxStringItem>(FN_PARAM_2); + if (pSignatureKey) + { + aSignatureKey = pSignatureKey->GetValue().toUtf8(); + } + + SfxViewFrame* pFrame = GetFrame(); + SfxViewShell* pViewShell = pFrame ? pFrame->GetViewShell() : nullptr; + if (pViewShell) + { + uno::Reference<security::XCertificate> xSigningCertificate; + if (!aSignatureCert.empty() && !aSignatureKey.empty()) + { + xSigningCertificate = SfxLokHelper::getSigningCertificate(aSignatureCert, aSignatureKey); + } + // Always set the signing certificate, to clear data from a previous dispatch. + pViewShell->SetSigningCertificate(xSigningCertificate); + } + } + bCreateDirectly = comphelper::LibreOfficeKit::isActive(); bRectangle = true; SetCurrentFunction( FuConstructRectangle::Create( this, GetActiveWindow(), mpDrawView.get(), GetDoc(), rReq, bPermanent ) ); |