diff options
Diffstat (limited to 'svx/source/sdr/contact/objectcontactofpageview.cxx')
-rw-r--r-- | svx/source/sdr/contact/objectcontactofpageview.cxx | 485 |
1 files changed, 485 insertions, 0 deletions
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 |