1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <com/sun/star/awt/XWindow.hpp>
21 #include <svx/svdpntv.hxx>
22 #include <vcl/msgbox.hxx>
23 #include <svx/sdrpaintwindow.hxx>
24 #include <svtools/grfmgr.hxx>
25 #include <svx/svdmodel.hxx>
28 #include <svdibrow.hxx>
30 #include <svx/svdpage.hxx>
31 #include <svx/svdpagv.hxx>
32 #include <svl/smplhint.hxx>
34 #include <editeng/editdata.hxx>
35 #include <svx/svdmrkv.hxx>
36 #include <svx/svdundo.hxx>
37 #include <svx/svdview.hxx>
38 #include <svx/svdglue.hxx>
39 #include <svx/svdobj.hxx>
40 #include <svx/svdograf.hxx>
41 #include "svdibrow.hxx"
42 #include "svx/svditer.hxx"
43 #include <svx/svdouno.hxx>
44 #include <svx/sdr/overlay/overlayobjectlist.hxx>
45 #include <sdr/overlay/overlayrollingrectangle.hxx>
46 #include <svx/sdr/overlay/overlaymanager.hxx>
47 #include <sxlayitm.hxx>
48 #include <svl/itemiter.hxx>
49 #include <editeng/eeitem.hxx>
50 #include <svl/whiter.hxx>
51 #include <svl/style.hxx>
52 #include <svx/sdrpagewindow.hxx>
53 #include <vcl/svapp.hxx>
54 #include <com/sun/star/awt/PosSize.hpp>
55 #include <com/sun/star/awt/XControl.hpp>
56 #include <svx/sdr/contact/objectcontact.hxx>
57 #include <svx/sdr/animation/objectanimator.hxx>
58 #include <svx/sdr/contact/viewcontact.hxx>
59 #include <drawinglayer/primitive2d/metafileprimitive2d.hxx>
60 #include <basegfx/matrix/b2dhommatrixtools.hxx>
62 using namespace ::rtl
;
63 using namespace ::com::sun::star
;
66 // interface to SdrPaintWindow
68 SdrPaintWindow
* SdrPaintView::FindPaintWindow(const OutputDevice
& rOut
) const
70 for(SdrPaintWindowVector::const_iterator a
= maPaintWindows
.begin(); a
!= maPaintWindows
.end(); ++a
)
72 if(&((*a
)->GetOutputDevice()) == &rOut
)
81 SdrPaintWindow
* SdrPaintView::GetPaintWindow(sal_uInt32 nIndex
) const
83 if(nIndex
< maPaintWindows
.size())
85 return maPaintWindows
[nIndex
];
91 void SdrPaintView::AppendPaintWindow(SdrPaintWindow
& rNew
)
93 maPaintWindows
.push_back(&rNew
);
96 SdrPaintWindow
* SdrPaintView::RemovePaintWindow(SdrPaintWindow
& rOld
)
98 SdrPaintWindow
* pRetval
= 0L;
99 const SdrPaintWindowVector::iterator aFindResult
= ::std::find(maPaintWindows
.begin(), maPaintWindows
.end(), &rOld
);
101 if(aFindResult
!= maPaintWindows
.end())
103 // remember return value, aFindResult is no longer valid after deletion
104 pRetval
= *aFindResult
;
105 maPaintWindows
.erase(aFindResult
);
111 OutputDevice
* SdrPaintView::GetFirstOutputDevice() const
113 if(PaintWindowCount())
115 return &(GetPaintWindow(0)->GetOutputDevice());
123 TYPEINIT1( SvxViewHint
, SfxHint
);
125 SvxViewHint::SvxViewHint (HintType eHintType
)
126 : meHintType(eHintType
)
130 SvxViewHint::HintType
SvxViewHint::GetHintType (void) const
138 BitmapEx
convertMetafileToBitmapEx(
139 const GDIMetaFile
& rMtf
,
140 const basegfx::B2DRange
& rTargetRange
,
141 const sal_uInt32 nMaximumQuadraticPixels
)
145 if(rMtf
.GetActionSize())
147 const drawinglayer::primitive2d::Primitive2DReference
aMtf(
148 new drawinglayer::primitive2d::MetafilePrimitive2D(
149 basegfx::tools::createScaleTranslateB2DHomMatrix(
150 rTargetRange
.getRange(),
151 rTargetRange
.getMinimum()),
153 aBitmapEx
= convertPrimitive2DSequenceToBitmapEx(
154 drawinglayer::primitive2d::Primitive2DSequence(&aMtf
, 1),
156 nMaximumQuadraticPixels
);
164 TYPEINIT2(SdrPaintView
,SfxListener
,SfxRepeatTarget
);
167 void SdrPaintView::ImpClearVars()
173 bPageBorderVisible
=true;
183 bSwapAsynchron
=false;
185 mbPreviewRenderer
=false;
187 eAnimationMode
= SDR_ANIMATION_ANIMATE
;
188 bAnimationPause
= false;
197 pDefaultStyleSheet
=NULL
;
198 bSomeObjChgdFlag
=false;
199 nGraphicManagerDrawMode
= GRFMGR_DRAW_STANDARD
;
200 aComeBackTimer
.SetTimeout(1);
201 aComeBackTimer
.SetTimeoutHdl(LINK(this,SdrPaintView
,ImpComeBackHdl
));
204 SetDefaultStyleSheet(pMod
->GetDefaultStyleSheet(), true);
206 maGridColor
= Color( COL_BLACK
);
209 SdrPaintView::SdrPaintView(SdrModel
* pModel1
, OutputDevice
* pOut
)
211 aDefaultAttr(pModel1
->GetItemPool()),
212 mbBufferedOutputAllowed(false),
213 mbBufferedOverlayAllowed(false),
214 mbPagePaintingAllowed(true),
218 mbHideFormControl(false)
225 AddWindowToPaintView(pOut
);
228 // flag to visualize groups
229 bVisualizeEnteredGroup
= true;
231 maColorConfig
.AddListener(this);
232 onChangeColorConfig();
235 SdrPaintView::~SdrPaintView()
237 if (pDefaultStyleSheet
)
238 EndListening(*pDefaultStyleSheet
);
240 maColorConfig
.RemoveListener(this);
250 // delete existing SdrPaintWindows
251 while(!maPaintWindows
.empty())
253 delete maPaintWindows
.back();
254 maPaintWindows
.pop_back();
260 void SdrPaintView::Notify(SfxBroadcaster
& rBC
, const SfxHint
& rHint
)
262 //If the stylesheet has been destroyed
263 if (&rBC
== pDefaultStyleSheet
)
265 if (rHint
.ISA(SfxSimpleHint
) && ((const SfxSimpleHint
&)rHint
).GetId() == SFX_HINT_DYING
)
266 pDefaultStyleSheet
= NULL
;
270 bool bObjChg
=!bSomeObjChgdFlag
; // if true, evaluate for ComeBack timer
272 SdrHint
* pSdrHint
=PTR_CAST(SdrHint
,&rHint
);
273 if (pSdrHint
!=NULL
) {
274 SdrHintKind eKind
=pSdrHint
->GetKind();
275 if (eKind
==HINT_OBJCHG
|| eKind
==HINT_OBJINSERTED
|| eKind
==HINT_OBJREMOVED
) {
277 bSomeObjChgdFlag
=true;
278 aComeBackTimer
.Start();
281 if (eKind
==HINT_PAGEORDERCHG
) {
282 const SdrPage
* pPg
=pSdrHint
->GetPage();
284 if(pPg
&& !pPg
->IsInserted())
286 if(mpPageView
&& mpPageView
->GetPage() == pPg
)
296 void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster
* , sal_uInt32
)
298 onChangeColorConfig();
304 IMPL_LINK_NOARG_INLINE_START(SdrPaintView
, ImpComeBackHdl
)
306 if (bSomeObjChgdFlag
) {
307 bSomeObjChgdFlag
=false;
312 IMPL_LINK_NOARG_INLINE_END(SdrPaintView
,ImpComeBackHdl
)
314 void SdrPaintView::FlushComeBackTimer() const
316 if (bSomeObjChgdFlag
) {
317 // casting to nonconst
318 ((SdrPaintView
*)this)->ImpComeBackHdl(&((SdrPaintView
*)this)->aComeBackTimer
);
319 ((SdrPaintView
*)this)->aComeBackTimer
.Stop();
323 void SdrPaintView::ModelHasChanged()
325 // broadcast to all PageViews
326 if(mpPageView
&& !mpPageView
->GetPage()->IsInserted())
331 // test mpPageView here again, HideSdrPage() may have invalidated it.
334 mpPageView
->ModelHasChanged();
340 pItemBrowser
->SetDirty();
347 bool SdrPaintView::IsAction() const
352 void SdrPaintView::MovAction(const Point
&)
356 void SdrPaintView::EndAction()
360 void SdrPaintView::BckAction()
364 void SdrPaintView::BrkAction()
368 void SdrPaintView::TakeActionRect(Rectangle
&) const
373 // info about TextEdit. Default is false.
374 bool SdrPaintView::IsTextEdit() const
379 // info about TextEditPageView. Default is 0L.
380 SdrPageView
* SdrPaintView::GetTextEditPageView() const
387 sal_uInt16
SdrPaintView::ImpGetMinMovLogic(short nMinMov
, const OutputDevice
* pOut
) const
389 if (nMinMov
>=0) return sal_uInt16(nMinMov
);
392 pOut
= GetFirstOutputDevice();
395 return short(-pOut
->PixelToLogic(Size(nMinMov
,0)).Width());
401 sal_uInt16
SdrPaintView::ImpGetHitTolLogic(short nHitTol
, const OutputDevice
* pOut
) const
403 if (nHitTol
>=0) return sal_uInt16(nHitTol
);
406 pOut
= GetFirstOutputDevice();
409 return short(-pOut
->PixelToLogic(Size(nHitTol
,0)).Width());
415 void SdrPaintView::TheresNewMapMode()
417 if (pActualOutDev
!=NULL
) {
418 nHitTolLog
=(sal_uInt16
)((OutputDevice
*)pActualOutDev
)->PixelToLogic(Size(nHitTolPix
,0)).Width();
419 nMinMovLog
=(sal_uInt16
)((OutputDevice
*)pActualOutDev
)->PixelToLogic(Size(nMinMovPix
,0)).Width();
423 void SdrPaintView::SetActualWin(const OutputDevice
* pWin
)
431 void SdrPaintView::ClearPageView()
443 SdrPageView
* SdrPaintView::ShowSdrPage(SdrPage
* pPage
)
445 if(pPage
&& (!mpPageView
|| mpPageView
->GetPage() != pPage
))
453 mpPageView
= new SdrPageView(pPage
, *((SdrView
*)this));
460 void SdrPaintView::HideSdrPage()
470 void SdrPaintView::AddWindowToPaintView(OutputDevice
* pNewWin
)
472 DBG_ASSERT(pNewWin
, "SdrPaintView::AddWindowToPaintView: No OutputDevice(!)");
473 SdrPaintWindow
* pNewPaintWindow
= new SdrPaintWindow(*this, *pNewWin
);
474 AppendPaintWindow(*pNewPaintWindow
);
478 mpPageView
->AddPaintWindowToPageView(*pNewPaintWindow
);
482 if (pItemBrowser
!=NULL
)
483 pItemBrowser
->ForceParent();
487 void SdrPaintView::DeleteWindowFromPaintView(OutputDevice
* pOldWin
)
489 DBG_ASSERT(pOldWin
, "SdrPaintView::DeleteWindowFromPaintView: No OutputDevice(!)");
490 SdrPaintWindow
* pCandidate
= FindPaintWindow(*pOldWin
);
496 mpPageView
->RemovePaintWindowFromPageView(*pCandidate
);
499 RemovePaintWindow(*pCandidate
);
504 if (pItemBrowser
!=NULL
)
505 pItemBrowser
->ForceParent();
509 void SdrPaintView::SetLayerVisible(const OUString
& rName
, bool bShow
)
513 mpPageView
->SetLayerVisible(rName
, bShow
);
519 bool SdrPaintView::IsLayerVisible(const OUString
& rName
) const
523 return mpPageView
->IsLayerVisible(rName
);
529 void SdrPaintView::SetLayerLocked(const OUString
& rName
, bool bLock
)
533 mpPageView
->SetLayerLocked(rName
,bLock
);
537 bool SdrPaintView::IsLayerLocked(const OUString
& rName
) const
541 return mpPageView
->IsLayerLocked(rName
);
547 void SdrPaintView::SetLayerPrintable(const OUString
& rName
, bool bPrn
)
551 mpPageView
->SetLayerPrintable(rName
,bPrn
);
555 bool SdrPaintView::IsLayerPrintable(const OUString
& rName
) const
559 return mpPageView
->IsLayerPrintable(rName
);
565 void SdrPaintView::PrePaint()
569 mpPageView
->PrePaint();
574 // #define SVX_REPAINT_TIMER_TEST
576 void SdrPaintView::CompleteRedraw(OutputDevice
* pOut
, const Region
& rReg
, sdr::contact::ViewObjectContactRedirector
* pRedirector
)
578 #ifdef SVX_REPAINT_TIMER_TEST
579 #define REMEMBERED_TIMES_COUNT (10)
580 static bool bDoTimerTest(false);
581 static bool bTimesInited(false);
582 static sal_uInt32
nRepeatCount(10L);
583 static double fLastTimes
[REMEMBERED_TIMES_COUNT
];
584 const sal_uInt32
nStartTime(Time::GetSystemTicks());
585 sal_uInt32
count(1L);
590 count
= nRepeatCount
;
593 for(a
= 0L; a
< count
; a
++)
595 #endif // SVX_REPAINT_TIMER_TEST
597 // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
598 // rReg may be made more granular (fine) with using it. Normally, rReg
599 // does come from Window::Paint() anyways and thus is based on a single
600 // rectangle which was derived from exactly that repaint region
601 Region
aOptimizedRepaintRegion(rReg
);
603 if(pOut
&& OUTDEV_WINDOW
== pOut
->GetOutDevType())
605 Window
* pWindow
= (Window
*)pOut
;
607 if(pWindow
->IsInPaint())
609 if(!pWindow
->GetPaintRegion().IsEmpty())
611 aOptimizedRepaintRegion
.Intersect(pWindow
->GetPaintRegion());
614 // #i74769# test-paint repaint region
615 static bool bDoPaintForVisualControl(false);
617 if(bDoPaintForVisualControl
)
619 RectangleVector aRectangles
;
620 aOptimizedRepaintRegion
.GetRegionRectangles(aRectangles
);
622 pWindow
->SetLineColor(COL_LIGHTGREEN
);
623 pWindow
->SetFillColor();
625 for(RectangleVector::const_iterator
aRectIter(aRectangles
.begin()); aRectIter
!= aRectangles
.end(); ++aRectIter
)
627 pWindow
->DrawRect(*aRectIter
);
630 //RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
631 //Rectangle aRegionRectangle;
633 //while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
635 // pWindow->SetLineColor(COL_LIGHTGREEN);
636 // pWindow->SetFillColor();
637 // pWindow->DrawRect(aRegionRectangle);
640 //aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
647 SdrPaintWindow
* pPaintWindow
= BeginCompleteRedraw(pOut
);
648 OSL_ENSURE(pPaintWindow
, "SdrPaintView::CompleteRedraw: No OutDev (!)");
650 DoCompleteRedraw(*pPaintWindow
, aOptimizedRepaintRegion
, pRedirector
);
651 EndCompleteRedraw(*pPaintWindow
, true);
653 #ifdef SVX_REPAINT_TIMER_TEST
658 const sal_uInt32
nStopTime(Time::GetSystemTicks());
659 const sal_uInt32
nNeededTime(nStopTime
- nStartTime
);
660 const double fTimePerPaint((double)nNeededTime
/ (double)nRepeatCount
);
664 for(a
= 0L; a
< REMEMBERED_TIMES_COUNT
; a
++)
666 fLastTimes
[a
] = fTimePerPaint
;
673 for(a
= 1L; a
< REMEMBERED_TIMES_COUNT
; a
++)
675 fLastTimes
[a
- 1L] = fLastTimes
[a
];
678 fLastTimes
[REMEMBERED_TIMES_COUNT
- 1L] = fTimePerPaint
;
681 double fAddedTimes(0.0);
683 for(a
= 0L; a
< REMEMBERED_TIMES_COUNT
; a
++)
685 fAddedTimes
+= fLastTimes
[a
];
688 const double fAverageTimePerPaint(fAddedTimes
/ (double)REMEMBERED_TIMES_COUNT
);
690 fprintf(stderr
, "-----------(start result)----------\n");
691 fprintf(stderr
, "StartTime : %u, StopTime: %u, NeededTime: %u, TimePerPaint: %f\n", nStartTime
, nStopTime
, nNeededTime
, fTimePerPaint
);
692 fprintf(stderr
, "Remembered times: ");
694 for(a
= 0L; a
< REMEMBERED_TIMES_COUNT
; a
++)
696 fprintf(stderr
, "%d: %f ", a
, fLastTimes
[a
]);
699 fprintf(stderr
, "\n");
700 fprintf(stderr
, "AverageTimePerPaint: %f\n", fAverageTimePerPaint
);
701 fprintf(stderr
, "-----------(stop result)----------\n");
703 #endif // SVX_REPAINT_TIMER_TEST
709 SdrPaintWindow
* SdrPaintView::BeginCompleteRedraw(OutputDevice
* pOut
)
711 OSL_ENSURE(pOut
, "SdrPaintView::BeginCompleteRedraw: No OutDev (!)");
712 SdrPaintWindow
* pPaintWindow
= FindPaintWindow(*pOut
);
716 // draw preprocessing, only for known devices
717 // prepare PreRendering
718 pPaintWindow
->PreparePreRenderDevice();
722 // None of the known OutputDevices is the target of this paint, use
723 // a temporary SdrPaintWindow for this Redraw.
724 pPaintWindow
= new SdrPaintWindow(*this, *pOut
);
725 pPaintWindow
->setTemporaryTarget(true);
731 void SdrPaintView::DoCompleteRedraw(SdrPaintWindow
& rPaintWindow
, const Region
& rReg
, sdr::contact::ViewObjectContactRedirector
* pRedirector
)
733 // redraw all PageViews with the target. This may expand the RedrawRegion
734 // at the PaintWindow, plus taking care of FormLayer expansion
737 mpPageView
->CompleteRedraw(rPaintWindow
, rReg
, pRedirector
);
741 void SdrPaintView::EndCompleteRedraw(SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
743 if(rPaintWindow
.getTemporaryTarget())
745 // get rid of temp target again
746 delete (&rPaintWindow
);
750 // draw postprocessing, only for known devices
751 // it is necessary to always paint FormLayer
754 ImpFormLayerDrawing(rPaintWindow
);
757 // look for active TextEdit. As long as this cannot be painted to a VDev,
758 // it cannot get part of buffering. In that case, output evtl. prerender
759 // early and paint text edit to window.
760 if(IsTextEdit() && GetSdrPageView())
762 static_cast< SdrView
* >(this)->TextEditDrawing(rPaintWindow
);
765 // draw Overlay, also to PreRender device if exists
766 rPaintWindow
.DrawOverlay(rPaintWindow
.GetRedrawRegion());
768 // output PreRendering
769 rPaintWindow
.OutputPreRenderDevice(rPaintWindow
.GetRedrawRegion());
775 SdrPaintWindow
* SdrPaintView::BeginDrawLayers(OutputDevice
* pOut
, const Region
& rReg
, bool bDisableIntersect
)
777 // #i74769# use BeginCompleteRedraw() as common base
778 SdrPaintWindow
* pPaintWindow
= BeginCompleteRedraw(pOut
);
779 OSL_ENSURE(pPaintWindow
, "SdrPaintView::BeginDrawLayers: No SdrPaintWindow (!)");
783 SdrPageWindow
* pKnownTarget
= mpPageView
->FindPageWindow(*pPaintWindow
);
787 Region aOptimizedRepaintRegion
= OptimizeDrawLayersRegion( pOut
, rReg
, bDisableIntersect
);
790 pKnownTarget
->PrepareRedraw(aOptimizedRepaintRegion
);
792 // remember prepared SdrPageWindow
793 mpPageView
->setPreparedPageWindow(pKnownTarget
);
800 void SdrPaintView::EndDrawLayers(SdrPaintWindow
& rPaintWindow
, bool bPaintFormLayer
)
802 // #i74769# use EndCompleteRedraw() as common base
803 EndCompleteRedraw(rPaintWindow
, bPaintFormLayer
);
807 // forget prepared SdrPageWindow
808 mpPageView
->setPreparedPageWindow(0);
812 void SdrPaintView::UpdateDrawLayersRegion(OutputDevice
* pOut
, const Region
& rReg
, bool bDisableIntersect
)
814 SdrPaintWindow
* pPaintWindow
= FindPaintWindow(*pOut
);
815 OSL_ENSURE(pPaintWindow
, "SdrPaintView::UpdateDrawLayersRegion: No SdrPaintWindow (!)");
819 SdrPageWindow
* pKnownTarget
= mpPageView
->FindPageWindow(*pPaintWindow
);
823 Region aOptimizedRepaintRegion
= OptimizeDrawLayersRegion( pOut
, rReg
, bDisableIntersect
);
824 pKnownTarget
->GetPaintWindow().SetRedrawRegion(aOptimizedRepaintRegion
);
825 mpPageView
->setPreparedPageWindow(pKnownTarget
); // already set actually
830 Region
SdrPaintView::OptimizeDrawLayersRegion(OutputDevice
* pOut
, const Region
& rReg
, bool bDisableIntersect
)
832 // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
833 // rReg may be made more granular (fine) with using it. Normally, rReg
834 // does come from Window::Paint() anyways and thus is based on a single
835 // rectangle which was derived from exactly that repaint region
836 Region
aOptimizedRepaintRegion(rReg
);
838 // #i76114# Intersecting the region with the Window's paint region is disabled
839 // for print preview in Calc, because the intersection can be empty (if the paint
840 // region is outside of the table area of the page), and then no clip region
842 if(pOut
&& OUTDEV_WINDOW
== pOut
->GetOutDevType() && !bDisableIntersect
)
844 Window
* pWindow
= (Window
*)pOut
;
846 if(pWindow
->IsInPaint())
848 if(!pWindow
->GetPaintRegion().IsEmpty())
850 aOptimizedRepaintRegion
.Intersect(pWindow
->GetPaintRegion());
854 return aOptimizedRepaintRegion
;
859 void SdrPaintView::ImpFormLayerDrawing(SdrPaintWindow
& rPaintWindow
) const
863 SdrPageWindow
* pKnownTarget
= mpPageView
->FindPageWindow(rPaintWindow
);
867 const SdrModel
& rModel
= *(GetModel());
868 const SdrLayerAdmin
& rLayerAdmin
= rModel
.GetLayerAdmin();
869 const SdrLayerID nControlLayerId
= rLayerAdmin
.GetLayerID(rLayerAdmin
.GetControlLayerName(), false);
871 // BUFFERED use GetTargetOutputDevice() now, it may be targeted to VDevs, too
872 // need to set PreparedPageWindow to make DrawLayer use the correct ObjectContact
873 mpPageView
->setPreparedPageWindow(pKnownTarget
);
874 mpPageView
->DrawLayer(nControlLayerId
, &rPaintWindow
.GetTargetOutputDevice());
875 mpPageView
->setPreparedPageWindow(0);
882 bool SdrPaintView::KeyInput(const KeyEvent
& /*rKEvt*/, Window
* /*pWin*/)
887 void SdrPaintView::GlueInvalidate() const
889 const sal_uInt32
nWindowCount(PaintWindowCount());
891 for(sal_uInt32
nWinNum(0L); nWinNum
< nWindowCount
; nWinNum
++)
893 SdrPaintWindow
* pPaintWindow
= GetPaintWindow(nWinNum
);
895 if(pPaintWindow
->OutputToWindow())
897 OutputDevice
& rOutDev
= pPaintWindow
->GetOutputDevice();
901 const SdrObjList
* pOL
=mpPageView
->GetObjList();
902 sal_uIntPtr nObjAnz
=pOL
->GetObjCount();
903 for (sal_uIntPtr nObjNum
=0; nObjNum
<nObjAnz
; nObjNum
++) {
904 const SdrObject
* pObj
=pOL
->GetObj(nObjNum
);
905 const SdrGluePointList
* pGPL
=pObj
->GetGluePointList();
906 if (pGPL
!=NULL
&& pGPL
->GetCount()!=0) {
907 pGPL
->Invalidate((Window
&)rOutDev
, pObj
);
915 void SdrPaintView::InvalidateAllWin()
917 const sal_uInt32
nWindowCount(PaintWindowCount());
919 for(sal_uInt32
a(0L); a
< nWindowCount
; a
++)
921 SdrPaintWindow
* pPaintWindow
= GetPaintWindow(a
);
923 if(pPaintWindow
->OutputToWindow())
925 InvalidateOneWin((Window
&)pPaintWindow
->GetOutputDevice());
930 void SdrPaintView::InvalidateAllWin(const Rectangle
& rRect
, bool bPlus1Pix
)
932 const sal_uInt32
nWindowCount(PaintWindowCount());
934 for(sal_uInt32
a(0L); a
< nWindowCount
; a
++)
936 SdrPaintWindow
* pPaintWindow
= GetPaintWindow(a
);
938 if(pPaintWindow
->OutputToWindow())
940 OutputDevice
& rOutDev
= pPaintWindow
->GetOutputDevice();
941 Rectangle
aRect(rRect
);
946 Size
aSiz(rOutDev
.PixelToLogic(aPixSiz
));
947 aRect
.Left ()-=aSiz
.Width();
948 aRect
.Top ()-=aSiz
.Height();
949 aRect
.Right ()+=aSiz
.Width();
950 aRect
.Bottom()+=aSiz
.Height();
953 Point
aOrg(rOutDev
.GetMapMode().GetOrigin());
954 aOrg
.X()=-aOrg
.X(); aOrg
.Y()=-aOrg
.Y();
955 Rectangle
aOutRect(aOrg
, rOutDev
.GetOutputSize());
957 if (aRect
.IsOver(aOutRect
))
959 InvalidateOneWin((Window
&)rOutDev
, aRect
);
965 void SdrPaintView::InvalidateOneWin(Window
& rWin
)
967 // do not erase background, that causes flicker (!)
968 rWin
.Invalidate(INVALIDATE_NOERASE
);
971 void SdrPaintView::InvalidateOneWin(Window
& rWin
, const Rectangle
& rRect
)
973 // do not erase background, that causes flicker (!)
974 rWin
.Invalidate(rRect
, INVALIDATE_NOERASE
);
977 void SdrPaintView::LeaveOneGroup()
981 mpPageView
->LeaveOneGroup();
985 void SdrPaintView::LeaveAllGroup()
989 mpPageView
->LeaveAllGroup();
993 bool SdrPaintView::IsGroupEntered() const
997 return (mpPageView
->GetEnteredLevel() != 0);
1003 void SdrPaintView::SetNotPersistDefaultAttr(const SfxItemSet
& rAttr
, bool /*bReplaceAll*/)
1005 // bReplaceAll has no effect here at all.
1006 bool bMeasure
=ISA(SdrView
) && ((SdrView
*)this)->IsMeasureTool();
1007 const SfxPoolItem
*pPoolItem
=NULL
;
1008 if (rAttr
.GetItemState(SDRATTR_LAYERID
,true,&pPoolItem
)==SFX_ITEM_SET
) {
1009 SdrLayerID nLayerId
=((const SdrLayerIdItem
*)pPoolItem
)->GetValue();
1010 const SdrLayer
* pLayer
=pMod
->GetLayerAdmin().GetLayerPerID(nLayerId
);
1012 if (bMeasure
) aMeasureLayer
=pLayer
->GetName();
1013 else aAktLayer
=pLayer
->GetName();
1016 if (rAttr
.GetItemState(SDRATTR_LAYERNAME
,true,&pPoolItem
)==SFX_ITEM_SET
) {
1017 if (bMeasure
) aMeasureLayer
=((const SdrLayerNameItem
*)pPoolItem
)->GetValue();
1018 else aAktLayer
=((const SdrLayerNameItem
*)pPoolItem
)->GetValue();
1022 void SdrPaintView::MergeNotPersistDefaultAttr(SfxItemSet
& rAttr
, bool /*bOnlyHardAttr*/) const
1024 // bOnlyHardAttr has no effect here at all.
1025 bool bMeasure
=ISA(SdrView
) && ((SdrView
*)this)->IsMeasureTool();
1026 const OUString
& aNam
= bMeasure
? aMeasureLayer
: aAktLayer
;
1027 rAttr
.Put(SdrLayerNameItem(aNam
));
1028 SdrLayerID nLayer
=pMod
->GetLayerAdmin().GetLayerID(aNam
,true);
1029 if (nLayer
!=SDRLAYER_NOTFOUND
) {
1030 rAttr
.Put(SdrLayerIdItem(nLayer
));
1034 void SdrPaintView::SetDefaultAttr(const SfxItemSet
& rAttr
, bool bReplaceAll
)
1038 bool bHasEEFeatureItems
=false;
1039 SfxItemIter
aIter(rAttr
);
1040 const SfxPoolItem
* pItem
=aIter
.FirstItem();
1041 while (!bHasEEFeatureItems
&& pItem
!=NULL
) {
1042 if (!IsInvalidItem(pItem
)) {
1043 sal_uInt16 nW
=pItem
->Which();
1044 if (nW
>=EE_FEATURE_START
&& nW
<=EE_FEATURE_END
) bHasEEFeatureItems
=true;
1046 pItem
=aIter
.NextItem();
1049 if(bHasEEFeatureItems
)
1051 OUString
aMessage("SdrPaintView::SetDefaultAttr(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.");
1052 InfoBox(NULL
, aMessage
).Execute();
1056 if (bReplaceAll
) aDefaultAttr
.Set(rAttr
);
1057 else aDefaultAttr
.Put(rAttr
,false); // if FALSE, regard InvalidItems as "holes," not as Default
1058 SetNotPersistDefaultAttr(rAttr
,bReplaceAll
);
1060 if (pItemBrowser
!=NULL
) pItemBrowser
->SetDirty();
1064 void SdrPaintView::SetDefaultStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1066 if (pDefaultStyleSheet
)
1067 EndListening(*pDefaultStyleSheet
);
1068 pDefaultStyleSheet
=pStyleSheet
;
1069 if (pDefaultStyleSheet
)
1070 StartListening(*pDefaultStyleSheet
);
1072 if (pStyleSheet
!=NULL
&& !bDontRemoveHardAttr
) {
1073 SfxWhichIter
aIter(pStyleSheet
->GetItemSet());
1074 sal_uInt16 nWhich
=aIter
.FirstWhich();
1076 if (pStyleSheet
->GetItemSet().GetItemState(nWhich
,true)==SFX_ITEM_SET
) {
1077 aDefaultAttr
.ClearItem(nWhich
);
1079 nWhich
=aIter
.NextWhich();
1083 if (pItemBrowser
!=NULL
) pItemBrowser
->SetDirty();
1087 bool SdrPaintView::GetAttributes(SfxItemSet
& rTargetSet
, bool bOnlyHardAttr
) const
1089 if(bOnlyHardAttr
|| !pDefaultStyleSheet
)
1091 rTargetSet
.Put(aDefaultAttr
, false);
1095 // else merge with DefStyleSheet
1096 rTargetSet
.Put(pDefaultStyleSheet
->GetItemSet(), false);
1097 rTargetSet
.Put(aDefaultAttr
, false);
1099 MergeNotPersistDefaultAttr(rTargetSet
, bOnlyHardAttr
);
1103 bool SdrPaintView::SetAttributes(const SfxItemSet
& rSet
, bool bReplaceAll
)
1105 SetDefaultAttr(rSet
,bReplaceAll
);
1109 SfxStyleSheet
* SdrPaintView::GetStyleSheet() const
1111 return GetDefaultStyleSheet();
1114 bool SdrPaintView::SetStyleSheet(SfxStyleSheet
* pStyleSheet
, bool bDontRemoveHardAttr
)
1116 SetDefaultStyleSheet(pStyleSheet
,bDontRemoveHardAttr
);
1123 void SdrPaintView::ShowItemBrowser(bool bShow
)
1126 if (pItemBrowser
==NULL
) {
1127 pItemBrowser
=new SdrItemBrowser(*(SdrView
*)this);
1128 pItemBrowser
->SetFloatingMode(true);
1130 pItemBrowser
->Show();
1131 pItemBrowser
->GrabFocus();
1133 if (pItemBrowser
!=NULL
) {
1134 pItemBrowser
->Hide();
1135 delete pItemBrowser
;
1142 void SdrPaintView::MakeVisible(const Rectangle
& rRect
, Window
& rWin
)
1144 MapMode
aMap(rWin
.GetMapMode());
1145 Size
aActualSize(rWin
.GetOutputSize());
1147 if( aActualSize
.Height() > 0 && aActualSize
.Width() > 0 )
1149 Size
aNewSize(rRect
.GetSize());
1150 bool bNewScale
=false;
1151 bool bNeedMoreX
=aNewSize
.Width()>aActualSize
.Width();
1152 bool bNeedMoreY
=aNewSize
.Height()>aActualSize
.Height();
1153 if (bNeedMoreX
|| bNeedMoreY
)
1156 // set new MapMode (Size+Org) and invalidate everything
1157 Fraction
aXFact(aNewSize
.Width(),aActualSize
.Width());
1158 Fraction
aYFact(aNewSize
.Height(),aActualSize
.Height());
1159 if (aYFact
>aXFact
) aXFact
=aYFact
;
1160 aXFact
*=aMap
.GetScaleX();
1161 aXFact
.ReduceInaccurate(10); // to avoid runovers and BigInt mapping
1162 aMap
.SetScaleX(aXFact
);
1163 aMap
.SetScaleY(aYFact
);
1164 rWin
.SetMapMode(aMap
);
1165 aActualSize
=rWin
.GetOutputSize();
1167 Point
aOrg(aMap
.GetOrigin());
1170 long r
=-aOrg
.X()+aActualSize
.Width()-1;
1172 long u
=-aOrg
.Y()+aActualSize
.Height()-1;
1173 if (l
>rRect
.Left()) dx
=rRect
.Left()-l
;
1174 else if (r
<rRect
.Right()) dx
=rRect
.Right()-r
;
1175 if (o
>rRect
.Top()) dy
=rRect
.Top()-o
;
1176 else if (u
<rRect
.Bottom()) dy
=rRect
.Bottom()-u
;
1177 aMap
.SetOrigin(Point(aOrg
.X()-dx
,aOrg
.Y()-dy
));
1179 if (dx
!=0 || dy
!=0) {
1180 rWin
.Scroll(-dx
,-dy
);
1181 rWin
.SetMapMode(aMap
);
1185 rWin
.SetMapMode(aMap
);
1186 InvalidateOneWin(rWin
);
1191 void SdrPaintView::DoConnect(SdrOle2Obj
* /*pOleObj*/)
1195 void SdrPaintView::SetAnimationEnabled( bool bEnable
)
1197 SetAnimationMode( bEnable
? SDR_ANIMATION_ANIMATE
: SDR_ANIMATION_DISABLE
);
1200 void SdrPaintView::SetAnimationPause( bool bSet
)
1202 if((bool)bAnimationPause
!= bSet
)
1204 bAnimationPause
= bSet
;
1208 for(sal_uInt32
b(0L); b
< mpPageView
->PageWindowCount(); b
++)
1210 const SdrPageWindow
& rPageWindow
= *(mpPageView
->GetPageWindow(b
));
1211 sdr::contact::ObjectContact
& rObjectContact
= rPageWindow
.GetObjectContact();
1212 sdr::animation::primitiveAnimator
& rAnimator
= rObjectContact
.getPrimitiveAnimator();
1214 if(rAnimator
.IsPaused() != bSet
)
1216 rAnimator
.SetPaused(bSet
);
1223 void SdrPaintView::SetAnimationMode( const SdrAnimationMode eMode
)
1225 eAnimationMode
= eMode
;
1228 void SdrPaintView::VisAreaChanged(const OutputDevice
* pOut
)
1234 SdrPageWindow
* pWindow
= mpPageView
->FindPageWindow(*((OutputDevice
*)pOut
));
1238 VisAreaChanged(*pWindow
);
1243 for(sal_uInt32
a(0L); a
< mpPageView
->PageWindowCount(); a
++)
1245 VisAreaChanged(*mpPageView
->GetPageWindow(a
));
1251 void SdrPaintView::VisAreaChanged(const SdrPageWindow
& /*rWindow*/)
1253 // notify SfxListener
1254 Broadcast(SvxViewHint(SvxViewHint::SVX_HINT_VIEWCHANGED
));
1257 const svtools::ColorConfig
& SdrPaintView::getColorConfig() const
1259 return maColorConfig
;
1262 void SdrPaintView::onChangeColorConfig()
1264 SetGridColor( Color( maColorConfig
.GetColorValue( svtools::DRAWGRID
).nColor
) );
1267 void SdrPaintView::SetGridColor( Color aColor
)
1269 maGridColor
= aColor
;
1272 Color
SdrPaintView::GetGridColor() const
1277 // Set background color for svx at SdrPageViews
1278 void SdrPaintView::SetApplicationBackgroundColor(Color aBackgroundColor
)
1282 mpPageView
->SetApplicationBackgroundColor(aBackgroundColor
);
1286 // Set document color for svx at SdrPageViews
1287 void SdrPaintView::SetApplicationDocumentColor(Color aDocumentColor
)
1291 mpPageView
->SetApplicationDocumentColor(aDocumentColor
);
1295 bool SdrPaintView::IsBufferedOutputAllowed() const
1297 return (mbBufferedOutputAllowed
&& maDrawinglayerOpt
.IsPaintBuffer());
1300 void SdrPaintView::SetBufferedOutputAllowed(bool bNew
)
1302 if(bNew
!= (bool)mbBufferedOutputAllowed
)
1304 mbBufferedOutputAllowed
= bNew
;
1308 bool SdrPaintView::IsBufferedOverlayAllowed() const
1310 return (mbBufferedOverlayAllowed
&& maDrawinglayerOpt
.IsOverlayBuffer());
1313 void SdrPaintView::SetBufferedOverlayAllowed(bool bNew
)
1315 if(bNew
!= (bool)mbBufferedOverlayAllowed
)
1317 mbBufferedOverlayAllowed
= bNew
;
1321 bool SdrPaintView::IsPagePaintingAllowed() const
1323 return mbPagePaintingAllowed
;
1326 void SdrPaintView::SetPagePaintingAllowed(bool bNew
)
1328 if(bNew
!= (bool)mbPagePaintingAllowed
)
1330 mbPagePaintingAllowed
= bNew
;
1334 // #i38135# Sets the timer for Object animations and restarts.
1335 void SdrPaintView::SetAnimationTimer(sal_uInt32 nTime
)
1339 // first, reset all timers at all windows to 0L
1340 for(sal_uInt32
a(0L); a
< mpPageView
->PageWindowCount(); a
++)
1342 const SdrPageWindow
& rPageWindow
= *mpPageView
->GetPageWindow(a
);
1343 sdr::contact::ObjectContact
& rObjectContact
= rPageWindow
.GetObjectContact();
1344 sdr::animation::primitiveAnimator
& rAnimator
= rObjectContact
.getPrimitiveAnimator();
1345 rAnimator
.SetTime(nTime
);
1350 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */