Version 3.6.0.4, tag libreoffice-3.6.0.4
[LibreOffice.git] / svx / source / svdraw / svdpntv.cxx
blobe2e462cb6235ddd009d6c0e2b680576479af2915
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*************************************************************************
4 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
6 * Copyright 2000, 2010 Oracle and/or its affiliates.
8 * OpenOffice.org - a multi-platform office productivity suite
10 * This file is part of OpenOffice.org.
12 * OpenOffice.org is free software: you can redistribute it and/or modify
13 * it under the terms of the GNU Lesser General Public License version 3
14 * only, as published by the Free Software Foundation.
16 * OpenOffice.org is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU Lesser General Public License version 3 for more details
20 * (a copy is included in the LICENSE file that accompanied this code).
22 * You should have received a copy of the GNU Lesser General Public License
23 * version 3 along with OpenOffice.org. If not, see
24 * <http://www.openoffice.org/license.html>
25 * for a copy of the LGPLv3 License.
27 ************************************************************************/
29 #include <com/sun/star/awt/XWindow.hpp>
30 #include <svx/svdpntv.hxx>
31 #include <vcl/msgbox.hxx>
32 #include <svx/sdrpaintwindow.hxx>
33 #include <svtools/grfmgr.hxx>
34 #include <svx/svdmodel.hxx>
36 #ifdef DBG_UTIL
37 #include <svdibrow.hxx>
38 #endif
39 #include <svx/svdpage.hxx>
40 #include <svx/svdpagv.hxx>
41 #include <svl/smplhint.hxx>
43 #include <editeng/editdata.hxx>
44 #include <svx/svdmrkv.hxx>
45 #include <svx/svdundo.hxx>
46 #include <svx/svdview.hxx>
47 #include <svx/svdglue.hxx>
48 #include <svx/svdobj.hxx>
49 #include <svx/svdograf.hxx>
50 #include <svx/svdattrx.hxx>
51 #include "svdibrow.hxx"
52 #include "svx/svditer.hxx"
53 #include <svx/svdouno.hxx>
54 #include <svx/sdr/overlay/overlayobjectlist.hxx>
55 #include <svx/sdr/overlay/overlayrollingrectangle.hxx>
56 #include <svx/sdr/overlay/overlaymanager.hxx>
57 #include <svx/sxlayitm.hxx>
58 #include <svl/itemiter.hxx>
59 #include <editeng/eeitem.hxx>
60 #include <svl/whiter.hxx>
61 #include <svl/style.hxx>
62 #include <svx/sdrpagewindow.hxx>
63 #include <vcl/svapp.hxx>
64 #include <com/sun/star/awt/PosSize.hpp>
65 #include <com/sun/star/awt/XControl.hpp>
67 // #i38135#
68 #include <svx/sdr/contact/objectcontact.hxx>
69 #include <svx/sdr/animation/objectanimator.hxx>
70 #include <svx/sdr/contact/viewcontact.hxx>
72 using namespace ::rtl;
73 using namespace ::com::sun::star;
75 ////////////////////////////////////////////////////////////////////////////////////////////////////
76 // interface to SdrPaintWindow
78 SdrPaintWindow* SdrPaintView::FindPaintWindow(const OutputDevice& rOut) const
80 for(SdrPaintWindowVector::const_iterator a = maPaintWindows.begin(); a != maPaintWindows.end(); ++a)
82 if(&((*a)->GetOutputDevice()) == &rOut)
84 return *a;
88 return 0L;
91 SdrPaintWindow* SdrPaintView::GetPaintWindow(sal_uInt32 nIndex) const
93 if(nIndex < maPaintWindows.size())
95 return maPaintWindows[nIndex];
98 return 0L;
101 void SdrPaintView::AppendPaintWindow(SdrPaintWindow& rNew)
103 maPaintWindows.push_back(&rNew);
106 SdrPaintWindow* SdrPaintView::RemovePaintWindow(SdrPaintWindow& rOld)
108 SdrPaintWindow* pRetval = 0L;
109 const SdrPaintWindowVector::iterator aFindResult = ::std::find(maPaintWindows.begin(), maPaintWindows.end(), &rOld);
111 if(aFindResult != maPaintWindows.end())
113 // remember return value, aFindResult is no longer valid after deletion
114 pRetval = *aFindResult;
115 maPaintWindows.erase(aFindResult);
118 return pRetval;
121 OutputDevice* SdrPaintView::GetFirstOutputDevice() const
123 if(PaintWindowCount())
125 return &(GetPaintWindow(0)->GetOutputDevice());
128 return 0L;
131 ////////////////////////////////////////////////////////////////////////////////////////////////////
133 TYPEINIT1( SvxViewHint, SfxHint );
135 SvxViewHint::SvxViewHint (HintType eHintType)
136 : meHintType(eHintType)
140 SvxViewHint::HintType SvxViewHint::GetHintType (void) const
142 return meHintType;
146 ////////////////////////////////////////////////////////////////////////////////////////////////////
148 TYPEINIT2(SdrPaintView,SfxListener,SfxRepeatTarget);
150 DBG_NAME(SdrPaintView);
152 void SdrPaintView::ImpClearVars()
154 #ifdef DBG_UTIL
155 pItemBrowser=NULL;
156 #endif
157 bPageVisible=sal_True;
158 bPageBorderVisible=sal_True;
159 bBordVisible=sal_True;
160 bGridVisible=sal_True;
161 bGridFront =sal_False;
162 bHlplVisible=sal_True;
163 bHlplFront =sal_True;
164 bGlueVisible=sal_False;
165 bGlueVisible2=sal_False;
166 bGlueVisible3=sal_False;
167 bGlueVisible4=sal_False;
168 bSwapAsynchron=sal_False;
169 bPrintPreview=sal_False;
170 mbPreviewRenderer=sal_False;
172 eAnimationMode = SDR_ANIMATION_ANIMATE;
173 bAnimationPause = sal_False;
175 nHitTolPix=2;
176 nMinMovPix=3;
177 nHitTolLog=0;
178 nMinMovLog=0;
179 pActualOutDev=NULL;
180 pDragWin=NULL;
181 bRestoreColors=sal_True;
182 pDefaultStyleSheet=NULL;
183 bSomeObjChgdFlag=sal_False;
184 nGraphicManagerDrawMode = GRFMGR_DRAW_STANDARD;
185 aComeBackTimer.SetTimeout(1);
186 aComeBackTimer.SetTimeoutHdl(LINK(this,SdrPaintView,ImpComeBackHdl));
187 String aNam; // System::GetUserName() just return an empty string
189 if (pMod)
190 SetDefaultStyleSheet(pMod->GetDefaultStyleSheet(), sal_True);
192 aNam.ToUpperAscii();
194 maGridColor = Color( COL_BLACK );
197 SdrPaintView::SdrPaintView(SdrModel* pModel1, OutputDevice* pOut)
198 : mpPageView(NULL),
199 aDefaultAttr(pModel1->GetItemPool()),
200 mbBufferedOutputAllowed(false),
201 mbBufferedOverlayAllowed(false),
202 mbPagePaintingAllowed(true),
203 mbHideOle(false),
204 mbHideChart(false),
205 mbHideDraw(false),
206 mbHideFormControl(false)
208 DBG_CTOR(SdrPaintView,NULL);
209 pMod=pModel1;
210 ImpClearVars();
212 if(pOut)
214 AddWindowToPaintView(pOut);
217 // flag to visualize groups
218 bVisualizeEnteredGroup = sal_True;
220 maColorConfig.AddListener(this);
221 onChangeColorConfig();
224 SdrPaintView::~SdrPaintView()
226 DBG_DTOR(SdrPaintView,NULL);
227 if (pDefaultStyleSheet)
228 EndListening(*pDefaultStyleSheet);
230 maColorConfig.RemoveListener(this);
231 ClearPageView();
233 #ifdef DBG_UTIL
234 if(pItemBrowser)
236 delete pItemBrowser;
238 #endif
240 // delete existing SdrPaintWindows
241 while(!maPaintWindows.empty())
243 delete maPaintWindows.back();
244 maPaintWindows.pop_back();
248 ////////////////////////////////////////////////////////////////////////////////////////////////////
250 void SdrPaintView::Notify(SfxBroadcaster& rBC, const SfxHint& rHint)
252 //If the stylesheet has been destroyed
253 if (&rBC == pDefaultStyleSheet)
255 if (rHint.ISA(SfxSimpleHint) && ((const SfxSimpleHint&)rHint).GetId() == SFX_HINT_DYING)
256 pDefaultStyleSheet = NULL;
257 return;
260 sal_Bool bObjChg=!bSomeObjChgdFlag; // if sal_True, evaluate for ComeBack timer
261 if (bObjChg) {
262 SdrHint* pSdrHint=PTR_CAST(SdrHint,&rHint);
263 if (pSdrHint!=NULL) {
264 SdrHintKind eKind=pSdrHint->GetKind();
265 if (eKind==HINT_OBJCHG || eKind==HINT_OBJINSERTED || eKind==HINT_OBJREMOVED) {
266 if (bObjChg) {
267 bSomeObjChgdFlag=sal_True;
268 aComeBackTimer.Start();
271 if (eKind==HINT_PAGEORDERCHG) {
272 const SdrPage* pPg=pSdrHint->GetPage();
274 if(pPg && !pPg->IsInserted())
276 if(mpPageView && mpPageView->GetPage() == pPg)
278 HideSdrPage();
286 void SdrPaintView::ConfigurationChanged( ::utl::ConfigurationBroadcaster* , sal_uInt32 )
288 onChangeColorConfig();
289 InvalidateAllWin();
292 ////////////////////////////////////////////////////////////////////////////////////////////////////
294 IMPL_LINK_NOARG_INLINE_START(SdrPaintView, ImpComeBackHdl)
296 if (bSomeObjChgdFlag) {
297 bSomeObjChgdFlag=sal_False;
298 ModelHasChanged();
300 return 0;
302 IMPL_LINK_NOARG_INLINE_END(SdrPaintView,ImpComeBackHdl)
304 void SdrPaintView::FlushComeBackTimer() const
306 if (bSomeObjChgdFlag) {
307 // casting to nonconst
308 ((SdrPaintView*)this)->ImpComeBackHdl(&((SdrPaintView*)this)->aComeBackTimer);
309 ((SdrPaintView*)this)->aComeBackTimer.Stop();
313 void SdrPaintView::ModelHasChanged()
315 // broadcast to all PageViews
316 if(mpPageView && !mpPageView->GetPage()->IsInserted())
318 HideSdrPage();
321 // test mpPageView here again, HideSdrPage() may have invalidated it.
322 if(mpPageView)
324 mpPageView->ModelHasChanged();
327 #ifdef DBG_UTIL
328 if(pItemBrowser)
330 pItemBrowser->SetDirty();
332 #endif
335 ////////////////////////////////////////////////////////////////////////////////////////////////////
337 sal_Bool SdrPaintView::IsAction() const
339 return false;
342 void SdrPaintView::MovAction(const Point&)
346 void SdrPaintView::EndAction()
350 void SdrPaintView::BckAction()
354 void SdrPaintView::BrkAction()
358 void SdrPaintView::TakeActionRect(Rectangle&) const
362 ////////////////////////////////////////////////////////////////////////////////////////////////////
363 // info about TextEdit. Default is sal_False.
364 bool SdrPaintView::IsTextEdit() const
366 return false;
369 // info about TextEditPageView. Default is 0L.
370 SdrPageView* SdrPaintView::GetTextEditPageView() const
372 return 0L;
375 ////////////////////////////////////////////////////////////////////////////////////////////////////
377 sal_uInt16 SdrPaintView::ImpGetMinMovLogic(short nMinMov, const OutputDevice* pOut) const
379 if (nMinMov>=0) return sal_uInt16(nMinMov);
380 if (pOut==NULL)
382 pOut = GetFirstOutputDevice();
384 if (pOut!=NULL) {
385 return short(-pOut->PixelToLogic(Size(nMinMov,0)).Width());
386 } else {
387 return 0;
391 sal_uInt16 SdrPaintView::ImpGetHitTolLogic(short nHitTol, const OutputDevice* pOut) const
393 if (nHitTol>=0) return sal_uInt16(nHitTol);
394 if (pOut==NULL)
396 pOut = GetFirstOutputDevice();
398 if (pOut!=NULL) {
399 return short(-pOut->PixelToLogic(Size(nHitTol,0)).Width());
400 } else {
401 return 0;
405 void SdrPaintView::TheresNewMapMode()
407 if (pActualOutDev!=NULL) {
408 nHitTolLog=(sal_uInt16)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nHitTolPix,0)).Width();
409 nMinMovLog=(sal_uInt16)((OutputDevice*)pActualOutDev)->PixelToLogic(Size(nMinMovPix,0)).Width();
413 void SdrPaintView::SetActualWin(const OutputDevice* pWin)
415 pActualOutDev=pWin;
416 TheresNewMapMode();
419 ////////////////////////////////////////////////////////////////////////////////////////////////////
421 void SdrPaintView::ClearPageView()
423 BrkAction();
425 if(mpPageView)
427 InvalidateAllWin();
428 delete mpPageView;
429 mpPageView = 0L;
433 SdrPageView* SdrPaintView::ShowSdrPage(SdrPage* pPage)
435 if(pPage && (!mpPageView || mpPageView->GetPage() != pPage))
437 if(mpPageView)
439 InvalidateAllWin();
440 delete mpPageView;
443 mpPageView = new SdrPageView(pPage, *((SdrView*)this));
444 mpPageView->Show();
447 return mpPageView;
450 void SdrPaintView::HideSdrPage()
452 if(mpPageView)
454 mpPageView->Hide();
455 delete mpPageView;
456 mpPageView = 0L;
460 void SdrPaintView::AddWindowToPaintView(OutputDevice* pNewWin)
462 DBG_ASSERT(pNewWin, "SdrPaintView::AddWindowToPaintView: No OutputDevice(!)");
463 SdrPaintWindow* pNewPaintWindow = new SdrPaintWindow(*this, *pNewWin);
464 AppendPaintWindow(*pNewPaintWindow);
466 if(mpPageView)
468 mpPageView->AddPaintWindowToPageView(*pNewPaintWindow);
471 #ifdef DBG_UTIL
472 if (pItemBrowser!=NULL)
473 pItemBrowser->ForceParent();
474 #endif
477 void SdrPaintView::DeleteWindowFromPaintView(OutputDevice* pOldWin)
479 DBG_ASSERT(pOldWin, "SdrPaintView::DeleteWindowFromPaintView: No OutputDevice(!)");
480 SdrPaintWindow* pCandidate = FindPaintWindow(*pOldWin);
482 if(pCandidate)
484 if(mpPageView)
486 mpPageView->RemovePaintWindowFromPageView(*pCandidate);
489 RemovePaintWindow(*pCandidate);
490 delete pCandidate;
493 #ifdef DBG_UTIL
494 if (pItemBrowser!=NULL)
495 pItemBrowser->ForceParent();
496 #endif
499 void SdrPaintView::SetLayerVisible(const XubString& rName, sal_Bool bShow)
501 if(mpPageView)
503 mpPageView->SetLayerVisible(rName,bShow);
506 InvalidateAllWin();
509 bool SdrPaintView::IsLayerVisible(const XubString& rName) const
511 if(mpPageView)
513 return mpPageView->IsLayerVisible(rName);
516 return false;
519 void SdrPaintView::SetLayerLocked(const XubString& rName, sal_Bool bLock)
521 if(mpPageView)
523 mpPageView->SetLayerLocked(rName,bLock);
527 bool SdrPaintView::IsLayerLocked(const XubString& rName) const
529 if(mpPageView)
531 return mpPageView->IsLayerLocked(rName);
534 return false;
537 void SdrPaintView::SetLayerPrintable(const XubString& rName, sal_Bool bPrn)
539 if(mpPageView)
541 mpPageView->SetLayerPrintable(rName,bPrn);
545 bool SdrPaintView::IsLayerPrintable(const XubString& rName) const
547 if(mpPageView)
549 return mpPageView->IsLayerPrintable(rName);
552 return false;
555 void SdrPaintView::PrePaint()
557 if(mpPageView)
559 mpPageView->PrePaint();
563 ////////////////////////////////////////////////////////////////////////////////////////////////////
564 // #define SVX_REPAINT_TIMER_TEST
566 void SdrPaintView::CompleteRedraw(OutputDevice* pOut, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector)
568 #ifdef SVX_REPAINT_TIMER_TEST
569 #define REMEMBERED_TIMES_COUNT (10)
570 static bool bDoTimerTest(false);
571 static bool bTimesInited(false);
572 static sal_uInt32 nRepeatCount(10L);
573 static double fLastTimes[REMEMBERED_TIMES_COUNT];
574 const sal_uInt32 nStartTime(Time::GetSystemTicks());
575 sal_uInt32 count(1L);
576 sal_uInt32 a;
578 if(bDoTimerTest)
580 count = nRepeatCount;
583 for(a = 0L; a < count; a++)
585 #endif // SVX_REPAINT_TIMER_TEST
587 // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
588 // rReg may be made more granular (fine) with using it. Normally, rReg
589 // does come from Window::Paint() anyways and thus is based on a single
590 // rectangle which was derived from exactly that repaint region
591 Region aOptimizedRepaintRegion(rReg);
593 if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType())
595 Window* pWindow = (Window*)pOut;
597 if(pWindow->IsInPaint())
599 if(!pWindow->GetPaintRegion().IsEmpty())
601 aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
603 #ifdef DBG_UTIL
604 // #i74769# test-paint repaint region
605 static bool bDoPaintForVisualControl(false);
606 if(bDoPaintForVisualControl)
608 RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
609 Rectangle aRegionRectangle;
611 while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
613 pWindow->SetLineColor(COL_LIGHTGREEN);
614 pWindow->SetFillColor();
615 pWindow->DrawRect(aRegionRectangle);
618 aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
620 #endif
625 SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut);
626 OSL_ENSURE(pPaintWindow, "SdrPaintView::CompleteRedraw: No OutDev (!)");
628 DoCompleteRedraw(*pPaintWindow, aOptimizedRepaintRegion, pRedirector);
629 EndCompleteRedraw(*pPaintWindow, true);
631 #ifdef SVX_REPAINT_TIMER_TEST
634 if(bDoTimerTest)
636 const sal_uInt32 nStopTime(Time::GetSystemTicks());
637 const sal_uInt32 nNeededTime(nStopTime - nStartTime);
638 const double fTimePerPaint((double)nNeededTime / (double)nRepeatCount);
640 if(!bTimesInited)
642 for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
644 fLastTimes[a] = fTimePerPaint;
647 bTimesInited = true;
649 else
651 for(a = 1L; a < REMEMBERED_TIMES_COUNT; a++)
653 fLastTimes[a - 1L] = fLastTimes[a];
656 fLastTimes[REMEMBERED_TIMES_COUNT - 1L] = fTimePerPaint;
659 double fAddedTimes(0.0);
661 for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
663 fAddedTimes += fLastTimes[a];
666 const double fAverageTimePerPaint(fAddedTimes / (double)REMEMBERED_TIMES_COUNT);
668 fprintf(stderr, "-----------(start result)----------\n");
669 fprintf(stderr, "StartTime : %u, StopTime: %u, NeededTime: %u, TimePerPaint: %f\n", nStartTime, nStopTime, nNeededTime, fTimePerPaint);
670 fprintf(stderr, "Remembered times: ");
672 for(a = 0L; a < REMEMBERED_TIMES_COUNT; a++)
674 fprintf(stderr, "%d: %f ", a, fLastTimes[a]);
677 fprintf(stderr, "\n");
678 fprintf(stderr, "AverageTimePerPaint: %f\n", fAverageTimePerPaint);
679 fprintf(stderr, "-----------(stop result)----------\n");
681 #endif // SVX_REPAINT_TIMER_TEST
684 ////////////////////////////////////////////////////////////////////////////////////////////////////
685 // #i72889#
687 SdrPaintWindow* SdrPaintView::BeginCompleteRedraw(OutputDevice* pOut)
689 OSL_ENSURE(pOut, "SdrPaintView::BeginCompleteRedraw: No OutDev (!)");
690 SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
692 if(pPaintWindow)
694 // draw preprocessing, only for known devices
695 // prepare PreRendering
696 pPaintWindow->PreparePreRenderDevice();
698 else
700 // None of the known OutputDevices is the target of this paint, use
701 // a temporary SdrPaintWindow for this Redraw.
702 pPaintWindow = new SdrPaintWindow(*this, *pOut);
703 pPaintWindow->setTemporaryTarget(true);
706 return pPaintWindow;
709 void SdrPaintView::DoCompleteRedraw(SdrPaintWindow& rPaintWindow, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector)
711 // redraw all PageViews with the target. This may expand the RedrawRegion
712 // at the PaintWindow, plus taking care of FormLayer expansion
713 if(mpPageView)
715 mpPageView->CompleteRedraw(rPaintWindow, rReg, pRedirector);
719 void SdrPaintView::EndCompleteRedraw(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer)
721 if(rPaintWindow.getTemporaryTarget())
723 // get rid of temp target again
724 delete (&rPaintWindow);
726 else
728 // draw postprocessing, only for known devices
729 // it is necessary to always paint FormLayer
730 if(bPaintFormLayer)
732 ImpFormLayerDrawing(rPaintWindow);
735 // look for active TextEdit. As long as this cannot be painted to a VDev,
736 // it cannot get part of buffering. In that case, output evtl. prerender
737 // early and paint text edit to window.
738 const bool bTextEditActive(IsTextEdit() && GetTextEditPageView());
740 if(bTextEditActive)
742 // output PreRendering and destroy it so that it is not used for FormLayer
743 // or overlay
744 rPaintWindow.OutputPreRenderDevice(rPaintWindow.GetRedrawRegion());
746 // draw old text edit stuff before overlay to have it as part of the background
747 // ATM. This will be changed to have the text editing on the overlay, bit it
748 // is not an easy thing to do, see BegTextEdit and the OutlinerView stuff used...
749 if(bTextEditActive)
751 ImpTextEditDrawing(rPaintWindow);
754 // draw Overlay directly to window. This will save the contents of the window
755 // in the RedrawRegion to the overlay background buffer, too.
756 // This may lead to problems when reading from the screen is slow from the
757 // graphics driver/graphiccard combination.
758 rPaintWindow.DrawOverlay(rPaintWindow.GetRedrawRegion(), false);
760 else
762 // draw Overlay, also to PreRender device if exists
763 rPaintWindow.DrawOverlay(rPaintWindow.GetRedrawRegion(), true);
765 // output PreRendering
766 rPaintWindow.OutputPreRenderDevice(rPaintWindow.GetRedrawRegion());
771 ////////////////////////////////////////////////////////////////////////////////////////////////////
773 SdrPaintWindow* SdrPaintView::BeginDrawLayers(OutputDevice* pOut, const Region& rReg, bool bDisableIntersect)
775 // #i74769# use BeginCompleteRedraw() as common base
776 SdrPaintWindow* pPaintWindow = BeginCompleteRedraw(pOut);
777 OSL_ENSURE(pPaintWindow, "SdrPaintView::BeginDrawLayers: No SdrPaintWindow (!)");
779 if(mpPageView)
781 SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(*pPaintWindow);
783 if(pKnownTarget)
785 Region aOptimizedRepaintRegion = OptimizeDrawLayersRegion( pOut, rReg, bDisableIntersect );
787 // prepare redraw
788 pKnownTarget->PrepareRedraw(aOptimizedRepaintRegion);
790 // remember prepared SdrPageWindow
791 mpPageView->setPreparedPageWindow(pKnownTarget);
795 return pPaintWindow;
798 void SdrPaintView::EndDrawLayers(SdrPaintWindow& rPaintWindow, bool bPaintFormLayer)
800 // #i74769# use EndCompleteRedraw() as common base
801 EndCompleteRedraw(rPaintWindow, bPaintFormLayer);
803 if(mpPageView)
805 // forget prepared SdrPageWindow
806 mpPageView->setPreparedPageWindow(0);
810 void SdrPaintView::UpdateDrawLayersRegion(OutputDevice* pOut, const Region& rReg, bool bDisableIntersect)
812 SdrPaintWindow* pPaintWindow = FindPaintWindow(*pOut);
813 OSL_ENSURE(pPaintWindow, "SdrPaintView::UpdateDrawLayersRegion: No SdrPaintWindow (!)");
815 if(mpPageView)
817 SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(*pPaintWindow);
819 if(pKnownTarget)
821 Region aOptimizedRepaintRegion = OptimizeDrawLayersRegion( pOut, rReg, bDisableIntersect );
822 pKnownTarget->GetPaintWindow().SetRedrawRegion(aOptimizedRepaintRegion);
823 mpPageView->setPreparedPageWindow(pKnownTarget); // already set actually
828 Region SdrPaintView::OptimizeDrawLayersRegion(OutputDevice* pOut, const Region& rReg, bool bDisableIntersect)
830 // #i74769# check if pOut is a win and has a ClipRegion. If Yes, the Region
831 // rReg may be made more granular (fine) with using it. Normally, rReg
832 // does come from Window::Paint() anyways and thus is based on a single
833 // rectangle which was derived from exactly that repaint region
834 Region aOptimizedRepaintRegion(rReg);
836 // #i76114# Intersecting the region with the Window's paint region is disabled
837 // for print preview in Calc, because the intersection can be empty (if the paint
838 // region is outside of the table area of the page), and then no clip region
839 // would be set.
840 if(pOut && OUTDEV_WINDOW == pOut->GetOutDevType() && !bDisableIntersect)
842 Window* pWindow = (Window*)pOut;
844 if(pWindow->IsInPaint())
846 if(!pWindow->GetPaintRegion().IsEmpty())
848 aOptimizedRepaintRegion.Intersect(pWindow->GetPaintRegion());
850 #ifdef DBG_UTIL
851 // #i74769# test-paint repaint region
852 static bool bDoPaintForVisualControl(false);
853 if(bDoPaintForVisualControl)
855 RegionHandle aRegionHandle(aOptimizedRepaintRegion.BeginEnumRects());
856 Rectangle aRegionRectangle;
858 while(aOptimizedRepaintRegion.GetEnumRects(aRegionHandle, aRegionRectangle))
860 pWindow->SetLineColor(COL_LIGHTGREEN);
861 pWindow->SetFillColor();
862 pWindow->DrawRect(aRegionRectangle);
865 aOptimizedRepaintRegion.EndEnumRects(aRegionHandle);
867 #endif
871 return aOptimizedRepaintRegion;
874 ////////////////////////////////////////////////////////////////////////////////////////////////////
876 void SdrPaintView::ImpTextEditDrawing(SdrPaintWindow& rPaintWindow) const
878 // draw old text edit stuff
879 if(IsTextEdit())
881 SdrPageView* pPageView = GetTextEditPageView();
883 if(pPageView)
885 // paint TextEdit directly to the destination OutDev
886 const Region& rRedrawRegion = rPaintWindow.GetRedrawRegion();
887 const Rectangle aCheckRect(rRedrawRegion.GetBoundRect());
888 pPageView->PaintOutlinerView(&rPaintWindow.GetOutputDevice(), aCheckRect);
893 void SdrPaintView::ImpFormLayerDrawing(SdrPaintWindow& rPaintWindow) const
895 if(mpPageView)
897 SdrPageWindow* pKnownTarget = mpPageView->FindPageWindow(rPaintWindow);
899 if(pKnownTarget)
901 const SdrModel& rModel = *(GetModel());
902 const SdrLayerAdmin& rLayerAdmin = rModel.GetLayerAdmin();
903 const SdrLayerID nControlLayerId = rLayerAdmin.GetLayerID(rLayerAdmin.GetControlLayerName(), sal_False);
905 // BUFFERED use GetTargetOutputDevice() now, it may be targeted to VDevs, too
906 // need to set PreparedPageWindow to make DrawLayer use the correct ObjectContact
907 mpPageView->setPreparedPageWindow(pKnownTarget);
908 mpPageView->DrawLayer(nControlLayerId, &rPaintWindow.GetTargetOutputDevice());
909 mpPageView->setPreparedPageWindow(0);
914 ////////////////////////////////////////////////////////////////////////////////////////////////////
916 sal_Bool SdrPaintView::KeyInput(const KeyEvent& /*rKEvt*/, Window* /*pWin*/)
918 return sal_False;
921 void SdrPaintView::GlueInvalidate() const
923 const sal_uInt32 nWindowCount(PaintWindowCount());
925 for(sal_uInt32 nWinNum(0L); nWinNum < nWindowCount; nWinNum++)
927 SdrPaintWindow* pPaintWindow = GetPaintWindow(nWinNum);
929 if(pPaintWindow->OutputToWindow())
931 OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
933 if(mpPageView)
935 const SdrObjList* pOL=mpPageView->GetObjList();
936 sal_uIntPtr nObjAnz=pOL->GetObjCount();
937 for (sal_uIntPtr nObjNum=0; nObjNum<nObjAnz; nObjNum++) {
938 const SdrObject* pObj=pOL->GetObj(nObjNum);
939 const SdrGluePointList* pGPL=pObj->GetGluePointList();
940 if (pGPL!=NULL && pGPL->GetCount()!=0) {
941 pGPL->Invalidate((Window&)rOutDev, pObj);
949 void SdrPaintView::InvalidateAllWin()
951 const sal_uInt32 nWindowCount(PaintWindowCount());
953 for(sal_uInt32 a(0L); a < nWindowCount; a++)
955 SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
957 if(pPaintWindow->OutputToWindow())
959 InvalidateOneWin((Window&)pPaintWindow->GetOutputDevice());
964 void SdrPaintView::InvalidateAllWin(const Rectangle& rRect, sal_Bool bPlus1Pix)
966 const sal_uInt32 nWindowCount(PaintWindowCount());
968 for(sal_uInt32 a(0L); a < nWindowCount; a++)
970 SdrPaintWindow* pPaintWindow = GetPaintWindow(a);
972 if(pPaintWindow->OutputToWindow())
974 OutputDevice& rOutDev = pPaintWindow->GetOutputDevice();
975 Rectangle aRect(rRect);
977 if(bPlus1Pix)
979 Size aPixSiz(1,1);
980 Size aSiz(rOutDev.PixelToLogic(aPixSiz));
981 aRect.Left ()-=aSiz.Width();
982 aRect.Top ()-=aSiz.Height();
983 aRect.Right ()+=aSiz.Width();
984 aRect.Bottom()+=aSiz.Height();
987 Point aOrg(rOutDev.GetMapMode().GetOrigin());
988 aOrg.X()=-aOrg.X(); aOrg.Y()=-aOrg.Y();
989 Rectangle aOutRect(aOrg, rOutDev.GetOutputSize());
991 if (aRect.IsOver(aOutRect))
993 InvalidateOneWin((Window&)rOutDev, aRect);
999 void SdrPaintView::InvalidateOneWin(Window& rWin)
1001 // do not erase background, that causes flicker (!)
1002 rWin.Invalidate(INVALIDATE_NOERASE);
1005 void SdrPaintView::InvalidateOneWin(Window& rWin, const Rectangle& rRect)
1007 // do not erase background, that causes flicker (!)
1008 rWin.Invalidate(rRect, INVALIDATE_NOERASE);
1011 void SdrPaintView::LeaveOneGroup()
1013 if(mpPageView)
1015 mpPageView->LeaveOneGroup();
1019 void SdrPaintView::LeaveAllGroup()
1021 if(mpPageView)
1023 mpPageView->LeaveAllGroup();
1027 bool SdrPaintView::IsGroupEntered() const
1029 if(mpPageView)
1031 return (mpPageView->GetEnteredLevel() != 0);
1034 return false;
1037 void SdrPaintView::SetNotPersistDefaultAttr(const SfxItemSet& rAttr, sal_Bool /*bReplaceAll*/)
1039 // bReplaceAll has no effect here at all.
1040 sal_Bool bMeasure=ISA(SdrView) && ((SdrView*)this)->IsMeasureTool();
1041 const SfxPoolItem *pPoolItem=NULL;
1042 if (rAttr.GetItemState(SDRATTR_LAYERID,sal_True,&pPoolItem)==SFX_ITEM_SET) {
1043 SdrLayerID nLayerId=((const SdrLayerIdItem*)pPoolItem)->GetValue();
1044 const SdrLayer* pLayer=pMod->GetLayerAdmin().GetLayerPerID(nLayerId);
1045 if (pLayer!=NULL) {
1046 if (bMeasure) aMeasureLayer=pLayer->GetName();
1047 else aAktLayer=pLayer->GetName();
1050 if (rAttr.GetItemState(SDRATTR_LAYERNAME,sal_True,&pPoolItem)==SFX_ITEM_SET) {
1051 if (bMeasure) aMeasureLayer=((const SdrLayerNameItem*)pPoolItem)->GetValue();
1052 else aAktLayer=((const SdrLayerNameItem*)pPoolItem)->GetValue();
1056 void SdrPaintView::MergeNotPersistDefaultAttr(SfxItemSet& rAttr, sal_Bool /*bOnlyHardAttr*/) const
1058 // bOnlyHardAttr has no effect here at all.
1059 sal_Bool bMeasure=ISA(SdrView) && ((SdrView*)this)->IsMeasureTool();
1060 const XubString& aNam=bMeasure?aMeasureLayer:aAktLayer;
1061 rAttr.Put(SdrLayerNameItem(aNam));
1062 SdrLayerID nLayer=pMod->GetLayerAdmin().GetLayerID(aNam,sal_True);
1063 if (nLayer!=SDRLAYER_NOTFOUND) {
1064 rAttr.Put(SdrLayerIdItem(nLayer));
1068 void SdrPaintView::SetDefaultAttr(const SfxItemSet& rAttr, sal_Bool bReplaceAll)
1070 #ifdef DBG_UTIL
1072 sal_Bool bHasEEFeatureItems=sal_False;
1073 SfxItemIter aIter(rAttr);
1074 const SfxPoolItem* pItem=aIter.FirstItem();
1075 while (!bHasEEFeatureItems && pItem!=NULL) {
1076 if (!IsInvalidItem(pItem)) {
1077 sal_uInt16 nW=pItem->Which();
1078 if (nW>=EE_FEATURE_START && nW<=EE_FEATURE_END) bHasEEFeatureItems=sal_True;
1080 pItem=aIter.NextItem();
1083 if(bHasEEFeatureItems)
1085 String aMessage;
1086 aMessage.AppendAscii("SdrPaintView::SetDefaultAttr(): Setting EE_FEATURE items at the SdrView does not make sense! It only leads to overhead and unreadable documents.");
1087 InfoBox(NULL, aMessage).Execute();
1090 #endif
1091 if (bReplaceAll) aDefaultAttr.Set(rAttr);
1092 else aDefaultAttr.Put(rAttr,sal_False); // if FALSE, regard InvalidItems as "holes," not as Default
1093 SetNotPersistDefaultAttr(rAttr,bReplaceAll);
1094 #ifdef DBG_UTIL
1095 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1096 #endif
1099 void SdrPaintView::SetDefaultStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1101 if (pDefaultStyleSheet)
1102 EndListening(*pDefaultStyleSheet);
1103 pDefaultStyleSheet=pStyleSheet;
1104 if (pDefaultStyleSheet)
1105 StartListening(*pDefaultStyleSheet);
1107 if (pStyleSheet!=NULL && !bDontRemoveHardAttr) {
1108 SfxWhichIter aIter(pStyleSheet->GetItemSet());
1109 sal_uInt16 nWhich=aIter.FirstWhich();
1110 while (nWhich!=0) {
1111 if (pStyleSheet->GetItemSet().GetItemState(nWhich,sal_True)==SFX_ITEM_SET) {
1112 aDefaultAttr.ClearItem(nWhich);
1114 nWhich=aIter.NextWhich();
1117 #ifdef DBG_UTIL
1118 if (pItemBrowser!=NULL) pItemBrowser->SetDirty();
1119 #endif
1122 sal_Bool SdrPaintView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
1124 if(bOnlyHardAttr || !pDefaultStyleSheet)
1126 rTargetSet.Put(aDefaultAttr, sal_False);
1128 else
1130 // else merge with DefStyleSheet
1131 rTargetSet.Put(pDefaultStyleSheet->GetItemSet(), sal_False);
1132 rTargetSet.Put(aDefaultAttr, sal_False);
1134 MergeNotPersistDefaultAttr(rTargetSet, bOnlyHardAttr);
1135 return sal_True;
1138 sal_Bool SdrPaintView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
1140 SetDefaultAttr(rSet,bReplaceAll);
1141 return sal_True;
1144 SfxStyleSheet* SdrPaintView::GetStyleSheet() const
1146 return GetDefaultStyleSheet();
1149 sal_Bool SdrPaintView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
1151 SetDefaultStyleSheet(pStyleSheet,bDontRemoveHardAttr);
1152 return sal_True;
1155 ////////////////////////////////////////////////////////////////////////////////////////////////////
1157 #ifdef DBG_UTIL
1158 void SdrPaintView::ShowItemBrowser(sal_Bool bShow)
1160 if (bShow) {
1161 if (pItemBrowser==NULL) {
1162 pItemBrowser=new SdrItemBrowser(*(SdrView*)this);
1163 pItemBrowser->SetFloatingMode(sal_True);
1165 pItemBrowser->Show();
1166 pItemBrowser->GrabFocus();
1167 } else {
1168 if (pItemBrowser!=NULL) {
1169 pItemBrowser->Hide();
1170 delete pItemBrowser;
1171 pItemBrowser=NULL;
1175 #endif
1177 void SdrPaintView::MakeVisible(const Rectangle& rRect, Window& rWin)
1179 MapMode aMap(rWin.GetMapMode());
1180 Size aActualSize(rWin.GetOutputSize());
1182 if( aActualSize.Height() > 0 && aActualSize.Width() > 0 )
1184 Size aNewSize(rRect.GetSize());
1185 sal_Bool bNewScale=sal_False;
1186 sal_Bool bNeedMoreX=aNewSize.Width()>aActualSize.Width();
1187 sal_Bool bNeedMoreY=aNewSize.Height()>aActualSize.Height();
1188 if (bNeedMoreX || bNeedMoreY)
1190 bNewScale=sal_True;
1191 // set new MapMode (Size+Org) and invalidate everything
1192 Fraction aXFact(aNewSize.Width(),aActualSize.Width());
1193 Fraction aYFact(aNewSize.Height(),aActualSize.Height());
1194 if (aYFact>aXFact) aXFact=aYFact;
1195 aXFact*=aMap.GetScaleX();
1196 aXFact.ReduceInaccurate(10); // to avoid runovers and BigInt mapping
1197 aMap.SetScaleX(aXFact);
1198 aMap.SetScaleY(aYFact);
1199 rWin.SetMapMode(aMap);
1200 aActualSize=rWin.GetOutputSize();
1202 Point aOrg(aMap.GetOrigin());
1203 long dx=0,dy=0;
1204 long l=-aOrg.X();
1205 long r=-aOrg.X()+aActualSize.Width()-1;
1206 long o=-aOrg.Y();
1207 long u=-aOrg.Y()+aActualSize.Height()-1;
1208 if (l>rRect.Left()) dx=rRect.Left()-l;
1209 else if (r<rRect.Right()) dx=rRect.Right()-r;
1210 if (o>rRect.Top()) dy=rRect.Top()-o;
1211 else if (u<rRect.Bottom()) dy=rRect.Bottom()-u;
1212 aMap.SetOrigin(Point(aOrg.X()-dx,aOrg.Y()-dy));
1213 if (!bNewScale) {
1214 if (dx!=0 || dy!=0) {
1215 rWin.Scroll(-dx,-dy);
1216 rWin.SetMapMode(aMap);
1217 rWin.Update();
1219 } else {
1220 rWin.SetMapMode(aMap);
1221 InvalidateOneWin(rWin);
1226 void SdrPaintView::DoConnect(SdrOle2Obj* /*pOleObj*/)
1230 void SdrPaintView::SetAnimationEnabled( sal_Bool bEnable )
1232 SetAnimationMode( bEnable ? SDR_ANIMATION_ANIMATE : SDR_ANIMATION_DISABLE );
1235 void SdrPaintView::SetAnimationPause( bool bSet )
1237 if((bool)bAnimationPause != bSet)
1239 bAnimationPause = bSet;
1241 if(mpPageView)
1243 for(sal_uInt32 b(0L); b < mpPageView->PageWindowCount(); b++)
1245 const SdrPageWindow& rPageWindow = *(mpPageView->GetPageWindow(b));
1246 sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact();
1247 sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator();
1249 if(rAnimator.IsPaused() != bSet)
1251 rAnimator.SetPaused(bSet);
1258 void SdrPaintView::SetAnimationMode( const SdrAnimationMode eMode )
1260 eAnimationMode = eMode;
1263 void SdrPaintView::VisAreaChanged(const OutputDevice* pOut)
1265 if(mpPageView)
1267 if (pOut)
1269 SdrPageWindow* pWindow = mpPageView->FindPageWindow(*((OutputDevice*)pOut));
1271 if(pWindow)
1273 VisAreaChanged(*pWindow);
1276 else
1278 for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++)
1280 VisAreaChanged(*mpPageView->GetPageWindow(a));
1286 void SdrPaintView::VisAreaChanged(const SdrPageWindow& /*rWindow*/)
1288 // notify SfxListener
1289 Broadcast(SvxViewHint(SvxViewHint::SVX_HINT_VIEWCHANGED));
1292 void SdrPaintView::onChangeColorConfig()
1294 SetGridColor( Color( maColorConfig.GetColorValue( svtools::DRAWGRID ).nColor ) );
1297 void SdrPaintView::SetGridColor( Color aColor )
1299 maGridColor = aColor;
1302 Color SdrPaintView::GetGridColor() const
1304 return maGridColor;
1307 // Set background color for svx at SdrPageViews
1308 void SdrPaintView::SetApplicationBackgroundColor(Color aBackgroundColor)
1310 if(mpPageView)
1312 mpPageView->SetApplicationBackgroundColor(aBackgroundColor);
1316 // Set document color for svx at SdrPageViews
1317 void SdrPaintView::SetApplicationDocumentColor(Color aDocumentColor)
1319 if(mpPageView)
1321 mpPageView->SetApplicationDocumentColor(aDocumentColor);
1325 bool SdrPaintView::IsBufferedOutputAllowed() const
1327 return (mbBufferedOutputAllowed && maDrawinglayerOpt.IsPaintBuffer());
1330 void SdrPaintView::SetBufferedOutputAllowed(bool bNew)
1332 if(bNew != (bool)mbBufferedOutputAllowed)
1334 mbBufferedOutputAllowed = bNew;
1338 bool SdrPaintView::IsBufferedOverlayAllowed() const
1340 return (mbBufferedOverlayAllowed && maDrawinglayerOpt.IsOverlayBuffer());
1343 void SdrPaintView::SetBufferedOverlayAllowed(bool bNew)
1345 if(bNew != (bool)mbBufferedOverlayAllowed)
1347 mbBufferedOverlayAllowed = bNew;
1351 sal_Bool SdrPaintView::IsPagePaintingAllowed() const
1353 return mbPagePaintingAllowed;
1356 void SdrPaintView::SetPagePaintingAllowed(bool bNew)
1358 if(bNew != (bool)mbPagePaintingAllowed)
1360 mbPagePaintingAllowed = bNew;
1364 // #i38135# Sets the timer for Object animations and restarts.
1365 void SdrPaintView::SetAnimationTimer(sal_uInt32 nTime)
1367 if(mpPageView)
1369 // first, reset all timers at all windows to 0L
1370 for(sal_uInt32 a(0L); a < mpPageView->PageWindowCount(); a++)
1372 const SdrPageWindow& rPageWindow = *mpPageView->GetPageWindow(a);
1373 sdr::contact::ObjectContact& rObjectContact = rPageWindow.GetObjectContact();
1374 sdr::animation::primitiveAnimator& rAnimator = rObjectContact.getPrimitiveAnimator();
1375 rAnimator.SetTime(nTime);
1380 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */