/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 . */ #include #include #include #include #include #include #ifdef DBG_UTIL #include #endif #include #include #include #include #include #include #include #include #include #include #include "svdibrow.hxx" #include "svx/svditer.hxx" #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace ::com::sun::star; // interface to SdrPaintWindow SdrPaintWindow* SdrPaintView::FindPaintWindow(const OutputDevice& rOut) const { for(SdrPaintWindowVector::const_iterator a = maPaintWindows.begin(); a != maPaintWindows.end(); ++a) { if(&((*a)->GetOutputDevice()) == &rOut) { return *a; } } return 0L; } SdrPaintWindow* SdrPaintView::GetPaintWindow(sal_uInt32 nIndex) const { if(nIndex < maPaintWindows.size()) { return maPaintWindows[nIndex]; } return 0L; } void SdrPaintView::AppendPaintWindow(SdrPaintWindow& rNew) { maPaintWindows.push_back(&rNew); } SdrPaintWindow* SdrPaintView::RemovePaintWindow(SdrPaintWindow& rOld) { SdrPaintWindow* pRetval = 0L; const SdrPaintWindowVector::iterator aFindResult = ::std::find(maPaintWindows.begin(), maPaintWindows.end(), &rOld); if(aFindResult != maPaintWindows.end()) { // remember return value, aFindResult is no longer valid after deletion pRetval = *aFindResult; maPaintWindows.erase(aFindResult); } return pRetval; } OutputDevice* SdrPaintView::GetFirstOutputDevice() const { if(PaintWindowCount()) { return &(GetPaintWindow(0)->GetOutputDevice()); } return 0L; } SvxViewHint::SvxViewHint (HintType eHintType) : meHintType(eHintType) { } BitmapEx convertMetafileToBitmapEx( const GDIMetaFile& rMtf, const basegfx::B2DRange& rTargetRange, const sal_uInt32 nMaximumQuadraticPixels) { BitmapEx aBitmapEx; if(rMtf.GetActionSize()) { const drawinglayer::primitive2d::Primitive2DReference aMtf( new drawinglayer::primitive2d::MetafilePrimitive2D( basegfx::tools::createScaleTranslateB2DHomMatrix( rTargetRange.getRange(), rTargetRange.getMinimum()), rMtf)); aBitmapEx = convertPrimitive2DSequenceToBitmapEx( drawinglayer::primitive2d::Primitive2DSequence(&aMtf, 1), rTargetRange, nMaximumQuadraticPixels); } return aBitmapEx; } TYPEINIT2(SdrPaintView,SfxListener,SfxRepeatTarget); void SdrPaintView::ImpClearVars() { #ifdef DBG_UTIL pItemBrowser=NULL; #endif bPageVisible=true; bPageBorderVisible=true; bBordVisible=true; bGridVisible=true; bGridFront =false; bHlplVisible=true; bHlplFront =true; bGlueVisible=false; bGlueVisible2=false; bGlueVisible3=false; bGlueVisible4=false; bSwapAsynchron=false; bPrintPreview=false; mbPreviewRenderer=false; eAnimationMode = SDR_ANIMATION_ANIMATE; bAnimationPause = false; nHitTolPix=2; nMinMovPix=3; nHitTolLog=0; nMinMovLog=0; pActualOutDev=NULL; pDragWin=NULL; bRestoreColors=true; pDefaultStyleSheet=NULL; bSomeObjChgdFlag=false; nGraphicManagerDrawMode = GRFMGR_DRAW_STANDARD; aComeBackIdle.SetPriority(VCL_IDLE_PRIORITY_REPAINT); aComeBackIdle.SetIdleHdl(LINK(this,SdrPaintView,ImpComeBackHdl)); if (pMod) SetDefaultStyleSheet(pMod->GetDefaultStyleSheet(), true); maGridColor = Color( COL_BLACK ); } SdrPaintView::SdrPaintView(SdrModel* pModel1, OutputDevice* pOut) : mpPageView(NULL), aDefaultAttr(pModel1->GetItemPool()), mbBufferedOutputAllowed(false), mbBufferedOverlayAllowed(false), mbPagePaintingAllowed(true), mbHideOle(false), mbHideChart(false), mbHideDraw(false), mbHideFormControl(false) { pMod=pModel1; ImpClearVars(); if(pOut) { AddWindowToPaintView(pOut); } // flag to visualize groups bVisualizeEnteredGroup = true; maColorConfig.AddListener(this); onChangeColorConfig(); } SdrPaintView::~SdrPaintView() { if (pDefaultStyleSheet) EndListening(*pDefaultStyleSheet); maColorConfig.RemoveListener(this); ClearPageView(); #ifdef DBG_UTIL if(pItemBrowser) { delete pItemBrowser; } #endif // delete existing SdrPaintWindows while(!maPaintWindows.empty()) { delete maPaintWindows.back(); maPaintWindows.pop_back(); } } void SdrPaintView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint) { //If the stylesheet has been destroyed if (&rBC == pDefaultStyleSheet) { const SfxSimpleHint* pSimpleHint = dynamic_cast(&rHint); if (pSimpleHint && pSimpleHint->GetId() == SFX_HINT_DYING) pDefaultStyleSheet = NULL; return; } bool bObjChg=!bSomeObjChgdFlag; // if true, evaluate for ComeBack timer if (bObjChg) { const SdrHint* pSdrHint = dynamic_cast(&rHint); if (pSdrHint) { SdrHintKind eKind=pSdrHint->GetKind(); if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED) { if (bObjChg) { bSomeObjChgdFlag=true; aComeBackIdle.Start(); } } if (eKind==HINT_PAGEORDERCHG) { const SdrPage* pPg=pSdrHint->GetPage(); if(pPg && !pPg->IsInserted()) { if(mpPageView && mpPageView->GetPage() == pPg) { HideSdrPage(); } } } } } } void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster* , sal_uInt32 ) { onChangeColorConfig(); InvalidateAllWin(); } IMPL_LINK_NOARG_INLINE_START(SdrPaintView, ImpComeBackHdl) { if (bSomeObjChgdFlag) { bSomeObjChgdFlag=false; ModelHasChanged(); } return 0; } IMPL_LINK_NOARG_INLINE_END(SdrPaintView,ImpComeBackHdl) void SdrPaintView::FlushComeBackTimer() const { if (bSomeObjChgdFlag) { // casting to nonconst ((SdrPaintView*)this)->ImpComeBackHdl(&((SdrPaintView*)this)->aComeBackIdle); ((SdrPaintView*)this)->aComeBackIdle.Stop(); } } void SdrPaintView::ModelHasChanged() { // broadcast to all PageViews if(mpPageView && !mpPageView->GetPage()->IsInserted()) { HideSdrPage(); } // test mpPageView here again, HideSdrPage() may have invalidated it. if(mpPageView) { mpPageView->ModelHasChanged(); } #ifdef DBG_UTIL if(pItemBrowser) { pItemBrowser->SetDirty(); } #endif } bool SdrPaintView::IsAction() const { return false; } void SdrPaintView::MovAction(const Point&) { } void SdrPaintView::EndAction() { } void SdrPaintView::BckAction() { } void SdrPaintView::BrkAction() { } void SdrPaintView::TakeActionRect(Rectangle&) const { } // info about TextEdit. Default is false. bool SdrPaintView::IsTextEdit() const { return false; } // info about TextEditPageView. Default is 0L. SdrPageView* SdrPaintView::GetTextEditPageView() const { return 0L; } sal_uInt16 SdrPaintView::ImpGetMinMovLogic(short nMinMov, const OutputDevice* pOut) const { if (nMinMov>=0) return sal_uInt16(nMinMov); if (pOut==NULL) { pOut = GetFirstOutputDevice(); } if (pOut!=NULL) { return short(-pOut->PixelToLogic(Size(nMinMov,0)).Width()); } else { return 0; } } sal_uInt16 SdrPaintView::ImpGetHitTolLogic(short nHitTol, const OutputDevice* pOut) const { if (nHitTol>=0) return sal_uInt16(nHitTol); if (pOut==NULL) { pOut = GetFirstOutputDevice(); } if (pOut!=NULL) { return short(-pOut->PixelToLogic(Size(nHitTol,0)).Width()); } else { return 0; } } void SdrPaintView::TheresNewMapMode() { if (pActualOutDev!=NULL) { nHitTolLog=(sal_uInt16)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nHitTolPix,0)).Width(); nMinMovLog=(sal_uInt16)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nMinMovPix,0)).Width(); } } void SdrPaintView::SetActualWin(const OutputDevice* pWin) { pActualOutDev=pWin; TheresNewMapMode(); } void SdrPaintView::ClearPageView() { BrkAction(); if(mpPageView) { InvalidateAllWin(); delete mpPageView; mpPageView = 0L; } } SdrPageView* SdrPaintView::ShowSdrPage(SdrPage* pPage) { if(pPage && (!mpPageView || mpPageView->GetPage() != pPage)) { if(mpPageView) { InvalidateAllWin(); delete mpPageView; } mpPageView = new SdrPageView(pPage, *static_cast(this)); mpPageView->Show(); } return mpPageView; } void SdrPaintView::HideSdrPage() { if(mpPageView) { mpPageView->Hide(); delete mpPageView; mpPageView = 0L; } } void SdrPaintView::AddWindowToPaintView(OutputDevice* pNewWin) { DBG_ASSERT(pNewWin, "SdrPaintView::AddWindowToPaintView: No OutputDevice(!)"); SdrPaintWindow* pNewPaintWindow = new SdrPaintWindow(*this, *pNewWin); AppendPaintWindow(*pNewPaintWindow); if(mpPageView) { mpPageView->AddPaintWindowToPageView(*pNewPaintWindow); } #ifdef DBG_UTIL if (pItemBrowser!=NULL) pItemBrowser->ForceParent(); #endif } void SdrPaintView::DeleteWindowFromPaintView(OutputDevice* pOldWin) { assert(pOldWin && "SdrPaintView::DeleteWindowFromPaintView: No OutputDevice(!)"); SdrPaintWindow* pCandidate = FindPaintWindow(*pOldWin); if(pCandidate) { if(mpPageView) { mpPageView->RemovePaintWindowFromPageView(*pCandidate); } RemovePaintWindow(*pCandidate); delete pCandidate; } #ifdef DBG_UTIL if (pItemBrowser!=NULL) pItemBrowser->ForceParent(); #endif } void SdrPaintView::SetLayerVisible(const OUString& rName, bool bShow) { if(mpPageView) { mpPageView->SetLayerVisible(rName, bShow); } InvalidateAllWin(); } bool SdrPaintView::IsLayerVisible(const OUString& rName) const { if(mpPageView) { return mpPageView->IsLayerVisible(rName); } return false; } void SdrPaintView::SetLayerLocked(const OUString& rName, bool bLock) { if(mpPageView) { mpPageView->SetLayerLocked(rName,bLock); } } bool SdrPaintView::IsLayerLocked(const OUString& rName) const { if(mpPageView) { return mpPageView->IsLayerLocked(rName); } return false; } void SdrPaintView::SetLayerPrintable(const OUString& rName, bool bPrn) { if(mpPageView) { mpPageView->SetLayerPrintable(rName,bPrn); } } bool SdrPaintView::IsLayerPrintable(const OUString& rName) const { if(mpPageView) { return mpPageView->IsLayerPrintable(rName); } return false; } void SdrPaintView::PrePaint() { if(mpPageView) { mpPageView->PrePaint(); } } // #define SVX_REPAINT_TIMER_TEST void SdrPaintView::CompleteRedraw(OutputDevice* pOut, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector) { #ifdef SVX_REPAINT_TIMER_TEST #define REMEMBERED_TIMES_COUNT (10) static bool bDoTimerTest(false); static bool bTimesInited(false); static sal_uInt32 nRepeatCount(10L); static double fLastTimes[REMEMBERED_TIMES_COUNT]; const sal_uInt32 nStartTime(tools::Time::GetSystemTicks()); sal_uInt32 count(1L); sal_uInt32 a; if(bDoTimerTest) { count = nRepeatCount; } for(a = 0L; a < count; a++) { #endif // SVX_REPAINT_TIMER_TEST // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region // rReg may be made more granular (fine) with using it. Normally, rReg // does come from Window::Paint() anyways and thus is based on a single // rectangle which was derived from exactly that repaint region vcl::Region aOptimizedRepaintRegion(rReg); if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType()) { vcl::Window* pWindow = static_cast(pOut); if(pWindow->IsInPaint()) { if(!pWindow->GetPaintRegion().IsEmpty()) { aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion()); #ifdef DBG_UTIL // #i74769# test-paint repaint region static bool bDoPaintForVisualControl(false); if(bDoPaintForVisualControl) { RectangleVector aRectangles; aOptimizedRepaintRegion.GetRegionRectangles(aRectangles); pWindow->SetLineColor(COL_LIGHTGREEN); pWindow->SetFillColor(); for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); ++aRectIter) { pWindow->DrawRect(*aRectIter); } //RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects()); //Rectangle aRegionRectangle; //while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle)) //{ // pWindow->SetLineColor(COL_LIGHTGREEN); // pWindow->SetFillColor(); // pWindow->DrawRect(aRegionRectangle); //} //aOptimizedRepaintRegion.EndEnumRects(aRegionHandle); } #endif } } } SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut); OSL_ENSURE(pPaintWindow, "SdrPaintView::CompleteRedraw: No OutDev (!)"); DoCompleteRedraw(*pPaintWindow, aOptimizedRepaintRegion, pRedirector); EndCompleteRedraw(*pPaintWindow, true); #ifdef SVX_REPAINT_TIMER_TEST } if(bDoTimerTest) { const sal_uInt32 nStopTime(tools::Time::GetSystemTicks()); const sal_uInt32 nNeededTime(nStopTime - nStartTime); const double fTimePerPaint((double)nNeededTime / (double)nRepeatCount); if(!bTimesInited) { for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++) { fLastTimes[a] = fTimePerPaint; } bTimesInited = true; } else { for(a = 1L; a < REMEMBERED_TIMES_COUNT; a++) { fLastTimes[a - 1L] = fLastTimes[a]; } fLastTimes[REMEMBERED_TIMES_COUNT - 1L] = fTimePerPaint; } double fAddedTimes(0.0); for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++) { fAddedTimes += fLastTimes[a]; } const double fAverageTimePerPaint(fAddedTimes / (double)REMEMBERED_TIMES_COUNT); fprintf(stderr, "-----------(start result)----------\n"); fprintf(stderr, "StartTime : %u, StopTime: %u, NeededTime: %u, TimePerPaint: %f\n", nStartTime, nStopTime, nNeededTime, fTimePerPaint); fprintf(stderr, "Remembered times: "); for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++) { fprintf(stderr, "%d: %f ", a, fLastTimes[a]); } fprintf(stderr, "\n"); fprintf(stderr, "AverageTimePerPaint: %f\n", fAverageTimePerPaint); fprintf(stderr, "-----------(stop result)----------\n"); } #endif // SVX_REPAINT_TIMER_TEST } // #i72889# SdrPaintWindow* SdrPaintView::BeginCompleteRedraw(OutputDevice* pOut) { OSL_ENSURE(pOut, "SdrPaintView::BeginCompleteRedraw: No OutDev (!)"); SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut); if(pPaintWindow) { // draw preprocessing, only for known devices // prepare PreRendering pPaintWindow->PreparePreRenderDevice(); } else { // None of the known OutputDevices is the target of this paint, use // a temporary SdrPaintWindow for this Redraw. pPaintWindow = new SdrPaintWindow(*this, *pOut); pPaintWindow->setTemporaryTarget(true); } return pPaintWindow; } void SdrPaintView::DoCompleteRedraw(SdrPaintWindow& rPaintWindow, const vcl::Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector) { // redraw all PageViews with the target. This may expand the RedrawRegion // at the PaintWindow, plus taking care of FormLayer expansion if(mpPageView) { mpPageView->CompleteRedraw(rPaintWindow, rReg, pRedirector); } } void SdrPaintView::EndCompleteRedraw(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer) { if(rPaintWindow.getTemporaryTarget()) { // get rid of temp target again delete (&rPaintWindow); } else { // draw postprocessing, only for known devices // it is necessary to always paint FormLayer if(bPaintFormLayer) { ImpFormLayerDrawing(rPaintWindow); } // look for active TextEdit. As long as this cannot be painted to a VDev, // it cannot get part of buffering. In that case, output evtl. prerender // early and paint text edit to window. if(IsTextEdit() && GetSdrPageView()) { static_cast< SdrView* >(this)->TextEditDrawing(rPaintWindow); } // draw Overlay, also to PreRender device if exists rPaintWindow.DrawOverlay(rPaintWindow.GetRedrawRegion()); // output PreRendering rPaintWindow.OutputPreRenderDevice(rPaintWindow.GetRedrawRegion()); } } SdrPaintWindow* SdrPaintView::BeginDrawLayers(OutputDevice* pOut, const vcl::Region& rReg, bool bDisableIntersect) { // #i74769# use BeginCompleteRedraw() as common base SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut); OSL_ENSURE(pPaintWindow, "SdrPaintView::BeginDrawLayers: No SdrPaintWindow (!)"); if(mpPageView) { SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(*pPaintWindow); if(pKnownTarget) { vcl::Region aOptimizedRepaintRegion = OptimizeDrawLayersRegion( pOut, rReg, bDisableIntersect ); // prepare redraw pKnownTarget->PrepareRedraw(aOptimizedRepaintRegion); // remember prepared SdrPageWindow mpPageView->setPreparedPageWindow(pKnownTarget); } } return pPaintWindow; } void SdrPaintView::EndDrawLayers(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer) { // #i74769# use EndCompleteRedraw() as common base EndCompleteRedraw(rPaintWindow, bPaintFormLayer); if(mpPageView) { // forget prepared SdrPageWindow mpPageView->setPreparedPageWindow(0); } } void SdrPaintView::UpdateDrawLayersRegion(OutputDevice* pOut, const vcl::Region& rReg, bool bDisableIntersect) { SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut); OSL_ENSURE(pPaintWindow, "SdrPaintView::UpdateDrawLayersRegion: No SdrPaintWindow (!)"); if(mpPageView) { SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(*pPaintWindow); if(pKnownTarget) { vcl::Region aOptimizedRepaintRegion = OptimizeDrawLayersRegion( pOut, rReg, bDisableIntersect ); pKnownTarget->GetPaintWindow().SetRedrawRegion(aOptimizedRepaintRegion); mpPageView->setPreparedPageWindow(pKnownTarget); // already set actually } } } vcl::Region SdrPaintView::OptimizeDrawLayersRegion(OutputDevice* pOut, const vcl::Region& rReg, bool bDisableIntersect) { // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region // rReg may be made more granular (fine) with using it. Normally, rReg // does come from Window::Paint() anyways and thus is based on a single // rectangle which was derived from exactly that repaint region vcl::Region aOptimizedRepaintRegion(rReg); // #i76114# Intersecting the region with the Window's paint region is disabled // for print preview in Calc, because the intersection can be empty (if the paint // region is outside of the table area of the page), and then no clip region // would be set. if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType() && !bDisableIntersect) { vcl::Window* pWindow = static_cast(pOut); if(pWindow->IsInPaint()) { if(!pWindow->GetPaintRegion().IsEmpty()) { aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion()); } } } return aOptimizedRepaintRegion; } void SdrPaintView::ImpFormLayerDrawing( SdrPaintWindow& rPaintWindow ) { if(mpPageView) { SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(rPaintWindow); if(pKnownTarget) { const SdrModel& rModel = *(GetModel()); const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin(); const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), false); // BUFFERED use GetTargetOutputDevice() now, it may be targeted to VDevs, too // need to set PreparedPageWindow to make DrawLayer use the correct ObjectContact mpPageView->setPreparedPageWindow(pKnownTarget); mpPageView->DrawLayer(nControlLayerId, &rPaintWindow.GetTargetOutputDevice()); mpPageView->setPreparedPageWindow(0); } } } bool SdrPaintView::KeyInput(const KeyEvent& /*rKEvt*/, vcl::Window* /*pWin*/) { return false; } void SdrPaintView::GlueInvalidate() const { const sal_uInt32 nWindowCount(PaintWindowCount()); for(sal_uInt32 nWinNum(0L); nWinNum < nWindowCount; nWinNum++) { SdrPaintWindow* pPaintWindow = GetPaintWindow(nWinNum); if(pPaintWindow->OutputToWindow()) { OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); if(mpPageView) { const SdrObjList* pOL=mpPageView->GetObjList(); const size_t nObjAnz = pOL->GetObjCount(); for (size_t nObjNum=0; nObjNumGetObj(nObjNum); const SdrGluePointList* pGPL=pObj->GetGluePointList(); if (pGPL!=NULL && pGPL->GetCount()!=0) { pGPL->Invalidate(static_cast(rOutDev), pObj); } } } } } } void SdrPaintView::InvalidateAllWin() { const sal_uInt32 nWindowCount(PaintWindowCount()); for(sal_uInt32 a(0L); a < nWindowCount; a++) { SdrPaintWindow* pPaintWindow = GetPaintWindow(a); if(pPaintWindow->OutputToWindow()) { InvalidateOneWin(static_cast(pPaintWindow->GetOutputDevice())); } } } void SdrPaintView::InvalidateAllWin(const Rectangle& rRect, bool bPlus1Pix) { const sal_uInt32 nWindowCount(PaintWindowCount()); for(sal_uInt32 a(0L); a < nWindowCount; a++) { SdrPaintWindow* pPaintWindow = GetPaintWindow(a); if(pPaintWindow->OutputToWindow()) { OutputDevice& rOutDev = pPaintWindow->GetOutputDevice(); Rectangle aRect(rRect); if(bPlus1Pix) { Size aPixSiz(1,1); Size aSiz(rOutDev.PixelToLogic(aPixSiz)); aRect.Left ()-=aSiz.Width(); aRect.Top ()-=aSiz.Height(); aRect.Right ()+=aSiz.Width(); aRect.Bottom()+=aSiz.Height(); } Point aOrg(rOutDev.GetMapMode().GetOrigin()); aOrg.X()=-aOrg.X(); aOrg.Y()=-aOrg.Y(); Rectangle aOutRect(aOrg, rOutDev.GetOutputSize()); if (aRect.IsOver(aOutRect)) { InvalidateOneWin(static_cast(rOutDev), aRect); } } } } void SdrPaintView::InvalidateOneWin(vcl::Window& rWin) { // do not erase background, that causes flicker (!) rWin.Invalidate(INVALIDATE_NOERASE); } void SdrPaintView::InvalidateOneWin(vcl::Window& rWin, const Rectangle& rRect) { // do not erase background, that causes flicker (!) rWin.Invalidate(rRect, INVALIDATE_NOERASE); } void SdrPaintView::LeaveOneGroup() { if(mpPageView) { mpPageView->LeaveOneGroup(); } } void SdrPaintView::LeaveAllGroup() { if(mpPageView) { mpPageView->LeaveAllGroup(); } } bool SdrPaintView::IsGroupEntered() const { if(mpPageView) { return (mpPageView->GetEnteredLevel() != 0); } return false; } void SdrPaintView::SetNotPersistDefaultAttr(const SfxItemSet& rAttr, bool /*bReplaceAll*/) { // bReplaceAll has no effect here at all. bool bMeasure=ISA(SdrView) && static_cast(this)->IsMeasureTool(); const SfxPoolItem *pPoolItem=NULL; if (rAttr.GetItemState(SDRATTR_LAYERID,true,&pPoolItem)==SfxItemState::SET) { SdrLayerID nLayerId=static_cast(pPoolItem)->GetValue(); const SdrLayer* pLayer=pMod->GetLayerAdmin().GetLayerPerID(nLayerId); if (pLayer!=NULL) { if (bMeasure) aMeasureLayer=pLayer->GetName(); else aAktLayer=pLayer->GetName(); } } if (rAttr.GetItemState(SDRATTR_LAYERNAME,true,&pPoolItem)==SfxItemState::SET) { if (bMeasure) aMeasureLayer=static_cast(pPoolItem)->GetValue(); else aAktLayer=static_cast(pPoolItem)->GetValue(); } } void SdrPaintView::MergeNotPersistDefaultAttr(SfxItemSet& rAttr, bool /*bOnlyHardAttr*/) const { // bOnlyHardAttr has no effect here at all. bool bMeasure=ISA(SdrView) && static_cast(this)->IsMeasureTool(); const OUString& aNam = bMeasure ? aMeasureLayer : aAktLayer; rAttr.Put(SdrLayerNameItem(aNam)); SdrLayerID nLayer=pMod->GetLayerAdmin().GetLayerID(aNam,true); if (nLayer!=SDRLAYER_NOTFOUND) { rAttr.Put(SdrLayerIdItem(nLayer)); } } void SdrPaintView::SetDefaultAttr(const SfxItemSet& rAttr, bool bReplaceAll) { #ifdef DBG_UTIL { bool bHasEEFeatureItems=false; SfxItemIter aIter(rAttr); const SfxPoolItem* pItem=aIter.FirstItem(); while (!bHasEEFeatureItems && pItem!=NULL) { if (!IsInvalidItem(pItem)) { sal_uInt16 nW=pItem->Which(); if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=true; } pItem=aIter.NextItem(); } if(bHasEEFeatureItems) { OUString aMessage("SdrPaintView::SetDefaultAttr(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents."); InfoBox(NULL, aMessage).Execute(); } } #endif if (bReplaceAll) aDefaultAttr.Set(rAttr); else aDefaultAttr.Put(rAttr,false); // if FALSE, regard InvalidItems as "holes," not as Default SetNotPersistDefaultAttr(rAttr,bReplaceAll); #ifdef DBG_UTIL if (pItemBrowser!=NULL) pItemBrowser->SetDirty(); #endif } void SdrPaintView::SetDefaultStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) { if (pDefaultStyleSheet) EndListening(*pDefaultStyleSheet); pDefaultStyleSheet=pStyleSheet; if (pDefaultStyleSheet) StartListening(*pDefaultStyleSheet); if (pStyleSheet!=NULL && !bDontRemoveHardAttr) { SfxWhichIter aIter(pStyleSheet->GetItemSet()); sal_uInt16 nWhich=aIter.FirstWhich(); while (nWhich!=0) { if (pStyleSheet->GetItemSet().GetItemState(nWhich,true)==SfxItemState::SET) { aDefaultAttr.ClearItem(nWhich); } nWhich=aIter.NextWhich(); } } #ifdef DBG_UTIL if (pItemBrowser!=NULL) pItemBrowser->SetDirty(); #endif } bool SdrPaintView::GetAttributes(SfxItemSet& rTargetSet, bool bOnlyHardAttr) const { if(bOnlyHardAttr || !pDefaultStyleSheet) { rTargetSet.Put(aDefaultAttr, false); } else { // else merge with DefStyleSheet rTargetSet.Put(pDefaultStyleSheet->GetItemSet(), false); rTargetSet.Put(aDefaultAttr, false); } MergeNotPersistDefaultAttr(rTargetSet, bOnlyHardAttr); return true; } bool SdrPaintView::SetAttributes(const SfxItemSet& rSet, bool bReplaceAll) { SetDefaultAttr(rSet,bReplaceAll); return true; } SfxStyleSheet* SdrPaintView::GetStyleSheet() const { return GetDefaultStyleSheet(); } bool SdrPaintView::SetStyleSheet(SfxStyleSheet* pStyleSheet, bool bDontRemoveHardAttr) { SetDefaultStyleSheet(pStyleSheet,bDontRemoveHardAttr); return true; } #ifdef DBG_UTIL void SdrPaintView::ShowItemBrowser(bool bShow) { if (bShow) { if (pItemBrowser==NULL) { pItemBrowser=new SdrItemBrowser(*static_cast(this)); pItemBrowser->SetFloatingMode(true); } pItemBrowser->Show(); pItemBrowser->GrabFocus(); } else { if (pItemBrowser!=NULL) { pItemBrowser->Hide(); delete pItemBrowser; pItemBrowser=NULL; } } } #endif void SdrPaintView::MakeVisible(const Rectangle& rRect, vcl::Window& rWin) { MapMode aMap(rWin.GetMapMode()); Size aActualSize(rWin.GetOutputSize()); if( aActualSize.Height() > 0 && aActualSize.Width() > 0 ) { Size aNewSize(rRect.GetSize()); bool bNewScale=false; bool bNeedMoreX=aNewSize.Width()>aActualSize.Width(); bool bNeedMoreY=aNewSize.Height()>aActualSize.Height(); if (bNeedMoreX || bNeedMoreY) { bNewScale=true; // set new MapMode (Size+Org) and invalidate everything Fraction aXFact(aNewSize.Width(),aActualSize.Width()); Fraction aYFact(aNewSize.Height(),aActualSize.Height()); if (aYFact>aXFact) aXFact=aYFact; aXFact*=aMap.GetScaleX(); aXFact.ReduceInaccurate(10); // to avoid runovers and BigInt mapping aMap.SetScaleX(aXFact); aMap.SetScaleY(aYFact); rWin.SetMapMode(aMap); aActualSize=rWin.GetOutputSize(); } Point aOrg(aMap.GetOrigin()); long dx=0,dy=0; long l=-aOrg.X(); long r=-aOrg.X()+aActualSize.Width()-1; long o=-aOrg.Y(); long u=-aOrg.Y()+aActualSize.Height()-1; if (l>rRect.Left()) dx=rRect.Left()-l; else if (rrRect.Top()) dy=rRect.Top()-o; else if (uPageWindowCount(); b++) { SdrPageWindow& rPageWindow = *(mpPageView->GetPageWindow(b)); sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact(); sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator(); if(rAnimator.IsPaused() != bSet) { rAnimator.SetPaused(bSet); } } } } } void SdrPaintView::SetAnimationMode( const SdrAnimationMode eMode ) { eAnimationMode = eMode; } void SdrPaintView::VisAreaChanged(const OutputDevice* pOut) { if(mpPageView) { if (pOut) { SdrPageWindow* pWindow = mpPageView->FindPageWindow(*((OutputDevice*)pOut)); if(pWindow) { VisAreaChanged(*pWindow); } } else { for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++) { VisAreaChanged(*mpPageView->GetPageWindow(a)); } } } } void SdrPaintView::VisAreaChanged(const SdrPageWindow& /*rWindow*/) { // notify SfxListener Broadcast(SvxViewHint(SvxViewHint::SVX_HINT_VIEWCHANGED)); } void SdrPaintView::onChangeColorConfig() { SetGridColor( Color( maColorConfig.GetColorValue( svtools::DRAWGRID ).nColor ) ); } void SdrPaintView::SetGridColor( Color aColor ) { maGridColor = aColor; } // Set background color for svx at SdrPageViews void SdrPaintView::SetApplicationBackgroundColor(Color aBackgroundColor) { if(mpPageView) { mpPageView->SetApplicationBackgroundColor(aBackgroundColor); } } // Set document color for svx at SdrPageViews void SdrPaintView::SetApplicationDocumentColor(Color aDocumentColor) { if(mpPageView) { mpPageView->SetApplicationDocumentColor(aDocumentColor); } } bool SdrPaintView::IsBufferedOutputAllowed() const { return (mbBufferedOutputAllowed && maDrawinglayerOpt.IsPaintBuffer()); } void SdrPaintView::SetBufferedOutputAllowed(bool bNew) { if(bNew != (bool)mbBufferedOutputAllowed) { mbBufferedOutputAllowed = bNew; } } bool SdrPaintView::IsBufferedOverlayAllowed() const { return (mbBufferedOverlayAllowed && maDrawinglayerOpt.IsOverlayBuffer()); } void SdrPaintView::SetBufferedOverlayAllowed(bool bNew) { if(bNew != (bool)mbBufferedOverlayAllowed) { mbBufferedOverlayAllowed = bNew; } } void SdrPaintView::SetPagePaintingAllowed(bool bNew) { if(bNew != (bool)mbPagePaintingAllowed) { mbPagePaintingAllowed = bNew; } } // #i38135# Sets the timer for Object animations and restarts. void SdrPaintView::SetAnimationTimer(sal_uInt32 nTime) { if(mpPageView) { // first, reset all timers at all windows to 0L for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++) { SdrPageWindow& rPageWindow = *mpPageView->GetPageWindow(a); sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact(); sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator(); rAnimator.SetTime(nTime); } } } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */