diff options
Diffstat (limited to 'svx/source/sdr/contact')
47 files changed, 11526 insertions, 0 deletions
diff --git a/svx/source/sdr/contact/displayinfo.cxx b/svx/source/sdr/contact/displayinfo.cxx new file mode 100644 index 000000000000..d964611c59a0 --- /dev/null +++ b/svx/source/sdr/contact/displayinfo.cxx @@ -0,0 +1,110 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <vcl/svapp.hxx> +#include <svx/svdobj.hxx> +#include <vcl/gdimtf.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> + +#define ALL_GHOSTED_DRAWMODES (DRAWMODE_GHOSTEDLINE|DRAWMODE_GHOSTEDFILL|DRAWMODE_GHOSTEDTEXT|DRAWMODE_GHOSTEDBITMAP|DRAWMODE_GHOSTEDGRADIENT) + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + DisplayInfo::DisplayInfo() + : maProcessLayers(true), // init layer info with all bits set to draw everything on default + maRedrawArea(), + mbControlLayerProcessingActive(false), + mbPageProcessingActive(true), + mbGhostedDrawModeActive(false), + mbSubContentActive(false) + { + } + + DisplayInfo::~DisplayInfo() + { + } + + // Access to LayerInfos (which layers to proccess) + void DisplayInfo::SetProcessLayers(const SetOfByte& rSet) + { + maProcessLayers = rSet; + } + + // access to RedrawArea + void DisplayInfo::SetRedrawArea(const Region& rRegion) + { + maRedrawArea = rRegion; + } + + void DisplayInfo::SetControlLayerProcessingActive(bool bDoProcess) + { + if((bool)mbControlLayerProcessingActive != bDoProcess) + { + mbControlLayerProcessingActive = bDoProcess; + } + } + + void DisplayInfo::SetPageProcessingActive(bool bDoProcess) + { + if((bool)mbPageProcessingActive != bDoProcess) + { + mbPageProcessingActive = bDoProcess; + } + } + + void DisplayInfo::ClearGhostedDrawMode() + { + mbGhostedDrawModeActive = false; + } + + void DisplayInfo::SetGhostedDrawMode() + { + mbGhostedDrawModeActive = true; + } + + void DisplayInfo::SetSubContentActive(bool bNew) + { + if((bool)mbSubContentActive != bNew) + { + mbSubContentActive = bNew; + } + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/makefile.mk b/svx/source/sdr/contact/makefile.mk new file mode 100644 index 000000000000..9e4356c4aa52 --- /dev/null +++ b/svx/source/sdr/contact/makefile.mk @@ -0,0 +1,92 @@ +#************************************************************************* +# +# DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. +# +# Copyright 2000, 2010 Oracle and/or its affiliates. +# +# OpenOffice.org - a multi-platform office productivity suite +# +# This file is part of OpenOffice.org. +# +# OpenOffice.org is free software: you can redistribute it and/or modify +# it under the terms of the GNU Lesser General Public License version 3 +# only, as published by the Free Software Foundation. +# +# OpenOffice.org is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU Lesser General Public License version 3 for more details +# (a copy is included in the LICENSE file that accompanied this code). +# +# You should have received a copy of the GNU Lesser General Public License +# version 3 along with OpenOffice.org. If not, see +# <http://www.openoffice.org/license.html> +# for a copy of the LGPLv3 License. +# +#************************************************************************* + +PRJ=..$/..$/.. +PRJINC=$(PRJ)$/source + +PRJNAME=svx +TARGET=contact +ENABLE_EXCEPTIONS=TRUE + +# --- Settings ----------------------------------------------------- + +.INCLUDE : settings.mk +.INCLUDE : $(PRJ)$/util$/makefile.pmk + +# --- Files -------------------------------------------------------- + +EXCEPTIONSFILES=\ + $(SLO)$/viewobjectcontactofunocontrol.obj + +SLOFILES=\ + $(EXCEPTIONSFILES) \ + $(SLO)$/displayinfo.obj \ + $(SLO)$/viewcontact.obj \ + $(SLO)$/viewcontactofe3d.obj \ + $(SLO)$/viewcontactofsdrobj.obj \ + $(SLO)$/viewcontactofvirtobj.obj \ + $(SLO)$/viewcontactoftextobj.obj \ + $(SLO)$/viewcontactofsdrrectobj.obj \ + $(SLO)$/viewcontactofsdrpathobj.obj \ + $(SLO)$/viewcontactofsdrole2obj.obj \ + $(SLO)$/viewcontactofsdrcircobj.obj \ + $(SLO)$/viewcontactofsdrcaptionobj.obj \ + $(SLO)$/viewcontactofsdrmeasureobj.obj \ + $(SLO)$/viewcontactofsdredgeobj.obj \ + $(SLO)$/viewcontactofsdrpage.obj \ + $(SLO)$/viewcontactofmasterpagedescriptor.obj \ + $(SLO)$/viewcontactofgroup.obj \ + $(SLO)$/viewcontactofe3dscene.obj \ + $(SLO)$/viewcontactofe3dcube.obj \ + $(SLO)$/viewcontactofe3dextrude.obj \ + $(SLO)$/viewcontactofe3dlathe.obj \ + $(SLO)$/viewcontactofe3dsphere.obj \ + $(SLO)$/viewcontactofe3dpolygon.obj \ + $(SLO)$/viewcontactofpageobj.obj \ + $(SLO)$/viewcontactofgraphic.obj \ + $(SLO)$/viewcontactofsdrobjcustomshape.obj \ + $(SLO)$/viewcontactofsdrmediaobj.obj \ + $(SLO)$/viewcontactofunocontrol.obj \ + $(SLO)$/objectcontact.obj \ + $(SLO)$/objectcontacttools.obj \ + $(SLO)$/objectcontactofobjlistpainter.obj \ + $(SLO)$/objectcontactofpageview.obj \ + $(SLO)$/viewobjectcontact.obj \ + $(SLO)$/viewobjectcontactofe3d.obj \ + $(SLO)$/viewobjectcontactredirector.obj \ + $(SLO)$/viewobjectcontactofsdrmediaobj.obj \ + $(SLO)$/viewobjectcontactofgroup.obj \ + $(SLO)$/viewobjectcontactofe3dscene.obj \ + $(SLO)$/viewobjectcontactofsdrpage.obj \ + $(SLO)$/viewobjectcontactofsdrobj.obj \ + $(SLO)$/viewobjectcontactofpageobj.obj \ + $(SLO)$/viewobjectcontactofsdrole2obj.obj \ + $(SLO)$/viewobjectcontactofgraphic.obj \ + $(SLO)$/viewobjectcontactofmasterpagedescriptor.obj \ + $(SLO)$/sdrmediawindow.obj + +.INCLUDE : target.mk diff --git a/svx/source/sdr/contact/objectcontact.cxx b/svx/source/sdr/contact/objectcontact.cxx new file mode 100644 index 000000000000..bda2e1529988 --- /dev/null +++ b/svx/source/sdr/contact/objectcontact.cxx @@ -0,0 +1,322 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/objectcontact.hxx> +#include <tools/debug.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/event/eventhandler.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ObjectContact::ObjectContact() + : maViewObjectContactVector(), + maPrimitiveAnimator(), + mpEventHandler(0), + mpViewObjectContactRedirector(0), + maViewInformation2D(uno::Sequence< beans::PropertyValue >()), + mbIsPreviewRenderer(false) + { + } + + ObjectContact::~ObjectContact() + { + // get rid of all registered contacts + // #i84257# To avoid that each 'delete pCandidate' again uses + // the local RemoveViewObjectContact with a search and removal in the + // vector, simply copy and clear local vector. + std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector); + maViewObjectContactVector.clear(); + + while(aLocalVOCList.size()) + { + ViewObjectContact* pCandidate = aLocalVOCList.back(); + aLocalVOCList.pop_back(); + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)"); + + // ViewObjectContacts only make sense with View and Object contacts. + // When the contact to the SdrObject is deleted like in this case, + // all ViewObjectContacts can be deleted, too. + delete pCandidate; + } + + // assert when there were new entries added during deletion + DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList (!)"); + + // delete the EventHandler. This will destroy all still contained events. + DeleteEventHandler(); + } + + // LazyInvalidate request. Default implementation directly handles + // this by calling back triggerLazyInvalidate() at the VOC + void ObjectContact::setLazyInvalidate(ViewObjectContact& rVOC) + { + rVOC.triggerLazyInvalidate(); + } + + // call this to support evtl. preparations for repaint. Default does nothing + void ObjectContact::PrepareProcessDisplay() + { + } + + // A new ViewObjectContact was created and shall be remembered. + void ObjectContact::AddViewObjectContact(ViewObjectContact& rVOContact) + { + maViewObjectContactVector.push_back(&rVOContact); + } + + // A ViewObjectContact was deleted and shall be forgotten. + void ObjectContact::RemoveViewObjectContact(ViewObjectContact& rVOContact) + { + std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact); + + if(aFindResult != maViewObjectContactVector.end()) + { + maViewObjectContactVector.erase(aFindResult); + } + } + + // Process the whole displaying + void ObjectContact::ProcessDisplay(DisplayInfo& /*rDisplayInfo*/) + { + // default does nothing + } + + // test if visualizing of entered groups is switched on at all + bool ObjectContact::DoVisualizeEnteredGroup() const + { + // Don not do that as default + return false; + } + + // get active group's (the entered group) ViewContact + const ViewContact* ObjectContact::getActiveViewContact() const + { + // default has no active VC + return 0; + } + + // Invalidate given rectangle at the window/output which is represented by + // this ObjectContact. + void ObjectContact::InvalidatePartOfView(const basegfx::B2DRange& /*rRange*/) const + { + // nothing to do here in the default version + } + + // Get info if given Rectangle is visible in this view + bool ObjectContact::IsAreaVisible(const basegfx::B2DRange& /*rRange*/) const + { + // always visible in default version + return true; + } + + // Get info about the need to visualize GluePoints + bool ObjectContact::AreGluePointsVisible() const + { + return false; + } + + // method to create a EventHandler. Needs to give a result. + sdr::event::TimerEventHandler* ObjectContact::CreateEventHandler() + { + // Create and return a new EventHandler + return new sdr::event::TimerEventHandler(); + } + + // method to get the primitiveAnimator + sdr::animation::primitiveAnimator& ObjectContact::getPrimitiveAnimator() + { + return maPrimitiveAnimator; + } + + // method to get the EventHandler. It will + // return a existing one or create a new one using CreateEventHandler(). + sdr::event::TimerEventHandler& ObjectContact::GetEventHandler() const + { + if(!HasEventHandler()) + { + const_cast< ObjectContact* >(this)->mpEventHandler = const_cast< ObjectContact* >(this)->CreateEventHandler(); + DBG_ASSERT(mpEventHandler, "ObjectContact::GetEventHandler(): Got no EventHandler (!)"); + } + + return *mpEventHandler; + } + + // delete the EventHandler + void ObjectContact::DeleteEventHandler() + { + if(mpEventHandler) + { + // If there are still Events registered, something has went wrong + delete mpEventHandler; + mpEventHandler = 0L; + } + } + + // test if there is an EventHandler without creating one on demand + bool ObjectContact::HasEventHandler() const + { + return (0L != mpEventHandler); + } + + // check if text animation is allowed. Default is sal_true. + bool ObjectContact::IsTextAnimationAllowed() const + { + return true; + } + + // check if graphic animation is allowed. Default is sal_true. + bool ObjectContact::IsGraphicAnimationAllowed() const + { + return true; + } + + // check if asynchronious graphis loading is allowed. Default is false. + bool ObjectContact::IsAsynchronGraphicsLoadingAllowed() const + { + return false; + } + + // access to ViewObjectContactRedirector + ViewObjectContactRedirector* ObjectContact::GetViewObjectContactRedirector() const + { + return mpViewObjectContactRedirector; + } + + void ObjectContact::SetViewObjectContactRedirector(ViewObjectContactRedirector* pNew) + { + if(mpViewObjectContactRedirector != pNew) + { + mpViewObjectContactRedirector = pNew; + } + } + + // check if buffering of MasterPages is allowed. Default is false. + bool ObjectContact::IsMasterPageBufferingAllowed() const + { + return false; + } + + // print? Default is false + bool ObjectContact::isOutputToPrinter() const + { + return false; + } + + // window? Default is true + bool ObjectContact::isOutputToWindow() const + { + return true; + } + + // VirtualDevice? Default is false + bool ObjectContact::isOutputToVirtualDevice() const + { + return false; + } + + // recording MetaFile? Default is false + bool ObjectContact::isOutputToRecordingMetaFile() const + { + return false; + } + + // pdf export? Default is false + bool ObjectContact::isOutputToPDFFile() const + { + return false; + } + + // gray display mode + bool ObjectContact::isDrawModeGray() const + { + return false; + } + + // gray display mode + bool ObjectContact::isDrawModeBlackWhite() const + { + return false; + } + + // high contrast display mode + bool ObjectContact::isDrawModeHighContrast() const + { + return false; + } + + // access to SdrPageView. Default implementation returns NULL + SdrPageView* ObjectContact::TryToGetSdrPageView() const + { + return 0; + } + + // access to OutputDevice. Default implementation returns NULL + OutputDevice* ObjectContact::TryToGetOutputDevice() const + { + return 0; + } + + void ObjectContact::resetViewPort() + { + const drawinglayer::geometry::ViewInformation2D& rCurrentVI2D = getViewInformation2D(); + + if(!rCurrentVI2D.getViewport().isEmpty()) + { + const basegfx::B2DRange aEmptyRange; + + drawinglayer::geometry::ViewInformation2D aNewVI2D( + rCurrentVI2D.getObjectTransformation(), + rCurrentVI2D.getViewTransformation(), + aEmptyRange, + rCurrentVI2D.getVisualizedPage(), + rCurrentVI2D.getViewTime(), + rCurrentVI2D.getExtendedInformationSequence()); + + updateViewInformation2D(aNewVI2D); + } + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx b/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx new file mode 100644 index 000000000000..da8518d7f1a1 --- /dev/null +++ b/svx/source/sdr/contact/objectcontactofobjlistpainter.cxx @@ -0,0 +1,207 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/svdmodel.hxx> +#include <drawinglayer/processor2d/vclprocessor2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <unoapi.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ObjectContactPainter::ObjectContactPainter() + { + } + + // The destructor. + ObjectContactPainter::~ObjectContactPainter() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + sal_uInt32 ObjectContactOfObjListPainter::GetPaintObjectCount() const + { + return maStartObjects.size(); + } + + ViewContact& ObjectContactOfObjListPainter::GetPaintObjectViewContact(sal_uInt32 nIndex) const + { + const SdrObject* pObj = maStartObjects[nIndex]; + DBG_ASSERT(pObj, "ObjectContactOfObjListPainter: Corrupt SdrObjectVector (!)"); + return pObj->GetViewContact(); + } + + ObjectContactOfObjListPainter::ObjectContactOfObjListPainter( + OutputDevice& rTargetDevice, + const SdrObjectVector& rObjects, + const SdrPage* pProcessedPage) + : ObjectContactPainter(), + mrTargetOutputDevice(rTargetDevice), + maStartObjects(rObjects), + mpProcessedPage(pProcessedPage) + { + } + + ObjectContactOfObjListPainter::~ObjectContactOfObjListPainter() + { + } + + // Process the whole displaying + void ObjectContactOfObjListPainter::ProcessDisplay(DisplayInfo& rDisplayInfo) + { + const sal_uInt32 nCount(GetPaintObjectCount()); + + if(nCount) + { + OutputDevice* pTargetDevice = TryToGetOutputDevice(); + + if(pTargetDevice) + { + // update current ViewInformation2D at the ObjectContact + const GDIMetaFile* pMetaFile = pTargetDevice->GetConnectMetaFile(); + const bool bOutputToRecordingMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + basegfx::B2DRange aViewRange; + + // create ViewRange + if(!bOutputToRecordingMetaFile) + { + // use visible pixels, but transform to world coordinates + const Size aOutputSizePixel(pTargetDevice->GetOutputSizePixel()); + aViewRange = ::basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + aViewRange.transform(pTargetDevice->GetInverseViewTransformation()); + } + + // upate local ViewInformation2D + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + basegfx::B2DHomMatrix(), + pTargetDevice->GetViewTransformation(), + aViewRange, + GetXDrawPageForSdrPage(const_cast< SdrPage* >(mpProcessedPage)), + 0.0, + 0); + updateViewInformation2D(aNewViewInformation2D); + + // collect primitive data in a sequence; this will already use the updated ViewInformation2D + drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence; + + for(sal_uInt32 a(0L); a < nCount; a++) + { + const ViewObjectContact& rViewObjectContact = GetPaintObjectViewContact(a).GetViewObjectContact(*this); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xPrimitiveSequence, + rViewObjectContact.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + } + + // if there is something to show, use a vclProcessor to render it + if(xPrimitiveSequence.hasElements()) + { + drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = createBaseProcessor2DFromOutputDevice( + *pTargetDevice, getViewInformation2D()); + + if(pProcessor2D) + { + pProcessor2D->process(xPrimitiveSequence); + delete pProcessor2D; + } + } + } + } + } + + OutputDevice* ObjectContactOfObjListPainter::TryToGetOutputDevice() const + { + return &mrTargetOutputDevice; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + sal_uInt32 ObjectContactOfPagePainter::GetPaintObjectCount() const + { + return (GetStartPage() ? 1L : 0L); + } + + ViewContact& ObjectContactOfPagePainter::GetPaintObjectViewContact(sal_uInt32 /*nIndex*/) const + { + DBG_ASSERT(GetStartPage(), "ObjectContactOfPagePainter::GetPaintObjectViewContact: no StartPage set (!)"); + return GetStartPage()->GetViewContact(); + } + + ObjectContactOfPagePainter::ObjectContactOfPagePainter( + const SdrPage* pPage, + ObjectContact& rOriginalObjectContact) + : ObjectContactPainter(), + mrOriginalObjectContact(rOriginalObjectContact), + mxStartPage(const_cast< SdrPage* >(pPage)) // no SdrPageWeakRef available to hold a const SdrPage* + { + } + + ObjectContactOfPagePainter::~ObjectContactOfPagePainter() + { + } + + void ObjectContactOfPagePainter::SetStartPage(const SdrPage* pPage) + { + if(pPage != GetStartPage()) + { + mxStartPage.reset(const_cast< SdrPage* >(pPage)); // no SdrPageWeakRef available to hold a const SdrPage* + } + } + + OutputDevice* ObjectContactOfPagePainter::TryToGetOutputDevice() const + { + return mrOriginalObjectContact.TryToGetOutputDevice(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontactofpageview.cxx b/svx/source/sdr/contact/objectcontactofpageview.cxx new file mode 100644 index 000000000000..1652855d84a8 --- /dev/null +++ b/svx/source/sdr/contact/objectcontactofpageview.cxx @@ -0,0 +1,485 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdview.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> +#include <drawinglayer/processor2d/vclprocessor2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <com/sun/star/rendering/XSpriteCanvas.hpp> +#include <unoapi.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // internal access to SdrPage of SdrPageView + SdrPage* ObjectContactOfPageView::GetSdrPage() const + { + return GetPageWindow().GetPageView().GetPage(); + } + + ObjectContactOfPageView::ObjectContactOfPageView(SdrPageWindow& rPageWindow) + : ObjectContact(), + mrPageWindow(rPageWindow) + { + // init PreviewRenderer flag + setPreviewRenderer(((SdrPaintView&)rPageWindow.GetPageView().GetView()).IsPreviewRenderer()); + + // init timer + SetTimeout(1); + Stop(); + } + + ObjectContactOfPageView::~ObjectContactOfPageView() + { + // execute missing LazyInvalidates and stop timer + Timeout(); + } + + // LazyInvalidate request. Take action. + void ObjectContactOfPageView::setLazyInvalidate(ViewObjectContact& /*rVOC*/) + { + // do NOT call parent, but remember that something is to do by + // starting the LazyInvalidateTimer + Start(); + } + + // call this to support evtl. preparations for repaint + void ObjectContactOfPageView::PrepareProcessDisplay() + { + if(IsActive()) + { + static bool bInvalidateDuringPaint(true); + + if(bInvalidateDuringPaint) + { + // there are still non-triggered LazyInvalidate events, trigger these + Timeout(); + } + } + } + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + void ObjectContactOfPageView::Timeout() + { + // stop the timer + Stop(); + + // invalidate all LazyInvalidate VOCs new situations + const sal_uInt32 nVOCCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nVOCCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + pCandidate->triggerLazyInvalidate(); + } + } + + // Process the whole displaying + void ObjectContactOfPageView::ProcessDisplay(DisplayInfo& rDisplayInfo) + { + const SdrPage* pStartPage = GetSdrPage(); + + if(pStartPage && !rDisplayInfo.GetProcessLayers().IsEmpty()) + { + const ViewContact& rDrawPageVC = pStartPage->GetViewContact(); + + if(rDrawPageVC.GetObjectCount()) + { + DoProcessDisplay(rDisplayInfo); + } + } + + // after paint take care of the evtl. scheduled asynchronious commands. + // Do this by resetting the timer contained there. Thus, after the paint + // that timer will be triggered and the events will be executed. + if(HasEventHandler()) + { + sdr::event::TimerEventHandler& rEventHandler = GetEventHandler(); + + if(!rEventHandler.IsEmpty()) + { + rEventHandler.Restart(); + } + } + } + + // Process the whole displaying. Only use given DsiplayInfo, do not access other + // OutputDevices then the given ones. + void ObjectContactOfPageView::DoProcessDisplay(DisplayInfo& rDisplayInfo) + { + // visualize entered group when that feature is switched on and it's not + // a print output. #i29129# No ghosted display for printing. + sal_Bool bVisualizeEnteredGroup(DoVisualizeEnteredGroup() && !isOutputToPrinter()); + + // Visualize entered groups: Set to ghosted as default + // start. Do this only for the DrawPage, not for MasterPages + if(bVisualizeEnteredGroup) + { + rDisplayInfo.SetGhostedDrawMode(); + } + + // #114359# save old and set clip region + OutputDevice* pOutDev = TryToGetOutputDevice(); + OSL_ENSURE(0 != pOutDev, "ObjectContactOfPageView without OutDev, someone has overloaded TryToGetOutputDevice wrong (!)"); + sal_Bool bClipRegionPushed(sal_False); + const Region& rRedrawArea(rDisplayInfo.GetRedrawArea()); + + if(!rRedrawArea.IsEmpty()) + { + bClipRegionPushed = sal_True; + pOutDev->Push(PUSH_CLIPREGION); + pOutDev->IntersectClipRegion(rRedrawArea); + } + + // Get start node and process DrawPage contents + const ViewObjectContact& rDrawPageVOContact = GetSdrPage()->GetViewContact().GetViewObjectContact(*this); + + // update current ViewInformation2D at the ObjectContact + const double fCurrentTime(getPrimitiveAnimator().GetTime()); + OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); + basegfx::B2DRange aViewRange; + + // create ViewRange + if(isOutputToRecordingMetaFile()) + { + if(isOutputToPDFFile() || isOutputToPrinter()) + { + // #i98402# if it's a PDF export, set the ClipRegion as ViewRange. This is + // mainly because SW does not use DrawingLayer Page-Oriented and if not doing this, + // all existing objects will be collected as primitives and processed. + // OD 2009-03-05 #i99876# perform the same also for SW on printing. + const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); + + aViewRange = basegfx::B2DRange( + aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), + aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); + } + } + else + { + // use visible pixels, but transform to world coordinates + const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); + aViewRange = basegfx::B2DRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + + // if a clip region is set, use it + if(!rDisplayInfo.GetRedrawArea().IsEmpty()) + { + // get logic clip range and create discrete one + const Rectangle aLogicClipRectangle(rDisplayInfo.GetRedrawArea().GetBoundRect()); + basegfx::B2DRange aLogicClipRange( + aLogicClipRectangle.Left(), aLogicClipRectangle.Top(), + aLogicClipRectangle.Right(), aLogicClipRectangle.Bottom()); + basegfx::B2DRange aDiscreteClipRange(aLogicClipRange); + aDiscreteClipRange.transform(rTargetOutDev.GetViewTransformation()); + + // align the discrete one to discrete boundaries (pixel bounds). Also + // expand X and Y max by one due to Rectangle definition source + aDiscreteClipRange.expand(basegfx::B2DTuple( + floor(aDiscreteClipRange.getMinX()), + floor(aDiscreteClipRange.getMinY()))); + aDiscreteClipRange.expand(basegfx::B2DTuple( + 1.0 + ceil(aDiscreteClipRange.getMaxX()), + 1.0 + ceil(aDiscreteClipRange.getMaxY()))); + + // intersect current ViewRange with ClipRange + aViewRange.intersect(aDiscreteClipRange); + } + + // transform to world coordinates + aViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); + } + + // update local ViewInformation2D + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + basegfx::B2DHomMatrix(), + rTargetOutDev.GetViewTransformation(), + aViewRange, + GetXDrawPageForSdrPage(GetSdrPage()), + fCurrentTime, + 0); + updateViewInformation2D(aNewViewInformation2D); + + // get whole Primitive2DSequence; this will already make use of updated ViewInformation2D + // and may use the MapMode from the Target OutDev in the DisplayInfo + drawinglayer::primitive2d::Primitive2DSequence xPrimitiveSequence(rDrawPageVOContact.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + + // if there is something to show, use a primitive processor to render it. There + // is a choice between VCL and Canvas processors currently. The decision is made in + // createBaseProcessor2DFromOutputDevice and takes into accout things like the + // Target is a MetaFile, a VDev or something else. The Canvas renderer is triggered + // currently using the shown boolean. Canvas is not yet the default. + if(xPrimitiveSequence.hasElements()) + { + // prepare OutputDevice (historical stuff, maybe soon removed) + rDisplayInfo.ClearGhostedDrawMode(); // reset, else the VCL-paint with the processor will not do the right thing + pOutDev->SetLayoutMode(0); // reset, default is no BiDi/RTL + + // create renderer + drawinglayer::processor2d::BaseProcessor2D* pProcessor2D = createBaseProcessor2DFromOutputDevice( + rTargetOutDev, getViewInformation2D()); + + if(pProcessor2D) + { + pProcessor2D->process(xPrimitiveSequence); + delete pProcessor2D; + } + } + + // #114359# restore old ClipReghion + if(bClipRegionPushed) + { + pOutDev->Pop(); + } + + // Visualize entered groups: Reset to original DrawMode + if(bVisualizeEnteredGroup) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + } + + // test if visualizing of entered groups is switched on at all + bool ObjectContactOfPageView::DoVisualizeEnteredGroup() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.DoVisualizeEnteredGroup(); + } + + // get active group's (the entered group) ViewContact + const ViewContact* ObjectContactOfPageView::getActiveViewContact() const + { + SdrObjList* pActiveGroupList = GetPageWindow().GetPageView().GetObjList(); + + if(pActiveGroupList) + { + if(pActiveGroupList->ISA(SdrPage)) + { + // It's a Page itself + return &(((SdrPage*)pActiveGroupList)->GetViewContact()); + } + else if(pActiveGroupList->GetOwnerObj()) + { + // Group object + return &(pActiveGroupList->GetOwnerObj()->GetViewContact()); + } + } + else if(GetSdrPage()) + { + // use page of associated SdrPageView + return &(GetSdrPage()->GetViewContact()); + } + + return 0; + } + + // Invalidate given rectangle at the window/output which is represented by + // this ObjectContact. + void ObjectContactOfPageView::InvalidatePartOfView(const basegfx::B2DRange& rRange) const + { + // invalidate at associated PageWindow + GetPageWindow().InvalidatePageWindow(rRange); + } + + // Get info if given Rectangle is visible in this view + bool ObjectContactOfPageView::IsAreaVisible(const basegfx::B2DRange& rRange) const + { + // compare with the visible rectangle + if(rRange.isEmpty()) + { + // no range -> not visible + return false; + } + else + { + const OutputDevice& rTargetOutDev = GetPageWindow().GetPaintWindow().GetTargetOutputDevice(); + const Size aOutputSizePixel(rTargetOutDev.GetOutputSizePixel()); + basegfx::B2DRange aLogicViewRange(0.0, 0.0, aOutputSizePixel.getWidth(), aOutputSizePixel.getHeight()); + + aLogicViewRange.transform(rTargetOutDev.GetInverseViewTransformation()); + + if(!aLogicViewRange.isEmpty() && !aLogicViewRange.overlaps(rRange)) + { + return false; + } + } + + // call parent + return ObjectContact::IsAreaVisible(rRange); + } + + // Get info about the need to visualize GluePoints + bool ObjectContactOfPageView::AreGluePointsVisible() const + { + return GetPageWindow().GetPageView().GetView().ImpIsGlueVisible(); + } + + // check if text animation is allowed. + bool ObjectContactOfPageView::IsTextAnimationAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); + return rOpt.GetIsAllowAnimatedText(); + } + + // check if graphic animation is allowed. + bool ObjectContactOfPageView::IsGraphicAnimationAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + const SvtAccessibilityOptions& rOpt = rView.getAccessibilityOptions(); + return rOpt.GetIsAllowAnimatedGraphics(); + } + + // check if asynchronious graphis loading is allowed. Default is sal_False. + bool ObjectContactOfPageView::IsAsynchronGraphicsLoadingAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.IsSwapAsynchron(); + } + + // check if buffering of MasterPages is allowed. Default is sal_False. + bool ObjectContactOfPageView::IsMasterPageBufferingAllowed() const + { + SdrView& rView = GetPageWindow().GetPageView().GetView(); + return rView.IsMasterPagePaintCaching(); + } + + // print? + bool ObjectContactOfPageView::isOutputToPrinter() const + { + return (OUTDEV_PRINTER == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // window? + bool ObjectContactOfPageView::isOutputToWindow() const + { + return (OUTDEV_WINDOW == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // VirtualDevice? + bool ObjectContactOfPageView::isOutputToVirtualDevice() const + { + return (OUTDEV_VIRDEV == mrPageWindow.GetPaintWindow().GetOutputDevice().GetOutDevType()); + } + + // recording MetaFile? + bool ObjectContactOfPageView::isOutputToRecordingMetaFile() const + { + GDIMetaFile* pMetaFile = mrPageWindow.GetPaintWindow().GetOutputDevice().GetConnectMetaFile(); + return (pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + } + + // pdf export? + bool ObjectContactOfPageView::isOutputToPDFFile() const + { + return (0 != mrPageWindow.GetPaintWindow().GetOutputDevice().GetPDFWriter()); + } + + // gray display mode + bool ObjectContactOfPageView::isDrawModeGray() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_GRAYLINE|DRAWMODE_GRAYFILL|DRAWMODE_BLACKTEXT|DRAWMODE_GRAYBITMAP|DRAWMODE_GRAYGRADIENT)); + } + + // gray display mode + bool ObjectContactOfPageView::isDrawModeBlackWhite() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_BLACKLINE|DRAWMODE_BLACKTEXT|DRAWMODE_WHITEFILL|DRAWMODE_GRAYBITMAP|DRAWMODE_WHITEGRADIENT)); + } + + // high contrast display mode + bool ObjectContactOfPageView::isDrawModeHighContrast() const + { + const sal_uInt32 nDrawMode(mrPageWindow.GetPaintWindow().GetOutputDevice().GetDrawMode()); + return (nDrawMode == (DRAWMODE_SETTINGSLINE|DRAWMODE_SETTINGSFILL|DRAWMODE_SETTINGSTEXT|DRAWMODE_SETTINGSGRADIENT)); + } + + // access to SdrPageView + SdrPageView* ObjectContactOfPageView::TryToGetSdrPageView() const + { + return &(mrPageWindow.GetPageView()); + } + + + // access to OutputDevice + OutputDevice* ObjectContactOfPageView::TryToGetOutputDevice() const + { + SdrPreRenderDevice* pPreRenderDevice = mrPageWindow.GetPaintWindow().GetPreRenderDevice(); + + if(pPreRenderDevice) + { + return &(pPreRenderDevice->GetPreRenderDevice()); + } + else + { + return &(mrPageWindow.GetPaintWindow().GetOutputDevice()); + } + } + + // set all UNO controls displayed in the view to design/alive mode + void ObjectContactOfPageView::SetUNOControlsDesignMode( bool _bDesignMode ) const + { + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + const ViewObjectContact* pVOC = getViewObjectContact(a); + const ViewObjectContactOfUnoControl* pUnoObjectVOC = dynamic_cast< const ViewObjectContactOfUnoControl* >(pVOC); + + if(pUnoObjectVOC) + { + pUnoObjectVOC->setControlDesignMode(_bDesignMode); + } + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/objectcontacttools.cxx b/svx/source/sdr/contact/objectcontacttools.cxx new file mode 100644 index 000000000000..5776bd8847ce --- /dev/null +++ b/svx/source/sdr/contact/objectcontacttools.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/objectcontacttools.hxx> +#include <vcl/outdev.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/range/b2drange.hxx> +#include <vcl/gdimtf.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/processor2d/vclmetafileprocessor2d.hxx> +#include <drawinglayer/processor2d/vclpixelprocessor2d.hxx> +#include <drawinglayer/processor2d/canvasprocessor.hxx> +#include <vcl/window.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::processor2d::BaseProcessor2D* createBaseProcessor2DFromOutputDevice( + OutputDevice& rTargetOutDev, + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D) + { + const GDIMetaFile* pMetaFile = rTargetOutDev.GetConnectMetaFile(); + const bool bOutputToRecordingMetaFile(pMetaFile && pMetaFile->IsRecord() && !pMetaFile->IsPause()); + + if(bOutputToRecordingMetaFile) + { + // create MetaFile Vcl-Processor and process + return new drawinglayer::processor2d::VclMetafileProcessor2D(rViewInformation2D, rTargetOutDev); + } + else + { +#ifdef WIN32 + // for a first AA incarnation VCL-PixelRenderer will be okay since + // simple (and fast) GDIPlus support over VCL will be used. + // Leaving the code below as a hint for what to do when we will + // use canvas renderers in the future + + //static SvtOptionsDrawinglayer aSvtOptionsDrawinglayer; + + //if(false && aSvtOptionsDrawinglayer.IsAntiAliasing()) + //{ + // // for WIN32 AA, create cairo canvas processor + // return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); + //} + //else + //{ + // create Pixel Vcl-Processor + return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); + //} +#else + static bool bTryTestCanvas(false); + + if(bTryTestCanvas) + { + // create test-cancas-Processor + return new drawinglayer::processor2d::canvasProcessor2D(rViewInformation2D, rTargetOutDev); + } + else + { + // create Pixel Vcl-Processor + return new drawinglayer::processor2d::VclPixelProcessor2D(rViewInformation2D, rTargetOutDev); + } +#endif + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/sdrmediawindow.cxx b/svx/source/sdr/contact/sdrmediawindow.cxx new file mode 100644 index 000000000000..f380a4b8a022 --- /dev/null +++ b/svx/source/sdr/contact/sdrmediawindow.cxx @@ -0,0 +1,193 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include "sdrmediawindow.hxx" +#include <svtools/transfer.hxx> + +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <vcl/window.hxx> + +namespace sdr { namespace contact { + +// ------------------ +// - SdrMediaWindow - +// ------------------ + +SdrMediaWindow::SdrMediaWindow( Window* pParent, ViewObjectContactOfSdrMediaObj& rViewObjContact ) : + ::avmedia::MediaWindow( pParent, false ), + mrViewObjectContactOfSdrMediaObj( rViewObjContact ) +{ +} + +// ------------------------------------------------------------------------------ + +SdrMediaWindow::~SdrMediaWindow() +{ +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseMove( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseMove( aTransformedEvent ); + setPointer( pWindow->GetPointer() ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseButtonDown( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseButtonDown( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::MouseButtonUp( const MouseEvent& rMEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const MouseEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rMEvt.GetPosPixel() ) ), + rMEvt.GetClicks(), rMEvt.GetMode(), rMEvt.GetButtons(), rMEvt.GetModifier() ); + + pWindow->MouseButtonUp( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::KeyInput( const KeyEvent& rKEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + pWindow->KeyInput( rKEvt ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::KeyUp( const KeyEvent& rKEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + pWindow->KeyUp( rKEvt ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::Command( const CommandEvent& rCEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow && getWindow() ) + { + const CommandEvent aTransformedEvent( pWindow->ScreenToOutputPixel( getWindow()->OutputToScreenPixel( rCEvt.GetMousePosPixel() ) ), + rCEvt.GetCommand(), rCEvt.IsMouseEvent(), rCEvt.GetData() ); + + pWindow->Command( aTransformedEvent ); + } +} + +// ------------------------------------------------------------------------------ + +sal_Int8 SdrMediaWindow::AcceptDrop( const AcceptDropEvent& rEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + sal_Int8 nRet = DND_ACTION_NONE; + + if( pWindow ) + { + DropTargetHelper* pDropTargetHelper = dynamic_cast< DropTargetHelper* >( pWindow ); + + if( pDropTargetHelper ) + { + nRet = pDropTargetHelper->AcceptDrop( rEvt ); + } + } + + return( nRet ); +} + +// ------------------------------------------------------------------------------ + +sal_Int8 SdrMediaWindow::ExecuteDrop( const ExecuteDropEvent& rEvt ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + sal_Int8 nRet = DND_ACTION_NONE; + + if( pWindow ) + { + DropTargetHelper* pDropTargetHelper = dynamic_cast< DropTargetHelper* >( pWindow ); + + if( pDropTargetHelper ) + { + nRet = pDropTargetHelper->ExecuteDrop( rEvt ); + } + } + + return( nRet ); +} + +// ------------------------------------------------------------------------------ + +void SdrMediaWindow::StartDrag( sal_Int8 nAction, const Point& rPosPixel ) +{ + Window* pWindow = mrViewObjectContactOfSdrMediaObj.getWindow(); + + if( pWindow ) + { + DragSourceHelper* pDragSourceHelper = dynamic_cast< DragSourceHelper* >( pWindow ); + + if( pDragSourceHelper ) + { + pDragSourceHelper->StartDrag( nAction, rPosPixel ); + } + } +} + +} } diff --git a/svx/source/sdr/contact/sdrmediawindow.hxx b/svx/source/sdr/contact/sdrmediawindow.hxx new file mode 100644 index 000000000000..0b9c42cdb615 --- /dev/null +++ b/svx/source/sdr/contact/sdrmediawindow.hxx @@ -0,0 +1,69 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#ifndef _SDR_CONTACT_SDRMEDIAWIMNDOW_HXX + +#include <avmedia/mediawindow.hxx> + +namespace sdr { namespace contact { + +// ------------------ +// - SdrMediaWindow - +// ------------------ + +class ViewObjectContactOfSdrMediaObj; + +class SdrMediaWindow : public ::avmedia::MediaWindow +{ +public: + + SdrMediaWindow( Window* pParent, ViewObjectContactOfSdrMediaObj& rViewObjContact ); + ~SdrMediaWindow(); + + virtual void MouseMove( const MouseEvent& rMEvt ); + virtual void MouseButtonDown( const MouseEvent& rMEvt ); + virtual void MouseButtonUp( const MouseEvent& rMEvt ); + + virtual void KeyInput( const KeyEvent& rKEvt ); + virtual void KeyUp( const KeyEvent& rKEvt ); + + virtual void Command( const CommandEvent& rCEvt ); + + virtual sal_Int8 AcceptDrop( const AcceptDropEvent& rEvt ); + virtual sal_Int8 ExecuteDrop( const ExecuteDropEvent& rEvt ); + + virtual void StartDrag( sal_Int8 nAction, const Point& rPosPixel ); + +private: + + ViewObjectContactOfSdrMediaObj& mrViewObjectContactOfSdrMediaObj; +}; + +} } + +#endif + diff --git a/svx/source/sdr/contact/viewcontact.cxx b/svx/source/sdr/contact/viewcontact.cxx new file mode 100644 index 000000000000..3057acf55df1 --- /dev/null +++ b/svx/source/sdr/contact/viewcontact.cxx @@ -0,0 +1,329 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. Default is to create + // a standard ViewObjectContact containing the given ObjectContact and *this + ViewObjectContact& ViewContact::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + return *(new ViewObjectContact(rObjectContact, *this)); + } + + ViewContact::ViewContact() + : maViewObjectContactVector(), + mxViewIndependentPrimitive2DSequence() + { + } + + // Methods to react on start getting viewed or stop getting + // viewed. This info is derived from the count of members of + // registered ViewObjectContacts. Default does nothing. + void ViewContact::StartGettingViewed() + { + } + + void ViewContact::StopGettingViewed() + { + } + + ViewContact::~ViewContact() + { + deleteAllVOCs(); + } + + void ViewContact::deleteAllVOCs() + { + // get rid of all VOCs + // #i84257# To avoid that each 'delete pCandidate' again uses + // the local RemoveViewObjectContact with a search and removal in the + // vector, simply copy and clear local vector. + std::vector< ViewObjectContact* > aLocalVOCList(maViewObjectContactVector); + maViewObjectContactVector.clear(); + + while(aLocalVOCList.size()) + { + ViewObjectContact* pCandidate = aLocalVOCList.back(); + aLocalVOCList.pop_back(); + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList in VC (!)"); + + // ViewObjectContacts only make sense with View and Object contacts. + // When the contact to the SdrObject is deleted like in this case, + // all ViewObjectContacts can be deleted, too. + delete pCandidate; + } + + // assert when there were new entries added during deletion + DBG_ASSERT(maViewObjectContactVector.empty(), "Corrupted ViewObjectContactList in VC (!)"); + } + + // get a Object-specific ViewObjectContact for a specific + // ObjectContact (->View). Always needs to return something. + ViewObjectContact& ViewContact::GetViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = 0L; + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + // first search if there exists a VOC for the given OC + for(sal_uInt32 a(0); !pRetval && a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "Corrupted ViewObjectContactList (!)"); + + if(&(pCandidate->GetObjectContact()) == &rObjectContact) + { + pRetval = pCandidate; + } + } + + if(!pRetval) + { + // create a new one. It's inserted to the local list from the + // VieObjectContact constructor via AddViewObjectContact() + pRetval = &CreateObjectSpecificViewObjectContact(rObjectContact); + } + + return *pRetval; + } + + // A new ViewObjectContact was created and shall be remembered. + void ViewContact::AddViewObjectContact(ViewObjectContact& rVOContact) + { + maViewObjectContactVector.push_back(&rVOContact); + + if(1L == maViewObjectContactVector.size()) + { + StartGettingViewed(); + } + } + + // A ViewObjectContact was deleted and shall be forgotten. + void ViewContact::RemoveViewObjectContact(ViewObjectContact& rVOContact) + { + std::vector< ViewObjectContact* >::iterator aFindResult = std::find(maViewObjectContactVector.begin(), maViewObjectContactVector.end(), &rVOContact); + + if(aFindResult != maViewObjectContactVector.end()) + { + maViewObjectContactVector.erase(aFindResult); + + if(0 == maViewObjectContactVector.size()) + { + // This may need to get asynchron later since it eventually triggers + // deletes of OCs where the VOC is still added. + StopGettingViewed(); + } + } + } + + // Test if this ViewContact has ViewObjectContacts at all. This can + // be used to test if this ViewContact is visualized ATM or not + bool ViewContact::HasViewObjectContacts(bool bExcludePreviews) const + { + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + if(bExcludePreviews) + { + for(sal_uInt32 a(0); a < nCount; a++) + { + if(!maViewObjectContactVector[a]->GetObjectContact().IsPreviewRenderer()) + { + return true; + } + } + + return false; + } + else + { + return (0L != nCount); + } + } + + // Test if this ViewContact has ViewObjectContacts at all. This can + // be used to test if this ViewContact is visualized ATM or not + bool ViewContact::isAnimatedInAnyViewObjectContact() const + { + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + if(maViewObjectContactVector[a]->isAnimated()) + { + return true; + } + } + + return false; + } + + // Access to possible sub-hierarchy and parent. GetObjectCount() default is 0L + // and GetViewContact default pops up an assert since it's an error if + // GetObjectCount has a result != 0 and it's not overloaded. + sal_uInt32 ViewContact::GetObjectCount() const + { + // no sub-objects + return 0; + } + + ViewContact& ViewContact::GetViewContact(sal_uInt32 /*nIndex*/) const + { + // This is the default implementation; call would be an error + DBG_ERROR("ViewContact::GetViewContact: This call needs to be overloaded when GetObjectCount() can return results != 0 (!)"); + return (ViewContact&)(*this); + } + + ViewContact* ViewContact::GetParentContact() const + { + // default has no parent + return 0; + } + + void ViewContact::ActionChildInserted(ViewContact& rChild) + { + // propagate change to all exsisting visualisations which + // will force a VOC for the new child and invalidate it's range + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)"); + + // take action at all VOCs. At the VOCs ObjectContact the initial + // rectangle will be invalidated at the associated OutputDevice. + pCandidate->ActionChildInserted(rChild); + } + } + + // React on changes of the object of this ViewContact + void ViewContact::ActionChanged() + { + // propagate change to all existing VOCs. This will invalidate + // all drawn visualisations in all known views + const sal_uInt32 nCount(maViewObjectContactVector.size()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = maViewObjectContactVector[a]; + DBG_ASSERT(pCandidate, "ViewContact::GetViewObjectContact() invalid ViewObjectContactList (!)"); + + pCandidate->ActionChanged(); + } + } + + // access to SdrObject and/or SdrPage. May return 0L like the default + // implementations do. Needs to be overloaded as needed. + SdrObject* ViewContact::TryToGetSdrObject() const + { + return 0L; + } + + SdrPage* ViewContact::TryToGetSdrPage() const + { + return 0L; + } + + ////////////////////////////////////////////////////////////////////////////// + // primitive stuff + + drawinglayer::primitive2d::Primitive2DSequence ViewContact::createViewIndependentPrimitive2DSequence() const + { + // This is the default impelemtation and should never be called (see header). If this is called, + // someone implemented a ViewContact (VC) visualisation object without defining the visualisation by + // providing a seqence of primitives -> which cannot be correct. + // Since we have no access to any known model data here, the default implementation creates a yellow placeholder + // hairline polygon with a default size of (1000, 1000, 5000, 3000) + DBG_ERROR("ViewContact::createViewIndependentPrimitive2DSequence(): Never call the fallback base implementation, this is always an error (!)"); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(basegfx::B2DRange(1000.0, 1000.0, 5000.0, 3000.0))); + const basegfx::BColor aYellow(1.0, 1.0, 0.0); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContact::getViewIndependentPrimitive2DSequence() const + { + // local up-to-date checks. Create new list and compare. + const drawinglayer::primitive2d::Primitive2DSequence xNew(createViewIndependentPrimitive2DSequence()); + + if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxViewIndependentPrimitive2DSequence, xNew)) + { + // has changed, copy content + const_cast< ViewContact* >(this)->mxViewIndependentPrimitive2DSequence = xNew; + } + + // return current Primitive2DSequence + return mxViewIndependentPrimitive2DSequence; + } + + // add Gluepoints (if available) + drawinglayer::primitive2d::Primitive2DSequence ViewContact::createGluePointPrimitive2DSequence() const + { + // default returns empty reference + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + void ViewContact::flushViewObjectContacts(bool bWithHierarchy) + { + if(bWithHierarchy) + { + // flush DrawingLayer hierarchy + const sal_uInt32 nCount(GetObjectCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewContact& rChild = GetViewContact(a); + rChild.flushViewObjectContacts(bWithHierarchy); + } + } + + // delete local VOCs + deleteAllVOCs(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3d.cxx b/svx/source/sdr/contact/viewcontactofe3d.cxx new file mode 100644 index 000000000000..9d6b253a676a --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3d.cxx @@ -0,0 +1,227 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3d.hxx> +#include <svx/obj3d.hxx> +#include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <svx/scene3d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <drawinglayer/attribute/sdrsceneattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightingattribute3d.hxx> +#include <drawinglayer/attribute/sdrlightattribute3d.hxx> +#include <drawinglayer/attribute/sdrlineattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + const sdr::contact::ViewContactOfE3dScene* tryToFindVCOfE3DScene( + const sdr::contact::ViewContact& rCandidate, + basegfx::B3DHomMatrix& o_rInBetweenObjectTransform) + { + const sdr::contact::ViewContactOfE3dScene* pSceneParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(rCandidate.GetParentContact()); + + if(pSceneParent) + { + // each 3d object (including in-between scenes) should have a scene as parent + const sdr::contact::ViewContactOfE3dScene* pSceneParentParent = + dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(pSceneParent->GetParentContact()); + + if(pSceneParentParent) + { + // the parent scene of rCandidate is a in-between scene, call recursively and collect + // the in-between scene's object transformation part in o_rInBetweenObjectTransform + const basegfx::B3DHomMatrix& rSceneParentTransform = pSceneParent->GetE3dScene().GetTransform(); + o_rInBetweenObjectTransform = rSceneParentTransform * o_rInBetweenObjectTransform; + return tryToFindVCOfE3DScene(*pSceneParent, o_rInBetweenObjectTransform); + } + else + { + // the parent scene is the outmost scene + return pSceneParent; + } + } + + // object hierarchy structure is incorrect; no result + return 0; + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::impCreateWithGivenPrimitive3DSequence( + const drawinglayer::primitive3d::Primitive3DSequence& rxContent3D) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(rxContent3D.hasElements()) + { + // try to get the outmost ViewObjectContactOfE3dScene for this single 3d object, + // the ones on the way there are grouping scenes. Collect the in-between scene's + // transformations to build a correct object transformation for the embedded + // object + basegfx::B3DHomMatrix aInBetweenObjectTransform; + const ViewContactOfE3dScene* pVCOfE3DScene = tryToFindVCOfE3DScene(*this, aInBetweenObjectTransform); + + if(pVCOfE3DScene) + { + basegfx::B3DVector aLightNormal; + const double fShadowSlant(pVCOfE3DScene->getSdrSceneAttribute().getShadowSlant()); + const basegfx::B3DRange& rAllContentRange = pVCOfE3DScene->getAllContentRange3D(); + drawinglayer::geometry::ViewInformation3D aViewInformation3D(pVCOfE3DScene->getViewInformation3D()); + + if(pVCOfE3DScene->getSdrLightingAttribute().getLightVector().size()) + { + // get light normal from first light and normalize + aLightNormal = pVCOfE3DScene->getSdrLightingAttribute().getLightVector()[0].getDirection(); + aLightNormal.normalize(); + } + + if(!aInBetweenObjectTransform.isIdentity()) + { + // if aInBetweenObjectTransform is used, create combined ViewInformation3D which + // contains the correct object transformation for the embedded 3d object + aViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aViewInformation3D.getObjectTransformation() * aInBetweenObjectTransform, + aViewInformation3D.getOrientation(), + aViewInformation3D.getProjection(), + aViewInformation3D.getDeviceToView(), + aViewInformation3D.getViewTime(), + aViewInformation3D.getExtendedInformationSequence()); + } + + // create embedded 2d primitive and add. LightNormal and ShadowSlant are needed for evtl. + // 3D shadow extraction for correct B2DRange calculation (shadow is part of the object) + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::Embedded3DPrimitive2D( + rxContent3D, + pVCOfE3DScene->getObjectTransformation(), + aViewInformation3D, + aLightNormal, + fShadowSlant, + rAllContentRange)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + return xRetval; + } + + ViewContactOfE3d::ViewContactOfE3d(E3dObject& rSdrObject) + : ViewContactOfSdrObj(rSdrObject) + { + } + + ViewContactOfE3d::~ViewContactOfE3d() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getVIP3DSWithoutObjectTransform() const + { + // local up-to-date checks. Create new list and compare. + drawinglayer::primitive3d::Primitive3DSequence xNew(createViewIndependentPrimitive3DSequence()); + + if(!drawinglayer::primitive3d::arePrimitive3DSequencesEqual(mxViewIndependentPrimitive3DSequence, xNew)) + { + // has changed, copy content + const_cast< ViewContactOfE3d* >(this)->mxViewIndependentPrimitive3DSequence = xNew; + } + + // return current Primitive2DSequence + return mxViewIndependentPrimitive3DSequence; + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3d::getViewIndependentPrimitive3DSequence() const + { + // get sequence without object transform + drawinglayer::primitive3d::Primitive3DSequence xRetval(getVIP3DSWithoutObjectTransform()); + + if(xRetval.hasElements()) + { + // add object transform if it's used + const basegfx::B3DHomMatrix& rObjectTransform(GetE3dObject().GetTransform()); + + if(!rObjectTransform.isIdentity()) + { + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::TransformPrimitive3D( + rObjectTransform, + xRetval)); + + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + } + } + + // return current Primitive2DSequence + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3d::createViewIndependentPrimitive2DSequence() const + { + // also need to create a 2D embedding when the view-independent part is requested, + // see view-dependent part in ViewObjectContactOfE3d::createPrimitive2DSequence + // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator + return impCreateWithGivenPrimitive3DSequence(getViewIndependentPrimitive3DSequence()); + } + + ViewObjectContact& ViewContactOfE3d::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfE3d(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfE3d::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::attribute::SdrLineAttribute* ViewContactOfE3d::impCreateFallbackLineAttribute(const basegfx::BColor& rBColor) const + { + static bool bFallbackToCreateAsLineForTest(false); + + if(bFallbackToCreateAsLineForTest) + { + return new drawinglayer::attribute::SdrLineAttribute(rBColor); + } + else + { + return 0; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dcube.cxx b/svx/source/sdr/contact/viewcontactofe3dcube.cxx new file mode 100644 index 000000000000..84d456a7a430 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dcube.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3dcube.hxx> +#include <svx/cube3d.hxx> +#include <drawinglayer/primitive3d/sdrcubeprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/range/b3drange.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dCube::ViewContactOfE3dCube(E3dCubeObj& rCubeObj) + : ViewContactOfE3d(rCubeObj) + { + } + + ViewContactOfE3dCube::~ViewContactOfE3dCube() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dCube::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dCubeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get cube geometry and use as traslation and scaling for unit cube + basegfx::B3DRange aCubeRange; + const basegfx::B3DVector aCubeSize(GetE3dCubeObj().GetCubeSize()); + const basegfx::B3DPoint aCubePosition(GetE3dCubeObj().GetCubePos()); + basegfx::B3DHomMatrix aWorldTransform; + + if(GetE3dCubeObj().GetPosIsCenter()) + { + const basegfx::B3DVector aHalfCubeSize(aCubeSize / 2.0); + aCubeRange.expand(aCubePosition - aHalfCubeSize); + aCubeRange.expand(aCubePosition + aHalfCubeSize); + } + else + { + aCubeRange.expand(aCubePosition); + aCubeRange.expand(aCubePosition + aCubeSize); + } + + // add scale and translate to world transformation + const basegfx::B3DVector abjectRange(aCubeRange.getRange()); + aWorldTransform.scale(abjectRange.getX(), abjectRange.getY(), abjectRange.getZ()); + aWorldTransform.translate(aCubeRange.getMinX(), aCubeRange.getMinY(), aCubeRange.getMinZ()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size to get a perfect mapping for + // the front/back sides + const basegfx::B2DVector aTextureSize(aCubeSize.getX(), aCubeSize.getY()); + + // create primitive and add + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrCubePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dextrude.cxx b/svx/source/sdr/contact/viewcontactofe3dextrude.cxx new file mode 100644 index 000000000000..1ff1d81c827c --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dextrude.cxx @@ -0,0 +1,100 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3dextrude.hxx> +#include <svx/extrud3d.hxx> +#include <drawinglayer/primitive3d/sdrextrudeprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dExtrude::ViewContactOfE3dExtrude(E3dExtrudeObj& rExtrude) + : ViewContactOfE3d(rExtrude) + { + } + + ViewContactOfE3dExtrude::~ViewContactOfE3dExtrude() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dExtrude::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dExtrudeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get extrude geometry + const basegfx::B2DPolyPolygon aPolyPolygon(GetE3dExtrudeObj().GetExtrudePolygon()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size; use size of top/bottom cap to get a perfect mapping + // for the caps. The in-between geometry will get a stretched size with a + // relative factor size of caps to extrude depth + const basegfx::B2DRange aRange(basegfx::tools::getRange(aPolyPolygon)); + const basegfx::B2DVector aTextureSize(aRange.getWidth(), aRange.getHeight()); + + // get more data + const double fDepth((double)GetE3dExtrudeObj().GetExtrudeDepth()); + const double fDiagonal((double)GetE3dExtrudeObj().GetPercentDiagonal() / 100.0); + const double fBackScale((double)GetE3dExtrudeObj().GetPercentBackScale() / 100.0); + const bool bSmoothNormals(GetE3dExtrudeObj().GetSmoothNormals()); // Plane itself + const bool bSmoothLids(GetE3dExtrudeObj().GetSmoothLids()); // Front/back + const bool bCharacterMode(GetE3dExtrudeObj().GetCharacterMode()); + const bool bCloseFront(GetE3dExtrudeObj().GetCloseFront()); + const bool bCloseBack(GetE3dExtrudeObj().GetCloseBack()); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrExtrudePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + aPolyPolygon, fDepth, fDiagonal, fBackScale, bSmoothNormals, true, bSmoothLids, + bCharacterMode, bCloseFront, bCloseBack)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dlathe.cxx b/svx/source/sdr/contact/viewcontactofe3dlathe.cxx new file mode 100644 index 000000000000..3cd55fcde828 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dlathe.cxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3dlathe.hxx> +#include <svx/lathe3d.hxx> +#include <drawinglayer/primitive3d/sdrlatheprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dLathe::ViewContactOfE3dLathe(E3dLatheObj& rLathe) + : ViewContactOfE3d(rLathe) + { + } + + ViewContactOfE3dLathe::~ViewContactOfE3dLathe() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dLathe::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dLatheObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get extrude geometry + const basegfx::B2DPolyPolygon aPolyPolygon(GetE3dLatheObj().GetPolyPoly2D()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size. Use the polygon length of the longest polygon for + // height and the rotated radius for width (using polygon center) to get a good + // texture mapping + const sal_uInt32 nPolygonCount(aPolyPolygon.count()); + double fPolygonMaxLength(0.0); + + for(sal_uInt32 a(0); a < nPolygonCount; a++) + { + const basegfx::B2DPolygon aCandidate(aPolyPolygon.getB2DPolygon(a)); + const double fPolygonLength(basegfx::tools::getLength(aCandidate)); + fPolygonMaxLength = std::max(fPolygonMaxLength, fPolygonLength); + } + + const basegfx::B2DRange aPolyPolygonRange(basegfx::tools::getRange(aPolyPolygon)); + const basegfx::B2DVector aTextureSize( + F_PI * fabs(aPolyPolygonRange.getCenter().getX()), // PI * d + fPolygonMaxLength); + + // get more data + const sal_uInt32 nHorizontalSegments(GetE3dLatheObj().GetHorizontalSegments()); + const sal_uInt32 nVerticalSegments(GetE3dLatheObj().GetVerticalSegments()); + const double fDiagonal((double)GetE3dLatheObj().GetPercentDiagonal() / 100.0); + const double fBackScale((double)GetE3dLatheObj().GetBackScale() / 100.0); + const double fRotation(((double)GetE3dLatheObj().GetEndAngle() / 1800.0) * F_PI); + const bool bSmoothNormals(GetE3dLatheObj().GetSmoothNormals()); // Plane itself + const bool bSmoothLids(GetE3dLatheObj().GetSmoothLids()); // Front/back + const bool bCharacterMode(GetE3dLatheObj().GetCharacterMode()); + const bool bCloseFront(GetE3dLatheObj().GetCloseFront()); + const bool bCloseBack(GetE3dLatheObj().GetCloseBack()); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrLathePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + aPolyPolygon, nHorizontalSegments, nVerticalSegments, + fDiagonal, fBackScale, fRotation, + bSmoothNormals, true, bSmoothLids, bCharacterMode, bCloseFront, bCloseBack)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx new file mode 100644 index 000000000000..ee6943bccd4a --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dpolygon.cxx @@ -0,0 +1,186 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3dpolygon.hxx> +#include <svx/polygn3d.hxx> +#include <drawinglayer/primitive3d/sdrpolypolygonprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> +#include <basegfx/polygon/b3dpolygon.hxx> +#include <basegfx/polygon/b3dpolypolygontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dPolygon::ViewContactOfE3dPolygon(E3dPolygonObj& rPolygon) + : ViewContactOfE3d(rPolygon) + { + } + + ViewContactOfE3dPolygon::~ViewContactOfE3dPolygon() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dPolygon::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dPolygonObj().GetMergedItemSet(); + const bool bSuppressFill(GetE3dPolygonObj().GetLineOnly()); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, bSuppressFill)); + + // get extrude geometry + basegfx::B3DPolyPolygon aPolyPolygon3D(GetE3dPolygonObj().GetPolyPolygon3D()); + const basegfx::B3DPolyPolygon aPolyNormals3D(GetE3dPolygonObj().GetPolyNormals3D()); + const basegfx::B2DPolyPolygon aPolyTexture2D(GetE3dPolygonObj().GetPolyTexture2D()); + const bool bNormals(aPolyNormals3D.count() && aPolyNormals3D.count() == aPolyPolygon3D.count()); + const bool bTexture(aPolyTexture2D.count() && aPolyTexture2D.count() == aPolyPolygon3D.count()); + + if(bNormals || bTexture) + { + for(sal_uInt32 a(0L); a < aPolyPolygon3D.count(); a++) + { + basegfx::B3DPolygon aCandidate3D(aPolyPolygon3D.getB3DPolygon(a)); + basegfx::B3DPolygon aNormals3D; + basegfx::B2DPolygon aTexture2D; + + if(bNormals) + { + aNormals3D = aPolyNormals3D.getB3DPolygon(a); + } + + if(bTexture) + { + aTexture2D = aPolyTexture2D.getB2DPolygon(a); + } + + for(sal_uInt32 b(0L); b < aCandidate3D.count(); b++) + { + if(bNormals) + { + sal_uInt32 nNormalCount = aNormals3D.count(); + if( b < nNormalCount ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(b)); + else if( nNormalCount > 0 ) + aCandidate3D.setNormal(b, aNormals3D.getB3DPoint(0)); + } + if(bTexture) + { + sal_uInt32 nTextureCount = aTexture2D.count(); + if( b < nTextureCount ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(b)); + else if( nTextureCount > 0 ) + aCandidate3D.setTextureCoordinate(b, aTexture2D.getB2DPoint(0)); + } + } + + aPolyPolygon3D.setB3DPolygon(a, aCandidate3D); + } + } + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // calculate texture size + basegfx::B2DVector aTextureSize(1.0, 1.0); + + if(bTexture) + { + // #i98314# + // create texture size from object's size + const basegfx::B3DRange aObjectRange(basegfx::tools::getRange(aPolyPolygon3D)); + + double fWidth(0.0); + double fHeight(0.0); + + // this is a polygon object, so Width/Height and/or Depth may be zero (e.g. left + // wall of chart). Take this into account + if(basegfx::fTools::equalZero(aObjectRange.getWidth())) + { + // width is zero, use height and depth + fWidth = aObjectRange.getHeight(); + fHeight = aObjectRange.getDepth(); + } + else if(basegfx::fTools::equalZero(aObjectRange.getHeight())) + { + // height is zero, use width and depth + fWidth = aObjectRange.getWidth(); + fHeight = aObjectRange.getDepth(); + } + else + { + // use width and height + fWidth = aObjectRange.getWidth(); + fHeight = aObjectRange.getHeight(); + } + + if(basegfx::fTools::lessOrEqual(fWidth, 0.0) ||basegfx::fTools::lessOrEqual(fHeight, 0.0)) + { + // no texture; fallback to very small size + aTextureSize.setX(0.01); + aTextureSize.setY(0.01); + } + else + { + aTextureSize.setX(fWidth); + aTextureSize.setY(fHeight); + } + } + + // #i98295# + // unfortunately, this SdrObject type which allows a free 3d geometry definition was defined + // wrong topologically in relation to it's plane normal and 3D visibility when it was invented + // a long time ago. Since the API allows creation of this SDrObject type, it is not possible to + // simply change this definition. Only the chart should use it, and at least this object type + // only exists at Runtime (is not saved and/or loaded in any FileFormat). Still someone external + // may have used it in it's API. To not risk wrong 3D lightings, i have to switch the orientation + // of the polygon here + aPolyPolygon3D.flip(); + + // create primitive and add + const basegfx::B3DHomMatrix aWorldTransform; + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrPolyPolygonPrimitive3D( + aPolyPolygon3D, aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dscene.cxx b/svx/source/sdr/contact/viewcontactofe3dscene.cxx new file mode 100644 index 000000000000..8a7d7694a315 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dscene.cxx @@ -0,0 +1,478 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <svx/polysc3d.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/range/b3drange.hxx> +#include <drawinglayer/primitive3d/baseprimitive3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <drawinglayer/primitive2d/sceneprimitive2d.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // pActiveVC is only true if ghosted is still activated and maybe needs to be switched off in this path + void createSubPrimitive3DVector( + const sdr::contact::ViewContact& rCandidate, + drawinglayer::primitive3d::Primitive3DSequence& o_rAllTarget, + drawinglayer::primitive3d::Primitive3DSequence* o_pVisibleTarget, + const SetOfByte* pVisibleLayerSet, + const bool bTestSelectedVisibility) + { + const sdr::contact::ViewContactOfE3dScene* pViewContactOfE3dScene = dynamic_cast< const sdr::contact::ViewContactOfE3dScene* >(&rCandidate); + + if(pViewContactOfE3dScene) + { + const sal_uInt32 nChildrenCount(rCandidate.GetObjectCount()); + + if(nChildrenCount) + { + // provide new collection sequences + drawinglayer::primitive3d::Primitive3DSequence aNewAllTarget; + drawinglayer::primitive3d::Primitive3DSequence aNewVisibleTarget; + + // add children recursively + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector( + rCandidate.GetViewContact(a), + aNewAllTarget, + o_pVisibleTarget ? &aNewVisibleTarget : 0, + pVisibleLayerSet, + bTestSelectedVisibility); + } + + // create transform primitive for the created content combining content and transformtion + const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::TransformPrimitive3D( + pViewContactOfE3dScene->GetE3dScene().GetTransform(), + aNewAllTarget)); + + // add created content to all target + drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(o_rAllTarget, xReference); + + // add created content to visibiel target if exists + if(o_pVisibleTarget) + { + drawinglayer::primitive3d::appendPrimitive3DReferenceToPrimitive3DSequence(*o_pVisibleTarget, xReference); + } + } + } + else + { + // access view independent representation of rCandidate + const sdr::contact::ViewContactOfE3d* pViewContactOfE3d = dynamic_cast< const sdr::contact::ViewContactOfE3d* >(&rCandidate); + + if(pViewContactOfE3d) + { + drawinglayer::primitive3d::Primitive3DSequence xPrimitive3DSeq(pViewContactOfE3d->getViewIndependentPrimitive3DSequence()); + + if(xPrimitive3DSeq.hasElements()) + { + // add to all target vector + drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(o_rAllTarget, xPrimitive3DSeq); + + if(o_pVisibleTarget) + { + // test visibility. Primitive is visible when both tests are true (AND) + bool bVisible(true); + + if(pVisibleLayerSet) + { + // test layer visibility + const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject(); + const SdrLayerID aLayerID(rE3dObject.GetLayer()); + + bVisible = pVisibleLayerSet->IsSet(aLayerID); + } + + if(bVisible && bTestSelectedVisibility) + { + // test selected visibility (see 3D View's DrawMarkedObj implementation) + const E3dObject& rE3dObject = pViewContactOfE3d->GetE3dObject(); + + bVisible = rE3dObject.GetSelected(); + } + + if(bVisible && o_pVisibleTarget) + { + // add to visible target vector + drawinglayer::primitive3d::appendPrimitive3DSequenceToPrimitive3DSequence(*o_pVisibleTarget, xPrimitive3DSeq); + } + } + } + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfE3dScene(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfE3dScene::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfE3dScene::ViewContactOfE3dScene(E3dScene& rScene) + : ViewContactOfSdrObj(rScene), + maViewInformation3D(), + maObjectTransformation(), + maSdrSceneAttribute(), + maSdrLightingAttribute() + { + } + + void ViewContactOfE3dScene::createViewInformation3D(const basegfx::B3DRange& rContentRange) + { + basegfx::B3DHomMatrix aTransformation; + basegfx::B3DHomMatrix aOrientation; + basegfx::B3DHomMatrix aProjection; + basegfx::B3DHomMatrix aDeviceToView; + + // create transformation (scene as group's transformation) + // For historical reasons, the outmost scene's transformation is handles as part of the + // view transformation. This means that the BoundRect of the contained 3D Objects is + // without that transformation and makes it necessary to NOT add the first scene to the + // Primitive3DSequence of contained objects. + { + aTransformation = GetE3dScene().GetTransform(); + } + + // create orientation (world to camera coordinate system) + { + // calculate orientation from VRP, VPN and VUV + const B3dCamera& rSceneCamera = GetE3dScene().GetCameraSet(); + const basegfx::B3DPoint aVRP(rSceneCamera.GetVRP()); + const basegfx::B3DVector aVPN(rSceneCamera.GetVRP()); + const basegfx::B3DVector aVUV(rSceneCamera.GetVUV()); + + aOrientation.orientation(aVRP, aVPN, aVUV); + } + + // create projection (camera coordinate system to relative 2d where X,Y and Z are [0.0 .. 1.0]) + { + const basegfx::B3DHomMatrix aWorldToCamera(aOrientation * aTransformation); + basegfx::B3DRange aCameraRange(rContentRange); + aCameraRange.transform(aWorldToCamera); + + // remember Z-Values, but change orientation + const double fMinZ(-aCameraRange.getMaxZ()); + const double fMaxZ(-aCameraRange.getMinZ()); + + // construct temorary matrix from world to device. Use unit values here to measure expansion + basegfx::B3DHomMatrix aWorldToDevice(aWorldToCamera); + const drawinglayer::attribute::SdrSceneAttribute& rSdrSceneAttribute = getSdrSceneAttribute(); + + if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode()) + { + aWorldToDevice.frustum(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ); + } + else + { + aWorldToDevice.ortho(-1.0, 1.0, -1.0, 1.0, fMinZ, fMaxZ); + } + + // create B3DRange in device. This will create the real used ranges + // in camera space. Do not use the Z-Values, though. + basegfx::B3DRange aDeviceRange(rContentRange); + aDeviceRange.transform(aWorldToDevice); + + // set projection + if(::com::sun::star::drawing::ProjectionMode_PERSPECTIVE == rSdrSceneAttribute.getProjectionMode()) + { + aProjection.frustum( + aDeviceRange.getMinX(), aDeviceRange.getMaxX(), + aDeviceRange.getMinY(), aDeviceRange.getMaxY(), + fMinZ, fMaxZ); + } + else + { + aProjection.ortho( + aDeviceRange.getMinX(), aDeviceRange.getMaxX(), + aDeviceRange.getMinY(), aDeviceRange.getMaxY(), + fMinZ, fMaxZ); + } + } + + // create device to view transform + { + // create standard deviceToView projection for geometry + // input is [-1.0 .. 1.0] in X,Y and Z. bring to [0.0 .. 1.0]. Also + // necessary to flip Y due to screen orientation + // Z is not needed, but will also be brought to [0.0 .. 1.0] + aDeviceToView.scale(0.5, -0.5, 0.5); + aDeviceToView.translate(0.5, 0.5, 0.5); + } + + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + maViewInformation3D = drawinglayer::geometry::ViewInformation3D( + aTransformation, aOrientation, aProjection, + aDeviceToView, 0.0, aEmptyProperties); + } + + void ViewContactOfE3dScene::createObjectTransformation() + { + // create 2d Object Transformation from relative point in 2d scene to world + const Rectangle& rRectangle = GetE3dScene().GetSnapRect(); + + maObjectTransformation.set(0, 0, rRectangle.getWidth()); + maObjectTransformation.set(1, 1, rRectangle.getHeight()); + maObjectTransformation.set(0, 2, rRectangle.Left()); + maObjectTransformation.set(1, 2, rRectangle.Top()); + } + + void ViewContactOfE3dScene::createSdrSceneAttribute() + { + const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet(); + maSdrSceneAttribute = drawinglayer::primitive2d::createNewSdrSceneAttribute(rItemSet); + } + + void ViewContactOfE3dScene::createSdrLightingAttribute() + { + const SfxItemSet& rItemSet = GetE3dScene().GetMergedItemSet(); + maSdrLightingAttribute = drawinglayer::primitive2d::createNewSdrLightingAttribute(rItemSet); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createScenePrimitive2DSequence( + const SetOfByte* pLayerVisibility) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nChildrenCount(GetObjectCount()); + + if(nChildrenCount) + { + // create 3d scene primitive with visible content tested against rLayerVisibility + drawinglayer::primitive3d::Primitive3DSequence aAllSequence; + drawinglayer::primitive3d::Primitive3DSequence aVisibleSequence; + const bool bTestLayerVisibility(0 != pLayerVisibility); + const bool bTestSelectedVisibility(GetE3dScene().GetDrawOnlySelected()); + const bool bTestVisibility(bTestLayerVisibility || bTestSelectedVisibility); + + // add children recursively. Do NOT start with (*this), this would create + // a 3D transformPrimitive for the start scene. While this is theoretically not + // a bad thing, for historical reasons the transformation of the outmost scene + // is seen as part of the ViewTransformation (see text in createViewInformation3D) + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector( + GetViewContact(a), + aAllSequence, + bTestLayerVisibility ? &aVisibleSequence : 0, + bTestLayerVisibility ? pLayerVisibility : 0, + bTestSelectedVisibility); + } + + const sal_uInt32 nAllSize(aAllSequence.hasElements() ? aAllSequence.getLength() : 0); + const sal_uInt32 nVisibleSize(aVisibleSequence.hasElements() ? aVisibleSequence.getLength() : 0); + + if((bTestVisibility && nVisibleSize) || nAllSize) + { + // for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D + // needs to be given for evtl. decompositions. At the same time createViewInformation3D + // currently is based on creating the target-ViewInformation3D using a given range. To + // get the true range, use a neutral ViewInformation3D here. This leaves all matrices + // on identity and the time on 0.0. + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties); + const basegfx::B3DRange aContentRange( + drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(aAllSequence, aNeutralViewInformation3D)); + + // create 2d primitive 3dscene with generated sub-list from collector + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::ScenePrimitive2D( + bTestVisibility ? aVisibleSequence : aAllSequence, + getSdrSceneAttribute(), + getSdrLightingAttribute(), + getObjectTransformation(), + getViewInformation3D(aContentRange))); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + // always append an invisible outline for the cases where no visible content exists + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, getObjectTransformation())); + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfE3dScene::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(GetObjectCount()) + { + // create a default ScenePrimitive2D (without visibility test of members) + xRetval = createScenePrimitive2DSequence(0); + } + + return xRetval; + } + + void ViewContactOfE3dScene::ActionChanged() + { + // call parent + ViewContactOfSdrObj::ActionChanged(); + + // mark locally cached values as invalid + maViewInformation3D = drawinglayer::geometry::ViewInformation3D(); + maObjectTransformation.identity(); + maSdrSceneAttribute = drawinglayer::attribute::SdrSceneAttribute(); + maSdrLightingAttribute = drawinglayer::attribute::SdrLightingAttribute(); + } + + const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D() const + { + if(maViewInformation3D.isDefault()) + { + // this version will create the content range on demand locally and thus is less + // performant than the other one. Since the information is buffered the planned + // behaviour is that the version with the given range is used initially. + basegfx::B3DRange aContentRange(getAllContentRange3D()); + + if(aContentRange.isEmpty()) + { + // empty scene, no 3d action should be necessary. Prepare some + // fallback size + OSL_ENSURE(false, "No need to get ViewInformation3D from an empty scene (!)"); + aContentRange.expand(basegfx::B3DPoint(-100.0, -100.0, -100.0)); + aContentRange.expand(basegfx::B3DPoint( 100.0, 100.0, 100.0)); + } + + const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(aContentRange); + } + + return maViewInformation3D; + } + + const drawinglayer::geometry::ViewInformation3D& ViewContactOfE3dScene::getViewInformation3D(const basegfx::B3DRange& rContentRange) const + { + if(maViewInformation3D.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createViewInformation3D(rContentRange); + } + + return maViewInformation3D; + } + + const basegfx::B2DHomMatrix& ViewContactOfE3dScene::getObjectTransformation() const + { + if(maObjectTransformation.isIdentity()) + { + const_cast < ViewContactOfE3dScene* >(this)->createObjectTransformation(); + } + + return maObjectTransformation; + } + + const drawinglayer::attribute::SdrSceneAttribute& ViewContactOfE3dScene::getSdrSceneAttribute() const + { + if(maSdrSceneAttribute.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createSdrSceneAttribute(); + } + + return maSdrSceneAttribute; + } + + const drawinglayer::attribute::SdrLightingAttribute& ViewContactOfE3dScene::getSdrLightingAttribute() const + { + if(maSdrLightingAttribute.isDefault()) + { + const_cast < ViewContactOfE3dScene* >(this)->createSdrLightingAttribute(); + } + + return maSdrLightingAttribute; + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dScene::getAllPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence aAllPrimitive3DSequence; + const sal_uInt32 nChildrenCount(GetObjectCount()); + + // add children recursively. Do NOT start with (*this), this would create + // a 3D transformPrimitive for the start scene. While this is theoretically not + // a bad thing, for historical reasons the transformation of the outmost scene + // is seen as part of the ViewTransformation (see text in createViewInformation3D) + for(sal_uInt32 a(0L); a < nChildrenCount; a++) + { + createSubPrimitive3DVector(GetViewContact(a), aAllPrimitive3DSequence, 0, 0, false); + } + + return aAllPrimitive3DSequence; + } + + basegfx::B3DRange ViewContactOfE3dScene::getAllContentRange3D() const + { + const drawinglayer::primitive3d::Primitive3DSequence xAllSequence(getAllPrimitive3DSequence()); + basegfx::B3DRange aAllContentRange3D; + + if(xAllSequence.hasElements()) + { + // for getting the 3D range using getB3DRangeFromPrimitive3DSequence a ViewInformation3D + // needs to be given for evtl. decompositions. Use a neutral ViewInformation3D here. This + // leaves all matrices on identity and the time on 0.0. + const uno::Sequence< beans::PropertyValue > aEmptyProperties; + const drawinglayer::geometry::ViewInformation3D aNeutralViewInformation3D(aEmptyProperties); + + aAllContentRange3D = drawinglayer::primitive3d::getB3DRangeFromPrimitive3DSequence(xAllSequence, aNeutralViewInformation3D); + } + + return aAllContentRange3D; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofe3dsphere.cxx b/svx/source/sdr/contact/viewcontactofe3dsphere.cxx new file mode 100644 index 000000000000..c16633f7f2c9 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofe3dsphere.cxx @@ -0,0 +1,98 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofe3dsphere.hxx> +#include <svx/sphere3d.hxx> +#include <drawinglayer/primitive3d/sdrsphereprimitive3d.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive3d/sdrattributecreator3d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfE3dSphere::ViewContactOfE3dSphere(E3dSphereObj& rSphere) + : ViewContactOfE3d(rSphere) + { + } + + ViewContactOfE3dSphere::~ViewContactOfE3dSphere() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewContactOfE3dSphere::createViewIndependentPrimitive3DSequence() const + { + drawinglayer::primitive3d::Primitive3DSequence xRetval; + const SfxItemSet& rItemSet = GetE3dSphereObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowAttribute3D aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowAttribute(rItemSet, false)); + + // get sphere center and size for geometry + basegfx::B3DRange aSphereRange; + const basegfx::B3DPoint aSpherePosition(GetE3dSphereObj().Center()); + const basegfx::B3DVector aSphereSize(GetE3dSphereObj().Size()); + basegfx::B3DHomMatrix aWorldTransform; + + aWorldTransform.translate(-0.5, -0.5, -0.5); + aWorldTransform.scale(aSphereSize.getX(), aSphereSize.getY(), aSphereSize.getZ()); + aWorldTransform.translate(aSpherePosition.getX(), aSpherePosition.getY(), aSpherePosition.getZ()); + + // get 3D Object Attributes + drawinglayer::attribute::Sdr3DObjectAttribute* pSdr3DObjectAttribute = drawinglayer::primitive2d::createNewSdr3DObjectAttribute(rItemSet); + + // get segment count + const sal_uInt32 nHorizontalSegments(GetE3dSphereObj().GetHorizontalSegments()); + const sal_uInt32 nVerticalSegments(GetE3dSphereObj().GetVerticalSegments()); + + // calculate texture size, use radii for (2 * PI * r) to get a perfect + // mapping on the sphere + const basegfx::B2DVector aTextureSize( + F_PI * ((aSphereSize.getX() + aSphereSize.getZ()) / 2.0), // PI * d + F_PI2 * aSphereSize.getY()); // half outline, (PI * d)/2 -> PI/2 * d + + // create primitive and add + const drawinglayer::primitive3d::Primitive3DReference xReference( + new drawinglayer::primitive3d::SdrSpherePrimitive3D( + aWorldTransform, aTextureSize, aAttribute, *pSdr3DObjectAttribute, + nHorizontalSegments, nVerticalSegments)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + + // delete 3D Object Attributes + delete pSdr3DObjectAttribute; + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx new file mode 100644 index 000000000000..7172b0840476 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx @@ -0,0 +1,463 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofgraphic.hxx> +#include <svx/sdr/contact/viewobjectcontactofgraphic.hxx> +#include <svx/svdograf.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svl/itemset.hxx> + +#ifndef ITEMID_GRF_CROP +#define ITEMID_GRF_CROP 0 +#endif + +#include <svx/sdgcpitm.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrgrafprimitive2d.hxx> +#include "svdstr.hrc" +#include <svdglob.hxx> +#include <vcl/svapp.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <drawinglayer/primitive2d/textprimitive2d.hxx> +#include <drawinglayer/primitive2d/textlayoutdevice.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx> +#include <editeng/eeitem.hxx> +#include <editeng/colritem.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfGraphic::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfGraphic(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfGraphic::ViewContactOfGraphic(SdrGrafObj& rGrafObj) + : ViewContactOfTextObj(rGrafObj) + { + } + + ViewContactOfGraphic::~ViewContactOfGraphic() + { + } + + void ViewContactOfGraphic::flushGraphicObjects() + { + // #i102380# The graphic is swapped out. To let that have an effect ist is necessary to + // delete copies of the GraphicObject which are not swapped out and have no SwapHandler set + // (this is what happnes when the GraphicObject gets copied to a SdrGrafPrimitive2D). This + // is best achieved for the VC by clearing the local decomposition cache. It would be possible + // to also do this for the VOC cache, but that VOCs exist exactly expresss that the object + // gets visualised, so this would be wrong. + flushViewIndependentPrimitive2DSequence(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute, + const GraphicAttr& rLocalGrafInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + // SdrGrafPrimitive2D with content (which is the preview graphic) scaled to smaller size and + // without attributes + basegfx::B2DHomMatrix aSmallerMatrix; + + // #i94431# for some reason, i forgot to take the PrefMapMode of the graphic + // into account. Since EmptyPresObj's are only used in Draw/Impress, it is + // safe to assume 100th mm as target. + Size aPrefSize(GetGrafObject().GetGrafPrefSize()); + + if(MAP_PIXEL == GetGrafObject().GetGrafPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aPrefSize, MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, GetGrafObject().GetGrafPrefMapMode(), MAP_100TH_MM); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + const double fOffsetX((aScale.getX() - aPrefSize.getWidth()) / 2.0); + const double fOffsetY((aScale.getY() - aPrefSize.getHeight()) / 2.0); + + if(basegfx::fTools::moreOrEqual(fOffsetX, 0.0) && basegfx::fTools::moreOrEqual(fOffsetY, 0.0)) + { + // create the EmptyPresObj fallback visualisation. The fallback graphic + // is already provided in rGraphicObject in this case, use it + aSmallerMatrix = basegfx::tools::createScaleTranslateB2DHomMatrix(aPrefSize.getWidth(), aPrefSize.getHeight(), fOffsetX, fOffsetY); + aSmallerMatrix = basegfx::tools::createShearXRotateTranslateB2DHomMatrix(fShearX, fRotate, aTranslate) + * aSmallerMatrix; + + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + aSmallerMatrix, + drawinglayer::attribute::SdrLineFillShadowTextAttribute(), + rGraphicObject, + rLocalGrafInfo)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForDraft( + const basegfx::B2DHomMatrix& rObjectMatrix, + const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + GraphicObject aEmptyGraphicObject; + GraphicAttr aEmptyGraphicAttr; + + // SdrGrafPrimitive2D without content in original size which carries all eventual attributes and texts + const drawinglayer::primitive2d::Primitive2DReference xReferenceA(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + rObjectMatrix, + rAttribute, + aEmptyGraphicObject, + aEmptyGraphicAttr)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReferenceA, 1); + + if(rAttribute.getLine().isDefault()) + { + // create a surrounding frame when no linestyle given + const Color aColor(Application::GetSettings().GetStyleSettings().GetShadowColor()); + const basegfx::BColor aBColor(aColor.getBColor()); + basegfx::B2DPolygon aOutline(basegfx::tools::createUnitPolygon()); + aOutline.transform(rObjectMatrix); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D( + aOutline, + aBColor))); + } + + // decompose object matrix to get single values + basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rObjectMatrix.decompose(aScale, aTranslate, fRotate, fShearX); + + // define a distance value, used for distance from bitmap to borders and from bitmap + // to text, too (2 mm) + const double fDistance(200.0); + + // consume borders from values + aScale.setX(std::max(0.0, aScale.getX() - (2.0 * fDistance))); + aScale.setY(std::max(0.0, aScale.getY() - (2.0 * fDistance))); + aTranslate.setX(aTranslate.getX() + fDistance); + aTranslate.setY(aTranslate.getY() + fDistance); + + // draw a draft bitmap + const Bitmap aDraftBitmap(ResId(BMAP_GrafikEi, *ImpGetResMgr())); + + if(!aDraftBitmap.IsEmpty()) + { + Size aPrefSize(aDraftBitmap.GetPrefSize()); + + if(MAP_PIXEL == aDraftBitmap.GetPrefMapMode().GetMapUnit()) + { + aPrefSize = Application::GetDefaultDevice()->PixelToLogic(aDraftBitmap.GetSizePixel(), MAP_100TH_MM); + } + else + { + aPrefSize = Application::GetDefaultDevice()->LogicToLogic(aPrefSize, aDraftBitmap.GetPrefMapMode(), MAP_100TH_MM); + } + + const double fBitmapScaling(2.0); + const double fWidth(aPrefSize.getWidth() * fBitmapScaling); + const double fHeight(aPrefSize.getHeight() * fBitmapScaling); + + if(basegfx::fTools::more(fWidth, 1.0) + && basegfx::fTools::more(fHeight, 1.0) + && basegfx::fTools::lessOrEqual(fWidth, aScale.getX()) + && basegfx::fTools::lessOrEqual(fHeight, aScale.getY())) + { + const basegfx::B2DHomMatrix aBitmapMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + fWidth, fHeight, fShearX, fRotate, aTranslate.getX(), aTranslate.getY())); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::BitmapPrimitive2D( + BitmapEx(aDraftBitmap), + aBitmapMatrix))); + + // consume bitmap size in X + aScale.setX(std::max(0.0, aScale.getX() - (fWidth + fDistance))); + aTranslate.setX(aTranslate.getX() + fWidth + fDistance); + } + } + + // Build the text for the draft object + XubString aDraftText = GetGrafObject().GetFileName(); + + if(!aDraftText.Len()) + { + aDraftText = GetGrafObject().GetName(); + aDraftText.AppendAscii(" ..."); + } + + if(aDraftText.Len() && GetGrafObject().GetModel()) + { + // #i103255# Goal is to produce TextPrimitives which hold the given text as + // BlockText in the available space. It would be very tricky to do + // an own word wrap/line layout here. + // Using SdrBlockTextPrimitive2D OTOH is critical since it internally + // uses the SdrObject it references. To solve this, create a temp + // SdrObject with Attributes and Text, generate a SdrBlockTextPrimitive2D + // directly and immediately decompose it. After that, it is no longer + // needed and can be deleted. + + // create temp RectObj as TextObj and set needed attributes + SdrRectObj aRectObj(OBJ_TEXT); + aRectObj.SetModel(GetGrafObject().GetModel()); + aRectObj.NbcSetText(aDraftText); + aRectObj.SetMergedItem(SvxColorItem(Color(COL_LIGHTRED), EE_CHAR_COLOR)); + + // get SdrText and OPO + SdrText* pSdrText = aRectObj.getText(0); + OutlinerParaObject* pOPO = aRectObj.GetOutlinerParaObject(); + + if(pSdrText && pOPO) + { + // directly use the remaining space as TextRangeTransform + const basegfx::B2DHomMatrix aTextRangeTransform(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aScale, fShearX, fRotate, aTranslate)); + + // directly create temp SdrBlockTextPrimitive2D + drawinglayer::primitive2d::SdrBlockTextPrimitive2D aBlockTextPrimitive( + pSdrText, + *pOPO, + aTextRangeTransform, + SDRTEXTHORZADJUST_LEFT, + SDRTEXTVERTADJUST_TOP, + false, + false, + false, + false, + false); + + // decompose immediately with neutral ViewInformation. This will + // layout the text to more simple TextPrimitives from drawinglayer + const drawinglayer::geometry::ViewInformation2D aViewInformation2D(0); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence( + xRetval, + aBlockTextPrimitive.get2DDecomposition(aViewInformation2D)); + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SfxItemSet& rItemSet = GetGrafObject().GetMergedItemSet(); + drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetGrafObject().getText(0))); + + // create and fill GraphicAttr + GraphicAttr aLocalGrafInfo; + const sal_uInt16 nTrans(((SdrGrafTransparenceItem&)rItemSet.Get(SDRATTR_GRAFTRANSPARENCE)).GetValue()); + const SdrGrafCropItem& rCrop((const SdrGrafCropItem&)rItemSet.Get(SDRATTR_GRAFCROP)); + aLocalGrafInfo.SetLuminance(((SdrGrafLuminanceItem&)rItemSet.Get(SDRATTR_GRAFLUMINANCE)).GetValue()); + aLocalGrafInfo.SetContrast(((SdrGrafContrastItem&)rItemSet.Get(SDRATTR_GRAFCONTRAST)).GetValue()); + aLocalGrafInfo.SetChannelR(((SdrGrafRedItem&)rItemSet.Get(SDRATTR_GRAFRED)).GetValue()); + aLocalGrafInfo.SetChannelG(((SdrGrafGreenItem&)rItemSet.Get(SDRATTR_GRAFGREEN)).GetValue()); + aLocalGrafInfo.SetChannelB(((SdrGrafBlueItem&)rItemSet.Get(SDRATTR_GRAFBLUE)).GetValue()); + aLocalGrafInfo.SetGamma(((SdrGrafGamma100Item&)rItemSet.Get(SDRATTR_GRAFGAMMA)).GetValue() * 0.01); + aLocalGrafInfo.SetTransparency((BYTE)::basegfx::fround(Min(nTrans, (USHORT)100) * 2.55)); + aLocalGrafInfo.SetInvert(((SdrGrafInvertItem&)rItemSet.Get(SDRATTR_GRAFINVERT)).GetValue()); + aLocalGrafInfo.SetDrawMode(((SdrGrafModeItem&)rItemSet.Get(SDRATTR_GRAFMODE)).GetValue()); + aLocalGrafInfo.SetCrop(rCrop.GetLeft(), rCrop.GetTop(), rCrop.GetRight(), rCrop.GetBottom()); + + if(aAttribute.isDefault() && 255L != aLocalGrafInfo.GetTransparency()) + { + // no fill, no line, no text (invisible), but the graphic content is visible. + // Create evtl. shadow for content which was not created by createNewSdrLineFillShadowTextAttribute yet + const drawinglayer::attribute::SdrShadowAttribute aShadow( + drawinglayer::primitive2d::createNewSdrShadowAttribute(rItemSet)); + + if(!aShadow.isDefault()) + { + // create new attribute set if indeed shadow is used + aAttribute = drawinglayer::attribute::SdrLineFillShadowTextAttribute( + aAttribute.getLine(), + aAttribute.getFill(), + aAttribute.getLineStartEnd(), + aShadow, + aAttribute.getFillFloatTransGradient(), + aAttribute.getText()); + } + } + + // take unrotated snap rect for position and size. Directly use model data, not getBoundRect() or getSnapRect() + // which will use the primitive data we just create in the near future + const Rectangle& rRectangle = GetGrafObject().GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // look for mirroring + const GeoStat& rGeoStat(GetGrafObject().GetGeoStat()); + const sal_Int32 nDrehWink(rGeoStat.nDrehWink); + const bool bRota180(18000 == nDrehWink); + const bool bMirrored(GetGrafObject().IsMirrored()); + const sal_uInt16 nMirrorCase(bRota180 ? (bMirrored ? 3 : 4) : (bMirrored ? 2 : 1)); + bool bHMirr((2 == nMirrorCase ) || (4 == nMirrorCase)); + bool bVMirr((3 == nMirrorCase ) || (4 == nMirrorCase)); + + // set mirror flags at LocalGrafInfo. Take into account that the geometry in + // aObjectRange is already changed and rotated when bRota180 is used. To rebuild + // that old behaviour (as long as part of the model data), correct the H/V flags + // accordingly. The created bitmapPrimitive WILL use the rotation, too. + if(bRota180) + { + // if bRota180 which is used for vertical mirroring, the graphic will already be rotated + // by 180 degrees. To correct, switch off VMirror and invert HMirroring. + bHMirr = !bHMirr; + bVMirr = false; + } + + if(bHMirr || bVMirr) + { + aLocalGrafInfo.SetMirrorFlags((bHMirr ? BMP_MIRROR_HORZ : 0)|(bVMirr ? BMP_MIRROR_VERT : 0)); + } + + // fill object matrix + const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); + const double fRotate(nDrehWink ? (36000 - nDrehWink) * F_PI18000 : 0.0); + const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + fShearX, fRotate, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // get the current, unchenged graphic obect from SdrGrafObj + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + + if(visualisationUsesPresObj()) + { + // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one + // with the content which is the placeholder graphic + xRetval = createVIP2DSForPresObj(aObjectMatrix, aAttribute, aLocalGrafInfo); + } + else if(visualisationUsesDraft()) + { + // #i102380# The graphic is swapped out. To not force a swap-in here, there is a mechanism + // which shows a swapped-out-visualisation (which gets created here now) and an asynchronious + // visual update mechanism for swapped-out grapgics when they were loaded (see AsynchGraphicLoadingEvent + // and ViewObjectContactOfGraphic implementation). Not forcing the swap-in here allows faster + // (non-blocking) processing here and thus in the effect e.g. fast scrolling through pages + xRetval = createVIP2DSForDraft(aObjectMatrix, aAttribute); + } + else + { + // create primitive. Info: Calling the copy-constructor of GraphicObject in this + // SdrGrafPrimitive2D constructor will force a full swap-in of the graphic + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::SdrGrafPrimitive2D( + aObjectMatrix, + aAttribute, + rGraphicObject, + aLocalGrafInfo)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + // always append an invisible outline for the cases where no visible content exists + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectMatrix)); + + return xRetval; + } + + bool ViewContactOfGraphic::visualisationUsesPresObj() const + { + return GetGrafObject().IsEmptyPresObj(); + } + + bool ViewContactOfGraphic::visualisationUsesDraft() const + { + // no draft when already PresObj + if(visualisationUsesPresObj()) + return false; + + // draft when swapped out + const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false); + static bool bAllowReplacements(true); + + if(rGraphicObject.IsSwappedOut() && bAllowReplacements) + return true; + + // draft when no graphic + if(GRAPHIC_NONE == rGraphicObject.GetType() || GRAPHIC_DEFAULT == rGraphicObject.GetType()) + return true; + + return false; + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofgroup.cxx b/svx/source/sdr/contact/viewcontactofgroup.cxx new file mode 100644 index 000000000000..6252811d32a3 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofgroup.cxx @@ -0,0 +1,103 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofgroup.hxx> +#include <svx/svdogrp.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewobjectcontactofgroup.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfGroup::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfGroup(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfGroup::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfGroup::ViewContactOfGroup(SdrObjGroup& rGroup) + : ViewContactOfSdrObj(rGroup) + { + } + + ViewContactOfGroup::~ViewContactOfGroup() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGroup::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nObjectCount(GetObjectCount()); + + if(nObjectCount) + { + // collect all sub-primitives + for(sal_uInt32 a(0); a < nObjectCount; a++) + { + const ViewContact& rCandidate(GetViewContact(a)); + const drawinglayer::primitive2d::Primitive2DSequence aCandSeq(rCandidate.getViewIndependentPrimitive2DSequence()); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, aCandSeq); + } + } + else + { + // append an invisible outline for the cases where no visible content exists + const Rectangle aCurrentBoundRect(GetSdrObjGroup().GetLastBoundRect()); + const basegfx::B2DRange aCurrentRange( + aCurrentBoundRect.Left(), aCurrentBoundRect.Top(), + aCurrentBoundRect.Right(), aCurrentBoundRect.Bottom()); + + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aCurrentRange)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx new file mode 100644 index 000000000000..6ca5f1c4d172 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofmasterpagedescriptor.cxx @@ -0,0 +1,126 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <vcl/timer.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdr/contact/viewcontactofsdrpage.hxx> +#include <svx/sdr/contact/viewobjectcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <svx/svdpage.hxx> +#include <drawinglayer/attribute/sdrfillattribute.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/attribute/fillgradientattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfMasterPageDescriptor::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + return *(new ViewObjectContactOfMasterPageDescriptor(rObjectContact, *this)); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfMasterPageDescriptor::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + drawinglayer::attribute::SdrFillAttribute aFill; + const SdrPageProperties* pCorrectProperties = GetMasterPageDescriptor().getCorrectSdrPageProperties(); + + if(pCorrectProperties) + { + // create page fill attributes when correct properties were identified + aFill = drawinglayer::primitive2d::createNewSdrFillAttribute(pCorrectProperties->GetItemSet()); + } + + if(!aFill.isDefault()) + { + // direct model data is the page size, get and use it + const SdrPage& rOwnerPage = GetMasterPageDescriptor().GetOwnerPage(); + const basegfx::B2DRange aInnerRange( + rOwnerPage.GetLftBorder(), rOwnerPage.GetUppBorder(), + rOwnerPage.GetWdt() - rOwnerPage.GetRgtBorder(), + rOwnerPage.GetHgt() - rOwnerPage.GetLwrBorder()); + const basegfx::B2DPolygon aInnerPolgon(basegfx::tools::createPolygonFromRect(aInnerRange)); + const basegfx::B2DHomMatrix aEmptyTransform; + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aInnerPolgon), + aEmptyTransform, + aFill, + drawinglayer::attribute::FillGradientAttribute())); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + return xRetval; + } + + // basic constructor + ViewContactOfMasterPageDescriptor::ViewContactOfMasterPageDescriptor(sdr::MasterPageDescriptor& rDescriptor) + : ViewContact(), + mrMasterPageDescriptor(rDescriptor) + { + } + + // The destructor. + ViewContactOfMasterPageDescriptor::~ViewContactOfMasterPageDescriptor() + { + } + + sal_uInt32 ViewContactOfMasterPageDescriptor::GetObjectCount() const + { + return GetMasterPageDescriptor().GetUsedPage().GetObjCount(); + } + + ViewContact& ViewContactOfMasterPageDescriptor::GetViewContact(sal_uInt32 nIndex) const + { + return GetMasterPageDescriptor().GetUsedPage().GetObj(nIndex)->GetViewContact(); + } + + ViewContact* ViewContactOfMasterPageDescriptor::GetParentContact() const + { + return &(GetMasterPageDescriptor().GetOwnerPage().GetViewContact()); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofpageobj.cxx b/svx/source/sdr/contact/viewcontactofpageobj.cxx new file mode 100644 index 000000000000..3740ec27bdb5 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofpageobj.cxx @@ -0,0 +1,105 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofpageobj.hxx> +#include <svx/svdopage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewobjectcontactofpageobj.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageObj(rObjectContact, *this); + return *pRetval; + } + + // Access to referenced page + const SdrPage* ViewContactOfPageObj::GetReferencedPage() const + { + return GetPageObj().GetReferencedPage(); + } + + ViewContactOfPageObj::ViewContactOfPageObj(SdrPageObj& rPageObj) + : ViewContactOfSdrObj(rPageObj) + { + } + + ViewContactOfPageObj::~ViewContactOfPageObj() + { + } + + // #i35972# React on changes of the object of this ViewContact + void ViewContactOfPageObj::ActionChanged() + { + static bool bIsInActionChange(false); + + if(!bIsInActionChange) + { + // set recursion flag, see description in *.hxx + bIsInActionChange = true; + + // call parent + ViewContactOfSdrObj::ActionChanged(); + + // reset recursion flag, see description in *.hxx + bIsInActionChange = false; + } + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageObj::createViewIndependentPrimitive2DSequence() const + { + // ceate graphical visualisation data. Since this is the view-independent version which should not be used, + // create a replacement graphic visualisation here. Use GetLastBoundRect to access the model data directly + // which is aOutRect for SdrPageObj. + const Rectangle aModelRectangle(GetPageObj().GetLastBoundRect()); + const basegfx::B2DRange aModelRange(aModelRectangle.Left(), aModelRectangle.Top(), aModelRectangle.Right(), aModelRectangle.Bottom()); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aModelRange)); + const basegfx::BColor aYellow(1.0, 1.0, 0.0); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aYellow)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx new file mode 100644 index 000000000000..84e60392a88f --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrcaptionobj.cxx @@ -0,0 +1,179 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrcaptionobj.hxx> +#include <svx/svdocapt.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrcaptionprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// +// includes for special text box shadow (SC) + +#include <svl/itemset.hxx> +#include <svx/xhatch.hxx> +#include <svx/xflhtit.hxx> +#include <svx/xflclit.hxx> +#include <svx/xfltrit.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrCaptionObj::ViewContactOfSdrCaptionObj(SdrCaptionObj& rCaptionObj) + : ViewContactOfSdrRectObj(rCaptionObj) + { + } + + ViewContactOfSdrCaptionObj::~ViewContactOfSdrCaptionObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCaptionObj::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrCaptionObj& rCaptionObj(GetCaptionObj()); + const SfxItemSet& rItemSet = rCaptionObj.GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + rCaptionObj.getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = rCaptionObj.GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(rCaptionObj.GetGeoStat()); + + // fill object matrix + basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // calculate corner radius + double fCornerRadiusX; + double fCornerRadiusY; + drawinglayer::primitive2d::calculateRelativeCornerRadius( + rCaptionObj.GetEckenradius(), aObjectRange, fCornerRadiusX, fCornerRadiusY); + + // create primitive. Always create one (even if invisible) to let the decomposition + // of SdrCaptionPrimitive2D create needed invisible elements for HitTest and BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrCaptionPrimitive2D( + aObjectMatrix, + aAttribute, + rCaptionObj.getTailPolygon(), + fCornerRadiusX, + fCornerRadiusY)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + + if(!aAttribute.isDefault() && rCaptionObj.GetSpecialTextBoxShadow()) + { + // for SC, the caption object may have a specialized shadow. The usual object shadow is off + // and a specialized shadow gets created here (see old paint) + const SdrShadowColorItem& rShadColItem = (SdrShadowColorItem&)(rItemSet.Get(SDRATTR_SHADOWCOLOR)); + const sal_uInt16 nTransp(((SdrShadowTransparenceItem&)(rItemSet.Get(SDRATTR_SHADOWTRANSPARENCE))).GetValue()); + const Color aShadCol(rShadColItem.GetColorValue()); + const XFillStyle eStyle = ((XFillStyleItem&)(rItemSet.Get(XATTR_FILLSTYLE))).GetValue(); + + // Create own ItemSet and modify as needed + // Always hide lines for special calc shadow + SfxItemSet aSet(rItemSet); + aSet.Put(XLineStyleItem(XLINE_NONE)); + + if(XFILL_HATCH == eStyle) + { + // #41666# Hatch color is set hard to shadow color + XHatch aHatch = ((XFillHatchItem&)(rItemSet.Get(XATTR_FILLHATCH))).GetHatchValue(); + aHatch.SetColor(aShadCol); + aSet.Put(XFillHatchItem(String(),aHatch)); + } + else + { + if(XFILL_NONE != eStyle && XFILL_SOLID != eStyle) + { + // force fill to solid (for Gradient and Bitmap) + aSet.Put(XFillStyleItem(XFILL_SOLID)); + } + + aSet.Put(XFillColorItem(String(),aShadCol)); + aSet.Put(XFillTransparenceItem(nTransp)); + } + + // crete FillAttribute from modified ItemSet + const drawinglayer::attribute::SdrFillAttribute aFill( + drawinglayer::primitive2d::createNewSdrFillAttribute(aSet)); + drawinglayer::primitive2d::Primitive2DReference xSpecialShadow; + + if(!aFill.isDefault() && 1.0 != aFill.getTransparence()) + { + // add shadow offset to object matrix + const sal_uInt32 nXDist(((SdrShadowXDistItem&)(rItemSet.Get(SDRATTR_SHADOWXDIST))).GetValue()); + const sal_uInt32 nYDist(((SdrShadowYDistItem&)(rItemSet.Get(SDRATTR_SHADOWYDIST))).GetValue()); + aObjectMatrix.translate(nXDist, nYDist); + + // create unit outline polygon as geometry (see SdrCaptionPrimitive2D::create2DDecomposition) + basegfx::B2DPolygon aUnitOutline(basegfx::tools::createPolygonFromRect( + basegfx::B2DRange(0.0, 0.0, 1.0, 1.0), fCornerRadiusX, fCornerRadiusY)); + + // create the specialized shadow primitive + xSpecialShadow = drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aUnitOutline), + aObjectMatrix, + aFill, + drawinglayer::attribute::FillGradientAttribute()); + } + + if(xSpecialShadow.is()) + { + // if we really got a special shadow, create a two-element retval with the shadow + // behind the standard object's geometry + xRetval.realloc(2); + + xRetval[0] = xSpecialShadow; + xRetval[1] = xReference; + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx new file mode 100644 index 000000000000..f6f2f094001b --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrcircobj.cxx @@ -0,0 +1,117 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrcircobj.hxx> +#include <svx/svdocirc.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrellipseprimitive2d.hxx> +#include <svl/itemset.hxx> +#include <svx/sxciaitm.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrCircObj::ViewContactOfSdrCircObj(SdrCircObj& rCircObj) + : ViewContactOfSdrRectObj(rCircObj) + { + } + + ViewContactOfSdrCircObj::~ViewContactOfSdrCircObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrCircObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetCircObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetCircObj().getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetCircObj().GetGeoRect(); + const basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(GetCircObj().GetGeoStat()); + + // fill object matrix + const basegfx::B2DHomMatrix aObjectMatrix( + basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // create primitive data + const sal_uInt16 nIdentifier(GetCircObj().GetObjIdentifier()); + + // always create primitives to allow the decomposition of SdrEllipsePrimitive2D + // or SdrEllipseSegmentPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + if(OBJ_CIRC == nIdentifier) + { + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrEllipsePrimitive2D( + aObjectMatrix, + aAttribute)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + else + { + const sal_Int32 nNewStart(((SdrCircStartAngleItem&)rItemSet.Get(SDRATTR_CIRCSTARTANGLE)).GetValue()); + const sal_Int32 nNewEnd(((SdrCircEndAngleItem&)rItemSet.Get(SDRATTR_CIRCENDANGLE)).GetValue()); + const double fStart(((36000 - nNewEnd) % 36000) * F_PI18000); + const double fEnd(((36000 - nNewStart) % 36000) * F_PI18000); + const bool bCloseSegment(OBJ_CARC != nIdentifier); + const bool bCloseUsingCenter(OBJ_SECT == nIdentifier); + + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrEllipseSegmentPrimitive2D( + aObjectMatrix, + aAttribute, + fStart, + fEnd, + bCloseSegment, + bCloseUsingCenter)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx new file mode 100644 index 000000000000..7b4ec93afb38 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdredgeobj.cxx @@ -0,0 +1,79 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdredgeobj.hxx> +#include <svx/svdoedge.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrconnectorprimitive2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrEdgeObj::ViewContactOfSdrEdgeObj(SdrEdgeObj& rEdgeObj) + : ViewContactOfTextObj(rEdgeObj) + { + } + + ViewContactOfSdrEdgeObj::~ViewContactOfSdrEdgeObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrEdgeObj::createViewIndependentPrimitive2DSequence() const + { + const basegfx::B2DPolygon& rEdgeTrack = GetEdgeObj().getEdgeTrack(); + + // what to do when no EdgeTrack is provided (HitTest and selectability) ? + OSL_ENSURE(0 != rEdgeTrack.count(), "Connectors with no geometry are not allowed (!)"); + + // ckeck attributes + const SfxItemSet& rItemSet = GetEdgeObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineShadowTextAttribute( + rItemSet, + GetEdgeObj().getText(0))); + + // create primitive. Always create primitives to allow the decomposition of + // SdrConnectorPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrConnectorPrimitive2D( + aAttribute, + rEdgeTrack)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx new file mode 100644 index 000000000000..9d0d38f688eb --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrmeasureobj.cxx @@ -0,0 +1,143 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrmeasureobj.hxx> +#include <svx/svdomeas.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svl/itemset.hxx> +#include <svx/sxmbritm.hxx> +#include <svx/sxmlhitm.hxx> +#include <svx/sxmtritm.hxx> +#include <svx/sxmtaitm.hxx> +#include <svx/sdr/primitive2d/sdrmeasureprimitive2d.hxx> +#include <svx/sxmtpitm.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrMeasureObj::ViewContactOfSdrMeasureObj(SdrMeasureObj& rMeasureObj) + : ViewContactOfTextObj(rMeasureObj) + { + } + + ViewContactOfSdrMeasureObj::~ViewContactOfSdrMeasureObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrMeasureObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetMeasureObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineShadowTextAttribute( + rItemSet, + GetMeasureObj().getText(0))); + + // take properties which are the model data. + const ::basegfx::B2DPoint aStart(GetMeasureObj().GetPoint(0).X(), GetMeasureObj().GetPoint(0).Y()); + const ::basegfx::B2DPoint aEnd(GetMeasureObj().GetPoint(1).X(), GetMeasureObj().GetPoint(1).Y()); + const double fDistance(((SdrMeasureLineDistItem&)rItemSet.Get(SDRATTR_MEASURELINEDIST)).GetValue()); + const double fUpperDistance(((SdrMeasureHelplineOverhangItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINEOVERHANG)).GetValue()); + const double fLowerDistance(((SdrMeasureHelplineDistItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINEDIST)).GetValue()); + const double fLeftDelta(((SdrMeasureHelpline1LenItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINE1LEN)).GetValue()); + const double fRightDelta(((SdrMeasureHelpline2LenItem&)rItemSet.Get(SDRATTR_MEASUREHELPLINE2LEN)).GetValue()); + const bool bBelow(((SdrMeasureBelowRefEdgeItem&)rItemSet.Get(SDRATTR_MEASUREBELOWREFEDGE)).GetValue()); + const bool bTextRotation(((SdrMeasureTextRota90Item&)rItemSet.Get(SDRATTR_MEASURETEXTROTA90)).GetValue()); + const bool bTextAutoAngle(((SdrMeasureTextAutoAngleItem&)rItemSet.Get(SDRATTR_MEASURETEXTAUTOANGLE)).GetValue()); + drawinglayer::primitive2d::MeasureTextPosition aMTPHor(drawinglayer::primitive2d::MEASURETEXTPOSITION_AUTOMATIC); + drawinglayer::primitive2d::MeasureTextPosition aMTPVer(drawinglayer::primitive2d::MEASURETEXTPOSITION_AUTOMATIC); + + switch(((SdrMeasureTextHPosItem&)rItemSet.Get(SDRATTR_MEASURETEXTHPOS)).GetValue()) + { + case SDRMEASURE_TEXTLEFTOUTSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_NEGATIVE; + break; + } + case SDRMEASURE_TEXTINSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_CENTERED; + break; + } + case SDRMEASURE_TEXTRIGHTOUTSIDE : + { + aMTPHor = drawinglayer::primitive2d::MEASURETEXTPOSITION_POSITIVE; + break; + } + default : // SDRMEASURE_TEXTHAUTO + { + break; + } + } + + switch(((SdrMeasureTextVPosItem&)rItemSet.Get(SDRATTR_MEASURETEXTVPOS)).GetValue()) + { + case SDRMEASURE_ABOVE : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_NEGATIVE; + break; + } + case SDRMEASURETEXT_BREAKEDLINE : + case SDRMEASURETEXT_VERTICALCENTERED : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_CENTERED; + break; + } + case SDRMEASURE_BELOW : + { + aMTPVer = drawinglayer::primitive2d::MEASURETEXTPOSITION_POSITIVE; + break; + } + default : // SDRMEASURE_TEXTVAUTO + { + break; + } + } + + // create primitive with the model data. Always create primitives to allow the + // decomposition of SdrMeasurePrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrMeasurePrimitive2D( + aAttribute, aStart, aEnd, + aMTPHor, aMTPVer, fDistance, + fUpperDistance, fLowerDistance, + fLeftDelta, fRightDelta, bBelow, + bTextRotation, bTextAutoAngle)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx new file mode 100644 index 000000000000..ab6598840a8e --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrmediaobj.cxx @@ -0,0 +1,184 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx> +#include <svx/svdomedia.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <drawinglayer/primitive2d/mediaprimitive2d.hxx> + +namespace sdr { namespace contact { + +// ---------------------------- +// - ViewContactOfSdrMediaObj - +// ---------------------------- + +ViewContactOfSdrMediaObj::ViewContactOfSdrMediaObj( SdrMediaObj& rMediaObj ) : + ViewContactOfSdrObj( rMediaObj ) +{ +} + +// ------------------------------------------------------------------------------ + +ViewContactOfSdrMediaObj::~ViewContactOfSdrMediaObj() +{ +} + +// ------------------------------------------------------------------------------ + +ViewObjectContact& ViewContactOfSdrMediaObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) +{ + return *( new ViewObjectContactOfSdrMediaObj( rObjectContact, *this, static_cast< SdrMediaObj& >( GetSdrObject() ).getMediaProperties() ) ); +} + +// ------------------------------------------------------------------------------ + +bool ViewContactOfSdrMediaObj::hasPreferredSize() const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + // return true if all have their preferred size + const sal_uInt32 nCount(getViewObjectContactCount()); + bool bRetval(true); + + for(sal_uInt32 a(0); bRetval && a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate && !static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->hasPreferredSize()) + { + bRetval = false; + } + } + + return bRetval; +} + +// ------------------------------------------------------------------------------ + +Size ViewContactOfSdrMediaObj::getPreferredSize() const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + // return first useful size -> the size from the first which is visualized as a window + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + Size aSize(pCandidate ? static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->getPreferredSize() : Size()); + + if(0 != aSize.getWidth() || 0 != aSize.getHeight()) + { + return aSize; + } + } + + return Size(); +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::updateMediaItem( ::avmedia::MediaItem& rItem ) const +{ + // #i71805# Since we may have a whole bunch of VOCs here, make a loop + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate) + { + static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->updateMediaItem(rItem); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::executeMediaItem( const ::avmedia::MediaItem& rItem ) +{ + const sal_uInt32 nCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + + if(pCandidate) + { + static_cast< ViewObjectContactOfSdrMediaObj* >(pCandidate)->executeMediaItem(rItem); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewContactOfSdrMediaObj::mediaPropertiesChanged( const ::avmedia::MediaItem& rNewState ) +{ + static_cast< SdrMediaObj& >(GetSdrObject()).mediaPropertiesChanged(rNewState); +} + +}} // end of namespace sdr::contact + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrMediaObj::createViewIndependentPrimitive2DSequence() const + { + // create range using the model data directly. This is in SdrTextObj::aRect which i will access using + // GetGeoRect() to not trigger any calculations. It's the unrotated geometry which is okay for MediaObjects ATM. + const Rectangle& rRectangle(GetSdrMediaObj().GetGeoRect()); + const basegfx::B2DRange aRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aTransform; + aTransform.set(0, 0, aRange.getWidth()); + aTransform.set(1, 1, aRange.getHeight()); + aTransform.set(0, 2, aRange.getMinX()); + aTransform.set(1, 2, aRange.getMinY()); + + // create media primitive. Always create primitives to allow the + // decomposition of MediaPrimitive2D to create needed invisible elements for HitTest + // and/or BoundRect + const basegfx::BColor aBackgroundColor(67.0 / 255.0, 67.0 / 255.0, 67.0 / 255.0); + const rtl::OUString& rURL(GetSdrMediaObj().getURL()); + const sal_uInt32 nPixelBorder(4L); + const drawinglayer::primitive2d::Primitive2DReference xRetval( + new drawinglayer::primitive2d::MediaPrimitive2D( + aTransform, rURL, aBackgroundColor, nPixelBorder)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrobj.cxx b/svx/source/sdr/contact/viewcontactofsdrobj.cxx new file mode 100644 index 000000000000..6d609108e580 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrobj.cxx @@ -0,0 +1,194 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdobj.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/outdev.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/markerarrayprimitive2d.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrObj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrObj(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContactOfSdrObj::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrObj::ViewContactOfSdrObj(SdrObject& rObj) + : ViewContact(), + mrObject(rObj), + meRememberedAnimationKind(SDRTEXTANI_NONE) + { + // init AnimationKind + if(GetSdrObject().ISA(SdrTextObj)) + { + SdrTextObj& rTextObj = (SdrTextObj&)GetSdrObject(); + meRememberedAnimationKind = rTextObj.GetTextAniKind(); + } + } + + ViewContactOfSdrObj::~ViewContactOfSdrObj() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfSdrObj::GetObjectCount() const + { + if(GetSdrObject().GetSubList()) + { + return GetSdrObject().GetSubList()->GetObjCount(); + } + + return 0L; + } + + ViewContact& ViewContactOfSdrObj::GetViewContact(sal_uInt32 nIndex) const + { + DBG_ASSERT(GetSdrObject().GetSubList(), + "ViewContactOfSdrObj::GetViewContact: Access to non-existent Sub-List (!)"); + SdrObject* pObj = GetSdrObject().GetSubList()->GetObj(nIndex); + DBG_ASSERT(pObj, "ViewContactOfSdrObj::GetViewContact: Corrupt SdrObjList (!)"); + return pObj->GetViewContact(); + } + + ViewContact* ViewContactOfSdrObj::GetParentContact() const + { + ViewContact* pRetval = 0L; + SdrObjList* pObjList = GetSdrObject().GetObjList(); + + if(pObjList) + { + if(pObjList->ISA(SdrPage)) + { + // Is a page + pRetval = &(((SdrPage*)pObjList)->GetViewContact()); + } + else + { + // Is a group? + if(pObjList->GetOwnerObj()) + { + pRetval = &(pObjList->GetOwnerObj()->GetViewContact()); + } + } + } + + return pRetval; + } + + // React on changes of the object of this ViewContact + void ViewContactOfSdrObj::ActionChanged() + { + // look for own changes + if(GetSdrObject().ISA(SdrTextObj)) + { + SdrTextObj& rTextObj = (SdrTextObj&)GetSdrObject(); + + if(rTextObj.GetTextAniKind() != meRememberedAnimationKind) + { + // #i38135# now remember new type + meRememberedAnimationKind = rTextObj.GetTextAniKind(); + } + } + + // call parent + ViewContact::ActionChanged(); + } + + // overload for acessing the SdrObject + SdrObject* ViewContactOfSdrObj::TryToGetSdrObject() const + { + return &GetSdrObject(); + } + + ////////////////////////////////////////////////////////////////////////////// + // primitive stuff + + // add Gluepoints (if available) + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObj::createGluePointPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrGluePointList* pGluePointList = GetSdrObject().GetGluePointList(); + + if(pGluePointList) + { + const sal_uInt32 nCount(pGluePointList->GetCount()); + + if(nCount) + { + // prepare point vector + std::vector< basegfx::B2DPoint > aGluepointVector; + + // create GluePoint primitives. ATM these are relative to the SnapRect + for(sal_uInt32 a(0L); a < nCount; a++) + { + const SdrGluePoint& rCandidate = (*pGluePointList)[(sal_uInt16)a]; + const Point aPosition(rCandidate.GetAbsolutePos(GetSdrObject())); + + aGluepointVector.push_back(basegfx::B2DPoint(aPosition.X(), aPosition.Y())); + } + + if(aGluepointVector.size()) + { + const basegfx::BColor aBackPen(1.0, 1.0, 1.0); + const basegfx::BColor aRGBFrontColor(0.0, 0.0, 1.0); // COL_LIGHTBLUE + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::MarkerArrayPrimitive2D( + aGluepointVector, + drawinglayer::primitive2d::createDefaultGluepoint_7x7(aBackPen, aRGBFrontColor))); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx new file mode 100644 index 000000000000..6fa63f7c073e --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrobjcustomshape.cxx @@ -0,0 +1,241 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofsdrobjcustomshape.hxx> +#include <svx/svdoashp.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svditer.hxx> +#include <svx/sdr/primitive2d/sdrcustomshapeprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <svx/obj3d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrObjCustomShape::ViewContactOfSdrObjCustomShape(SdrObjCustomShape& rCustomShape) + : ViewContactOfTextObj(rCustomShape) + { + } + + ViewContactOfSdrObjCustomShape::~ViewContactOfSdrObjCustomShape() + { + } + + basegfx::B2DRange ViewContactOfSdrObjCustomShape::getCorrectedTextBoundRect() const + { + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + Rectangle aTextBound(aObjectBound); + GetCustomShapeObj().GetTextBounds(aTextBound); + basegfx::B2DRange aTextRange(aTextBound.Left(), aTextBound.Top(), aTextBound.Right(), aTextBound.Bottom()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + + // no need to correct if no extra text range + if(aTextRange != aObjectRange) + { + const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); + + // only correct when rotation and/or shear is used + if(rGeoStat.nShearWink || rGeoStat.nDrehWink ) + { + // text range needs to be corrected by + // aObjectRange.getCenter() - aRotObjectRange.getCenter() since it's + // defined differenly by using rotation around object center. Start + // with positive part + basegfx::B2DVector aTranslation(aObjectRange.getCenter()); + + // get rotated and sheared object's range + basegfx::B2DRange aRotObjectRange(aObjectRange); + basegfx::B2DHomMatrix aRotMatrix; + + aRotMatrix.translate(-aObjectRange.getMinimum().getX(), -aObjectRange.getMinimum().getY()); + + if(rGeoStat.nShearWink) + { + aRotMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aRotMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + aRotMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + aRotObjectRange.transform(aRotMatrix); + + // add negative translation part + aTranslation -= aRotObjectRange.getCenter(); + + // create new range + aTextRange = basegfx::B2DRange( + aTextRange.getMinX() + aTranslation.getX(), aTextRange.getMinY() + aTranslation.getY(), + aTextRange.getMaxX() + aTranslation.getX(), aTextRange.getMaxY() + aTranslation.getY()); + } + } + + return aTextRange; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrObjCustomShape::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SfxItemSet& rItemSet = GetCustomShapeObj().GetMergedItemSet(); + + // #i98072# Get shandow and text; eventually suppress the text if it's + // a TextPath FontworkGallery object + const drawinglayer::attribute::SdrShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrShadowTextAttribute( + rItemSet, + GetCustomShapeObj().getText(0), + GetCustomShapeObj().IsTextPath())); + drawinglayer::primitive2d::Primitive2DSequence xGroup; + bool bHasText(!aAttribute.getText().isDefault()); + + // create Primitive2DSequence from sub-geometry + const SdrObject* pSdrObjRepresentation = GetCustomShapeObj().GetSdrObjectFromCustomShape(); + bool b3DShape(false); + + if(pSdrObjRepresentation) + { + SdrObjListIter aIterator(*pSdrObjRepresentation); + + while(aIterator.IsMore()) + { + SdrObject& rCandidate = *aIterator.Next(); + + if(!b3DShape && dynamic_cast< E3dObject* >(&rCandidate)) + { + b3DShape = true; + } + + const drawinglayer::primitive2d::Primitive2DSequence xNew(rCandidate.GetViewContact().getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xGroup, xNew); + } + } + + if(bHasText || xGroup.hasElements()) + { + // prepare text box geometry + basegfx::B2DHomMatrix aTextBoxMatrix; + bool bWordWrap(false); + + if(bHasText) + { + // take unrotated snap rect as default, then get the + // unrotated text box. Rotation needs to be done centered + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange(aObjectBound.Left(), aObjectBound.Top(), aObjectBound.Right(), aObjectBound.Bottom()); + + // #i101684# get the text range unrotated and absolute to the object range + const basegfx::B2DRange aTextRange(getCorrectedTextBoundRect()); + + // give text object a size + aTextBoxMatrix.scale(aTextRange.getWidth(), aTextRange.getHeight()); + + // check if we have a rotation/shear at all to take care of + const double fExtraTextRotation(GetCustomShapeObj().GetExtraTextRotation()); + const GeoStat& rGeoStat(GetCustomShapeObj().GetGeoStat()); + + if(rGeoStat.nShearWink || rGeoStat.nDrehWink || !basegfx::fTools::equalZero(fExtraTextRotation)) + { + if(aObjectRange != aTextRange) + { + // move relative to unrotated object range + aTextBoxMatrix.translate( + aTextRange.getMinX() - aObjectRange.getMinimum().getX(), + aTextRange.getMinY() - aObjectRange.getMinimum().getY()); + } + + if(!basegfx::fTools::equalZero(fExtraTextRotation)) + { + basegfx::B2DVector aTranslation( + ( aTextRange.getWidth() / 2 ) + ( aTextRange.getMinX() - aObjectRange.getMinimum().getX() ), + ( aTextRange.getHeight() / 2 ) + ( aTextRange.getMinY() - aObjectRange.getMinimum().getY() ) ); + aTextBoxMatrix.translate( -aTranslation.getX(), -aTranslation.getY() ); + aTextBoxMatrix.rotate((360.0 - fExtraTextRotation) * F_PI180); + aTextBoxMatrix.translate( aTranslation.getX(), aTranslation.getY() ); + } + + if(rGeoStat.nShearWink) + { + aTextBoxMatrix.shearX(tan((36000 - rGeoStat.nShearWink) * F_PI18000)); + } + + if(rGeoStat.nDrehWink) + { + aTextBoxMatrix.rotate((36000 - rGeoStat.nDrehWink) * F_PI18000); + } + + // give text it's target position + aTextBoxMatrix.translate(aObjectRange.getMinimum().getX(), aObjectRange.getMinimum().getY()); + } + else + { + aTextBoxMatrix.translate(aTextRange.getMinX(), aTextRange.getMinY()); + } + + // check if SdrTextWordWrapItem is set + bWordWrap = ((SdrTextWordWrapItem&)(GetCustomShapeObj().GetMergedItem(SDRATTR_TEXT_WORDWRAP))).GetValue(); + } + + // create primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrCustomShapePrimitive2D( + aAttribute, + xGroup, + aTextBoxMatrix, + bWordWrap, + b3DShape, + false)); // #SJ# New parameter to force to clipped BlockText for SC + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + // always append an invisible outline for the cases where no visible content exists + const Rectangle aObjectBound(GetCustomShapeObj().GetGeoRect()); + const basegfx::B2DRange aObjectRange( + aObjectBound.Left(), aObjectBound.Top(), + aObjectBound.Right(), aObjectBound.Bottom()); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectRange)); + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx new file mode 100644 index 000000000000..b88578113c5d --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrole2obj.cxx @@ -0,0 +1,130 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrole2obj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrole2obj.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/sdr/primitive2d/sdrole2primitive2d.hxx> +#include <drawinglayer/primitive2d/graphicprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/bitmapprimitive2d.hxx> +#include <svtools/colorcfg.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <vcl/svapp.hxx> +#include <svx/sdr/primitive2d/sdrolecontentprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrOle2Obj::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrOle2Obj(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrOle2Obj::ViewContactOfSdrOle2Obj(SdrOle2Obj& rOle2Obj) + : ViewContactOfSdrRectObj(rOle2Obj) + { + } + + ViewContactOfSdrOle2Obj::~ViewContactOfSdrOle2Obj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createPrimitive2DSequenceWithParameters( + bool bHighContrast) const + { + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetOle2Obj().GetGeoRect(); + const basegfx::B2DRange aObjectRange(rRectangle.Left(), rRectangle.Top(), rRectangle.Right(), rRectangle.Bottom()); + + // create object matrix + const GeoStat& rGeoStat(GetOle2Obj().GetGeoStat()); + const double fShearX(rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0); + const double fRotate(rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0); + const basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), fShearX, fRotate, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // Prepare attribute settings, will be used soon anyways + const SfxItemSet& rItemSet = GetOle2Obj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetOle2Obj().getText(0))); + + // #i102063# embed OLE content in an own primitive; this will be able to decompose accessing + // the weak SdrOle2 reference and will also implement getB2DRange() for fast BoundRect + // calculations without OLE Graphic access (which may trigger e.g. chart recalculation). + // It will also take care of HighContrast and ScaleContent + const drawinglayer::primitive2d::Primitive2DReference xOleContent( + new drawinglayer::primitive2d::SdrOleContentPrimitive2D( + GetOle2Obj(), + aObjectMatrix, + + // #i104867# add GraphicVersion number to be able to check for + // content change in the primitive later + GetOle2Obj().getEmbeddedObjectRef().getGraphicVersion(), + + bHighContrast)); + + // create primitive. Use Ole2 primitive here. Prepare attribute settings, will + // be used soon anyways. Always create primitives to allow the decomposition of + // SdrOle2Primitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DSequence xOLEContent(&xOleContent, 1); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrOle2Primitive2D( + xOLEContent, + aObjectMatrix, + aAttribute)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrOle2Obj::createViewIndependentPrimitive2DSequence() const + { + // do as if no HC and call standard creator + return createPrimitive2DSequenceWithParameters(false); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrpage.cxx b/svx/source/sdr/contact/viewcontactofsdrpage.cxx new file mode 100644 index 000000000000..ad65b647001e --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrpage.cxx @@ -0,0 +1,726 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofsdrpage.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrpage.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <vcl/svapp.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrdecompositiontools.hxx> +#include <vcl/lazydelete.hxx> +#include "svdstr.hrc" +#include "svdglob.hxx" +#include <drawinglayer/primitive2d/discreteshadowprimitive2d.hxx> +#include <drawinglayer/attribute/sdrfillattribute.hxx> + +////////////////////////////////////////////////////////////////////////////// + +#define PAPER_SHADOW(SIZE) (SIZE >> 8) + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfPageSubObject::ViewContactOfPageSubObject(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : mrParentViewContactOfSdrPage(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageSubObject::~ViewContactOfPageSubObject() + { + } + + ViewContact* ViewContactOfPageSubObject::GetParentContact() const + { + return &mrParentViewContactOfSdrPage; + } + + const SdrPage& ViewContactOfPageSubObject::getPage() const + { + return mrParentViewContactOfSdrPage.GetSdrPage(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageBackground::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageBackground(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageBackground::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information. Use the + // svtools::DOCCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aInitColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + const basegfx::BColor aRGBColor(aInitColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::BackgroundColorPrimitive2D(aRGBColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfPageBackground::ViewContactOfPageBackground(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageBackground::~ViewContactOfPageBackground() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageShadow::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageShadow(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageShadow::createViewIndependentPrimitive2DSequence() const + { + static bool bUseOldPageShadow(false); + const SdrPage& rPage = getPage(); + basegfx::B2DHomMatrix aPageMatrix; + aPageMatrix.set(0, 0, (double)rPage.GetWdt()); + aPageMatrix.set(1, 1, (double)rPage.GetHgt()); + + if(bUseOldPageShadow) + { + // create page shadow polygon + const double fPageBorderFactor(1.0 / 256.0); + basegfx::B2DPolygon aPageShadowPolygon; + aPageShadowPolygon.append(basegfx::B2DPoint(1.0, fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0 + fPageBorderFactor, fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0 + fPageBorderFactor, 1.0 + fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(fPageBorderFactor, 1.0 + fPageBorderFactor)); + aPageShadowPolygon.append(basegfx::B2DPoint(fPageBorderFactor, 1.0)); + aPageShadowPolygon.append(basegfx::B2DPoint(1.0, 1.0)); + aPageShadowPolygon.setClosed(true); + aPageShadowPolygon.transform(aPageMatrix); + + // We have only the page information, not the view information. Use the + // svtools::FONTCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aShadowColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor); + const basegfx::BColor aRGBShadowColor(aShadowColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D( + basegfx::B2DPolyPolygon(aPageShadowPolygon), + aRGBShadowColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + else + { + static vcl::DeleteOnDeinit<drawinglayer::primitive2d::DiscreteShadow> + aDiscreteShadow(new drawinglayer::primitive2d::DiscreteShadow( + BitmapEx(ResId(SIP_SA_PAGESHADOW35X35, *ImpGetResMgr())))); + if (aDiscreteShadow.get() != NULL) + { + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::DiscreteShadowPrimitive2D( + aPageMatrix, + *aDiscreteShadow.get())); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + return drawinglayer::primitive2d::Primitive2DSequence(); + } + } + + ViewContactOfPageShadow::ViewContactOfPageShadow(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageShadow::~ViewContactOfPageShadow() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfMasterPage::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfMasterPage(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfMasterPage::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // this class is used when the page is a MasterPage and is responsible to + // create a visualisation for the MPBGO, if exists. This needs to be suppressed + // when a SdrPage which uses a MasterPage creates it's output. Suppression + // is done in the corresponding VOC since DisplayInfo data is needed + const SdrPage& rPage = getPage(); + + if(rPage.IsMasterPage()) + { + if(0 == rPage.GetPageNum()) + { + // #i98063# + // filter MasterPage 0 since it's the HandoutPage. Thus, it's a + // MasterPage, but has no MPBGO, so there is nothing to do here. + } + else + { + drawinglayer::attribute::SdrFillAttribute aFill; + + // #i110846# Suppress SdrPage FillStyle for MasterPages without StyleSheets, + // else the PoolDefault (XFILL_COLOR and Blue8) will be used. Normally, all + // MasterPages should have a StyleSheet excactly for this reason, but historically + // e.g. the Notes MasterPage has no StyleSheet set (and there maybe others). + if(rPage.getSdrPageProperties().GetStyleSheet()) + { + // create page fill attributes with correct properties + aFill = drawinglayer::primitive2d::createNewSdrFillAttribute( + rPage.getSdrPageProperties().GetItemSet()); + } + + if(!aFill.isDefault()) + { + // direct model data is the page size, get and use it + const basegfx::B2DRange aInnerRange( + rPage.GetLftBorder(), rPage.GetUppBorder(), + rPage.GetWdt() - rPage.GetRgtBorder(), rPage.GetHgt() - rPage.GetLwrBorder()); + const basegfx::B2DPolygon aInnerPolgon(basegfx::tools::createPolygonFromRect(aInnerRange)); + const basegfx::B2DHomMatrix aEmptyTransform; + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createPolyPolygonFillPrimitive( + basegfx::B2DPolyPolygon(aInnerPolgon), + aEmptyTransform, + aFill, + drawinglayer::attribute::FillGradientAttribute())); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } + + return xRetval; + } + + ViewContactOfMasterPage::ViewContactOfMasterPage(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfMasterPage::~ViewContactOfMasterPage() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageFill::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageFill(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageFill::createViewIndependentPrimitive2DSequence() const + { + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageFillRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + const basegfx::B2DPolygon aPageFillPolygon(basegfx::tools::createPolygonFromRect(aPageFillRange)); + + // We have only the page information, not the view information. Use the + // svtools::DOCCOLOR color for initialisation + const svtools::ColorConfig aColorConfig; + const Color aPageFillColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + + // create and add primitive + const basegfx::BColor aRGBColor(aPageFillColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPageFillPolygon), aRGBColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfPageFill::ViewContactOfPageFill(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageFill::~ViewContactOfPageFill() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfOuterPageBorder::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfOuterPageBorder(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfOuterPageBorder::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageBorderRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + + // Changed to 0x949599 for renaissance, before svtools::FONTCOLOR was used. + // Added old case as fallback for HighContrast. + basegfx::BColor aRGBBorderColor(0x94 / (double)0xff, 0x95 / (double)0xff, 0x99 / (double)0xff); + + if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) + { + const svtools::ColorConfig aColorConfig; + const Color aBorderColor(aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor); + + aRGBBorderColor = aBorderColor.getBColor(); + } + + if(rPage.getPageBorderOnlyLeftRight()) + { + // #i93597# for Report Designer, the page border shall be only displayed right and left, + // but not top and bottom. Create simplified geometry. + basegfx::B2DPolygon aLeft, aRight; + + aLeft.append(basegfx::B2DPoint(aPageBorderRange.getMinX(), aPageBorderRange.getMinY())); + aLeft.append(basegfx::B2DPoint(aPageBorderRange.getMinX(), aPageBorderRange.getMaxY())); + + aRight.append(basegfx::B2DPoint(aPageBorderRange.getMaxX(), aPageBorderRange.getMinY())); + aRight.append(basegfx::B2DPoint(aPageBorderRange.getMaxX(), aPageBorderRange.getMaxY())); + + xRetval.realloc(2); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aLeft, aRGBBorderColor)); + xRetval[1] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aRight, aRGBBorderColor)); + } + else + { + xRetval.realloc(1); + const basegfx::B2DPolygon aPageBorderPolygon(basegfx::tools::createPolygonFromRect(aPageBorderRange)); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aPageBorderPolygon, aRGBBorderColor)); + } + + return xRetval; + } + + ViewContactOfOuterPageBorder::ViewContactOfOuterPageBorder(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfOuterPageBorder::~ViewContactOfOuterPageBorder() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfInnerPageBorder::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfInnerPageBorder(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfInnerPageBorder::createViewIndependentPrimitive2DSequence() const + { + const SdrPage& rPage = getPage(); + const basegfx::B2DRange aPageBorderRange( + (double)rPage.GetLftBorder(), (double)rPage.GetUppBorder(), + (double)(rPage.GetWdt() - rPage.GetRgtBorder()), (double)(rPage.GetHgt() - rPage.GetLwrBorder())); + const basegfx::B2DPolygon aPageBorderPolygon(basegfx::tools::createPolygonFromRect(aPageBorderRange)); + + // We have only the page information, not the view information. Use the + // svtools::FONTCOLOR or svtools::DOCBOUNDARIES color for initialisation + const svtools::ColorConfig aColorConfig; + Color aBorderColor; + + if(Application::GetSettings().GetStyleSettings().GetHighContrastMode()) + { + aBorderColor = aColorConfig.GetColorValue(svtools::FONTCOLOR).nColor; + } + else + { + aBorderColor = aColorConfig.GetColorValue(svtools::DOCBOUNDARIES).nColor; + } + + // create page outer border primitive + const basegfx::BColor aRGBBorderColor(aBorderColor.getBColor()); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aPageBorderPolygon, aRGBBorderColor)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + + ViewContactOfInnerPageBorder::ViewContactOfInnerPageBorder(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfInnerPageBorder::~ViewContactOfInnerPageBorder() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfPageHierarchy::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageHierarchy(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfPageHierarchy::createViewIndependentPrimitive2DSequence() const + { + // collect sub-hierarchy + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const sal_uInt32 nObjectCount(GetObjectCount()); + + // collect all sub-primitives + for(sal_uInt32 a(0); a < nObjectCount; a++) + { + const ViewContact& rCandidate(GetViewContact(a)); + const drawinglayer::primitive2d::Primitive2DSequence aCandSeq(rCandidate.getViewIndependentPrimitive2DSequence()); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, aCandSeq); + } + + return xRetval; + } + + ViewContactOfPageHierarchy::ViewContactOfPageHierarchy(ViewContactOfSdrPage& rParentViewContactOfSdrPage) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage) + { + } + + ViewContactOfPageHierarchy::~ViewContactOfPageHierarchy() + { + } + + sal_uInt32 ViewContactOfPageHierarchy::GetObjectCount() const + { + return getPage().GetObjCount(); + } + + ViewContact& ViewContactOfPageHierarchy::GetViewContact(sal_uInt32 nIndex) const + { + SdrObject* pObj = getPage().GetObj(nIndex); + DBG_ASSERT(pObj, "ViewContactOfPageHierarchy::GetViewContact: Corrupt SdrObjList (!)"); + return pObj->GetViewContact(); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfGrid::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageGrid(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGrid::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information and thus no grid settings. Create empty + // default. For the view-dependent implementation, see ViewObjectContactOfPageGrid::createPrimitive2DSequence + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + ViewContactOfGrid::ViewContactOfGrid(ViewContactOfSdrPage& rParentViewContactOfSdrPage, bool bFront) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage), + mbFront(bFront) + { + } + + ViewContactOfGrid::~ViewContactOfGrid() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact& ViewContactOfHelplines::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfPageHelplines(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfHelplines::createViewIndependentPrimitive2DSequence() const + { + // We have only the page information, not the view information and thus no helplines. Create empty + // default. For the view-dependent implementation, see ViewObjectContactOfPageHelplines::createPrimitive2DSequence + return drawinglayer::primitive2d::Primitive2DSequence(); + } + + ViewContactOfHelplines::ViewContactOfHelplines(ViewContactOfSdrPage& rParentViewContactOfSdrPage, bool bFront) + : ViewContactOfPageSubObject(rParentViewContactOfSdrPage), + mbFront(bFront) + { + } + + ViewContactOfHelplines::~ViewContactOfHelplines() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Create a Object-Specific ViewObjectContact, set ViewContact and + // ObjectContact. Always needs to return something. + ViewObjectContact& ViewContactOfSdrPage::CreateObjectSpecificViewObjectContact(ObjectContact& rObjectContact) + { + ViewObjectContact* pRetval = new ViewObjectContactOfSdrPage(rObjectContact, *this); + DBG_ASSERT(pRetval, "ViewContact::CreateObjectSpecificViewObjectContact() failed (!)"); + + return *pRetval; + } + + ViewContactOfSdrPage::ViewContactOfSdrPage(SdrPage& rPage) + : ViewContact(), + mrPage(rPage), + maViewContactOfPageBackground(*this), + maViewContactOfPageShadow(*this), + maViewContactOfPageFill(*this), + maViewContactOfMasterPage(*this), + maViewContactOfOuterPageBorder(*this), + maViewContactOfInnerPageBorder(*this), + maViewContactOfGridBack(*this, false), + maViewContactOfHelplinesBack(*this, false), + maViewContactOfPageHierarchy(*this), + maViewContactOfGridFront(*this, true), + maViewContactOfHelplinesFront(*this, true) + { + } + + ViewContactOfSdrPage::~ViewContactOfSdrPage() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfSdrPage::GetObjectCount() const + { + // Fixed count of content. It contains PageBackground (Wiese), PageShadow, PageFill, + // then - depending on if the page has a MasterPage - either MasterPage Hierarchy + // or MPBGO. Also OuterPageBorder, InnerPageBorder and two pairs of Grid and Helplines + // (for front and back) which internally are visible or not depending on the current + // front/back setting for those. + return 11; + } + + ViewContact& ViewContactOfSdrPage::GetViewContact(sal_uInt32 nIndex) const + { + switch(nIndex) + { + case 0: return (ViewContact&)maViewContactOfPageBackground; + case 1: return (ViewContact&)maViewContactOfPageShadow; + case 2: return (ViewContact&)maViewContactOfPageFill; + case 3: + { + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + return rPage.TRG_GetMasterPageDescriptorViewContact(); + } + else + { + return (ViewContact&)maViewContactOfMasterPage; + } + } + case 4: return (ViewContact&)maViewContactOfOuterPageBorder; + case 5: return (ViewContact&)maViewContactOfInnerPageBorder; + case 6: return (ViewContact&)maViewContactOfGridBack; + case 7: return (ViewContact&)maViewContactOfHelplinesBack; + case 8: return (ViewContact&)maViewContactOfPageHierarchy; + case 9: return (ViewContact&)maViewContactOfGridFront; + default: return (ViewContact&)maViewContactOfHelplinesFront; + } + } + + // React on changes of the object of this ViewContact + void ViewContactOfSdrPage::ActionChanged() + { + // call parent + ViewContact::ActionChanged(); + + // apply to local viewContacts, they all rely on page information. Exception + // is the sub hierarchy; this will not be influenced by the change + maViewContactOfPageBackground.ActionChanged(); + maViewContactOfPageShadow.ActionChanged(); + maViewContactOfPageFill.ActionChanged(); + + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + rPage.TRG_GetMasterPageDescriptorViewContact().ActionChanged(); + } + else if(rPage.IsMasterPage()) + { + maViewContactOfMasterPage.ActionChanged(); + } + + maViewContactOfOuterPageBorder.ActionChanged(); + maViewContactOfInnerPageBorder.ActionChanged(); + maViewContactOfGridBack.ActionChanged(); + maViewContactOfHelplinesBack.ActionChanged(); + maViewContactOfGridFront.ActionChanged(); + maViewContactOfHelplinesFront.ActionChanged(); + } + + // overload for acessing the SdrPage + SdrPage* ViewContactOfSdrPage::TryToGetSdrPage() const + { + return &GetSdrPage(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPage::createViewIndependentPrimitive2DSequence() const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // collect all sub-sequences including sub hierarchy. + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageBackground.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageShadow.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageFill.getViewIndependentPrimitive2DSequence()); + + const SdrPage& rPage = GetSdrPage(); + + if(rPage.TRG_HasMasterPage()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + rPage.TRG_GetMasterPageDescriptorViewContact().getViewIndependentPrimitive2DSequence()); + } + else if(rPage.IsMasterPage()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, + maViewContactOfMasterPage.getViewIndependentPrimitive2DSequence()); + } + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfOuterPageBorder.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfInnerPageBorder.getViewIndependentPrimitive2DSequence()); + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfPageHierarchy.getViewIndependentPrimitive2DSequence()); + + // Only add front versions of grid and helplines since no visibility test is done, + // so adding the back incarnations is not necessary. This makes the Front + // visualisation the default when no visibility tests are done. + // + // Since we have no view here, no grid and helpline definitions are available currently. The used + // methods at ViewContactOfHelplines and ViewContactOfGrid return only empty sequences and + // do not need to be called ATM. This may change later if grid or helpline info gets + // model data (it should not). Keeping the lines commented to hold this hint. + // + // drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfGridFront.getViewIndependentPrimitive2DSequence()); + // drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, maViewContactOfHelplinesFront.getViewIndependentPrimitive2DSequence()); + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx new file mode 100644 index 000000000000..bc4c500ff155 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrpathobj.cxx @@ -0,0 +1,145 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrpathobj.hxx> +#include <svx/svdopath.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <basegfx/polygon/b2dpolypolygontools.hxx> +#include <svx/sdr/primitive2d/sdrpathprimitive2d.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrPathObj::ViewContactOfSdrPathObj(SdrPathObj& rPathObj) + : ViewContactOfTextObj(rPathObj) + { + } + + ViewContactOfSdrPathObj::~ViewContactOfSdrPathObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrPathObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetPathObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetPathObj().getText(0))); + basegfx::B2DPolyPolygon aUnitPolyPolygon(GetPathObj().GetPathPoly()); + sal_uInt32 nPolyCount(aUnitPolyPolygon.count()); + sal_uInt32 nPointCount(0); + + for(sal_uInt32 a(0); a < nPolyCount; a++) + { + nPointCount += aUnitPolyPolygon.getB2DPolygon(a).count(); + } + + if(!nPointCount) + { + OSL_ENSURE(false, "PolyPolygon object without geometry detected, this should not be created (!)"); + basegfx::B2DPolygon aFallbackLine; + aFallbackLine.append(basegfx::B2DPoint(0.0, 0.0)); + aFallbackLine.append(basegfx::B2DPoint(1000.0, 1000.0)); + aUnitPolyPolygon = basegfx::B2DPolyPolygon(aFallbackLine); + + nPolyCount = 1; + } + + // prepare object transformation and unit polygon (direct model data) + basegfx::B2DHomMatrix aObjectMatrix; + const bool bIsLine( + !aUnitPolyPolygon.areControlPointsUsed() + && 1 == nPolyCount + && 2 == aUnitPolyPolygon.getB2DPolygon(0).count()); + + if(bIsLine) + { + // special handling for single line mode (2 points) + const basegfx::B2DPolygon aSubPolygon(aUnitPolyPolygon.getB2DPolygon(0)); + const basegfx::B2DPoint aStart(aSubPolygon.getB2DPoint(0)); + const basegfx::B2DPoint aEnd(aSubPolygon.getB2DPoint(1)); + const basegfx::B2DVector aLine(aEnd - aStart); + + // #i102548# create new unit polygon for line (horizontal) + basegfx::B2DPolygon aNewPolygon; + aNewPolygon.append(basegfx::B2DPoint(0.0, 0.0)); + aNewPolygon.append(basegfx::B2DPoint(1.0, 0.0)); + aUnitPolyPolygon.setB2DPolygon(0, aNewPolygon); + + // #i102548# fill objectMatrix with rotation and offset (no shear for lines) + aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aLine.getLength(), 1.0, + 0.0, + atan2(aLine.getY(), aLine.getX()), + aStart.getX(), aStart.getY()); + } + else + { + // #i102548# create unscaled, unsheared, unrotated and untranslated polygon + // (unit polygon) by creating the object matrix and back-transforming the polygon + const basegfx::B2DRange aObjectRange(basegfx::tools::getRange(aUnitPolyPolygon)); + const GeoStat& rGeoStat(GetPathObj().GetGeoStat()); + const double fWidth(aObjectRange.getWidth()); + const double fHeight(aObjectRange.getHeight()); + const double fScaleX(basegfx::fTools::equalZero(fWidth) ? 1.0 : fWidth); + const double fScaleY(basegfx::fTools::equalZero(fHeight) ? 1.0 : fHeight); + + aObjectMatrix = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + fScaleX, fScaleY, + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY()); + + // ceate unit polygon from object's absolute path + basegfx::B2DHomMatrix aInverse(aObjectMatrix); + aInverse.invert(); + aUnitPolyPolygon.transform(aInverse); + } + + // create primitive. Always create primitives to allow the decomposition of + // SdrPathPrimitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrPathPrimitive2D( + aObjectMatrix, + aAttribute, + aUnitPolyPolygon)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx new file mode 100644 index 000000000000..fdbfa16dd584 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofsdrrectobj.cxx @@ -0,0 +1,104 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofsdrrectobj.hxx> +#include <svx/svdorect.hxx> +#include <svx/sdr/primitive2d/sdrattributecreator.hxx> +#include <svx/sdr/primitive2d/sdrrectangleprimitive2d.hxx> +#include <svl/itemset.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> +#include <basegfx/matrix/b2dhommatrixtools.hxx> +#include <svx/svdmodel.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfSdrRectObj::ViewContactOfSdrRectObj(SdrRectObj& rRectObj) + : ViewContactOfTextObj(rRectObj) + { + } + + ViewContactOfSdrRectObj::~ViewContactOfSdrRectObj() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfSdrRectObj::createViewIndependentPrimitive2DSequence() const + { + const SfxItemSet& rItemSet = GetRectObj().GetMergedItemSet(); + const drawinglayer::attribute::SdrLineFillShadowTextAttribute aAttribute( + drawinglayer::primitive2d::createNewSdrLineFillShadowTextAttribute( + rItemSet, + GetRectObj().getText(0))); + + // take unrotated snap rect (direct model data) for position and size + const Rectangle& rRectangle = GetRectObj().GetGeoRect(); + const ::basegfx::B2DRange aObjectRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + const GeoStat& rGeoStat(GetRectObj().GetGeoStat()); + + // fill object matrix + basegfx::B2DHomMatrix aObjectMatrix(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix( + aObjectRange.getWidth(), aObjectRange.getHeight(), + rGeoStat.nShearWink ? tan((36000 - rGeoStat.nShearWink) * F_PI18000) : 0.0, + rGeoStat.nDrehWink ? (36000 - rGeoStat.nDrehWink) * F_PI18000 : 0.0, + aObjectRange.getMinX(), aObjectRange.getMinY())); + + // calculate corner radius + sal_uInt32 nCornerRadius(((SdrEckenradiusItem&)(rItemSet.Get(SDRATTR_ECKENRADIUS))).GetValue()); + double fCornerRadiusX; + double fCornerRadiusY; + drawinglayer::primitive2d::calculateRelativeCornerRadius(nCornerRadius, aObjectRange, fCornerRadiusX, fCornerRadiusY); + + // #i105856# use knowledge about pickthrough from the model + const bool bPickThroughTransparentTextFrames( + GetRectObj().GetModel() && GetRectObj().GetModel()->IsPickThroughTransparentTextFrames()); + + // create primitive. Always create primitives to allow the decomposition of + // SdrRectanglePrimitive2D to create needed invisible elements for HitTest and/or BoundRect + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::SdrRectanglePrimitive2D( + aObjectMatrix, + aAttribute, + fCornerRadiusX, + fCornerRadiusY, + // #i105856# use fill for HitTest when TextFrame and not PickThrough + GetRectObj().IsTextFrame() && !bPickThroughTransparentTextFrames)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactoftextobj.cxx b/svx/source/sdr/contact/viewcontactoftextobj.cxx new file mode 100644 index 000000000000..bfa7aa41565c --- /dev/null +++ b/svx/source/sdr/contact/viewcontactoftextobj.cxx @@ -0,0 +1,51 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactoftextobj.hxx> +#include <svx/svdotext.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewContactOfTextObj::ViewContactOfTextObj(SdrTextObj& rTextObj) + : ViewContactOfSdrObj(rTextObj) + { + } + + ViewContactOfTextObj::~ViewContactOfTextObj() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewcontactofunocontrol.cxx b/svx/source/sdr/contact/viewcontactofunocontrol.cxx new file mode 100644 index 000000000000..2a4d527fdcdd --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofunocontrol.cxx @@ -0,0 +1,181 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewcontactofunocontrol.hxx> +#include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdrpagewindow.hxx> + +/** === begin UNO includes === **/ +#include <com/sun/star/awt/XWindow2.hpp> +/** === end UNO includes === **/ + +#include "sdrpaintwindow.hxx" +#include <tools/diagnose_ex.h> +#include <vcl/pdfextoutdevdata.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/controlprimitive2d.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +//........................................................................ +namespace sdr { namespace contact { +//........................................................................ + + /** === begin UNO using === **/ + using ::com::sun::star::awt::XControl; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::awt::XControlContainer; + using ::com::sun::star::awt::XControlModel; + using ::com::sun::star::awt::XWindow2; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::Exception; + /** === end UNO using === **/ + + //==================================================================== + //= ViewContactOfUnoControl + //==================================================================== + class ViewContactOfUnoControl_Impl + { + public: + ViewContactOfUnoControl_Impl(); + ~ViewContactOfUnoControl_Impl(); + + private: + ViewContactOfUnoControl_Impl( const ViewContactOfUnoControl_Impl& ); // never implemented + ViewContactOfUnoControl_Impl& operator=( const ViewContactOfUnoControl_Impl& ); // never implemented + }; + + //-------------------------------------------------------------------- + ViewContactOfUnoControl_Impl::ViewContactOfUnoControl_Impl() + { + } + + //-------------------------------------------------------------------- + ViewContactOfUnoControl_Impl::~ViewContactOfUnoControl_Impl() + { + } + + //==================================================================== + //= ViewContactOfUnoControl + //==================================================================== + DBG_NAME( ViewContactOfUnoControl ) + //-------------------------------------------------------------------- + ViewContactOfUnoControl::ViewContactOfUnoControl( SdrUnoObj& _rUnoObject ) + :ViewContactOfSdrObj( _rUnoObject ) + ,m_pImpl( new ViewContactOfUnoControl_Impl ) + { + DBG_CTOR( ViewContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + ViewContactOfUnoControl::~ViewContactOfUnoControl() + { + DBG_DTOR( ViewContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewContactOfUnoControl::getTemporaryControlForWindow( + const Window& _rWindow, Reference< XControlContainer >& _inout_ControlContainer ) const + { + SdrUnoObj* pUnoObject = dynamic_cast< SdrUnoObj* >( TryToGetSdrObject() ); + OSL_ENSURE( pUnoObject, "ViewContactOfUnoControl::getTemporaryControlForDevice: no SdrUnoObj!" ); + if ( !pUnoObject ) + return NULL; + return ViewObjectContactOfUnoControl::getTemporaryControlForWindow( _rWindow, _inout_ControlContainer, *pUnoObject ); + } + + //-------------------------------------------------------------------- + ViewObjectContact& ViewContactOfUnoControl::CreateObjectSpecificViewObjectContact( ObjectContact& _rObjectContact ) + { + // print or print preview requires special handling + const OutputDevice* pDevice = _rObjectContact.TryToGetOutputDevice(); + bool bPrintOrPreview = ( pDevice != NULL ) && ( pDevice->GetOutDevType() == OUTDEV_PRINTER ); + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &_rObjectContact ); + bPrintOrPreview |= ( pPageViewContact != NULL ) && pPageViewContact->GetPageWindow().GetPageView().GetView().IsPrintPreview(); + + if ( bPrintOrPreview ) + return *new UnoControlPrintOrPreviewContact( *pPageViewContact, *this ); + + // all others are nowadays served by the same implementation + return *new ViewObjectContactOfUnoControl( _rObjectContact, *this ); + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfUnoControl::createViewIndependentPrimitive2DSequence() const + { + // create range. Use model data directly, not getBoundRect()/getSnapRect; these will use + // the primitive data themselves in the long run. Use SdrUnoObj's (which is a SdrRectObj) + // call to GetGeoRect() to access SdrTextObj::aRect directly and without executing anything + const Rectangle& rRectangle(GetSdrUnoObj().GetGeoRect()); + const basegfx::B2DRange aRange( + rRectangle.Left(), rRectangle.Top(), + rRectangle.Right(), rRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aTransform; + + aTransform.set(0, 0, aRange.getWidth()); + aTransform.set(1, 1, aRange.getHeight()); + aTransform.set(0, 2, aRange.getMinX()); + aTransform.set(1, 2, aRange.getMinY()); + + Reference< XControlModel > xControlModel = GetSdrUnoObj().GetUnoControlModel(); + + if(xControlModel.is()) + { + // create control primitive WITHOUT possibly existing XControl; this would be done in + // the VOC in createPrimitive2DSequence() + const drawinglayer::primitive2d::Primitive2DReference xRetval( + new drawinglayer::primitive2d::ControlPrimitive2D( + aTransform, + xControlModel)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + else + { + // always append an invisible outline for the cases where no visible content exists + const drawinglayer::primitive2d::Primitive2DReference xRetval( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aTransform)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + } + +//........................................................................ +} } // namespace sdr::contact +//........................................................................ diff --git a/svx/source/sdr/contact/viewcontactofvirtobj.cxx b/svx/source/sdr/contact/viewcontactofvirtobj.cxx new file mode 100644 index 000000000000..54d7e6ddae97 --- /dev/null +++ b/svx/source/sdr/contact/viewcontactofvirtobj.cxx @@ -0,0 +1,116 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewcontactofvirtobj.hxx> +#include <svx/svdovirt.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/transformprimitive2d.hxx> +#include <vcl/outdev.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + SdrVirtObj& ViewContactOfVirtObj::GetVirtObj() const + { + return (SdrVirtObj&)mrObject; + } + + ViewContactOfVirtObj::ViewContactOfVirtObj(SdrVirtObj& rObj) + : ViewContactOfSdrObj(rObj) + { + } + + ViewContactOfVirtObj::~ViewContactOfVirtObj() + { + } + + // Access to possible sub-hierarchy + sal_uInt32 ViewContactOfVirtObj::GetObjectCount() const + { + // Here, SdrVirtObj's need to return 0L to show that they have no + // sub-hierarchy, even when they are group objects. This is necessary + // to avoid that the same VOCs will be added to the draw hierarchy + // twice which leads to problems. + // + // This solution is only a first solution to get things running. Later + // this needs to be replaced with creating real VOCs for the objects + // referenced by virtual objects to avoid the 'trick' of setting the + // offset for painting at the destination OutputDevive. + // + // As can be seen, with primitives, the problem will be solved using + // a transformPrimitive, so this solution can stay with primitives. + return 0L; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewContactOfVirtObj::createViewIndependentPrimitive2DSequence() const + { + // create displacement transformation if we have content + basegfx::B2DHomMatrix aObjectMatrix; + Point aAnchor(GetVirtObj().GetAnchorPos()); + + if(aAnchor.X() || aAnchor.Y()) + { + aObjectMatrix.set(0, 2, aAnchor.X()); + aObjectMatrix.set(1, 2, aAnchor.Y()); + } + + // use method from referenced object to get the Primitive2DSequence + const drawinglayer::primitive2d::Primitive2DSequence xSequenceVirtual( + GetVirtObj().GetReferencedObj().GetViewContact().getViewIndependentPrimitive2DSequence()); + + if(xSequenceVirtual.hasElements()) + { + // create transform primitive + const drawinglayer::primitive2d::Primitive2DReference xReference( + new drawinglayer::primitive2d::TransformPrimitive2D( + aObjectMatrix, + xSequenceVirtual)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + else + { + // always append an invisible outline for the cases where no visible content exists + const drawinglayer::primitive2d::Primitive2DReference xReference( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, aObjectMatrix)); + + return drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontact.cxx b/svx/source/sdr/contact/viewobjectcontact.cxx new file mode 100644 index 000000000000..73e4c12e5066 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontact.cxx @@ -0,0 +1,438 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <vcl/region.hxx> +#include <svx/sdr/animation/objectanimator.hxx> +#include <svx/sdr/animation/animationstate.hxx> +#include <svx/sdr/contact/viewobjectcontactredirector.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <drawinglayer/primitive2d/animatedprimitive2d.hxx> +#include <drawinglayer/processor2d/baseprocessor2d.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/sdr/contact/viewobjectcontactredirector.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // animated extractor + + // Necessary to filter a sequence of animated primitives from + // a sequence of primitives to find out if animated or not. The decision for + // what to decompose is hard-coded and only done for knowingly animated primitives + // to not decompose too deeply and unnecessarily. This implies that the list + // which is view-specific needs to be expanded by hand when new animated objects + // are added. This may eventually be changed to a dynamically configurable approach + // if necessary. + class AnimatedExtractingProcessor2D : public drawinglayer::processor2d::BaseProcessor2D + { + protected: + // the found animated primitives + drawinglayer::primitive2d::Primitive2DSequence maPrimitive2DSequence; + + // bitfield + // text animation allowed? + unsigned mbTextAnimationAllowed : 1; + + // graphic animation allowed? + unsigned mbGraphicAnimationAllowed : 1; + + // as tooling, the process() implementation takes over API handling and calls this + // virtual render method when the primitive implementation is BasePrimitive2D-based. + virtual void processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate); + + public: + AnimatedExtractingProcessor2D( + const drawinglayer::geometry::ViewInformation2D& rViewInformation, + bool bTextAnimationAllowed, + bool bGraphicAnimationAllowed); + virtual ~AnimatedExtractingProcessor2D(); + + // data access + const drawinglayer::primitive2d::Primitive2DSequence& getPrimitive2DSequence() const { return maPrimitive2DSequence; } + bool isTextAnimationAllowed() const { return mbTextAnimationAllowed; } + bool isGraphicAnimationAllowed() const { return mbGraphicAnimationAllowed; } + }; + + AnimatedExtractingProcessor2D::AnimatedExtractingProcessor2D( + const drawinglayer::geometry::ViewInformation2D& rViewInformation, + bool bTextAnimationAllowed, + bool bGraphicAnimationAllowed) + : drawinglayer::processor2d::BaseProcessor2D(rViewInformation), + maPrimitive2DSequence(), + mbTextAnimationAllowed(bTextAnimationAllowed), + mbGraphicAnimationAllowed(bGraphicAnimationAllowed) + { + } + + AnimatedExtractingProcessor2D::~AnimatedExtractingProcessor2D() + { + } + + void AnimatedExtractingProcessor2D::processBasePrimitive2D(const drawinglayer::primitive2d::BasePrimitive2D& rCandidate) + { + // known implementation, access directly + switch(rCandidate.getPrimitive2DID()) + { + // add and accept animated primitives directly, no need to decompose + case PRIMITIVE2D_ID_ANIMATEDSWITCHPRIMITIVE2D : + case PRIMITIVE2D_ID_ANIMATEDBLINKPRIMITIVE2D : + case PRIMITIVE2D_ID_ANIMATEDINTERPOLATEPRIMITIVE2D : + { + const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& rSwitchPrimitive = static_cast< const drawinglayer::primitive2d::AnimatedSwitchPrimitive2D& >(rCandidate); + + if((rSwitchPrimitive.isTextAnimation() && isTextAnimationAllowed()) + || (rSwitchPrimitive.isGraphicAnimation() && isGraphicAnimationAllowed())) + { + const drawinglayer::primitive2d::Primitive2DReference xReference(const_cast< drawinglayer::primitive2d::BasePrimitive2D* >(&rCandidate)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(maPrimitive2DSequence, xReference); + } + break; + } + + // decompose animated gifs where SdrGrafPrimitive2D produces a GraphicPrimitive2D + // which then produces the animation infos (all when used/needed) + case PRIMITIVE2D_ID_SDRGRAFPRIMITIVE2D : + case PRIMITIVE2D_ID_GRAPHICPRIMITIVE2D : + + // decompose SdrObjects with evtl. animated text + case PRIMITIVE2D_ID_SDRCAPTIONPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRCONNECTORPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRCUSTOMSHAPEPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRELLIPSEPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRELLIPSESEGMENTPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRMEASUREPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRPATHPRIMITIVE2D : + case PRIMITIVE2D_ID_SDRRECTANGLEPRIMITIVE2D : + + // decompose evtl. animated text contained in MaskPrimitive2D + // or group rimitives + case PRIMITIVE2D_ID_MASKPRIMITIVE2D : + case PRIMITIVE2D_ID_GROUPPRIMITIVE2D : + { + process(rCandidate.get2DDecomposition(getViewInformation2D())); + break; + } + + default : + { + // nothing to do for the rest + break; + } + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContact::ViewObjectContact(ObjectContact& rObjectContact, ViewContact& rViewContact) + : mrObjectContact(rObjectContact), + mrViewContact(rViewContact), + maObjectRange(), + mxPrimitive2DSequence(), + mpPrimitiveAnimation(0), + mbLazyInvalidate(false) + { + // make the ViewContact remember me + mrViewContact.AddViewObjectContact(*this); + + // make the ObjectContact remember me + mrObjectContact.AddViewObjectContact(*this); + } + + ViewObjectContact::~ViewObjectContact() + { + // invalidate in view + if(!maObjectRange.isEmpty()) + { + GetObjectContact().InvalidatePartOfView(maObjectRange); + } + + // delete PrimitiveAnimation + if(mpPrimitiveAnimation) + { + delete mpPrimitiveAnimation; + mpPrimitiveAnimation = 0; + } + + // take care of remebered ObjectContact. Remove from + // OC first. The VC removal (below) CAN trigger a StopGettingViewed() + // which (depending of it's implementation) may destroy other OCs. This + // can trigger the deletion of the helper OC of a page visualising object + // which IS the OC of this object. Eventually StopGettingViewed() needs + // to get asynchron later + GetObjectContact().RemoveViewObjectContact(*this); + + // take care of remebered ViewContact + GetViewContact().RemoveViewObjectContact(*this); + } + + const basegfx::B2DRange& ViewObjectContact::getObjectRange() const + { + if(maObjectRange.isEmpty()) + { + // if range is not computed (new or LazyInvalidate objects), force it + const DisplayInfo aDisplayInfo; + const drawinglayer::primitive2d::Primitive2DSequence xSequence(getPrimitive2DSequence(aDisplayInfo)); + + if(xSequence.hasElements()) + { + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const_cast< ViewObjectContact* >(this)->maObjectRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xSequence, rViewInformation2D); + } + } + + return maObjectRange; + } + + void ViewObjectContact::ActionChanged() + { + if(!mbLazyInvalidate) + { + // set local flag + mbLazyInvalidate = true; + + // force ObjectRange + getObjectRange(); + + if(!maObjectRange.isEmpty()) + { + // invalidate current valid range + GetObjectContact().InvalidatePartOfView(maObjectRange); + + // reset ObjectRange, it needs to be recalculated + maObjectRange.reset(); + } + + // register at OC for lazy invalidate + GetObjectContact().setLazyInvalidate(*this); + } + } + + void ViewObjectContact::triggerLazyInvalidate() + { + if(mbLazyInvalidate) + { + // reset flag + mbLazyInvalidate = false; + + // force ObjectRange + getObjectRange(); + + if(!maObjectRange.isEmpty()) + { + // invalidate current valid range + GetObjectContact().InvalidatePartOfView(maObjectRange); + } + } + } + + // Take some action when new objects are inserted + void ViewObjectContact::ActionChildInserted(ViewContact& rChild) + { + // force creation of the new VOC and trigger it's refresh, so it + // will take part in LazyInvalidate immediately + rChild.GetViewObjectContact(GetObjectContact()).ActionChanged(); + + // forward action to ObjectContact + // const ViewObjectContact& rChildVOC = rChild.GetViewObjectContact(GetObjectContact()); + // GetObjectContact().InvalidatePartOfView(rChildVOC.getObjectRange()); + } + + void ViewObjectContact::checkForPrimitive2DAnimations() + { + // remove old one + if(mpPrimitiveAnimation) + { + delete mpPrimitiveAnimation; + mpPrimitiveAnimation = 0; + } + + // check for animated primitives + if(mxPrimitive2DSequence.hasElements()) + { + const bool bTextAnimationAllowed(GetObjectContact().IsTextAnimationAllowed()); + const bool bGraphicAnimationAllowed(GetObjectContact().IsGraphicAnimationAllowed()); + + if(bTextAnimationAllowed || bGraphicAnimationAllowed) + { + AnimatedExtractingProcessor2D aAnimatedExtractor(GetObjectContact().getViewInformation2D(), + bTextAnimationAllowed, bGraphicAnimationAllowed); + aAnimatedExtractor.process(mxPrimitive2DSequence); + + if(aAnimatedExtractor.getPrimitive2DSequence().hasElements()) + { + // dervied primitiveList is animated, setup new PrimitiveAnimation + mpPrimitiveAnimation = new sdr::animation::PrimitiveAnimation(*this, aAnimatedExtractor.getPrimitive2DSequence()); + } + } + } + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // get the view-independent Primitive from the viewContact + drawinglayer::primitive2d::Primitive2DSequence xRetval(GetViewContact().getViewIndependentPrimitive2DSequence()); + + if(xRetval.hasElements()) + { + // handle GluePoint + if(!GetObjectContact().isOutputToPrinter() && GetObjectContact().AreGluePointsVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence xGlue(GetViewContact().createGluePointPrimitive2DSequence()); + + if(xGlue.hasElements()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xGlue); + } + } + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ModifiedColorPrimitive2D(xRetval, aBColorModifier)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xNewPrimitiveSequence; + + // take care of redirectors and create new list + ViewObjectContactRedirector* pRedirector = GetObjectContact().GetViewObjectContactRedirector(); + + if(pRedirector) + { + xNewPrimitiveSequence = pRedirector->createRedirectedPrimitive2DSequence(*this, rDisplayInfo); + } + else + { + xNewPrimitiveSequence = createPrimitive2DSequence(rDisplayInfo); + } + + // local up-to-date checks. New list different from local one? + if(!drawinglayer::primitive2d::arePrimitive2DSequencesEqual(mxPrimitive2DSequence, xNewPrimitiveSequence)) + { + // has changed, copy content + const_cast< ViewObjectContact* >(this)->mxPrimitive2DSequence = xNewPrimitiveSequence; + + // check for animated stuff + const_cast< ViewObjectContact* >(this)->checkForPrimitive2DAnimations(); + + // always update object range when PrimitiveSequence changes + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const_cast< ViewObjectContact* >(this)->maObjectRange = + drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(mxPrimitive2DSequence, rViewInformation2D); + } + + // return current Primitive2DSequence + return mxPrimitive2DSequence; + } + + bool ViewObjectContact::isPrimitiveVisible(const DisplayInfo& /*rDisplayInfo*/) const + { + // default: always visible + return true; + } + + bool ViewObjectContact::isPrimitiveGhosted(const DisplayInfo& rDisplayInfo) const + { + // default: standard check + return (GetObjectContact().DoVisualizeEnteredGroup() && !GetObjectContact().isOutputToPrinter() && rDisplayInfo.IsGhostedDrawModeActive()); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // check model-view visibility + if(isPrimitiveVisible(rDisplayInfo)) + { + xRetval = getPrimitive2DSequence(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContact::getPrimitive2DSequenceSubHierarchy(DisplayInfo& rDisplayInfo) const + { + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + drawinglayer::primitive2d::Primitive2DSequence xSeqRetval; + + for(sal_uInt32 a(0); a < nSubHierarchyCount; a++) + { + const ViewObjectContact& rCandidate(GetViewContact().GetViewContact(a).GetViewObjectContact(GetObjectContact())); + + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xSeqRetval, rCandidate.getPrimitive2DSequenceHierarchy(rDisplayInfo)); + } + + return xSeqRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofe3d.cxx b/svx/source/sdr/contact/viewobjectcontactofe3d.cxx new file mode 100644 index 000000000000..ec8cdb4ef5ba --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofe3d.cxx @@ -0,0 +1,101 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofe3d.hxx> +#include <svx/sdr/contact/viewcontactofe3d.hxx> +#include <basegfx/color/bcolor.hxx> +#include <drawinglayer/primitive3d/modifiedcolorprimitive3d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx> +#include <drawinglayer/primitive2d/embedded3dprimitive2d.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> + +////////////////////////////////////////////////////////////////////////////// +// predeclarations + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfE3d::ViewObjectContactOfE3d(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfE3d::~ViewObjectContactOfE3d() + { + } + + drawinglayer::primitive3d::Primitive3DSequence ViewObjectContactOfE3d::createPrimitive3DSequence(const DisplayInfo& rDisplayInfo) const + { + // get the view-independent Primitive from the viewContact + const ViewContactOfE3d& rViewContactOfE3d(dynamic_cast< const ViewContactOfE3d& >(GetViewContact())); + drawinglayer::primitive3d::Primitive3DSequence xRetval(rViewContactOfE3d.getViewIndependentPrimitive3DSequence()); + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const ::basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const ::basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, ::basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive3d::Primitive3DReference xReference(new drawinglayer::primitive3d::ModifiedColorPrimitive3D(xRetval, aBColorModifier)); + xRetval = drawinglayer::primitive3d::Primitive3DSequence(&xReference, 1); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3d::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + const ViewContactOfE3d& rViewContact = static_cast< const ViewContactOfE3d& >(GetViewContact()); + + // get 3d primitive vector, isPrimitiveVisible() is done in 3d creator + return rViewContact.impCreateWithGivenPrimitive3DSequence(getPrimitive3DSequence(rDisplayInfo)); + } + + drawinglayer::primitive3d::Primitive3DSequence ViewObjectContactOfE3d::getPrimitive3DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive3d::Primitive3DSequence xNewPrimitive3DSeq(createPrimitive3DSequence(rDisplayInfo)); + + // local up-to-date checks. New list different from local one? + if(!drawinglayer::primitive3d::arePrimitive3DSequencesEqual(mxPrimitive3DSequence, xNewPrimitive3DSeq)) + { + // has changed, copy content + const_cast< ViewObjectContactOfE3d* >(this)->mxPrimitive3DSequence = xNewPrimitive3DSeq; + } + + // return current Primitive2DSequence + return mxPrimitive3DSequence; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx b/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx new file mode 100644 index 000000000000..a549b1db1233 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofe3dscene.cxx @@ -0,0 +1,148 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofe3dscene.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/viewcontactofe3dscene.hxx> +#include <basegfx/matrix/b3dhommatrix.hxx> +#include <drawinglayer/primitive3d/transformprimitive3d.hxx> +#include <basegfx/color/bcolormodifier.hxx> +#include <drawinglayer/primitive2d/modifiedcolorprimitive2d.hxx> +#include <svx/sdr/contact/viewobjectcontactofe3d.hxx> +#include <basegfx/tools/canvastools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace +{ + // Helper method to recursively travel the DrawHierarchy for 3D objects contained in + // the 2D Scene. This will chreate all VOCs for the currenbt OC which are needed + // for ActionChanged() functionality + void impInternalSubHierarchyTraveller(const sdr::contact::ViewObjectContact& rVOC) + { + const sdr::contact::ViewContact& rVC = rVOC.GetViewContact(); + const sal_uInt32 nSubHierarchyCount(rVC.GetObjectCount()); + + for(sal_uInt32 a(0); a < nSubHierarchyCount; a++) + { + const sdr::contact::ViewObjectContact& rCandidate(rVC.GetViewContact(a).GetViewObjectContact(rVOC.GetObjectContact())); + impInternalSubHierarchyTraveller(rCandidate); + } + } +} // end of anonymous namespace + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfE3dScene::ViewObjectContactOfE3dScene(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfE3dScene::~ViewObjectContactOfE3dScene() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3dScene::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // handle ghosted, else the whole 3d group will be encapsulated to a ghosted primitive set (see below) + const bool bHandleGhostedDisplay(GetObjectContact().DoVisualizeEnteredGroup() && !GetObjectContact().isOutputToPrinter() && rDisplayInfo.IsGhostedDrawModeActive()); + const bool bIsActiveVC(bHandleGhostedDisplay && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bIsActiveVC) + { + // switch off ghosted, display contents normal + const_cast< DisplayInfo& >(rDisplayInfo).ClearGhostedDrawMode(); + } + + // create 2d primitive with content, use layer visibility test + // this uses no ghosted mode, so scenes in scenes and entering them will not + // support ghosted for now. This is no problem currently but would need to be + // added when sub-groups in 3d will be added one day. + const ViewContactOfE3dScene& rViewContact = dynamic_cast< ViewContactOfE3dScene& >(GetViewContact()); + const SetOfByte& rVisibleLayers = rDisplayInfo.GetProcessLayers(); + drawinglayer::primitive2d::Primitive2DSequence xRetval(rViewContact.createScenePrimitive2DSequence(&rVisibleLayers)); + + if(xRetval.hasElements()) + { + // handle GluePoint + if(!GetObjectContact().isOutputToPrinter() && GetObjectContact().AreGluePointsVisible()) + { + const drawinglayer::primitive2d::Primitive2DSequence xGlue(GetViewContact().createGluePointPrimitive2DSequence()); + + if(xGlue.hasElements()) + { + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xGlue); + } + } + + // handle ghosted + if(isPrimitiveGhosted(rDisplayInfo)) + { + const ::basegfx::BColor aRGBWhite(1.0, 1.0, 1.0); + const ::basegfx::BColorModifier aBColorModifier(aRGBWhite, 0.5, ::basegfx::BCOLORMODIFYMODE_INTERPOLATE); + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ModifiedColorPrimitive2D(xRetval, aBColorModifier)); + + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + } + } + + if(bIsActiveVC) + { + // set back, display ghosted again + const_cast< DisplayInfo& >(rDisplayInfo).SetGhostedDrawMode(); + } + + return xRetval; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfE3dScene::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + // To get the VOCs for the contained 3D objects created to get the correct + // Draw hierarchy and ActionChanged() working properly, travel the DrawHierarchy + // using a local tooling method + impInternalSubHierarchyTraveller(*this); + + // call parent + return ViewObjectContactOfSdrObj::getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx new file mode 100644 index 000000000000..cd2d9670bf7c --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofgraphic.cxx @@ -0,0 +1,327 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofgraphic.hxx> +#include <svx/sdr/contact/viewcontactofgraphic.hxx> +#include <svx/sdr/event/eventhandler.hxx> +#include <svx/svdograf.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdmodel.hxx> +#include <svx/svdpage.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace event + { + class AsynchGraphicLoadingEvent : public BaseEvent + { + // the ViewContactOfGraphic to work with + sdr::contact::ViewObjectContactOfGraphic& mrVOCOfGraphic; + + public: + // basic constructor. + AsynchGraphicLoadingEvent(EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic); + + // destructor + virtual ~AsynchGraphicLoadingEvent(); + + // the called method if the event is triggered + virtual void ExecuteEvent(); + }; + + AsynchGraphicLoadingEvent::AsynchGraphicLoadingEvent( + EventHandler& rEventHandler, sdr::contact::ViewObjectContactOfGraphic& rVOCOfGraphic) + : BaseEvent(rEventHandler), + mrVOCOfGraphic(rVOCOfGraphic) + { + } + + AsynchGraphicLoadingEvent::~AsynchGraphicLoadingEvent() + { + mrVOCOfGraphic.forgetAsynchGraphicLoadingEvent(this); + } + + void AsynchGraphicLoadingEvent::ExecuteEvent() + { + mrVOCOfGraphic.doAsynchGraphicLoading(); + } + } // end of namespace event +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // Test graphics state and eventually trigger a SwapIn event or an Asynchronous + // load event. Return value gives info if SwapIn was triggered or not + bool ViewObjectContactOfGraphic::impPrepareGraphicWithAsynchroniousLoading() + { + bool bRetval(false); + SdrGrafObj& rGrafObj = getSdrGrafObj(); + + if(rGrafObj.IsSwappedOut()) + { + if(rGrafObj.IsLinkedGraphic()) + { + // update graphic link + rGrafObj.ImpUpdateGraphicLink(); + } + else + { + // SwapIn needs to be done. Decide if it can be done asynchronious. + bool bSwapInAsynchronious(false); + ObjectContact& rObjectContact = GetObjectContact(); + + // only when allowed from configuration + if(rObjectContact.IsAsynchronGraphicsLoadingAllowed()) + { + // direct output or vdev output (PageView buffering) + if(rObjectContact.isOutputToWindow() || rObjectContact.isOutputToVirtualDevice()) + { + // only when no metafile recording + if(!rObjectContact.isOutputToRecordingMetaFile()) + { + // allow asynchronious loading + bSwapInAsynchronious = true; + } + } + } + + if(bSwapInAsynchronious) + { + // maybe it's on the way, then do nothing + if(!mpAsynchLoadEvent) + { + // Trigger asynchronious SwapIn. + sdr::event::TimerEventHandler& rEventHandler = rObjectContact.GetEventHandler(); + + mpAsynchLoadEvent = new sdr::event::AsynchGraphicLoadingEvent(rEventHandler, *this); + } + } + else + { + if(rObjectContact.isOutputToPrinter()) + { + // #i76395# preview mechanism is only active if + // swapin is called from inside paint preparation, so mbInsidePaint + // has to be false to be able to print with high resolution + rGrafObj.ForceSwapIn(); + } + else + { + // SwapIn direct + rGrafObj.mbInsidePaint = sal_True; + rGrafObj.ForceSwapIn(); + rGrafObj.mbInsidePaint = sal_False; + } + + bRetval = true; + } + } + } + else + { + // it is not swapped out, somehow it was loaded. In that case, forget + // about an existing triggered event + if(mpAsynchLoadEvent) + { + // just delete it, this will remove it from the EventHandler and + // will trigger forgetAsynchGraphicLoadingEvent from the destructor + delete mpAsynchLoadEvent; + } + } + + return bRetval; + } + + // Test graphics state and eventually trigger a SwapIn event. Return value + // gives info if SwapIn was triggered or not + bool ViewObjectContactOfGraphic::impPrepareGraphicWithSynchroniousLoading() + { + bool bRetval(false); + SdrGrafObj& rGrafObj = getSdrGrafObj(); + + if(rGrafObj.IsSwappedOut()) + { + if(rGrafObj.IsLinkedGraphic()) + { + // update graphic link + rGrafObj.ImpUpdateGraphicLink(); + } + else + { + ObjectContact& rObjectContact = GetObjectContact(); + + if(rObjectContact.isOutputToPrinter()) + { + // #i76395# preview mechanism is only active if + // swapin is called from inside paint preparation, so mbInsidePaint + // has to be false to be able to print with high resolution + rGrafObj.ForceSwapIn(); + } + else + { + // SwapIn direct + rGrafObj.mbInsidePaint = sal_True; + rGrafObj.ForceSwapIn(); + rGrafObj.mbInsidePaint = sal_False; + } + + bRetval = true; + } + } + + return bRetval; + } + + // This is the call from the asynch graphic loading. This may only be called from + // AsynchGraphicLoadingEvent::ExecuteEvent(). Do load the graphics. The event will + // be deleted (consumed) and forgetAsynchGraphicLoadingEvent will be called. + void ViewObjectContactOfGraphic::doAsynchGraphicLoading() + { + DBG_ASSERT(mpAsynchLoadEvent, "ViewObjectContactOfGraphic::doAsynchGraphicLoading: I did not trigger a event, why am i called (?)"); + + // swap it in + SdrGrafObj& rGrafObj = getSdrGrafObj(); + rGrafObj.ForceSwapIn(); + + // #i103720# forget event to avoid possible deletion by the following ActionChanged call + // which may use createPrimitive2DSequence/impPrepareGraphicWithAsynchroniousLoading again. + // Deletion is actally done by the scheduler who leaded to coming here + mpAsynchLoadEvent = 0; + + // Invalidate all paint areas and check existing animation (which may have changed). + GetViewContact().ActionChanged(); + } + + // This is the call from the destructor of the asynch graphic loading event. + // No one else has to call this. It is needed to let this object forget about + // the event. The parameter allows checking for the correct event. + void ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent(sdr::event::AsynchGraphicLoadingEvent* pEvent) + { + (void) pEvent; // suppress warning + + if(mpAsynchLoadEvent) + { + OSL_ENSURE(!pEvent || mpAsynchLoadEvent == pEvent, + "ViewObjectContactOfGraphic::forgetAsynchGraphicLoadingEvent: Forced to forget another event then i have scheduled (?)"); + + // forget event + mpAsynchLoadEvent = 0; + } + } + + SdrGrafObj& ViewObjectContactOfGraphic::getSdrGrafObj() + { + return static_cast< ViewContactOfGraphic& >(GetViewContact()).GetGrafObject(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfGraphic::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + // prepare primitive generation with evtl. loading the graphic when it's swapped out + SdrGrafObj& rGrafObj = const_cast< ViewObjectContactOfGraphic* >(this)->getSdrGrafObj(); + bool bDoAsynchronGraphicLoading(rGrafObj.GetModel() && rGrafObj.GetModel()->IsSwapGraphics()); + static bool bSuppressAsynchLoading(false); + bool bSwapInDone(false); + + if(bDoAsynchronGraphicLoading + && rGrafObj.IsSwappedOut() + && rGrafObj.GetPage() + && rGrafObj.GetPage()->IsMasterPage()) + { + // #i102380# force Swap-In for GraphicObjects on MasterPage to have a nicer visualisation + bDoAsynchronGraphicLoading = false; + } + + if(bDoAsynchronGraphicLoading && !bSuppressAsynchLoading) + { + bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithAsynchroniousLoading(); + } + else + { + bSwapInDone = const_cast< ViewObjectContactOfGraphic* >(this)->impPrepareGraphicWithSynchroniousLoading(); + } + + // get return value by calling parent + drawinglayer::primitive2d::Primitive2DSequence xRetval = ViewObjectContactOfSdrObj::createPrimitive2DSequence(rDisplayInfo); + + if(xRetval.hasElements()) + { + // #i103255# suppress when graphic needs draft visualisation and output + // is for PDF export/Printer + const ViewContactOfGraphic& rVCOfGraphic = static_cast< const ViewContactOfGraphic& >(GetViewContact()); + + if(rVCOfGraphic.visualisationUsesDraft()) + { + const ObjectContact& rObjectContact = GetObjectContact(); + + if(rObjectContact.isOutputToPDFFile() || rObjectContact.isOutputToPrinter()) + { + xRetval = drawinglayer::primitive2d::Primitive2DSequence(); + } + } + } + + // if swap in was forced only for printing, swap out again + const bool bSwapInExclusiveForPrinting(bSwapInDone && GetObjectContact().isOutputToPrinter()); + + if(bSwapInExclusiveForPrinting) + { + rGrafObj.ForceSwapOut(); + } + + return xRetval; + } + + ViewObjectContactOfGraphic::ViewObjectContactOfGraphic(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact), + mpAsynchLoadEvent(0) + { + } + + ViewObjectContactOfGraphic::~ViewObjectContactOfGraphic() + { + // evtl. delete the asynch loading event + if(mpAsynchLoadEvent) + { + // just delete it, this will remove it from the EventHandler and + // will trigger forgetAsynchGraphicLoadingEvent from the destructor + delete mpAsynchLoadEvent; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofgroup.cxx b/svx/source/sdr/contact/viewobjectcontactofgroup.cxx new file mode 100644 index 000000000000..392b8e923212 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofgroup.cxx @@ -0,0 +1,115 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofgroup.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <basegfx/numeric/ftools.hxx> +#include <drawinglayer/primitive2d/groupprimitive2d.hxx> +#include <basegfx/tools/canvastools.hxx> +#include <svx/sdr/contact/viewcontact.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfGroup::ViewObjectContactOfGroup(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfGroup::~ViewObjectContactOfGroup() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfGroup::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // check model-view visibility + if(isPrimitiveVisible(rDisplayInfo)) + { + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + const sal_Bool bDoGhostedDisplaying( + GetObjectContact().DoVisualizeEnteredGroup() + && !GetObjectContact().isOutputToPrinter() + && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bDoGhostedDisplaying) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + + // create object hierarchy + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const ::basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + + if(bDoGhostedDisplaying) + { + rDisplayInfo.SetGhostedDrawMode(); + } + } + else + { + // draw replacement object for group. This will use ViewContactOfGroup::createViewIndependentPrimitive2DSequence + // which creates the replacement primitives for an empty group + xRetval = ViewObjectContactOfSdrObj::getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + } + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx new file mode 100644 index 000000000000..e779cac4151e --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofmasterpagedescriptor.cxx @@ -0,0 +1,153 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/viewcontactofmasterpagedescriptor.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/svdpage.hxx> +#include <drawinglayer/primitive2d/maskprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfMasterPageDescriptor::ViewObjectContactOfMasterPageDescriptor(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfMasterPageDescriptor::~ViewObjectContactOfMasterPageDescriptor() + { + } + + sdr::MasterPageDescriptor& ViewObjectContactOfMasterPageDescriptor::GetMasterPageDescriptor() const + { + return static_cast< ViewContactOfMasterPageDescriptor& >(GetViewContact()).GetMasterPageDescriptor(); + } + + bool ViewObjectContactOfMasterPageDescriptor::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(rDisplayInfo.GetControlLayerProcessingActive()) + { + return false; + } + + if(!rDisplayInfo.GetPageProcessingActive()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfMasterPageDescriptor::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + drawinglayer::primitive2d::Primitive2DSequence xMasterPageSequence; + const sdr::MasterPageDescriptor& rDescriptor = GetMasterPageDescriptor(); + + // used range (retval) is fixed here, it's the MasterPage fill range + const SdrPage& rOwnerPage = rDescriptor.GetOwnerPage(); + const basegfx::B2DRange aPageFillRange( + rOwnerPage.GetLftBorder(), rOwnerPage.GetUppBorder(), + rOwnerPage.GetWdt() - rOwnerPage.GetRgtBorder(), rOwnerPage.GetHgt() - rOwnerPage.GetLwrBorder()); + + // Modify DisplayInfo for MasterPageContent collection; remember original layers and + // set combined LayerSet; set MasterPagePaint flag + const SetOfByte aRememberedLayers(rDisplayInfo.GetProcessLayers()); + SetOfByte aPreprocessedLayers(aRememberedLayers); + aPreprocessedLayers &= rDescriptor.GetVisibleLayers(); + rDisplayInfo.SetProcessLayers(aPreprocessedLayers); + rDisplayInfo.SetSubContentActive(true); + + // check layer visibility (traditionally was member of layer 1) + if(aPreprocessedLayers.IsSet(1)) + { + // hide PageBackground for special DrawModes; historical reasons + if(!GetObjectContact().isDrawModeGray() && !GetObjectContact().isDrawModeHighContrast()) + { + // if visible, create the default background primitive sequence + xRetval = static_cast< ViewContactOfMasterPageDescriptor& >(GetViewContact()).getViewIndependentPrimitive2DSequence(); + } + } + + // hide MasterPage content? Test self here for hierarchy + if(isPrimitiveVisible(rDisplayInfo)) + { + // get the VOC of the Master-SdrPage and get it's object hierarchy + ViewContact& rViewContactOfMasterPage(rDescriptor.GetUsedPage().GetViewContact()); + ViewObjectContact& rVOCOfMasterPage(rViewContactOfMasterPage.GetViewObjectContact(GetObjectContact())); + + xMasterPageSequence = rVOCOfMasterPage.getPrimitive2DSequenceHierarchy(rDisplayInfo); + } + + // reset DisplayInfo changes for MasterPage paint + rDisplayInfo.SetProcessLayers(aRememberedLayers); + rDisplayInfo.SetSubContentActive(false); + + if(xMasterPageSequence.hasElements()) + { + // get range of MasterPage sub hierarchy + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aSubHierarchyRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xMasterPageSequence, rViewInformation2D)); + + if(aPageFillRange.isInside(aSubHierarchyRange)) + { + // completely inside, just render MasterPage content. Add to target + drawinglayer::primitive2d::appendPrimitive2DSequenceToPrimitive2DSequence(xRetval, xMasterPageSequence); + } + else if(aPageFillRange.overlaps(aSubHierarchyRange)) + { + // overlapping, compute common area + basegfx::B2DRange aCommonArea(aPageFillRange); + aCommonArea.intersect(aSubHierarchyRange); + + // need to create a clip primitive, add clipped list to target + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::MaskPrimitive2D( + basegfx::B2DPolyPolygon(basegfx::tools::createPolygonFromRect(aCommonArea)), xMasterPageSequence)); + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + } + } + + // return grouped primitive + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx new file mode 100644 index 000000000000..34731f100b5d --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofpageobj.cxx @@ -0,0 +1,352 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofpageobj.hxx> +#include <svx/sdr/contact/viewcontactofpageobj.hxx> +#include <svx/svdopage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/polygonprimitive2d.hxx> +#include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <svx/svdpage.hxx> +#include <unoapi.hxx> +#include <drawinglayer/primitive2d/pagepreviewprimitive2d.hxx> +#include <drawinglayer/primitive2d/sdrdecompositiontools2d.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + class PagePrimitiveExtractor : public ObjectContactOfPagePainter, public Timer + { + private: + // the ViewObjectContactOfPageObj using this painter + ViewObjectContactOfPageObj& mrViewObjectContactOfPageObj; + + public: + // basic constructor/destructor + PagePrimitiveExtractor(ViewObjectContactOfPageObj& rVOC); + virtual ~PagePrimitiveExtractor(); + + // LazyInvalidate request. Supported here to not automatically + // invalidate the second interaction state all the time at the + // original OC + virtual void setLazyInvalidate(ViewObjectContact& rVOC); + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + virtual void Timeout(); + + // get primitive visualization + drawinglayer::primitive2d::Primitive2DSequence createPrimitive2DSequenceForPage(const DisplayInfo& rDisplayInfo); + + // Own reaction on changes which will be forwarded to the OC of the owner-VOC + virtual void InvalidatePartOfView(const basegfx::B2DRange& rRange) const; + + // forward access to SdrPageView of ViewObjectContactOfPageObj + virtual bool isOutputToPrinter() const; + virtual bool isOutputToWindow() const; + virtual bool isOutputToVirtualDevice() const; + virtual bool isOutputToRecordingMetaFile() const; + virtual bool isOutputToPDFFile() const; + virtual bool isDrawModeGray() const; + virtual bool isDrawModeBlackWhite() const; + virtual bool isDrawModeHighContrast() const; + virtual SdrPageView* TryToGetSdrPageView() const; + virtual OutputDevice* TryToGetOutputDevice() const; + }; + + PagePrimitiveExtractor::PagePrimitiveExtractor( + ViewObjectContactOfPageObj& rVOC) + : ObjectContactOfPagePainter(0, rVOC.GetObjectContact()), + mrViewObjectContactOfPageObj(rVOC) + { + // make this renderer a preview renderer + setPreviewRenderer(true); + + // init timer + SetTimeout(1); + Stop(); + } + + PagePrimitiveExtractor::~PagePrimitiveExtractor() + { + // execute missing LazyInvalidates and stop timer + Timeout(); + } + + void PagePrimitiveExtractor::setLazyInvalidate(ViewObjectContact& /*rVOC*/) + { + // do NOT call parent, but remember that something is to do by + // starting the LazyInvalidateTimer + Start(); + } + + // From baseclass Timer, the timeout call triggered by te LazyInvalidate mechanism + void PagePrimitiveExtractor::Timeout() + { + // stop the timer + Stop(); + + // invalidate all LazyInvalidate VOCs new situations + const sal_uInt32 nVOCCount(getViewObjectContactCount()); + + for(sal_uInt32 a(0); a < nVOCCount; a++) + { + ViewObjectContact* pCandidate = getViewObjectContact(a); + pCandidate->triggerLazyInvalidate(); + } + } + + drawinglayer::primitive2d::Primitive2DSequence PagePrimitiveExtractor::createPrimitive2DSequenceForPage(const DisplayInfo& /*rDisplayInfo*/) + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPage* pStartPage = GetStartPage(); + + if(pStartPage) + { + // update own ViewInformation2D for visualized page + const drawinglayer::geometry::ViewInformation2D& rOriginalViewInformation = mrViewObjectContactOfPageObj.GetObjectContact().getViewInformation2D(); + const drawinglayer::geometry::ViewInformation2D aNewViewInformation2D( + rOriginalViewInformation.getObjectTransformation(), + rOriginalViewInformation.getViewTransformation(), + + // #i101075# use empty range for page content here to force + // the content not to be physically clipped in any way. This + // would be possible, but would require the internal transformation + // which maps between the page visualisation object and the page + // content, including the aspect ratios (for details see in + // PagePreviewPrimitive2D::create2DDecomposition) + basegfx::B2DRange(), + + GetXDrawPageForSdrPage(const_cast< SdrPage* >(pStartPage)), + 0.0, // no time; page previews are not animated + rOriginalViewInformation.getExtendedInformationSequence()); + updateViewInformation2D(aNewViewInformation2D); + + // create copy of DisplayInfo to set PagePainting + DisplayInfo aDisplayInfo; + + // get page's VOC + ViewObjectContact& rDrawPageVOContact = pStartPage->GetViewContact().GetViewObjectContact(*this); + + // get whole Primitive2DSequence + xRetval = rDrawPageVOContact.getPrimitive2DSequenceHierarchy(aDisplayInfo); + } + + return xRetval; + } + + void PagePrimitiveExtractor::InvalidatePartOfView(const basegfx::B2DRange& rRange) const + { + // an invalidate is called at this view, this needs to be translated to an invalidate + // for the using VOC. Coordinates are in page coordinate system. + const SdrPage* pStartPage = GetStartPage(); + + if(pStartPage && !rRange.isEmpty()) + { + const basegfx::B2DRange aPageRange(0.0, 0.0, (double)pStartPage->GetWdt(), (double)pStartPage->GetHgt()); + + if(rRange.overlaps(aPageRange)) + { + // if object on the page is inside or overlapping with page, create ActionChanged() for + // involved VOC + mrViewObjectContactOfPageObj.ActionChanged(); + } + } + } + + // forward access to SdrPageView to VOCOfPageObj + bool PagePrimitiveExtractor::isOutputToPrinter() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPrinter(); } + bool PagePrimitiveExtractor::isOutputToWindow() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToWindow(); } + bool PagePrimitiveExtractor::isOutputToVirtualDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToVirtualDevice(); } + bool PagePrimitiveExtractor::isOutputToRecordingMetaFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToRecordingMetaFile(); } + bool PagePrimitiveExtractor::isOutputToPDFFile() const { return mrViewObjectContactOfPageObj.GetObjectContact().isOutputToPDFFile(); } + bool PagePrimitiveExtractor::isDrawModeGray() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeGray(); } + bool PagePrimitiveExtractor::isDrawModeBlackWhite() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeBlackWhite(); } + bool PagePrimitiveExtractor::isDrawModeHighContrast() const { return mrViewObjectContactOfPageObj.GetObjectContact().isDrawModeHighContrast(); } + SdrPageView* PagePrimitiveExtractor::TryToGetSdrPageView() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetSdrPageView(); } + OutputDevice* PagePrimitiveExtractor::TryToGetOutputDevice() const { return mrViewObjectContactOfPageObj.GetObjectContact().TryToGetOutputDevice(); } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageObj::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPageObj& rPageObject((static_cast< ViewContactOfPageObj& >(GetViewContact())).GetPageObj()); + const SdrPage* pPage = rPageObject.GetReferencedPage(); + const svtools::ColorConfig aColorConfig; + + // get PageObject's geometry + basegfx::B2DHomMatrix aPageObjectTransform; + { + const Rectangle aPageObjectModelData(rPageObject.GetLastBoundRect()); + const basegfx::B2DRange aPageObjectBound( + aPageObjectModelData.Left(), aPageObjectModelData.Top(), + aPageObjectModelData.Right(), aPageObjectModelData.Bottom()); + + aPageObjectTransform.set(0, 0, aPageObjectBound.getWidth()); + aPageObjectTransform.set(1, 1, aPageObjectBound.getHeight()); + aPageObjectTransform.set(0, 2, aPageObjectBound.getMinX()); + aPageObjectTransform.set(1, 2, aPageObjectBound.getMinY()); + } + + // #i102637# add gray frame also when printing and page exists (handout pages) + const bool bCreateGrayFrame(!GetObjectContact().isOutputToPrinter() || pPage); + + // get displayed page's content. This is the uscaled page content + if(mpExtractor && pPage) + { + // get displayed page's geometry + drawinglayer::primitive2d::Primitive2DSequence xPageContent; + const Size aPageSize(pPage->GetSize()); + const double fPageWidth(aPageSize.getWidth()); + const double fPageHeight(aPageSize.getHeight()); + + // The case that a PageObject contains another PageObject which visualizes the + // same page again would lead to a recursion. Limit that recursion depth to one + // by using a local static bool + static bool bInCreatePrimitive2D(false); + + if(bInCreatePrimitive2D) + { + // Recursion is possible. Create a replacement primitive + xPageContent.realloc(2); + const Color aDocColor(aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor); + const Color aBorderColor(aColorConfig.GetColorValue(svtools::DOCBOUNDARIES).nColor); + const basegfx::B2DRange aPageBound(0.0, 0.0, fPageWidth, fPageHeight); + const basegfx::B2DPolygon aOutline(basegfx::tools::createPolygonFromRect(aPageBound)); + + // add replacement fill + xPageContent[0L] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aOutline), aDocColor.getBColor())); + + // add replacement border + xPageContent[1L] = drawinglayer::primitive2d::Primitive2DReference( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOutline, aBorderColor.getBColor())); + } + else + { + // set recursion flag + bInCreatePrimitive2D = true; + + // init extractor, guarantee existance, set page there + mpExtractor->SetStartPage(pPage); + + // #i105548# also need to copy the VOCRedirector for sub-content creation + mpExtractor->SetViewObjectContactRedirector(GetObjectContact().GetViewObjectContactRedirector()); + + // create page content + xPageContent = mpExtractor->createPrimitive2DSequenceForPage(rDisplayInfo); + + // #i105548# reset VOCRedirector to not accidentially have a pointer to a + // temporary class, so calls to it are avoided safely + mpExtractor->SetViewObjectContactRedirector(0); + + // reset recursion flag + bInCreatePrimitive2D = false; + } + + // prepare retval + if(xPageContent.hasElements()) + { + const uno::Reference< drawing::XDrawPage > xDrawPage(GetXDrawPageForSdrPage(const_cast< SdrPage*>(pPage))); + const drawinglayer::primitive2d::Primitive2DReference xPagePreview(new drawinglayer::primitive2d::PagePreviewPrimitive2D( + xDrawPage, aPageObjectTransform, fPageWidth, fPageHeight, xPageContent, true)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xPagePreview, 1); + } + } + else if(bCreateGrayFrame) + { + // #i105146# no content, but frame display. To make hitting the page preview objects + // on the handout page more simple, add hidden fill geometry + const drawinglayer::primitive2d::Primitive2DReference xFrameHit( + drawinglayer::primitive2d::createHiddenGeometryPrimitives2D( + false, + aPageObjectTransform)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xFrameHit, 1); + } + + // add a gray outline frame, except not when printing + if(bCreateGrayFrame) + { + const Color aFrameColor(aColorConfig.GetColorValue(svtools::OBJECTBOUNDARIES).nColor); + basegfx::B2DPolygon aOwnOutline(basegfx::tools::createUnitPolygon()); + aOwnOutline.transform(aPageObjectTransform); + + const drawinglayer::primitive2d::Primitive2DReference xGrayFrame( + new drawinglayer::primitive2d::PolygonHairlinePrimitive2D(aOwnOutline, aFrameColor.getBColor())); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xGrayFrame); + } + + return xRetval; + } + + ViewObjectContactOfPageObj::ViewObjectContactOfPageObj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact), + mpExtractor(new PagePrimitiveExtractor(*this)) + { + } + + ViewObjectContactOfPageObj::~ViewObjectContactOfPageObj() + { + // delete the helper OC + if(mpExtractor) + { + // remember candidate and reset own pointer to avoid action when createPrimitive2DSequence() + // would be called for any reason + PagePrimitiveExtractor* pCandidate = mpExtractor; + mpExtractor = 0; + + // also reset the StartPage to avoid ActionChanged() forwardings in the + // PagePrimitiveExtractor::InvalidatePartOfView() implementation + pCandidate->SetStartPage(0); + delete pCandidate; + } + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx new file mode 100644 index 000000000000..ce8d0c79a5f9 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrmediaobj.cxx @@ -0,0 +1,176 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrmediaobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrmediaobj.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdomedia.hxx> +#include <svx/svdpagv.hxx> +#include <vcl/outdev.hxx> +#include <vcl/window.hxx> +#include <avmedia/mediaitem.hxx> +#include "sdrmediawindow.hxx" +#include <svx/sdrpagewindow.hxx> +#include <sdrpaintwindow.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr { namespace contact { + +// ---------------------------------- +// - ViewObjectContactOfSdrMediaObj - +// ---------------------------------- + +ViewObjectContactOfSdrMediaObj::ViewObjectContactOfSdrMediaObj( ObjectContact& rObjectContact, + ViewContact& rViewContact, + const ::avmedia::MediaItem& rMediaItem ) : + ViewObjectContactOfSdrObj( rObjectContact, rViewContact ), + mpMediaWindow( NULL ) +{ + Window* pWindow = getWindow(); + + if( pWindow ) + { + mpMediaWindow = new SdrMediaWindow( pWindow, *this ); + mpMediaWindow->hide(); + executeMediaItem( rMediaItem ); + } +} + +// ------------------------------------------------------------------------------ + +ViewObjectContactOfSdrMediaObj::~ViewObjectContactOfSdrMediaObj() +{ + delete mpMediaWindow; + mpMediaWindow = NULL; +} + +// ------------------------------------------------------------------------------ + +Window* ViewObjectContactOfSdrMediaObj::getWindow() const +{ + Window* pRetval = 0; + + const ObjectContactOfPageView* pObjectContactOfPageView = dynamic_cast< const ObjectContactOfPageView* >(&GetObjectContact()); + + if(pObjectContactOfPageView) + { + const SdrPageWindow& rPageWindow = pObjectContactOfPageView->GetPageWindow(); + const SdrPaintWindow* pPaintWindow = &rPageWindow.GetPaintWindow(); + + if(rPageWindow.GetOriginalPaintWindow()) + { + // #i83183# prefer OriginalPaintWindow if set; this is + // the real target device. GetPaintWindow() may return + // the current buffer device instead + pPaintWindow = rPageWindow.GetOriginalPaintWindow(); + } + + OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); + + if(OUTDEV_WINDOW == rOutDev.GetOutDevType()) + { + pRetval = static_cast< Window* >(&rOutDev); + } + } + + return pRetval; +} + +// ------------------------------------------------------------------------------ + +bool ViewObjectContactOfSdrMediaObj::hasPreferredSize() const +{ + return( mpMediaWindow != NULL && mpMediaWindow->hasPreferredSize() ); +} + +// ------------------------------------------------------------------------------ + +Size ViewObjectContactOfSdrMediaObj::getPreferredSize() const +{ + Size aRet; + + if( mpMediaWindow ) + aRet = mpMediaWindow->getPreferredSize(); + + return aRet; +} + +// ------------------------------------------------------------------------------ + +void ViewObjectContactOfSdrMediaObj::updateMediaItem( ::avmedia::MediaItem& rItem ) const +{ + if( mpMediaWindow ) + { + mpMediaWindow->updateMediaItem( rItem ); + + // show/hide is now dependent of play state + if(avmedia::MEDIASTATE_STOP == rItem.getState()) + { + mpMediaWindow->hide(); + } + else + { + basegfx::B2DRange aViewRange(getObjectRange()); + aViewRange.transform(GetObjectContact().getViewInformation2D().getViewTransformation()); + + const Rectangle aViewRectangle( + (sal_Int32)floor(aViewRange.getMinX()), (sal_Int32)floor(aViewRange.getMinY()), + (sal_Int32)ceil(aViewRange.getMaxX()), (sal_Int32)ceil(aViewRange.getMaxY())); + + mpMediaWindow->setPosSize(aViewRectangle); + mpMediaWindow->show(); + } + } +} + +// ------------------------------------------------------------------------------ + +void ViewObjectContactOfSdrMediaObj::executeMediaItem( const ::avmedia::MediaItem& rItem ) +{ + if( mpMediaWindow ) + { + ::avmedia::MediaItem aUpdatedItem; + + mpMediaWindow->executeMediaItem( rItem ); + + // query new properties after trying to set the new properties + updateMediaItem( aUpdatedItem ); + static_cast< ViewContactOfSdrMediaObj& >( GetViewContact() ).mediaPropertiesChanged( aUpdatedItem ); + } +} + +// ------------------------------------------------------------------------------ + +}} // end of namespace sdr::contact + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx new file mode 100644 index 000000000000..485afe35f9c1 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrobj.cxx @@ -0,0 +1,152 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrobj.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/svdobj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/svdview.hxx> + +#include "fmobj.hxx" + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrObject& ViewObjectContactOfSdrObj::getSdrObject() const + { + return static_cast< ViewContactOfSdrObj& >(GetViewContact()).GetSdrObject(); + } + + ViewObjectContactOfSdrObj::ViewObjectContactOfSdrObj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrObj::~ViewObjectContactOfSdrObj() + { + } + + bool ViewObjectContactOfSdrObj::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + const SdrObject& rObject = getSdrObject(); + + // Test layer visibility + if(!rDisplayInfo.GetProcessLayers().IsSet(rObject.GetLayer())) + { + return false; + } + + if(GetObjectContact().isOutputToPrinter() ) + { + // Test if print output but not printable + if( !rObject.IsPrintable()) + return false; + } + else + { + // test is object is not visible on screen + if( !rObject.IsVisible() ) + return false; + } + + // Test for hidden object on MasterPage + if(rDisplayInfo.GetSubContentActive() && rObject.IsNotVisibleAsMaster()) + { + return false; + } + + // Test for Calc object hiding (for OLE and Graphic it's extra, see there) + const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pSdrPageView) + { + const SdrView& rSdrView = pSdrPageView->GetView(); + const bool bHideOle(rSdrView.getHideOle()); + const bool bHideChart(rSdrView.getHideChart()); + const bool bHideDraw(rSdrView.getHideDraw()); + const bool bHideFormControl(rSdrView.getHideFormControl()); + + if(bHideOle || bHideChart || bHideDraw || bHideFormControl) + { + if(OBJ_OLE2 == rObject.GetObjIdentifier()) + { + if(((SdrOle2Obj&)rObject).IsChart()) + { + // chart + if(bHideChart) + { + return false; + } + } + else + { + // OLE + if(bHideOle) + { + return false; + } + } + } + else if(OBJ_GRAF == rObject.GetObjIdentifier()) + { + // graphic handled like OLE + if(bHideOle) + { + return false; + } + } + else + { + const bool bIsFormControl = dynamic_cast< const FmFormObj * >( &rObject ) != 0; + if(bIsFormControl && bHideFormControl) + { + return false; + } + // any other draw object + if(!bIsFormControl && bHideDraw) + { + return false; + } + } + } + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx new file mode 100644 index 000000000000..b1a4826609f9 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrole2obj.cxx @@ -0,0 +1,243 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofsdrole2obj.hxx> +#include <svx/sdr/contact/viewobjectcontactofsdrobj.hxx> +#include <svx/sdr/contact/viewcontactofsdrole2obj.hxx> +#include <svx/svdoole2.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <svx/svdview.hxx> +#include <drawinglayer/primitive2d/chartprimitive2d.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <com/sun/star/embed/EmbedMisc.hpp> +#include <com/sun/star/embed/EmbedStates.hpp> +#include <basegfx/polygon/b2dpolygon.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrOle2Obj& ViewObjectContactOfSdrOle2Obj::getSdrOle2Object() const + { + return static_cast< ViewContactOfSdrOle2Obj& >(GetViewContact()).GetOle2Obj(); + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrOle2Obj::createPrimitive2DSequence( + const DisplayInfo& /*rDisplayInfo*/) const + { + // this method is overloaded to do some things the old SdrOle2Obj::DoPaintObject did. + // In the future, some of these may be solved different, but ATM try to stay compatible + // with the old behaviour + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrOle2Obj& rSdrOle2 = getSdrOle2Object(); + sal_Int32 nState(-1); + + { + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if ( xObjRef.is() ) + nState = xObjRef->getCurrentState(); + } + + const bool bIsOutplaceActive(nState == embed::EmbedStates::ACTIVE); + const bool bIsInplaceActive((nState == embed::EmbedStates::INPLACE_ACTIVE) || (nState == embed::EmbedStates::UI_ACTIVE)); + const bool bIsChart(rSdrOle2.IsChart()); + bool bDone(false); + + if(!bDone && bIsInplaceActive) + { + if( !GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile() ) + { + //no need to create a primitive sequence here as the OLE object does render itself + //in case of charts the superfluous creation of a metafile is strongly performance relevant! + bDone = true; + } + } + + if( !bDone ) + { + const Rectangle& rObjectRectangle(rSdrOle2.GetGeoRect()); + const basegfx::B2DRange aObjectRange(rObjectRectangle.Left(), rObjectRectangle.Top(), rObjectRectangle.Right(), rObjectRectangle.Bottom()); + + // create object transform + basegfx::B2DHomMatrix aObjectTransform; + aObjectTransform.set(0, 0, aObjectRange.getWidth()); + aObjectTransform.set(1, 1, aObjectRange.getHeight()); + aObjectTransform.set(0, 2, aObjectRange.getMinX()); + aObjectTransform.set(1, 2, aObjectRange.getMinY()); + + if(bIsChart) + { + //charts must be painted resolution dependent!! #i82893#, #i75867# + + // for chart, to not lose the current better quality visualisation which + // uses a direct paint, use a primtive wrapper for that exceptional case. The renderers + // will then ATM paint it to an OutputDevice directly. + // In later versions this should be replaced by getting the Primitive2DSequnce from + // the chart and using it. + // to be able to render something in non-VCL using renderers, the wrapper is a + // GroupPrimitive2D which automatically decomposes to the already created Metafile + // content. + // For being completely compatible, ATM Window and VDEV PrettyPrinting is suppressed. + // It works in the VCL renderers, though. So for activating again with VCL primitive + // renderers, change conditions here. + + // determine if embedding and PrettyPrinting shall be done at all + uno::Reference< frame::XModel > xChartModel; + bool bDoChartPrettyPrinting(true); + + // the original ChartPrettyPainter does not do it for Window + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToWindow()) + { + bDoChartPrettyPrinting = false; + } + + // the original ChartPrettyPainter does not do it for VDEV + if(bDoChartPrettyPrinting && GetObjectContact().isOutputToVirtualDevice()) + { + if(GetObjectContact().isOutputToPDFFile()) + { + // #i97982# + // For PDF files, allow PrettyPrinting + } + else + { + bDoChartPrettyPrinting = false; + } + } + + // the chart model is needed. Check if it's available + if(bDoChartPrettyPrinting) + { + // get chart model + xChartModel = rSdrOle2.getXModel(); + + if(!xChartModel.is()) + { + bDoChartPrettyPrinting = false; + } + } + + if(bDoChartPrettyPrinting) + { + // embed MetaFile data in a specialized Wrapper Primitive which holds also the ChartModel needed + // for PrettyPrinting + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::ChartPrimitive2D( + xChartModel, aObjectTransform, xRetval)); + xRetval = drawinglayer::primitive2d::Primitive2DSequence(&xReference, 1); + bDone = true; + } + } + + if( !bDone ) + { + //old stuff that should be reworked + { + //if no replacement image is available load the OLE object + if(!rSdrOle2.GetGraphic()) //try to fetch the metafile - this can lead to the actual creation of the metafile what can be extremely expensive (e.g. for big charts)!!! #i101925# + { + // try to create embedded object + rSdrOle2.GetObjRef(); //this loads the OLE object if it is not loaded already + } + const svt::EmbeddedObjectRef& xObjRef = rSdrOle2.getEmbeddedObjectRef(); + if(xObjRef.is()) + { + const sal_Int64 nMiscStatus(xObjRef->getStatus(rSdrOle2.GetAspect())); + + // this hack (to change model data during PAINT argh(!)) should be reworked + if(!rSdrOle2.IsResizeProtect() && (nMiscStatus & embed::EmbedMisc::EMBED_NEVERRESIZE)) + { + const_cast< SdrOle2Obj* >(&rSdrOle2)->SetResizeProtect(true); + } + + SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + if(pPageView && (nMiscStatus & embed::EmbedMisc::MS_EMBED_ACTIVATEWHENVISIBLE)) + { + // connect plugin object + pPageView->GetView().DoConnect(const_cast< SdrOle2Obj* >(&rSdrOle2)); + } + } + }//end old stuff to rework + + // create OLE primitive stuff directly at VC with HC as parameter + const ViewContactOfSdrOle2Obj& rVC = static_cast< const ViewContactOfSdrOle2Obj& >(GetViewContact()); + xRetval = rVC.createPrimitive2DSequenceWithParameters(GetObjectContact().isDrawModeHighContrast()); + } + + if(bIsOutplaceActive) + { + // do not shade when printing or PDF exporting + if(!GetObjectContact().isOutputToPrinter() && !GetObjectContact().isOutputToRecordingMetaFile()) + { + // shade the representation if the object is activated outplace + basegfx::B2DPolygon aObjectOutline(basegfx::tools::createUnitPolygon()); + aObjectOutline.transform(aObjectTransform); + + // Use a FillHatchPrimitive2D with necessary attributes + const drawinglayer::attribute::FillHatchAttribute aFillHatch( + drawinglayer::attribute::HATCHSTYLE_SINGLE, // single hatch + 125.0, // 1.25 mm + 45.0 * F_PI180, // 45 degree diagonal + Color(COL_BLACK).getBColor(), // black color + false); // no filling + + const drawinglayer::primitive2d::Primitive2DReference xReference(new drawinglayer::primitive2d::PolyPolygonHatchPrimitive2D( + basegfx::B2DPolyPolygon(aObjectOutline), + Color(COL_BLACK).getBColor(), + aFillHatch)); + + drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReference); + } + } + + } + + return xRetval; + } + + ViewObjectContactOfSdrOle2Obj::ViewObjectContactOfSdrOle2Obj(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfSdrObj(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrOle2Obj::~ViewObjectContactOfSdrOle2Obj() + { + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx b/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx new file mode 100644 index 000000000000..f7145dcd9d73 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofsdrpage.cxx @@ -0,0 +1,729 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofsdrpage.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/contact/viewcontactofsdrpage.hxx> +#include <svx/svdview.hxx> +#include <svx/svdpage.hxx> +#include <svx/sdr/contact/objectcontact.hxx> +#include <drawinglayer/primitive2d/backgroundcolorprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <drawinglayer/primitive2d/polypolygonprimitive2d.hxx> +#include <drawinglayer/primitive2d/gridprimitive2d.hxx> +#include <drawinglayer/primitive2d/helplineprimitive2d.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <svx/sdr/primitive2d/sdrprimitivetools.hxx> + +////////////////////////////////////////////////////////////////////////////// + +using namespace com::sun::star; + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + const SdrPage& ViewObjectContactOfPageSubObject::getPage() const + { + return static_cast< ViewContactOfPageSubObject& >(GetViewContact()).getPage(); + } + + ViewObjectContactOfPageSubObject::ViewObjectContactOfPageSubObject(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageSubObject::~ViewObjectContactOfPageSubObject() + { + } + + bool ViewObjectContactOfPageSubObject::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(rDisplayInfo.GetSubContentActive()) + { + return false; + } + + if(rDisplayInfo.GetControlLayerProcessingActive()) + { + return false; + } + + if(!rDisplayInfo.GetPageProcessingActive()) + { + return false; + } + + if(GetObjectContact().isOutputToPrinter()) + { + return false; + } + + if(!GetObjectContact().TryToGetSdrPageView()) + { + return false; + } + + return true; + } + + bool ViewObjectContactOfPageSubObject::isPrimitiveGhosted(const DisplayInfo& /*rDisplayInfo*/) const + { + // suppress ghosted for page parts + return false; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageBackground::ViewObjectContactOfPageBackground(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageBackground::~ViewObjectContactOfPageBackground() + { + } + + bool ViewObjectContactOfPageBackground::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + // no page background for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageBackground::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + // Initialize background. Dependent of IsPageVisible, use ApplicationBackgroundColor or ApplicationDocumentColor. Most + // old renderers for export (html, pdf, gallery, ...) set the page to not visible (SetPageVisible(false)). They expect the + // given OutputDevice to be initialized with the ApplicationDocumentColor then. + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrView& rView = pPageView->GetView(); + Color aInitColor; + + if(rView.IsPageVisible()) + { + aInitColor = pPageView->GetApplicationBackgroundColor(); + } + else + { + aInitColor = pPageView->GetApplicationDocumentColor(); + + if(Color(COL_AUTO) == aInitColor) + { + const svtools::ColorConfig aColorConfig; + aInitColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor; + } + } + + // init background with InitColor + xRetval.realloc(1); + const basegfx::BColor aRGBColor(aInitColor.getBColor()); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::BackgroundColorPrimitive2D(aRGBColor)); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfMasterPage::ViewObjectContactOfMasterPage(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfMasterPage::~ViewObjectContactOfMasterPage() + { + } + + bool ViewObjectContactOfMasterPage::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + // this object is only used for MasterPages. When not the MasterPage is + // displayed as a page, but another page is using it as sub-object, the + // geometry needs to be hidden + if(rDisplayInfo.GetSubContentActive()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageFill::ViewObjectContactOfPageFill(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageFill::~ViewObjectContactOfPageFill() + { + } + + bool ViewObjectContactOfPageFill::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsPageVisible()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageFill::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrPage& rPage = getPage(); + + const basegfx::B2DRange aPageFillRange(0.0, 0.0, (double)rPage.GetWdt(), (double)rPage.GetHgt()); + const basegfx::B2DPolygon aPageFillPolygon(basegfx::tools::createPolygonFromRect(aPageFillRange)); + Color aPageFillColor; + + if(pPageView->GetApplicationDocumentColor() != COL_AUTO) + { + aPageFillColor = pPageView->GetApplicationDocumentColor(); + } + else + { + const svtools::ColorConfig aColorConfig; + aPageFillColor = aColorConfig.GetColorValue(svtools::DOCCOLOR).nColor; + } + + // create and add primitive + xRetval.realloc(1); + const basegfx::BColor aRGBColor(aPageFillColor.getBColor()); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::PolyPolygonColorPrimitive2D(basegfx::B2DPolyPolygon(aPageFillPolygon), aRGBColor)); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageShadow::ViewObjectContactOfPageShadow(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageShadow::~ViewObjectContactOfPageShadow() + { + } + + bool ViewObjectContactOfPageShadow::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsPageVisible()) + { + return false; + } + + // no page shadow for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + // no page shadow for high contrast mode + if(GetObjectContact().isDrawModeHighContrast()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfOuterPageBorder::ViewObjectContactOfOuterPageBorder(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfOuterPageBorder::~ViewObjectContactOfOuterPageBorder() + { + } + + bool ViewObjectContactOfOuterPageBorder::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsPageVisible() && rView.IsPageBorderVisible()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfInnerPageBorder::ViewObjectContactOfInnerPageBorder(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfInnerPageBorder::~ViewObjectContactOfInnerPageBorder() + { + } + + bool ViewObjectContactOfInnerPageBorder::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + if(!pSdrPageView->GetView().IsBordVisible()) + { + return false; + } + + const SdrPage& rPage = getPage(); + + if(!rPage.GetLftBorder() && !rPage.GetUppBorder() && !rPage.GetRgtBorder() && !rPage.GetLwrBorder()) + { + return false; + } + + // no inner page border for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + return true; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageHierarchy::ViewObjectContactOfPageHierarchy(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageHierarchy::~ViewObjectContactOfPageHierarchy() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageHierarchy::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // process local sub-hierarchy + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageGrid::ViewObjectContactOfPageGrid(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageGrid::~ViewObjectContactOfPageGrid() + { + } + + bool ViewObjectContactOfPageGrid::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsGridVisible()) + { + return false; + } + + // no page grid for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + if(static_cast< ViewContactOfGrid& >(GetViewContact()).getFront() != (bool)rView.IsGridFront()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageGrid::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + if(pPageView) + { + const SdrView& rView = pPageView->GetView(); + const SdrPage& rPage = getPage(); + const Color aGridColor(rView.GetGridColor()); + const basegfx::BColor aRGBGridColor(aGridColor.getBColor()); + + basegfx::B2DHomMatrix aGridMatrix; + aGridMatrix.set(0, 0, (double)(rPage.GetWdt() - (rPage.GetRgtBorder() + rPage.GetLftBorder()))); + aGridMatrix.set(1, 1, (double)(rPage.GetHgt() - (rPage.GetLwrBorder() + rPage.GetUppBorder()))); + aGridMatrix.set(0, 2, (double)rPage.GetLftBorder()); + aGridMatrix.set(1, 2, (double)rPage.GetUppBorder()); + + const Size aRaw(rView.GetGridCoarse()); + const Size aFine(rView.GetGridFine()); + const double fWidthX(aRaw.getWidth()); + const double fWidthY(aRaw.getHeight()); + const sal_uInt32 nSubdivisionsX(aFine.getWidth() ? aRaw.getWidth() / aFine.getWidth() : 0L); + const sal_uInt32 nSubdivisionsY(aFine.getHeight() ? aRaw.getHeight() / aFine.getHeight() : 0L); + + xRetval.realloc(1); + xRetval[0] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::GridPrimitive2D( + aGridMatrix, fWidthX, fWidthY, 10.0, 3.0, nSubdivisionsX, nSubdivisionsY, aRGBGridColor, + drawinglayer::primitive2d::createDefaultCross_3x3(aRGBGridColor))); + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfPageHelplines::ViewObjectContactOfPageHelplines(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContactOfPageSubObject(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfPageHelplines::~ViewObjectContactOfPageHelplines() + { + } + + bool ViewObjectContactOfPageHelplines::isPrimitiveVisible(const DisplayInfo& rDisplayInfo) const + { + if(!ViewObjectContactOfPageSubObject::isPrimitiveVisible(rDisplayInfo)) + { + return false; + } + + SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(!pSdrPageView) + { + return false; + } + + const SdrView& rView = pSdrPageView->GetView(); + + if(!rView.IsHlplVisible()) + { + return false; + } + + // no helplines for preview renderers + if(GetObjectContact().IsPreviewRenderer()) + { + return false; + } + + if(static_cast< ViewContactOfHelplines& >(GetViewContact()).getFront() != (bool)rView.IsHlplFront()) + { + return false; + } + + return true; + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfPageHelplines::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + const SdrPageView* pPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pPageView) + { + const SdrHelpLineList& rHelpLineList = pPageView->GetHelpLines(); + const sal_uInt32 nCount(rHelpLineList.GetCount()); + + if(nCount) + { + const basegfx::BColor aRGBColorA(1.0, 1.0, 1.0); + const basegfx::BColor aRGBColorB(0.0, 0.0, 0.0); + xRetval.realloc(nCount); + + for(sal_uInt32 a(0L); a < nCount; a++) + { + const SdrHelpLine& rHelpLine = rHelpLineList[(sal_uInt16)a]; + const basegfx::B2DPoint aPosition((double)rHelpLine.GetPos().X(), (double)rHelpLine.GetPos().Y()); + const double fDiscreteDashLength(4.0); + + switch(rHelpLine.GetKind()) + { + default : // SDRHELPLINE_POINT + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(1.0, 0.0), drawinglayer::primitive2d::HELPLINESTYLE2D_POINT, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + case SDRHELPLINE_VERTICAL : + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(0.0, 1.0), drawinglayer::primitive2d::HELPLINESTYLE2D_LINE, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + case SDRHELPLINE_HORIZONTAL : + { + xRetval[a] = drawinglayer::primitive2d::Primitive2DReference(new drawinglayer::primitive2d::HelplinePrimitive2D( + aPosition, basegfx::B2DVector(1.0, 0.0), drawinglayer::primitive2d::HELPLINESTYLE2D_LINE, + aRGBColorA, aRGBColorB, fDiscreteDashLength)); + break; + } + } + } + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + ViewObjectContactOfSdrPage::ViewObjectContactOfSdrPage(ObjectContact& rObjectContact, ViewContact& rViewContact) + : ViewObjectContact(rObjectContact, rViewContact) + { + } + + ViewObjectContactOfSdrPage::~ViewObjectContactOfSdrPage() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfSdrPage::getPrimitive2DSequenceHierarchy(DisplayInfo& rDisplayInfo) const + { + drawinglayer::primitive2d::Primitive2DSequence xRetval; + + // process local sub-hierarchy + const sal_uInt32 nSubHierarchyCount(GetViewContact().GetObjectCount()); + + if(nSubHierarchyCount) + { + const sal_Bool bDoGhostedDisplaying( + GetObjectContact().DoVisualizeEnteredGroup() + && !GetObjectContact().isOutputToPrinter() + && GetObjectContact().getActiveViewContact() == &GetViewContact()); + + if(bDoGhostedDisplaying) + { + rDisplayInfo.ClearGhostedDrawMode(); + } + + // create object hierarchy + xRetval = getPrimitive2DSequenceSubHierarchy(rDisplayInfo); + + if(xRetval.hasElements()) + { + // get ranges + const drawinglayer::geometry::ViewInformation2D& rViewInformation2D(GetObjectContact().getViewInformation2D()); + const basegfx::B2DRange aObjectRange(drawinglayer::primitive2d::getB2DRangeFromPrimitive2DSequence(xRetval, rViewInformation2D)); + const basegfx::B2DRange aViewRange(rViewInformation2D.getViewport()); + + // check geometrical visibility + if(!aViewRange.isEmpty() && !aViewRange.overlaps(aObjectRange)) + { + // not visible, release + xRetval.realloc(0); + } + } + + if(bDoGhostedDisplaying) + { + rDisplayInfo.SetGhostedDrawMode(); + } + } + + return xRetval; + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof diff --git a/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx new file mode 100644 index 000000000000..1da80b6c245e --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactofunocontrol.cxx @@ -0,0 +1,1925 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" + +#include <svx/sdr/contact/viewobjectcontactofunocontrol.hxx> +#include <svx/sdr/contact/viewcontactofunocontrol.hxx> +#include <svx/sdr/contact/displayinfo.hxx> +#include <svx/sdr/properties/properties.hxx> +#include <svx/sdr/contact/objectcontactofpageview.hxx> +#include <svx/sdr/primitive2d/svx_primitivetypes2d.hxx> +#include <svx/svdouno.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdview.hxx> +#include <svx/sdrpagewindow.hxx> +#include "sdrpaintwindow.hxx" + +/** === begin UNO includes === **/ +#include <com/sun/star/lang/XMultiServiceFactory.hpp> +#include <com/sun/star/awt/XControl.hpp> +#include <com/sun/star/awt/XControlModel.hpp> +#include <com/sun/star/awt/XControlContainer.hpp> +#include <com/sun/star/awt/XWindow2.hpp> +#include <com/sun/star/awt/PosSize.hpp> +#include <com/sun/star/awt/XView.hpp> +#include <com/sun/star/beans/XPropertySet.hpp> +#include <com/sun/star/lang/XComponent.hpp> +#include <com/sun/star/awt/InvalidateStyle.hpp> +#include <com/sun/star/util/XModeChangeListener.hpp> +#include <com/sun/star/util/XModeChangeBroadcaster.hpp> +#include <com/sun/star/container/XContainerListener.hpp> +#include <com/sun/star/container/XContainer.hpp> +/** === end UNO includes === **/ + +#include <toolkit/helper/formpdfexport.hxx> +#include <vcl/pdfextoutdevdata.hxx> +#include <vcl/svapp.hxx> +#include <vos/mutex.hxx> +#include <comphelper/processfactory.hxx> +#include <comphelper/scopeguard.hxx> +#include <cppuhelper/implbase4.hxx> +#include <toolkit/helper/vclunohelper.hxx> +#include <tools/diagnose_ex.h> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <drawinglayer/primitive2d/controlprimitive2d.hxx> + +#include <boost/shared_ptr.hpp> +#include <boost/bind.hpp> + +/* + +Form controls (more precise: UNO Controls) in the drawing layer are ... prone to breakage, since they have some +specialities which the drawing layer currently doesn't capture too well. In particular, having a living VCL +window as child of the document window, and coupling this Window to a drawing layer object, makes things +difficult sometimes. + +Below is a list of issues which existed in the past. Whenever you change code here, you're encouraged to +verify those issues are still fixed. (Whenever you have some additional time, you're encouraged to write +an automatic test for one or more of those issues for which this is possible :) + +http://www.openoffice.org/issues/show_bug.cgi?id=105992 +zooming documents containg (alive) form controls improperly positions the controls + +http://www.openoffice.org/issues/show_bug.cgi?id=104362 +crash when copy a control + +http://www.openoffice.org/issues/show_bug.cgi?id=104544 +Gridcontrol duplicated after design view on/off + +http://www.openoffice.org/issues/show_bug.cgi?id=102089 +print preview shows control elements with property printable=false + +http://www.openoffice.org/issues/show_bug.cgi?id=102090 +problem with setVisible on TextControl + +http://www.openoffice.org/issues/show_bug.cgi?id=103138 +loop when insert a control in draw + +http://www.openoffice.org/issues/show_bug.cgi?id=101398 +initially-displaying a document with many controls is very slow + +http://www.openoffice.org/issues/show_bug.cgi?id=72429 +repaint error in form wizard in bugdoc database + +http://www.openoffice.org/issues/show_bug.cgi?id=72694 +form control artifacts when scrolling a text fast + + +issues in the old (Sun-internal) bug tracking system: + +#110592# +form controls being in redlining or in hidden section are visible in alive-mode + +*/ + +//........................................................................ +namespace sdr { namespace contact { +//........................................................................ + + /** === begin UNO using === **/ + using namespace ::com::sun::star::awt::InvalidateStyle; + using ::com::sun::star::uno::Reference; + using ::com::sun::star::uno::XInterface; + using ::com::sun::star::uno::UNO_QUERY; + using ::com::sun::star::uno::UNO_QUERY_THROW; + using ::com::sun::star::uno::UNO_SET_THROW; + using ::com::sun::star::uno::Exception; + using ::com::sun::star::uno::RuntimeException; + using ::com::sun::star::awt::XControl; + using ::com::sun::star::lang::XMultiServiceFactory; + using ::com::sun::star::awt::XControlModel; + using ::com::sun::star::awt::XControlContainer; + using ::com::sun::star::awt::XWindow; + using ::com::sun::star::awt::XWindow2; + using ::com::sun::star::awt::XWindowListener; + using ::com::sun::star::awt::PosSize::POSSIZE; + using ::com::sun::star::awt::XView; + using ::com::sun::star::awt::XGraphics; + using ::com::sun::star::awt::WindowEvent; + using ::com::sun::star::beans::XPropertySet; + using ::com::sun::star::beans::XPropertySetInfo; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::awt::XWindowPeer; + using ::com::sun::star::beans::XPropertyChangeListener; + using ::com::sun::star::util::XModeChangeListener; + using ::com::sun::star::util::XModeChangeBroadcaster; + using ::com::sun::star::util::ModeChangeEvent; + using ::com::sun::star::lang::EventObject; + using ::com::sun::star::beans::PropertyChangeEvent; + using ::com::sun::star::lang::XComponent; + using ::com::sun::star::container::XContainerListener; + using ::com::sun::star::container::XContainer; + using ::com::sun::star::container::ContainerEvent; + using ::com::sun::star::uno::Any; + /** === end UNO using === **/ + + //==================================================================== + //= ControlHolder + //==================================================================== + class ControlHolder + { + private: + Reference< XControl > m_xControl; + Reference< XWindow2 > m_xControlWindow; + Reference< XView > m_xControlView; + + public: + ControlHolder() + :m_xControl() + ,m_xControlWindow() + ,m_xControlView() + { + } + + explicit ControlHolder( const Reference< XControl >& _rxControl ) + :m_xControl() + ,m_xControlWindow() + ,m_xControlView() + { + *this = _rxControl; + } + + ControlHolder& operator=( const Reference< XControl >& _rxControl ) + { + clear(); + + m_xControl = _rxControl; + if ( m_xControl.is() ) + { + m_xControlWindow.set( m_xControl, UNO_QUERY ); + m_xControlView.set( m_xControl, UNO_QUERY ); + if ( !m_xControlWindow.is() || !m_xControlView.is() ) + { + OSL_ENSURE( false, "ControlHolder::operator=: invalid XControl, missing required interfaces!" ); + clear(); + } + } + + return *this; + } + + public: + inline bool is() const { return m_xControl.is() && m_xControlWindow.is() && m_xControlView.is(); } + inline void clear() { m_xControl.clear(); m_xControlWindow.clear(); m_xControlView.clear(); } + + // delegators for the methods of the UNO interfaces + // Note all those will crash if called for a NULL object. + inline bool isDesignMode() const { return m_xControl->isDesignMode(); } + inline void setDesignMode( const bool _bDesign ) const { m_xControl->setDesignMode( _bDesign ); } + inline bool isVisible() const { return m_xControlWindow->isVisible(); } + inline void setVisible( const bool _bVisible ) const { m_xControlWindow->setVisible( _bVisible ); } + inline Reference< XControlModel > + getModel() const { return m_xControl->getModel(); } + inline void setModel( const Reference< XControlModel >& _m ) const { m_xControl->setModel( _m ); } + inline bool isTransparent() const { return m_xControl->isTransparent(); } + inline Reference< XWindowPeer > + getPeer() const { return m_xControl->getPeer(); } + + inline void addWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->addWindowListener( _l ); } + inline void removeWindowListener( const Reference< XWindowListener >& _l ) const { m_xControlWindow->removeWindowListener( _l ); } + void setPosSize( const Rectangle& _rPosSize ) const; + Rectangle + getPosSize() const; + void setZoom( const ::basegfx::B2DVector& _rScale ) const; + ::basegfx::B2DVector + getZoom() const; + + inline void setGraphics( const Reference< XGraphics >& _g ) const { m_xControlView->setGraphics( _g ); } + inline Reference< XGraphics > + getGraphics() const { return m_xControlView->getGraphics(); } + inline void draw( const Point& _rTopLeft ) const { m_xControlView->draw( _rTopLeft.X(), _rTopLeft.Y() ); } + + void invalidate() const; + + public: + inline const Reference< XControl >& getControl() const { return m_xControl; } + }; + + //-------------------------------------------------------------------- + bool operator==( const ControlHolder& _rControl, const Reference< XInterface >& _rxCompare ) + { + return _rControl.getControl() == _rxCompare; + } + + //-------------------------------------------------------------------- + bool operator==( const Reference< XInterface >& _rxCompare, const ControlHolder& _rControl ) + { + return _rxCompare == _rControl.getControl(); + } + + //-------------------------------------------------------------------- + bool operator==( const ControlHolder& _rControl, const Any& _rxCompare ) + { + return _rControl == Reference< XInterface >( _rxCompare, UNO_QUERY ); + } + + //-------------------------------------------------------------------- + bool operator==( const Any& _rxCompare, const ControlHolder& _rControl ) + { + return Reference< XInterface >( _rxCompare, UNO_QUERY ) == _rControl; + } + + //-------------------------------------------------------------------- + void ControlHolder::setPosSize( const Rectangle& _rPosSize ) const + { + // no check whether we're valid, this is the responsibility of the caller + + // don't call setPosSize when pos/size did not change + // #i104181# / 2009-08-18 / frank.schoenheit@sun.com + ::Rectangle aCurrentRect( getPosSize() ); + if ( aCurrentRect != _rPosSize ) + { + m_xControlWindow->setPosSize( + _rPosSize.Left(), _rPosSize.Top(), _rPosSize.GetWidth(), _rPosSize.GetHeight(), + POSSIZE + ); + } + } + + //-------------------------------------------------------------------- + ::Rectangle ControlHolder::getPosSize() const + { + // no check whether we're valid, this is the responsibility of the caller + return VCLUnoHelper::ConvertToVCLRect( m_xControlWindow->getPosSize() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::setZoom( const ::basegfx::B2DVector& _rScale ) const + { + // no check whether we're valid, this is the responsibility of the caller + m_xControlView->setZoom( (float)_rScale.getX(), (float)_rScale.getY() ); + } + + //-------------------------------------------------------------------- + void ControlHolder::invalidate() const + { + Reference< XWindowPeer > xPeer( m_xControl->getPeer() ); + if ( xPeer.is() ) + { + Window* pWindow = VCLUnoHelper::GetWindow( xPeer ); + OSL_ENSURE( pWindow, "ControlHolder::invalidate: no implementation access!" ); + if ( pWindow ) + pWindow->Invalidate(); + } + } + + //-------------------------------------------------------------------- + ::basegfx::B2DVector ControlHolder::getZoom() const + { + // no check whether we're valid, this is the responsibility of the caller + + // Argh. Why does XView have a setZoom only, but not a getZoom? + Window* pWindow = VCLUnoHelper::GetWindow( m_xControl->getPeer() ); + OSL_ENSURE( pWindow, "ControlHolder::getZoom: no implementation access!" ); + + ::basegfx::B2DVector aZoom( 1, 1 ); + if ( pWindow ) + { + const Fraction& rZoom( pWindow->GetZoom() ); + aZoom.setX( (double)rZoom ); + aZoom.setY( (double)rZoom ); + } + return aZoom; + } + + //==================================================================== + //= UnoControlContactHelper + //==================================================================== + class UnoControlContactHelper + { + public: + /** positions a control, and sets its zoom mode, using a given transformation and output device + */ + static void adjustControlGeometry_throw( + const ControlHolder& _rControl, + const Rectangle& _rLogicBoundingRect, + const ::basegfx::B2DHomMatrix& _rViewTransformation, + const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization + ); + + /** disposes the given control + */ + static void disposeAndClearControl_nothrow( + ControlHolder& _rControl + ); + + private: + UnoControlContactHelper(); // never implemented + UnoControlContactHelper( const UnoControlContactHelper& ); // never implemented + UnoControlContactHelper& operator=( const UnoControlContactHelper& ); // never implemented + }; + + //-------------------------------------------------------------------- + void UnoControlContactHelper::adjustControlGeometry_throw( const ControlHolder& _rControl, const Rectangle& _rLogicBoundingRect, + const basegfx::B2DHomMatrix& _rViewTransformation, const ::basegfx::B2DHomMatrix& _rZoomLevelNormalization ) + { + OSL_PRECOND( _rControl.is(), "UnoControlContactHelper::adjustControlGeometry_throw: illegal control!" ); + if ( !_rControl.is() ) + return; + + #if OSL_DEBUG_LEVEL > 0 + ::basegfx::B2DTuple aViewScale, aViewTranslate; + double nViewRotate(0), nViewShearX(0); + _rViewTransformation.decompose( aViewScale, aViewTranslate, nViewRotate, nViewShearX ); + #endif + + // transform the logic bound rect, using the view transformation, to pixel coordinates + ::basegfx::B2DPoint aTopLeft( _rLogicBoundingRect.Left(), _rLogicBoundingRect.Top() ); + aTopLeft *= _rViewTransformation; + ::basegfx::B2DPoint aBottomRight( _rLogicBoundingRect.Right(), _rLogicBoundingRect.Bottom() ); + aBottomRight *= _rViewTransformation; + + const Rectangle aPaintRectPixel( (long)aTopLeft.getX(), (long)aTopLeft.getY(), (long)aBottomRight.getX(), (long)aBottomRight.getY() ); + _rControl.setPosSize( aPaintRectPixel ); + + // determine the scale from the current view transformation, and the normalization matrix + ::basegfx::B2DHomMatrix aObtainResolutionDependentScale( _rViewTransformation * _rZoomLevelNormalization ); + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + aObtainResolutionDependentScale.decompose( aScale, aTranslate, fRotate, fShearX ); + _rControl.setZoom( aScale ); + } + + //-------------------------------------------------------------------- + void UnoControlContactHelper::disposeAndClearControl_nothrow( ControlHolder& _rControl ) + { + try + { + Reference< XComponent > xControlComp( _rControl.getControl(), UNO_QUERY ); + if ( xControlComp.is() ) + xControlComp->dispose(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + _rControl.clear(); + } + + //==================================================================== + //= IPageViewAccess + //==================================================================== + /** interface encapsulating access to an SdrPageView, stripped down to the methods we really need + */ + class IPageViewAccess + { + public: + /** determines whether the view is currently in design mode + */ + virtual bool isDesignMode() const = 0; + + /** retrieves the control container for a given output device + */ + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const = 0; + + /** determines whether a given layer is visible + */ + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const = 0; + }; + + //==================================================================== + //= SdrPageViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation based on a real ->SdrPageView instance + */ + class SdrPageViewAccess : public IPageViewAccess + { + const SdrPageView& m_rPageView; + public: + SdrPageViewAccess( const SdrPageView& _rPageView ) : m_rPageView( _rPageView ) { } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool SdrPageViewAccess::isDesignMode() const + { + return m_rPageView.GetView().IsDesignMode(); + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > SdrPageViewAccess::getControlContainer( const OutputDevice& _rDevice ) const + { + Reference< XControlContainer > xControlContainer = m_rPageView.GetControlContainer( _rDevice ); + DBG_ASSERT( xControlContainer.is() || NULL == m_rPageView.FindPageWindow( ( const_cast< OutputDevice& >( _rDevice ) ) ), + "SdrPageViewAccess::getControlContainer: the output device is known, but there is no control container for it?" ); + return xControlContainer; + } + + //-------------------------------------------------------------------- + bool SdrPageViewAccess::isLayerVisible( SdrLayerID _nLayerID ) const + { + return m_rPageView.GetVisibleLayers().IsSet( _nLayerID ); + } + + //==================================================================== + //= InvisibleControlViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation which can be used to create an invisble control for + an arbitrary window + */ + class InvisibleControlViewAccess : public IPageViewAccess + { + private: + Reference< XControlContainer >& m_rControlContainer; + public: + InvisibleControlViewAccess( Reference< XControlContainer >& _inout_ControlContainer ) + :m_rControlContainer( _inout_ControlContainer ) + { + } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool InvisibleControlViewAccess::isDesignMode() const + { + return true; + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > InvisibleControlViewAccess::getControlContainer( const OutputDevice& _rDevice ) const + { + if ( !m_rControlContainer.is() ) + { + const Window* pWindow = dynamic_cast< const Window* >( &_rDevice ); + OSL_ENSURE( pWindow, "InvisibleControlViewAccess::getControlContainer: expected to be called for a window only!" ); + if ( pWindow ) + m_rControlContainer = VCLUnoHelper::CreateControlContainer( const_cast< Window* >( pWindow ) ); + } + return m_rControlContainer; + } + + //-------------------------------------------------------------------- + bool InvisibleControlViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const + { + return false; + } + + //==================================================================== + //= DummyPageViewAccess + //==================================================================== + /** is a ->IPageViewAccess implementation which can be used to create a control for an arbitrary + non-Window device + + The implementation will report the "PageView" as being in design mode, all layers to be visible, + and will not return any ControlContainer, so all control container related features (notifications etc) + are not available. + */ + class DummyPageViewAccess : public IPageViewAccess + { + public: + DummyPageViewAccess() + { + } + + virtual bool isDesignMode() const; + virtual Reference< XControlContainer > + getControlContainer( const OutputDevice& _rDevice ) const; + virtual bool isLayerVisible( SdrLayerID _nLayerID ) const; + }; + + //-------------------------------------------------------------------- + bool DummyPageViewAccess::isDesignMode() const + { + return true; + } + + //-------------------------------------------------------------------- + Reference< XControlContainer > DummyPageViewAccess::getControlContainer( const OutputDevice& /*_rDevice*/ ) const + { + return NULL; + } + + //-------------------------------------------------------------------- + bool DummyPageViewAccess::isLayerVisible( SdrLayerID /*_nLayerID*/ ) const + { + return true; + } + + //==================================================================== + //= ViewObjectContactOfUnoControl_Impl + //==================================================================== + typedef ::cppu::WeakImplHelper4 < XWindowListener + , XPropertyChangeListener + , XContainerListener + , XModeChangeListener + > ViewObjectContactOfUnoControl_Impl_Base; + + class SVX_DLLPRIVATE ViewObjectContactOfUnoControl_Impl : public ViewObjectContactOfUnoControl_Impl_Base + { + private: + /// the instance whose IMPL we are + ViewObjectContactOfUnoControl* m_pAntiImpl; + + /// are we currently inside impl_ensureControl_nothrow? + bool m_bCreatingControl; + + /** thread safety + + (not really. ATM only our X* implementations are guarded with this, but not + the object as a whole.) + */ + mutable ::osl::Mutex m_aMutex; + + /// the control we're responsible for + ControlHolder m_aControl; + + /// the ControlContainer where we inserted our control + Reference< XContainer > m_xContainer; + + /// the output device for which the control was created + const OutputDevice* m_pOutputDeviceForWindow; + + /// flag indicating whether the control is currently visible + bool m_bControlIsVisible; + + /// are we currently listening at a design mode control? + bool m_bIsDesignModeListening; + + enum ViewControlMode + { + eDesign, + eAlive, + eUnknown + }; + /// is the control currently in design mode? + mutable ViewControlMode m_eControlDesignMode; + + ::basegfx::B2DHomMatrix m_aZoomLevelNormalization; + + public: + ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ); + + /** disposes the instance, which is nonfunctional afterwards + */ + void dispose(); + + /** determines whether the instance is disposed + */ + bool isDisposed() const { return impl_isDisposed_nofail(); } + + /** determines whether the instance is alive + */ + bool isAlive() const { return !isDisposed(); } + + /** returns the SdrUnoObject associated with the ViewContact + + @precond + We're not disposed. + */ + bool getUnoObject( SdrUnoObj*& _out_rpObject ) const; + + /** ensures that we have an ->XControl + + Must only be called if a control is needed when no DisplayInfo is present, yet. + + For creating a control, an ->OutputDevice is needed, and an ->SdrPageView. Both will be obtained + from a ->ObjectContactOfPageView. So, if our (anti-impl's) object contact is not a ->ObjectContactOfPageView, + this method fill fail. + + Failure of this method will be reported via an assertion in a non-product version. + */ + bool ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL ); + + /** returns our XControl, if it already has been created + + If you want to ensure that the control exists before accessing it, use ->ensureControl + */ + inline const ControlHolder& + getExistentControl() const { return m_aControl; } + + inline bool + hasControl() const { return m_aControl.is(); } + + /** positions our XControl according to the geometry settings in the SdrUnoObj, modified by the given + transformation, and sets proper zoom settings according to our device + + @precond + ->m_pOutputDeviceForWindow and ->m_aControl are not <NULL/> + */ + void positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const; + + /** determines whether or not our control is printable + + Effectively, this method returns the value of the "Printable" property + of the control's model. If we have no control, <FALSE/> is returned. + */ + bool isPrintableControl() const; + + /** sets the design mode on the control, or at least remembers the flag for the + time the control is created + */ + void setControlDesignMode( bool _bDesignMode ) const; + + /** determines whether our control is currently visible + @nofail + */ + bool isControlVisible() const { return impl_isControlVisible_nofail(); } + + /// creates an XControl for the given device and SdrUnoObj + static bool + createControlForDevice( + IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, + const SdrUnoObj& _rUnoObject, + const basegfx::B2DHomMatrix& _rInitialViewTransformation, + const basegfx::B2DHomMatrix& _rInitialZoomNormalization, + ControlHolder& _out_rControl + ); + + struct GuardAccess { friend class VOCGuard; private: GuardAccess() { } }; + ::osl::Mutex& getMutex( GuardAccess ) const { return m_aMutex; } + + const ViewContactOfUnoControl& + getViewContact() const + { + ENSURE_OR_THROW( !impl_isDisposed_nofail(), "already disposed" ); + return static_cast< const ViewContactOfUnoControl& >( m_pAntiImpl->GetViewContact() ); + } + + protected: + ~ViewObjectContactOfUnoControl_Impl(); + + // XEventListener + virtual void SAL_CALL disposing( const EventObject& Source ) throw(RuntimeException); + + // XWindowListener + virtual void SAL_CALL windowResized( const WindowEvent& e ) throw(RuntimeException); + virtual void SAL_CALL windowMoved( const WindowEvent& e ) throw(RuntimeException); + virtual void SAL_CALL windowShown( const EventObject& e ) throw(RuntimeException); + virtual void SAL_CALL windowHidden( const EventObject& e ) throw(RuntimeException); + + // XPropertyChangeListener + virtual void SAL_CALL propertyChange( const PropertyChangeEvent& evt ) throw(RuntimeException); + + // XModeChangeListener + virtual void SAL_CALL modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException); + + // XContainerListener + virtual void SAL_CALL elementInserted( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementRemoved( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + virtual void SAL_CALL elementReplaced( const ::com::sun::star::container::ContainerEvent& Event ) throw (::com::sun::star::uno::RuntimeException); + + private: + /** retrieves the SdrPageView which our associated SdrPageViewWindow belongs to + + @param out_rpPageView + a reference to a pointer holding, upon return, the desired SdrPageView + + @return + <TRUE/> if and only if a ->SdrPageView could be obtained + + @precond + We really belong to an SdrPageViewWindow. Perhaps (I'm not sure ATM :) + there are instance for which this might not be true, but those instances + should never have a need to call this method. + + @precond + We're not disposed. + + @postcond + The method expects success, if it returns with <FALSE/>, this will have been + asserted. + + @nothrow + */ + bool impl_getPageView_nothrow( SdrPageView*& _out_rpPageView ); + + /** adjusts the control visibility so it respects its layer's visibility + + @param _bForce + set to <TRUE/> if you want to force a ->XWindow::setVisible call, + no matter if the control visibility is already correct + + @precond + ->m_aControl is not <NULL/> + + @precond + We're not disposed. + + @precond + We really belong to an SdrPageViewWindow. There are instance for which this + might not be true, but those instances should never have a need to call + this method. + */ + void impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce ); + + /** adjusts the control visibility so it respects its layer's visibility + + The control must never be visibile if it's in design mode. + In alive mode, it must be visibility if and only it's on a visible layer. + + @param _rxControl + the control whose visibility is to be adjusted + + @param _rPageView + provides access to the attributes of the SdrPageView which the control finally belongs to + + @param _rUnoObject + our SdrUnoObj + + @param _bIsCurrentlyVisible + determines whether the control is currently visible. Note that this is only a shortcut for + querying _rxControl for the XWindow2 interface, and calling isVisible at this interface. + This shortcut has been chosen since the caller usually already has this information. + If _bForce is <TRUE/>, _bIsCurrentlyVisible is ignored. + + @param _bForce + set to <TRUE/> if you want to force a ->XWindow::setVisible call, + no matter if the control visibility is already correct + + @precond + We're not disposed. + */ + static void impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rxControl, const SdrUnoObj& _rUnoObject, + IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce ); + + /** starts or stops listening at various aspects of our control + + @precond + ->m_aControl is not <NULL/> + */ + void impl_switchControlListening_nothrow( bool _bStart ); + + /** starts or stops listening at our control container + + @precond + ->m_xContainer is not <NULL/> + */ + void impl_switchContainerListening_nothrow( bool _bStart ); + + /** starts or stops listening at the control for design-mode relevant facets + */ + void impl_switchDesignModeListening_nothrow( bool _bStart ); + + /** starts or stops listening for all properties at our control + + @param _bStart + determines whether to start or to stop listening + + @precond + ->m_aControl is not <NULL/> + */ + void impl_switchPropertyListening_nothrow( bool _bStart ); + + /** disposes the instance + @param _bAlsoDisposeControl + determines whether the XControl should be disposed, too + */ + void impl_dispose_nothrow( bool _bAlsoDisposeControl ); + + /** determines whether the instance is disposed + @nofail + */ + bool impl_isDisposed_nofail() const { return m_pAntiImpl == NULL; } + + /** determines whether our control is currently visible + @nofail + */ + bool impl_isControlVisible_nofail() const { return m_bControlIsVisible; } + + /** determines whether we are currently a listener at the control for desgin-mode relevant facets + @nofail + */ + bool impl_isDesignModeListening_nofail() const { return m_bIsDesignModeListening; } + + /** determines whether the control currently is in design mode + + @precond + The design mode must already be known. It is known when we first had access to + an SdrPageView (which carries this flag), or somebody explicitly set it from + outside. + */ + inline bool impl_isControlDesignMode_nothrow() const + { + DBG_ASSERT( m_eControlDesignMode != eUnknown, "ViewObjectContactOfUnoControl_Impl::impl_isControlDesignMode_nothrow: mode is still unknown!" ); + return m_eControlDesignMode == eDesign; + } + + /** ensures that we have a control for the given PageView/OutputDevice + */ + bool impl_ensureControl_nothrow( + IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, + const basegfx::B2DHomMatrix& _rInitialViewTransformation + ); + + /** retrieves the device which a PageView belongs to, starting from its ObjectContactOfPageView + + Since #i72752#, the PaintWindow (and thus the OutputDevice) associated with a PageView is not + constant over its lifetime. Instead, during some paint operations, the PaintWindow/OutputDevice + might be temporarily patched. + + This method cares for this, by retrieving the very original OutputDevice. + */ + static const OutputDevice& impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ); + + const OutputDevice& impl_getOutputDevice_throw() const; + + private: + ViewObjectContactOfUnoControl_Impl(); // never implemented + ViewObjectContactOfUnoControl_Impl( const ViewObjectContactOfUnoControl_Impl& ); // never implemented + ViewObjectContactOfUnoControl_Impl& operator=( const ViewObjectContactOfUnoControl_Impl& ); // never implemented + }; + + //==================================================================== + //= VOCGuard + //==================================================================== + /** class for guarding a ViewObjectContactOfUnoControl_Impl method + */ + class VOCGuard + { + private: + ::osl::MutexGuard m_aMutexGuard; + + public: + VOCGuard( const ViewObjectContactOfUnoControl_Impl& _rImpl ) + :m_aMutexGuard( _rImpl.getMutex( ViewObjectContactOfUnoControl_Impl::GuardAccess() ) ) + { + } + }; + + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + class LazyControlCreationPrimitive2D : public ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D + { + private: + typedef ::drawinglayer::primitive2d::BufferedDecompositionPrimitive2D BufferedDecompositionPrimitive2D; + + protected: + virtual ::drawinglayer::primitive2d::Primitive2DSequence + get2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::drawinglayer::primitive2d::Primitive2DSequence + create2DDecomposition( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + virtual ::basegfx::B2DRange + getB2DRange( + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation + ) const; + + public: + LazyControlCreationPrimitive2D( const ::rtl::Reference< ViewObjectContactOfUnoControl_Impl >& _pVOCImpl ) + :m_pVOCImpl( _pVOCImpl ) + { + ENSURE_OR_THROW( m_pVOCImpl.is(), "Illegal argument." ); + getTransformation( m_pVOCImpl->getViewContact(), m_aTransformation ); + } + + virtual bool operator==(const BasePrimitive2D& rPrimitive) const; + + // declare unique ID for this primitive class + DeclPrimitrive2DIDBlock() + + static void getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ); + + private: + void impl_positionAndZoomControl( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + if ( !_rViewInformation.getViewport().isEmpty() ) + m_pVOCImpl->positionAndZoomControl( _rViewInformation.getObjectToViewTransformation() ); + } + + private: + ::rtl::Reference< ViewObjectContactOfUnoControl_Impl > m_pVOCImpl; + /** The geometry is part of the identity of an primitive, so we cannot calculate it on demand + (since the data the calculation is based on might have changed then), but need to calc + it at construction time, and remember it. + */ + ::basegfx::B2DHomMatrix m_aTransformation; + }; + + //==================================================================== + //= ViewObjectContactOfUnoControl_Impl + //==================================================================== + DBG_NAME( ViewObjectContactOfUnoControl_Impl ) + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl( ViewObjectContactOfUnoControl* _pAntiImpl ) + :m_pAntiImpl( _pAntiImpl ) + ,m_bCreatingControl( false ) + ,m_pOutputDeviceForWindow( NULL ) + ,m_bControlIsVisible( false ) + ,m_bIsDesignModeListening( false ) + ,m_eControlDesignMode( eUnknown ) + ,m_aZoomLevelNormalization() + { + DBG_CTOR( ViewObjectContactOfUnoControl_Impl, NULL ); + DBG_ASSERT( m_pAntiImpl, "ViewObjectContactOfUnoControl_Impl::ViewObjectContactOfUnoControl_Impl: invalid AntiImpl!" ); + + const OutputDevice& rPageViewDevice( impl_getOutputDevice_throw() ); + m_aZoomLevelNormalization = rPageViewDevice.GetInverseViewTransformation(); + + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + m_aZoomLevelNormalization.decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + + ::basegfx::B2DHomMatrix aScaleNormalization; + MapMode aCurrentDeviceMapMode( rPageViewDevice.GetMapMode() ); + aScaleNormalization.set( 0, 0, (double)aCurrentDeviceMapMode.GetScaleX() ); + aScaleNormalization.set( 1, 1, (double)aCurrentDeviceMapMode.GetScaleY() ); + m_aZoomLevelNormalization *= aScaleNormalization; + } + + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl_Impl::~ViewObjectContactOfUnoControl_Impl() + { + if ( !impl_isDisposed_nofail() ) + { + acquire(); + dispose(); + } + + DBG_DTOR( ViewObjectContactOfUnoControl_Impl, NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_dispose_nothrow( bool _bAlsoDisposeControl ) + { + if ( impl_isDisposed_nofail() ) + return; + + if ( m_aControl.is() ) + impl_switchControlListening_nothrow( false ); + + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( false ); + + // dispose the control + if ( _bAlsoDisposeControl ) + UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl ); + + m_aControl.clear(); + m_xContainer.clear(); + m_pOutputDeviceForWindow = NULL; + m_bControlIsVisible = false; + + m_pAntiImpl = NULL; + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::dispose() + { + VOCGuard aGuard( *this ); + impl_dispose_nothrow( true ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::getUnoObject( SdrUnoObj*& _out_rpObject ) const + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::getUnoObject: already disposed()" ); + if ( impl_isDisposed_nofail() ) + _out_rpObject = NULL; + else + { + _out_rpObject = dynamic_cast< SdrUnoObj* >( m_pAntiImpl->GetViewContact().TryToGetSdrObject() ); + DBG_ASSERT( _out_rpObject || !m_pAntiImpl->GetViewContact().TryToGetSdrObject(), + "ViewObjectContactOfUnoControl_Impl::getUnoObject: invalid SdrObject!" ); + } + return ( _out_rpObject != NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::positionAndZoomControl( const basegfx::B2DHomMatrix& _rViewTransformation ) const + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no output device or no control!" ); + if ( !m_aControl.is() ) + return; + + try + { + SdrUnoObj* pUnoObject( NULL ); + if ( getUnoObject( pUnoObject ) ) + { + UnoControlContactHelper::adjustControlGeometry_throw( m_aControl, pUnoObject->GetLogicRect(), _rViewTransformation, m_aZoomLevelNormalization ); + } + else + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::positionAndZoomControl: no SdrUnoObj!" ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::ensureControl( const basegfx::B2DHomMatrix* _pInitialViewTransformationOrNULL ) + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::ensureControl: already disposed()" ); + if ( impl_isDisposed_nofail() ) + return false; + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + { + SdrPageViewAccess aPVAccess( pPageViewContact->GetPageWindow().GetPageView() ); + const OutputDevice& rDevice( impl_getPageViewOutputDevice_nothrow( *pPageViewContact ) ); + return impl_ensureControl_nothrow( + aPVAccess, + rDevice, + _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation() + ); + } + + DummyPageViewAccess aNoPageView; + const OutputDevice& rDevice( impl_getOutputDevice_throw() ); + return impl_ensureControl_nothrow( + aNoPageView, + rDevice, + _pInitialViewTransformationOrNULL ? *_pInitialViewTransformationOrNULL : rDevice.GetViewTransformation() + ); + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getOutputDevice_throw() const + { + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + { + // do not use ObjectContact::TryToGetOutputDevice here, it would not care for the PageWindow's + // OriginalPaintWindow + return impl_getPageViewOutputDevice_nothrow( *pPageViewContact ); + } + + const OutputDevice* pDevice = m_pAntiImpl->GetObjectContact().TryToGetOutputDevice(); + ENSURE_OR_THROW( pDevice, "no output device -> no control" ); + return *pDevice; + } + + //-------------------------------------------------------------------- + const OutputDevice& ViewObjectContactOfUnoControl_Impl::impl_getPageViewOutputDevice_nothrow( const ObjectContactOfPageView& _rObjectContact ) + { + // if the PageWindow has a patched PaintWindow, use the original PaintWindow + // this ensures that our control is _not_ re-created just because somebody + // (temporarily) changed the window to paint onto. + // #i72429# / 2007-02-20 / frank.schoenheit@sun.com + SdrPageWindow& rPageWindow( _rObjectContact.GetPageWindow() ); + if ( rPageWindow.GetOriginalPaintWindow() ) + return rPageWindow.GetOriginalPaintWindow()->GetOutputDevice(); + + return rPageWindow.GetPaintWindow().GetOutputDevice(); + } + + namespace + { + static void lcl_resetFlag( bool& rbFlag ) + { + rbFlag = false; + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow( IPageViewAccess& _rPageView, const OutputDevice& _rDevice, + const basegfx::B2DHomMatrix& _rInitialViewTransformation ) + { + if ( m_bCreatingControl ) + { + OSL_ENSURE( false, "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: reentrance is not really good here!" ); + // We once had a situation where this was called reentrantly, which lead to all kind of strange effects. All + // those affected the grid control, which is the only control so far which is visible in design mode (and + // not only in alive mode). + // Creating the control triggered an Window::Update on some of its child windows, which triggered a + // Paint on parent of the grid control (e.g. the SwEditWin), which triggered a reentrant call to this method, + // which it is not really prepared for. + // + // /me thinks that re-entrance should be caught on a higher level, i.e. the Drawing Layer should not allow + // reentrant paint requests. For the moment, until /me can discuss this with AW, catch it here. + // 2009-08-27 / #i104544# frank.schoenheit@sun.com + return false; + } + + m_bCreatingControl = true; + ::comphelper::ScopeGuard aGuard( ::boost::bind( lcl_resetFlag, ::boost::ref( m_bCreatingControl ) ) ); + + if ( m_aControl.is() ) + { + if ( m_pOutputDeviceForWindow == &_rDevice ) + return true; + + // Somebody requested a control for a new device, which means either of + // - our PageView's paint window changed since we were last here + // - we don't belong to a page view, and are simply painted onto different devices + // The first sounds strange (doens't it?), the second means we could perhaps + // optimize this in the future - there is no need to re-create the control every time, + // is it? + // #i74523# / 2007-02-15 / frank.schoenheit@sun.com + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( false ); + impl_switchControlListening_nothrow( false ); + UnoControlContactHelper::disposeAndClearControl_nothrow( m_aControl ); + } + + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return false; + + ControlHolder aControl; + if ( !createControlForDevice( _rPageView, _rDevice, *pUnoObject, _rInitialViewTransformation, m_aZoomLevelNormalization, aControl ) ) + return false; + + m_pOutputDeviceForWindow = &_rDevice; + m_aControl = aControl; + m_xContainer = m_xContainer.query( _rPageView.getControlContainer( _rDevice ) ); + DBG_ASSERT( ( m_xContainer.is() // either have a XControlContainer + || ( ( !_rPageView.getControlContainer( _rDevice ).is() ) // or don't have any container, + && ( dynamic_cast< const Window* >( &_rDevice ) == NULL ) // which is allowed for non-Window instances only + ) + ), + "ViewObjectContactOfUnoControl_Impl::impl_ensureControl_nothrow: no XContainer at the ControlContainer!" ); + + try + { + m_eControlDesignMode = m_aControl.isDesignMode() ? eDesign : eAlive; + m_bControlIsVisible = m_aControl.isVisible(); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + // start listening at all aspects of the control which are interesting to us ... + impl_switchControlListening_nothrow( true ); + + // start listening at the control container, in case somebody tampers with our control + if ( m_xContainer.is() ) + impl_switchContainerListening_nothrow( true ); + + return m_aControl.is(); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::createControlForDevice( IPageViewAccess& _rPageView, + const OutputDevice& _rDevice, const SdrUnoObj& _rUnoObject, const basegfx::B2DHomMatrix& _rInitialViewTransformation, + const basegfx::B2DHomMatrix& _rInitialZoomNormalization, ControlHolder& _out_rControl ) + { + _out_rControl.clear(); + + Reference< XControlModel > xControlModel( _rUnoObject.GetUnoControlModel() ); + DBG_ASSERT( xControlModel.is(), "ViewObjectContactOfUnoControl_Impl::createControlForDevice: no control model at the SdrUnoObject!?" ); + if ( !xControlModel.is() ) + return false; + + bool bSuccess = false; + try + { + const ::rtl::OUString sControlServiceName( _rUnoObject.GetUnoControlTypeName() ); + + Reference< XMultiServiceFactory > xFactory( ::comphelper::getProcessServiceFactory(), UNO_SET_THROW ); + _out_rControl = Reference< XControl >( xFactory->createInstance( sControlServiceName ), UNO_QUERY_THROW ); + + // knit the model and the control + _out_rControl.setModel( xControlModel ); + + // proper geometry + UnoControlContactHelper::adjustControlGeometry_throw( + _out_rControl, + _rUnoObject.GetLogicRect(), + _rInitialViewTransformation, + _rInitialZoomNormalization + ); + + // #107049# set design mode before peer is created, + // this is also needed for accessibility + _out_rControl.setDesignMode( _rPageView.isDesignMode() ); + + // adjust the initial visibility according to the visibility of the layer + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( _out_rControl, _rUnoObject, _rPageView, false, true ); + + // add the control to the respective control container + // #108327# do this last + Reference< XControlContainer > xControlContainer( _rPageView.getControlContainer( _rDevice ) ); + if ( xControlContainer.is() ) + xControlContainer->addControl( sControlServiceName, _out_rControl.getControl() ); + + bSuccess = true; + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + + if ( !bSuccess ) + { + // delete the control which might have been created already + UnoControlContactHelper::disposeAndClearControl_nothrow( _out_rControl ); + } + + return _out_rControl.is(); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow( SdrPageView*& _out_rpPageView ) + { + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: already disposed!" ); + + _out_rpPageView = NULL; + if ( impl_isDisposed_nofail() ) + return false; + + ObjectContactOfPageView* pPageViewContact = dynamic_cast< ObjectContactOfPageView* >( &m_pAntiImpl->GetObjectContact() ); + if ( pPageViewContact ) + _out_rpPageView = &pPageViewContact->GetPageWindow().GetPageView(); + + DBG_ASSERT( _out_rpPageView != NULL, "ViewObjectContactOfUnoControl_Impl::impl_getPageView_nothrow: this method is expected to always have success!" ); + return ( _out_rpPageView != NULL ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( bool _bForce ) + { + OSL_PRECOND( m_aControl.is(), + "ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw: only valid if we have a control!" ); + + SdrPageView* pPageView( NULL ); + if ( !impl_getPageView_nothrow( pPageView ) ) + return; + + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return; + + SdrPageViewAccess aPVAccess( *pPageView ); + impl_adjustControlVisibilityToLayerVisibility_throw( m_aControl, *pUnoObject, aPVAccess, impl_isControlVisible_nofail(), _bForce ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_adjustControlVisibilityToLayerVisibility_throw( const ControlHolder& _rControl, + const SdrUnoObj& _rUnoObject, IPageViewAccess& _rPageView, bool _bIsCurrentlyVisible, bool _bForce ) + { + // in design mode, there is no problem with the visibility: The XControl is hidden by + // default, and the Drawing Layer will simply not call our paint routine, if we're in + // a hidden layer. So, only alive mode matters. + if ( !_rControl.isDesignMode() ) + { + // the layer of our object + SdrLayerID nObjectLayer = _rUnoObject.GetLayer(); + // is the object we're residing in visible in this view? + bool bIsObjectVisible = _rUnoObject.IsVisible() && _rPageView.isLayerVisible( nObjectLayer ); + + if ( _bForce || ( bIsObjectVisible != _bIsCurrentlyVisible ) ) + { + _rControl.setVisible( bIsObjectVisible ); + } + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_xContainer.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchContainerListening_nothrow: no control container!" ); + if ( !m_xContainer.is() ) + return; + + try + { + if ( _bStart ) + m_xContainer->addContainerListener( this ); + else + m_xContainer->removeContainerListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchControlListening_nothrow: invalid control!" ); + if ( !m_aControl.is() ) + return; + + try + { + // listen for visibility changes + if ( _bStart ) + m_aControl.addWindowListener( this ); + else + m_aControl.removeWindowListener( this ); + + // in design mode, listen for some more aspects + impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() && _bStart ); + + // listen for design mode changes + Reference< XModeChangeBroadcaster > xDesignModeChanges( m_aControl.getControl(), UNO_QUERY_THROW ); + if ( _bStart ) + xDesignModeChanges->addModeChangeListener( this ); + else + xDesignModeChanges->removeModeChangeListener( this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::impl_switchDesignModeListening_nothrow( bool _bStart ) + { + if ( impl_isDesignModeListening_nofail() != _bStart ) + { + m_bIsDesignModeListening = _bStart; + impl_switchPropertyListening_nothrow( _bStart ); + } + } + + //------------------------------------------------------------------------------ + void ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow( bool _bStart ) + { + OSL_PRECOND( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::impl_switchPropertyListening_nothrow: no control!" ); + if ( !m_aControl.is() ) + return; + + try + { + Reference< XPropertySet > xModelProperties( m_aControl.getModel(), UNO_QUERY_THROW ); + if ( _bStart ) + xModelProperties->addPropertyChangeListener( ::rtl::OUString(), this ); + else + xModelProperties->removePropertyChangeListener( ::rtl::OUString(), this ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl_Impl::isPrintableControl() const + { + SdrUnoObj* pUnoObject( NULL ); + if ( !getUnoObject( pUnoObject ) ) + return false; + + bool bIsPrintable = false; + try + { + Reference< XPropertySet > xModelProperties( pUnoObject->GetUnoControlModel(), UNO_QUERY_THROW ); + static const ::rtl::OUString s_sPrintablePropertyName( RTL_CONSTASCII_USTRINGPARAM( "Printable" ) ); + OSL_VERIFY( xModelProperties->getPropertyValue( s_sPrintablePropertyName ) >>= bIsPrintable ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + return bIsPrintable; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::disposing( const EventObject& Source ) throw(RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // some code below - in particular our disposal - might trigger actions which require the + // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control, + // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex - + // is the real bug. Toolkit really is infested with solar mutex usage ... :( + // #i82169# / 2007-11-14 / frank.schoenheit@sun.com + VOCGuard aGuard( *this ); + + if ( !m_aControl.is() ) + return; + + if ( ( m_aControl == Source.Source ) + || ( m_aControl.getModel() == Source.Source ) + ) + { + // the model or the control is dying ... hmm, not much sense in that we ourself continue + // living + impl_dispose_nothrow( false ); + return; + } + + DBG_ASSERT( Source.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::disposing: Who's this?" ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowResized( const WindowEvent& /*e*/ ) throw(RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowMoved( const WindowEvent& /*e*/ ) throw(RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowShown( const EventObject& /*e*/ ) throw(RuntimeException) + { + VOCGuard aGuard( *this ); + m_bControlIsVisible = true; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::windowHidden( const EventObject& /*e*/ ) throw(RuntimeException) + { + VOCGuard aGuard( *this ); + m_bControlIsVisible = false; + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::propertyChange( const PropertyChangeEvent& /*_rEvent*/ ) throw(RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // (re)painting might require VCL operations, which need the SolarMutex + + OSL_PRECOND( !impl_isDisposed_nofail(), "ViewObjectContactOfUnoControl_Impl::propertyChange: already disposed()" ); + if ( impl_isDisposed_nofail() ) + return; + + VOCGuard aGuard( *this ); + DBG_ASSERT( m_aControl.is(), "ViewObjectContactOfUnoControl_Impl::propertyChange: " ); + if ( !m_aControl.is() ) + return; + + // a generic property changed. If we're in design mode, we need to repaint the control + if ( impl_isControlDesignMode_nothrow() ) + { + m_pAntiImpl->propertyChange(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::modeChanged( const ModeChangeEvent& _rSource ) throw (RuntimeException) + { + VOCGuard aGuard( *this ); + + DBG_ASSERT( _rSource.NewMode.equalsAscii( "design" ) || _rSource.NewMode.equalsAscii( "alive" ), + "ViewObjectContactOfUnoControl_Impl::modeChanged: unexpected mode!" ); + + m_eControlDesignMode = _rSource.NewMode.equalsAscii( "design" ) ? eDesign : eAlive; + + impl_switchDesignModeListening_nothrow( impl_isControlDesignMode_nothrow() ); + + try + { + // if the control is part of a invisible layer, we need to explicitly hide it in alive mode + // 2003-06-03 - #110592# - fs@openoffice.org + impl_adjustControlVisibilityToLayerVisibility_throw( false ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementInserted( const ContainerEvent& /*_Event*/ ) throw (RuntimeException) + { + // not interested in + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementRemoved( const ContainerEvent& Event ) throw (RuntimeException) + { + ::vos::OGuard aSolarGuard( Application::GetSolarMutex() ); + // some code below - in particular our disposal - might trigger actions which require the + // SolarMutex. In particular, in our disposal, we remove ourself as listener from the control, + // which alone needs the SolarMutex. Of course this - a removeFooListener needed the SolarMutex - + // is the real bug. Toolkit really is infested with solar mutex usage ... :( + // #i82169# / 2007-11-14 / frank.schoenheit@sun.com + VOCGuard aGuard( *this ); + DBG_ASSERT( Event.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::elementRemoved: where did this come from?" ); + + if ( m_aControl == Event.Element ) + impl_dispose_nothrow( false ); + } + + //-------------------------------------------------------------------- + void SAL_CALL ViewObjectContactOfUnoControl_Impl::elementReplaced( const ContainerEvent& Event ) throw (RuntimeException) + { + VOCGuard aGuard( *this ); + DBG_ASSERT( Event.Source == m_xContainer, "ViewObjectContactOfUnoControl_Impl::elementReplaced: where did this come from?" ); + + if ( ! ( m_aControl == Event.ReplacedElement ) ) + return; + + Reference< XControl > xNewControl( Event.Element, UNO_QUERY ); + DBG_ASSERT( xNewControl.is(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: invalid new control!" ); + if ( !xNewControl.is() ) + return; + + ENSURE_OR_THROW( m_pOutputDeviceForWindow, "calling this without /me having an output device should be impossible." ); + + DBG_ASSERT( xNewControl->getModel() == m_aControl.getModel(), "ViewObjectContactOfUnoControl_Impl::elementReplaced: another model at the new control?" ); + // another model should - in the drawing layer - also imply another SdrUnoObj, which + // should also result in new ViewContact, and thus in new ViewObjectContacts + + impl_switchControlListening_nothrow( false ); + + ControlHolder aNewControl( xNewControl ); + aNewControl.setZoom( m_aControl.getZoom() ); + aNewControl.setPosSize( m_aControl.getPosSize() ); + aNewControl.setDesignMode( impl_isControlDesignMode_nothrow() ); + + m_aControl = xNewControl; + m_bControlIsVisible = m_aControl.isVisible(); + + impl_switchControlListening_nothrow( true ); + + m_pAntiImpl->onControlChangedOrModified( ViewObjectContactOfUnoControl::ImplAccess() ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl_Impl::setControlDesignMode( bool _bDesignMode ) const + { + if ( ( m_eControlDesignMode != eUnknown ) && ( _bDesignMode == impl_isControlDesignMode_nothrow() ) ) + // nothing to do + return; + m_eControlDesignMode = _bDesignMode ? eDesign : eAlive; + + if ( !m_aControl.is() ) + // nothing to do, the setting will be respected as soon as the control + // is created + return; + + try + { + m_aControl.setDesignMode( _bDesignMode ); + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //==================================================================== + //= LazyControlCreationPrimitive2D + //==================================================================== + //-------------------------------------------------------------------- + bool LazyControlCreationPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const + { + if ( !BufferedDecompositionPrimitive2D::operator==( rPrimitive ) ) + return false; + + const LazyControlCreationPrimitive2D* pRHS = dynamic_cast< const LazyControlCreationPrimitive2D* >( &rPrimitive ); + if ( !pRHS ) + return false; + + if ( m_pVOCImpl != pRHS->m_pVOCImpl ) + return false; + + if ( m_aTransformation != pRHS->m_aTransformation ) + return false; + + return true; + } + + //-------------------------------------------------------------------- + void LazyControlCreationPrimitive2D::getTransformation( const ViewContactOfUnoControl& _rVOC, ::basegfx::B2DHomMatrix& _out_Transformation ) + { + // Do use model data directly to create the correct geometry. Do NOT + // use getBoundRect()/getSnapRect() here; tese will use the sequence of + // primitives themselves in the long run. + const Rectangle aSdrGeoData( _rVOC.GetSdrUnoObj().GetGeoRect() ); + const basegfx::B2DRange aRange( + aSdrGeoData.Left(), + aSdrGeoData.Top(), + aSdrGeoData.Right(), + aSdrGeoData.Bottom() + ); + + _out_Transformation.identity(); + _out_Transformation.set( 0, 0, aRange.getWidth() ); + _out_Transformation.set( 1, 1, aRange.getHeight() ); + _out_Transformation.set( 0, 2, aRange.getMinX() ); + _out_Transformation.set( 1, 2, aRange.getMinY() ); + } + + //-------------------------------------------------------------------- + ::basegfx::B2DRange LazyControlCreationPrimitive2D::getB2DRange( const ::drawinglayer::geometry::ViewInformation2D& /*rViewInformation*/ ) const + { + ::basegfx::B2DRange aRange( 0.0, 0.0, 1.0, 1.0 ); + aRange.transform( m_aTransformation ); + return aRange; + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::get2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + if ( m_pVOCImpl->hasControl() ) + impl_positionAndZoomControl( _rViewInformation ); + return BufferedDecompositionPrimitive2D::get2DDecomposition( _rViewInformation ); + } + + //-------------------------------------------------------------------- + ::drawinglayer::primitive2d::Primitive2DSequence LazyControlCreationPrimitive2D::create2DDecomposition( const ::drawinglayer::geometry::ViewInformation2D& _rViewInformation ) const + { + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + _rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + const bool bHadControl = m_pVOCImpl->getExistentControl().is(); + + // force control here to make it a VCL ChildWindow. Will be fetched + // and used below by getExistentControl() + m_pVOCImpl->ensureControl( &_rViewInformation.getObjectToViewTransformation() ); + impl_positionAndZoomControl( _rViewInformation ); + + // get needed data + const ViewContactOfUnoControl& rViewContactOfUnoControl( m_pVOCImpl->getViewContact() ); + Reference< XControlModel > xControlModel( rViewContactOfUnoControl.GetSdrUnoObj().GetUnoControlModel() ); + const ControlHolder& rControl( m_pVOCImpl->getExistentControl() ); + + if ( !bHadControl && rControl.is() && rControl.isVisible() ) + rControl.invalidate(); + + if ( !bHadControl && rControl.is() && rControl.isVisible() ) + rControl.invalidate(); + + // check if we already have an XControl. + if ( !xControlModel.is() || !rControl.is() ) + // use the default mechanism. This will create a ControlPrimitive2D without + // handing over a XControl. If not even a XControlModel exists, it will + // create the SdrObject fallback visualisation + return rViewContactOfUnoControl.getViewIndependentPrimitive2DSequence(); + + // create a primitive and hand over the existing xControl. This will + // allow the primitive to not need to create another one on demand. + const drawinglayer::primitive2d::Primitive2DReference xRetval( new ::drawinglayer::primitive2d::ControlPrimitive2D( + m_aTransformation, xControlModel, rControl.getControl() ) ); + + return drawinglayer::primitive2d::Primitive2DSequence(&xRetval, 1); + } + + //-------------------------------------------------------------------- + ImplPrimitrive2DIDBlock( LazyControlCreationPrimitive2D, PRIMITIVE2D_ID_SDRCONTROLPRIMITIVE2D ) + + //==================================================================== + //= ViewObjectContactOfUnoControl + //==================================================================== + DBG_NAME( ViewObjectContactOfUnoControl ) + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl::ViewObjectContactOfUnoControl( ObjectContact& _rObjectContact, ViewContactOfUnoControl& _rViewContact ) + :ViewObjectContactOfSdrObj( _rObjectContact, _rViewContact ) + ,m_pImpl( new ViewObjectContactOfUnoControl_Impl( this ) ) + { + DBG_CTOR( ViewObjectContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + ViewObjectContactOfUnoControl::~ViewObjectContactOfUnoControl() + { + m_pImpl->dispose(); + m_pImpl = NULL; + + DBG_DTOR( ViewObjectContactOfUnoControl, NULL ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl::isControlVisible() const + { + VOCGuard aGuard( *m_pImpl ); + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + return rControl.is() && rControl.isVisible(); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewObjectContactOfUnoControl::getControl() + { + VOCGuard aGuard( *m_pImpl ); + m_pImpl->ensureControl( NULL ); + return m_pImpl->getExistentControl().getControl(); + } + + //-------------------------------------------------------------------- + Reference< XControl > ViewObjectContactOfUnoControl::getTemporaryControlForWindow( + const Window& _rWindow, Reference< XControlContainer >& _inout_ControlContainer, const SdrUnoObj& _rUnoObject ) + { + ControlHolder aControl; + + InvisibleControlViewAccess aSimulatePageView( _inout_ControlContainer ); + OSL_VERIFY( ViewObjectContactOfUnoControl_Impl::createControlForDevice( aSimulatePageView, _rWindow, _rUnoObject, + _rWindow.GetViewTransformation(), _rWindow.GetInverseViewTransformation(), aControl ) ); + return aControl.getControl(); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::ensureControlVisibility( bool _bVisible ) const + { + VOCGuard aGuard( *m_pImpl ); + + try + { + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + if ( !rControl.is() ) + return; + + // only need to care for alive mode + if ( rControl.isDesignMode() ) + return; + + // is the visibility correct? + if ( m_pImpl->isControlVisible() == _bVisible ) + return; + + // no -> adjust it + rControl.setVisible( _bVisible ); + DBG_ASSERT( m_pImpl->isControlVisible() == _bVisible, "ViewObjectContactOfUnoControl::ensureControlVisibility: this didn't work!" ); + // now this would mean that either isControlVisible is not reliable, + // or that showing/hiding the window did not work as intended. + } + catch( const Exception& ) + { + DBG_UNHANDLED_EXCEPTION(); + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::setControlDesignMode( bool _bDesignMode ) const + { + VOCGuard aGuard( *m_pImpl ); + m_pImpl->setControlDesignMode( _bDesignMode ); + + if(!_bDesignMode) + { + // when live mode is switched on, a refresh is needed. The edit mode visualisation + // needs to be repainted and the now used VCL-Window needs to be positioned and + // sized. Both is done from the repant refresh. + const_cast< ViewObjectContactOfUnoControl* >(this)->ActionChanged(); + } + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactOfUnoControl::createPrimitive2DSequence(const DisplayInfo& /*rDisplayInfo*/) const + { + if ( m_pImpl->isDisposed() ) + // our control already died. + // TODO: Is it worth re-creating the control? Finally, this is a pathological situation, it means some instance + // disposed the control though it doesn't own it. So, /me thinks we should not bother here. + return drawinglayer::primitive2d::Primitive2DSequence(); + + // ignore existing controls which are in alive mode and manually switched to "invisible" + // #102090# / 2009-06-05 / frank.schoenheit@sun.com + const ControlHolder& rControl( m_pImpl->getExistentControl() ); + if ( rControl.is() && !rControl.isDesignMode() && !rControl.isVisible() ) + return drawinglayer::primitive2d::Primitive2DSequence(); + + ::drawinglayer::primitive2d::Primitive2DReference xPrimitive( new LazyControlCreationPrimitive2D( m_pImpl ) ); + return ::drawinglayer::primitive2d::Primitive2DSequence( &xPrimitive, 1 ); + } + + //-------------------------------------------------------------------- + bool ViewObjectContactOfUnoControl::isPrimitiveVisible( const DisplayInfo& _rDisplayInfo ) const + { + VOCGuard aGuard( *m_pImpl ); + + if ( m_pImpl->hasControl() ) + { + const ::drawinglayer::geometry::ViewInformation2D& rViewInformation( GetObjectContact().getViewInformation2D() ); + #if OSL_DEBUG_LEVEL > 1 + ::basegfx::B2DVector aScale, aTranslate; + double fRotate, fShearX; + rViewInformation.getObjectToViewTransformation().decompose( aScale, aTranslate, fRotate, fShearX ); + #endif + + if ( !rViewInformation.getViewport().isEmpty() ) + m_pImpl->positionAndZoomControl( rViewInformation.getObjectToViewTransformation() ); + } + + return ViewObjectContactOfSdrObj::isPrimitiveVisible( _rDisplayInfo ); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::propertyChange() + { + impl_onControlChangedOrModified(); + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::ActionChanged() + { + // call parent + ViewObjectContactOfSdrObj::ActionChanged(); + const ControlHolder& rControl(m_pImpl->getExistentControl()); + + if(rControl.is() && !rControl.isDesignMode()) + { + // #i93180# if layer visibility has changed and control is in live mode, it is necessary + // to correct visibility to make those control vanish on SdrObject LayerID changes + const SdrPageView* pSdrPageView = GetObjectContact().TryToGetSdrPageView(); + + if(pSdrPageView) + { + const SdrObject& rObject = getSdrObject(); + const bool bIsLayerVisible( rObject.IsVisible() && pSdrPageView->GetVisibleLayers().IsSet(rObject.GetLayer())); + + if(rControl.isVisible() != bIsLayerVisible) + { + rControl.setVisible(bIsLayerVisible); + } + } + } + } + + //-------------------------------------------------------------------- + void ViewObjectContactOfUnoControl::impl_onControlChangedOrModified() + { + // graphical invalidate at all views + ActionChanged(); + + // #i93318# flush Primitive2DSequence to force recreation with updated XControlModel + // since e.g. background color has changed and existing decompositions are possibly no + // longer valid. Unfortunately this is not detected from ControlPrimitive2D::operator== + // since it only has a uno reference to the XControlModel + flushPrimitive2DSequence(); + } + + //==================================================================== + //= UnoControlPrintOrPreviewContact + //==================================================================== + DBG_NAME( UnoControlPrintOrPreviewContact ) + //-------------------------------------------------------------------- + UnoControlPrintOrPreviewContact::UnoControlPrintOrPreviewContact( ObjectContactOfPageView& _rObjectContact, ViewContactOfUnoControl& _rViewContact ) + :ViewObjectContactOfUnoControl( _rObjectContact, _rViewContact ) + { + DBG_CTOR( UnoControlPrintOrPreviewContact, NULL ); + } + + //-------------------------------------------------------------------- + UnoControlPrintOrPreviewContact::~UnoControlPrintOrPreviewContact() + { + DBG_DTOR( UnoControlPrintOrPreviewContact, NULL ); + } + + //-------------------------------------------------------------------- + drawinglayer::primitive2d::Primitive2DSequence UnoControlPrintOrPreviewContact::createPrimitive2DSequence(const DisplayInfo& rDisplayInfo ) const + { + if ( !m_pImpl->isPrintableControl() ) + return drawinglayer::primitive2d::Primitive2DSequence(); + return ViewObjectContactOfUnoControl::createPrimitive2DSequence( rDisplayInfo ); + } + +//........................................................................ +} } // namespace sdr::contact +//........................................................................ + diff --git a/svx/source/sdr/contact/viewobjectcontactredirector.cxx b/svx/source/sdr/contact/viewobjectcontactredirector.cxx new file mode 100644 index 000000000000..8d96b17f0a58 --- /dev/null +++ b/svx/source/sdr/contact/viewobjectcontactredirector.cxx @@ -0,0 +1,60 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +// MARKER(update_precomp.py): autogen include statement, do not remove +#include "precompiled_svx.hxx" +#include <svx/sdr/contact/viewobjectcontactredirector.hxx> +#include <svx/sdr/contact/viewobjectcontact.hxx> +#include <svx/sdr/contact/viewcontact.hxx> + +////////////////////////////////////////////////////////////////////////////// + +namespace sdr +{ + namespace contact + { + // basic constructor. + ViewObjectContactRedirector::ViewObjectContactRedirector() + { + } + + // The destructor. + ViewObjectContactRedirector::~ViewObjectContactRedirector() + { + } + + drawinglayer::primitive2d::Primitive2DSequence ViewObjectContactRedirector::createRedirectedPrimitive2DSequence( + const sdr::contact::ViewObjectContact& rOriginal, + const sdr::contact::DisplayInfo& rDisplayInfo) + { + return rOriginal.createPrimitive2DSequence(rDisplayInfo); + } + } // end of namespace contact +} // end of namespace sdr + +////////////////////////////////////////////////////////////////////////////// +// eof |