xref: /trunk/main/svx/source/svdraw/svdpagv.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 #include <svx/svdpagv.hxx>
31 #include <com/sun/star/awt/XWindow.hpp>
32 #include <com/sun/star/awt/PosSize.hpp>
33 #include <comphelper/processfactory.hxx>
34 #include <svx/svdoutl.hxx>
35 #include <svx/xpoly.hxx>
36 #include <svx/svdouno.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdview.hxx>
39 
40 #include <svx/svdedxv.hxx>
41 #include <svx/svdpagv.hxx>
42 #include <svx/svdoutl.hxx>
43 #include <svx/svdpagv.hxx>
44 #include <editeng/outliner.hxx>
45 #include <svx/svdetc.hxx>
46 #include <svx/svdobj.hxx>
47 #include <svx/svdouno.hxx>
48 #include <svx/svdpage.hxx>
49 #include <svx/svdview.hxx>
50 #include "svx/svditer.hxx"
51 #include <svx/svdogrp.hxx>
52 #include <svx/svdtypes.hxx>
53 
54 #include <svx/svdotext.hxx> // fuer PaintOutlinerView
55 #include <svx/svdoole2.hxx>
56 
57 // #110094#
58 #include <svx/sdr/contact/objectcontactofpageview.hxx>
59 #include <svx/svdogrp.hxx>
60 #include <svx/sdr/contact/viewobjectcontactredirector.hxx>
61 #include <svx/fmview.hxx>
62 
63 // for search on vector
64 #include <algorithm>
65 
66 using namespace ::rtl;
67 using namespace ::com::sun::star;
68 #include <svx/sdrpagewindow.hxx>
69 #include <svx/sdrpaintwindow.hxx>
70 
71 TYPEINIT1(SdrPageView, SfxListener);
72 DBG_NAME(SdrPageView);
73 
74 ////////////////////////////////////////////////////////////////////////////////////////////////////
75 // interface to SdrPageWindow
76 
77 SdrPageWindow* SdrPageView::FindPageWindow(SdrPaintWindow& rPaintWindow) const
78 {
79     for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
80     {
81         if(&((*a)->GetPaintWindow()) == &rPaintWindow)
82         {
83             return *a;
84         }
85     }
86 
87     return 0L;
88 }
89 
90 const SdrPageWindow* SdrPageView::FindPatchedPageWindow( const OutputDevice& _rOutDev ) const
91 {
92     for (   SdrPageWindowVector::const_iterator loop = maPageWindows.begin();
93             loop != maPageWindows.end();
94             ++loop
95         )
96     {
97         const SdrPageWindow& rPageWindow( *(*loop) );
98         const SdrPaintWindow& rPaintWindow( rPageWindow.GetOriginalPaintWindow() ? *rPageWindow.GetOriginalPaintWindow() : rPageWindow.GetPaintWindow() );
99         if ( &rPaintWindow.GetOutputDevice() == &_rOutDev )
100         {
101             return &rPageWindow;
102         }
103     }
104 
105     return NULL;
106 }
107 
108 SdrPageWindow* SdrPageView::FindPageWindow(const OutputDevice& rOutDev) const
109 {
110     for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
111     {
112         if(&((*a)->GetPaintWindow().GetOutputDevice()) == &rOutDev)
113         {
114             return *a;
115         }
116     }
117 
118     return 0L;
119 }
120 
121 SdrPageWindow* SdrPageView::GetPageWindow(sal_uInt32 nIndex) const
122 {
123     // #126416#
124     if(nIndex < maPageWindows.size())
125     {
126         return maPageWindows[nIndex];
127     }
128 
129     return 0L;
130 }
131 
132 void SdrPageView::ClearPageWindows()
133 {
134     // #126416#
135     for(SdrPageWindowVector::const_iterator a = maPageWindows.begin(); a != maPageWindows.end(); a++)
136     {
137         delete *a;
138     }
139 
140     maPageWindows.clear();
141 }
142 
143 void SdrPageView::AppendPageWindow(SdrPageWindow& rNew)
144 {
145     maPageWindows.push_back(&rNew);
146 }
147 
148 SdrPageWindow* SdrPageView::RemovePageWindow(sal_uInt32 nPos)
149 {
150     if(nPos < maPageWindows.size())
151     {
152         SdrPageWindowVector::iterator aAccess = maPageWindows.begin() + nPos;
153         // #114376# remember return value
154         SdrPageWindow* pErasedSdrPageWindow = *aAccess;
155         maPageWindows.erase(aAccess);
156         return pErasedSdrPageWindow;
157     }
158 
159     return 0L;
160 }
161 
162 SdrPageWindow* SdrPageView::RemovePageWindow(SdrPageWindow& rOld)
163 {
164     const SdrPageWindowVector::iterator aFindResult = ::std::find(maPageWindows.begin(), maPageWindows.end(), &rOld);
165 
166     if(aFindResult != maPageWindows.end())
167     {
168         // #114376# remember return value
169         SdrPageWindow* pSdrPageWindow = *aFindResult;
170         maPageWindows.erase(aFindResult);
171         return pSdrPageWindow;
172     }
173 
174     return 0L;
175 }
176 
177 //////////////////////////////////////////////////////////////////////////////
178 
179 SdrPageView::SdrPageView(SdrPage* pPage1, SdrView& rNewView)
180 :   mrView(rNewView),
181     // #103911# col_auto color lets the view takes the default SvxColorConfig entry
182     maDocumentColor( COL_AUTO ),
183     maBackgroundColor(COL_AUTO ), // #i48367# also react on autocolor
184     mpPreparedPageWindow(0) // #i72752#
185 {
186     DBG_CTOR(SdrPageView,NULL);
187     mpPage = pPage1;
188 
189     if(mpPage)
190     {
191         aPgOrg.X()=mpPage->GetLftBorder();
192         aPgOrg.Y()=mpPage->GetUppBorder();
193     }
194     mbHasMarked = sal_False;
195     aLayerVisi.SetAll();
196     aLayerPrn.SetAll();
197 
198     mbVisible = sal_False;
199     pAktList = NULL;
200     pAktGroup = NULL;
201     SetAktGroupAndList(NULL, mpPage);
202 
203     StartListening(*rNewView.GetModel());
204 
205     for(sal_uInt32 a(0L); a < rNewView.PaintWindowCount(); a++)
206     {
207         AddPaintWindowToPageView(*rNewView.GetPaintWindow(a));
208     }
209 }
210 
211 SdrPageView::~SdrPageView()
212 {
213     DBG_DTOR(SdrPageView,NULL);
214 
215     // cleanup window vector
216     ClearPageWindows();
217 }
218 
219 SdrPageWindow& SdrPageView::CreateNewPageWindowEntry(SdrPaintWindow& rPaintWindow)
220 {
221     // MIB 3.7.08: Das WinRec muss sofort in die Liste eingetragen werden,
222     // weil sich das InsertControlContainer darauf verlaesst
223     //SdrPageViewWinRec* pRec = new SdrPageViewWinRec( *this, pOut );
224     //pWinList->Insert(pRec);
225     SdrPageWindow& rWindow = *(new SdrPageWindow(*this, rPaintWindow));
226     AppendPageWindow(rWindow);
227 
228     return rWindow;
229 }
230 
231 void SdrPageView::AddPaintWindowToPageView(SdrPaintWindow& rPaintWindow)
232 {
233     if(!FindPageWindow(rPaintWindow))
234     {
235         CreateNewPageWindowEntry(rPaintWindow);
236     }
237 }
238 
239 void SdrPageView::RemovePaintWindowFromPageView(SdrPaintWindow& rPaintWindow)
240 {
241     SdrPageWindow* pCandidate = FindPageWindow(rPaintWindow);
242 
243     if(pCandidate)
244     {
245         pCandidate = RemovePageWindow(*pCandidate);
246 
247         if(pCandidate)
248         {
249             delete pCandidate;
250         }
251     }
252 }
253 
254 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > SdrPageView::GetControlContainer( const OutputDevice& _rDevice ) const
255 {
256     ::com::sun::star::uno::Reference< ::com::sun::star::awt::XControlContainer > xReturn;
257     const SdrPageWindow* pCandidate = FindPatchedPageWindow( _rDevice );
258 
259     if ( pCandidate )
260         xReturn = pCandidate->GetControlContainer( true );
261 
262     return xReturn;
263 }
264 
265 void __EXPORT SdrPageView::Notify(SfxBroadcaster& /*rBC*/, const SfxHint& /*rHint*/)
266 {
267     // not really interested in
268 }
269 
270 void SdrPageView::ModelHasChanged()
271 {
272     if (GetAktGroup()!=NULL) CheckAktGroup();
273 }
274 
275 sal_Bool SdrPageView::IsReadOnly() const
276 {
277     return (0L == GetPage() || GetView().GetModel()->IsReadOnly() || GetPage()->IsReadOnly() || GetObjList()->IsReadOnly());
278 }
279 
280 void SdrPageView::Show()
281 {
282     if(!IsVisible())
283     {
284         mbVisible = sal_True;
285         InvalidateAllWin();
286 
287         for(sal_uInt32 a(0L); a < GetView().PaintWindowCount(); a++)
288         {
289             AddPaintWindowToPageView(*GetView().GetPaintWindow(a));
290         }
291     }
292 }
293 
294 void SdrPageView::Hide()
295 {
296     if(IsVisible())
297     {
298         InvalidateAllWin();
299         mbVisible = sal_False;
300         ClearPageWindows();
301     }
302 }
303 
304 Rectangle SdrPageView::GetPageRect() const
305 {
306     if (GetPage()==NULL) return Rectangle();
307     return Rectangle(Point(),Size(GetPage()->GetWdt()+1,GetPage()->GetHgt()+1));
308 }
309 
310 void SdrPageView::InvalidateAllWin()
311 {
312     if(IsVisible() && GetPage())
313     {
314         Rectangle aRect(Point(0,0),Size(GetPage()->GetWdt()+1,GetPage()->GetHgt()+1));
315         aRect.Union(GetPage()->GetAllObjBoundRect());
316         GetView().InvalidateAllWin(aRect);
317     }
318 }
319 
320 void SdrPageView::InvalidateAllWin(const Rectangle& rRect, sal_Bool bPlus1Pix)
321 {
322     if(IsVisible())
323     {
324         GetView().InvalidateAllWin(rRect, bPlus1Pix);
325     }
326 }
327 
328 void SdrPageView::PaintOutlinerView(OutputDevice* pOut, const Rectangle& rRect) const
329 {
330     if (GetView().pTextEditOutliner==NULL) return;
331     //const SdrObject* pTextObjTmp=GetView().GetTextEditObject();
332     //const SdrTextObj* pText=PTR_CAST(SdrTextObj,pTextObjTmp);
333     //FASTBOOL bTextFrame=pText!=NULL && pText->IsTextFrame();
334     sal_uIntPtr nViewAnz=GetView().pTextEditOutliner->GetViewCount();
335     for (sal_uIntPtr i=0; i<nViewAnz; i++) {
336         OutlinerView* pOLV=GetView().pTextEditOutliner->GetView(i);
337         if (pOLV->GetWindow()==pOut) {
338             GetView().ImpPaintOutlinerView(*pOLV, rRect);
339             return;
340         }
341     }
342 }
343 
344 ////////////////////////////////////////////////////////////////////////////////////////////////////
345 
346 void SdrPageView::PrePaint()
347 {
348     const sal_uInt32 nCount(PageWindowCount());
349 
350     for(sal_uInt32 a(0); a < nCount; a++)
351     {
352         SdrPageWindow* pCandidate = GetPageWindow(a);
353 
354         if(pCandidate)
355         {
356             pCandidate->PrePaint();
357         }
358     }
359 }
360 
361 void SdrPageView::PostPaint()
362 {
363     const sal_uInt32 nCount(PageWindowCount());
364 
365     for(sal_uInt32 a(0); a < nCount; a++)
366     {
367         SdrPageWindow* pCandidate = GetPageWindow(a);
368 
369         if(pCandidate)
370         {
371             pCandidate->PostPaint();
372         }
373     }
374 }
375 
376 void SdrPageView::CompleteRedraw(SdrPaintWindow& rPaintWindow, const Region& rReg, sdr::contact::ViewObjectContactRedirector* pRedirector) const
377 {
378     if(GetPage())
379     {
380         SdrPageWindow* pPageWindow = FindPageWindow(rPaintWindow);
381         sal_Bool bIsTempTarget(sal_False);
382 
383         if(!pPageWindow)
384         {
385             // create temp PageWindow
386             pPageWindow = new SdrPageWindow(*((SdrPageView*)this), rPaintWindow);
387             bIsTempTarget = sal_True;
388         }
389 
390         // do the redraw
391         pPageWindow->PrepareRedraw(rReg);
392         pPageWindow->RedrawAll(pRedirector);
393 
394         // get rid of temp PageWindow
395         if(bIsTempTarget)
396         {
397             delete pPageWindow;
398             pPageWindow = 0L;
399         }
400     }
401 }
402 
403 ////////////////////////////////////////////////////////////////////////////////////////////////////
404 // #i74769# use SdrPaintWindow directly
405 
406 void SdrPageView::setPreparedPageWindow(SdrPageWindow* pKnownTarget)
407 {
408     // #i72752# remember prepared SdrPageWindow
409     mpPreparedPageWindow = pKnownTarget;
410 }
411 
412 void SdrPageView::DrawLayer(SdrLayerID nID, OutputDevice* pGivenTarget, sdr::contact::ViewObjectContactRedirector* pRedirector) const
413 {
414     if(GetPage())
415     {
416         if(pGivenTarget)
417         {
418             const SdrPageWindow* pKnownTarget = FindPageWindow(*pGivenTarget);
419 
420             if(pKnownTarget)
421             {
422                 // paint known target
423                 pKnownTarget->RedrawLayer(&nID, pRedirector);
424             }
425             else
426             {
427                 // #i72752# DrawLayer() uses a OutputDevice different from BeginDrawLayer. This happens
428                 // e.g. when SW paints a single text line in text edit mode. Try to use it
429                 SdrPageWindow* pPreparedTarget = mpPreparedPageWindow;
430 
431                 if(pPreparedTarget)
432                 {
433                     // if we have a prepared target, do not use a new SdrPageWindow since this
434                     // works but is expensive. Just use a temporary PaintWindow
435                     SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
436 
437                     // Copy existing paint region to use the same as prepared in BeginDrawLayer
438                     SdrPaintWindow& rExistingPaintWindow = pPreparedTarget->GetPaintWindow();
439                     const Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
440                     aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
441 
442                     // patch the ExistingPageWindow
443                     pPreparedTarget->patchPaintWindow(aTemporaryPaintWindow);
444 
445                     // redraw the layer
446                     pPreparedTarget->RedrawLayer(&nID, pRedirector);
447 
448                     // restore the ExistingPageWindow
449                     pPreparedTarget->unpatchPaintWindow();
450                 }
451                 else
452                 {
453                     OSL_ENSURE(false, "SdrPageView::DrawLayer: Creating temporary SdrPageWindow (ObjectContact), this should never be needed (!)");
454 
455                     // None of the known OutputDevices is the target of this paint, use
456                     // a temporary SdrPageWindow for this Redraw.
457                     SdrPaintWindow aTemporaryPaintWindow(mrView, *pGivenTarget);
458                     SdrPageWindow aTemporaryPageWindow(*((SdrPageView*)this), aTemporaryPaintWindow);
459 
460                     // #i72752#
461                     // Copy existing paint region if other PageWindows exist, this was created by
462                     // PrepareRedraw() from BeginDrawLayer(). Needs to be used e.g. when suddenly SW
463                     // paints into an unknown device other than the view was created for (e.g. VirtualDevice)
464                     if(PageWindowCount())
465                     {
466                         SdrPageWindow* pExistingPageWindow = GetPageWindow(0L);
467                         SdrPaintWindow& rExistingPaintWindow = pExistingPageWindow->GetPaintWindow();
468                         const Region& rExistingRegion = rExistingPaintWindow.GetRedrawRegion();
469                         aTemporaryPaintWindow.SetRedrawRegion(rExistingRegion);
470                     }
471 
472                     aTemporaryPageWindow.RedrawLayer(&nID, pRedirector);
473                 }
474             }
475         }
476         else
477         {
478             // paint in all known windows
479             for(sal_uInt32 a(0L); a < PageWindowCount(); a++)
480             {
481                 SdrPageWindow* pTarget = GetPageWindow(a);
482                 pTarget->RedrawLayer(&nID, pRedirector);
483             }
484         }
485     }
486 }
487 
488 void SdrPageView::SetDesignMode( bool _bDesignMode ) const
489 {
490     for ( sal_uInt32 i = 0L; i < PageWindowCount(); ++i )
491     {
492         const SdrPageWindow& rPageViewWindow = *GetPageWindow(i);
493         rPageViewWindow.SetDesignMode( _bDesignMode );
494     }
495 }
496 
497 ////////////////////////////////////////////////////////////////////////////////////////////////////
498 
499 #ifdef OS2
500 #define RGBCOLOR(r,g,b) ((sal_uIntPtr)(((sal_uInt8)(b) | ((sal_uInt16)(g)<<8)) | (((sal_uIntPtr)(sal_uInt8)(r))<<16)))
501 #endif
502 
503 void SdrPageView::DrawPageViewGrid(OutputDevice& rOut, const Rectangle& rRect, Color aColor)
504 {
505     if (GetPage()==NULL)
506         return;
507 
508     long nx1=GetView().aGridBig.Width();
509     long nx2=GetView().aGridFin.Width();
510     long ny1=GetView().aGridBig.Height();
511     long ny2=GetView().aGridFin.Height();
512 
513     if (nx1==0) nx1=nx2;
514     if (nx2==0) nx2=nx1;
515     if (ny1==0) ny1=ny2;
516     if (ny2==0) ny2=ny1;
517     if (nx1==0) { nx1=ny1; nx2=ny2; }
518     if (ny1==0) { ny1=nx1; ny2=nx2; }
519     if (nx1<0) nx1=-nx1;
520     if (nx2<0) nx2=-nx2;
521     if (ny1<0) ny1=-ny1;
522     if (ny2<0) ny2=-ny2;
523 
524     if (nx1!=0)
525     {
526         // no more global output size, use window size instead to decide grid sizes
527         long nScreenWdt = rOut.GetOutputSizePixel().Width();
528         // old: long nScreenWdt=System::GetDesktopRectPixel().GetWidth();
529 
530         // Grid bei kleinen Zoomstufen etwas erweitern
531         //Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
532         long nMinDotPix=2;
533         long nMinLinPix=4;
534 
535         if (nScreenWdt>=1600)
536         {
537             nMinDotPix=4;
538             nMinLinPix=8;
539         }
540         else if (nScreenWdt>=1024)
541         {
542             nMinDotPix=3;
543             nMinLinPix=6;
544         }
545         else
546         { // z.B. 640x480
547             nMinDotPix=2;
548             nMinLinPix=4;
549         }
550         Size aMinDotDist(rOut.PixelToLogic(Size(nMinDotPix,nMinDotPix)));
551         //Size a3PixSiz(rOut.PixelToLogic(Size(2,2)));
552         Size aMinLinDist(rOut.PixelToLogic(Size(nMinLinPix,nMinLinPix)));
553         FASTBOOL bHoriSolid=nx2<aMinDotDist.Width();
554         FASTBOOL bVertSolid=ny2<aMinDotDist.Height();
555         // Linienabstand vergroessern (mind. 4 Pixel)
556         // Vergroesserung: *2 *5 *10 *20 *50 *100 ...
557         int nTgl=0;
558         long nVal0=nx1;
559         while (nx1<aMinLinDist.Width())
560         {
561             long a=nx1;
562 
563             if (nTgl==0) nx1*=2;
564             if (nTgl==1) nx1=nVal0*5; // => nx1*=2.5
565             if (nTgl==2) nx1*=2;
566 
567             nVal0=a;
568             nTgl++; if (nTgl>=3) nTgl=0;
569         }
570         nTgl=0;
571         nVal0=ny1;
572         while (ny1<aMinLinDist.Height())
573         {
574             long a=ny1;
575 
576             if (nTgl==0) ny1*=2;
577             if (nTgl==1) ny1=nVal0*5; // => ny1*=2.5
578             if (nTgl==2) ny1*=2;
579 
580             nVal0=a;
581             nTgl++;
582 
583             if (nTgl>=3) nTgl=0;
584         }
585         // Keine Zwischenpunkte, wenn...
586         //if (nx2<a2PixSiz.Width()) nx2=nx1;
587         //if (ny2<a2PixSiz.Height()) ny2=ny1;
588 
589         FASTBOOL bHoriFine=nx2<nx1;
590         FASTBOOL bVertFine=ny2<ny1;
591         FASTBOOL bHoriLines=bHoriSolid || bHoriFine || !bVertFine;
592         FASTBOOL bVertLines=bVertSolid || bVertFine;
593 
594         Color aColorMerk( rOut.GetLineColor() );
595         rOut.SetLineColor( aColor );
596 
597         bool bMap0=rOut.IsMapModeEnabled();
598 
599         long nWrX=0;//aWriterPageOffset.X();
600         long nWrY=0;//aWriterPageOffset.Y();
601         Point aOrg(aPgOrg);
602         long x1=GetPage()->GetLftBorder()+1+nWrX;
603         long x2=GetPage()->GetWdt()-GetPage()->GetRgtBorder()-1+nWrY;
604         long y1=GetPage()->GetUppBorder()+1+nWrX;
605         long y2=GetPage()->GetHgt()-GetPage()->GetLwrBorder()-1+nWrY;
606         const SdrPageGridFrameList* pFrames=GetPage()->GetGridFrameList(this,NULL);
607         //sal_uInt16 nBufSiz=1024; // 4k Buffer = max. 512 Punkte
608         // #90353# long* pBuf = NULL;
609         sal_uInt16 nGridPaintAnz=1;
610         if (pFrames!=NULL) nGridPaintAnz=pFrames->GetCount();
611         for (sal_uInt16 nGridPaintNum=0; nGridPaintNum<nGridPaintAnz; nGridPaintNum++) {
612             if (pFrames!=NULL) {
613                 const SdrPageGridFrame& rGF=(*pFrames)[nGridPaintNum];
614                 nWrX=rGF.GetPaperRect().Left();
615                 nWrY=rGF.GetPaperRect().Top();
616                 x1=rGF.GetUserArea().Left();
617                 x2=rGF.GetUserArea().Right();
618                 y1=rGF.GetUserArea().Top();
619                 y2=rGF.GetUserArea().Bottom();
620                 aOrg=rGF.GetUserArea().TopLeft();
621                 aOrg-=rGF.GetPaperRect().TopLeft();
622             }
623             if (!rRect.IsEmpty()) {
624                 Size a1PixSiz(rOut.PixelToLogic(Size(1,1)));
625                 long nX1Pix=a1PixSiz.Width();  // 1 Pixel Toleranz drauf
626                 long nY1Pix=a1PixSiz.Height();
627                 if (x1<rRect.Left()  -nX1Pix) x1=rRect.Left()  -nX1Pix;
628                 if (x2>rRect.Right() +nX1Pix) x2=rRect.Right() +nX1Pix;
629                 if (y1<rRect.Top()   -nY1Pix) y1=rRect.Top()   -nY1Pix;
630                 if (y2>rRect.Bottom()+nY1Pix) y2=rRect.Bottom()+nY1Pix;
631             }
632             Point aPnt;
633 
634             long xBigOrg=aOrg.X()+nWrX;
635             while (xBigOrg>=x1) xBigOrg-=nx1;
636             while (xBigOrg<x1) xBigOrg+=nx1;
637             long xFinOrg=xBigOrg;
638             while (xFinOrg>=x1) xFinOrg-=nx2;
639             while (xFinOrg<x1) xFinOrg+=nx2;
640 
641             long yBigOrg=aOrg.Y()+nWrY;
642             while (yBigOrg>=y1) yBigOrg-=ny1;
643             while (yBigOrg<y1) yBigOrg+=ny1;
644             long yFinOrg=yBigOrg;
645             while (yFinOrg>=y1) yFinOrg-=ny2;
646             while (yFinOrg<y1) yFinOrg+=ny2;
647 
648             if( x1 <= x2 && y1 <= y2 )
649             {
650                 if( bHoriLines )
651                 {
652                     sal_uIntPtr nGridFlags = ( bHoriSolid ? GRID_HORZLINES : GRID_DOTS );
653                     sal_uInt16 nSteps = sal_uInt16(nx1 / nx2);
654                     sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((nx1 * 1000L)/ nSteps) - (nx2 * 1000L) ) : 0;
655                     sal_uInt32 nStepOffset = 0;
656                     sal_uInt16 nPointOffset = 0;
657 
658                     for(sal_uInt16 a=0;a<nSteps;a++)
659                     {
660                         // Zeichnen
661                         rOut.DrawGrid(
662                             Rectangle( xFinOrg + (a * nx2) + nPointOffset, yBigOrg, x2, y2 ),
663                             Size( nx1, ny1 ), nGridFlags );
664 
665                         // Schritt machen
666                         nStepOffset += nRestPerStepMul1000;
667                         while(nStepOffset >= 1000)
668                         {
669                             nStepOffset -= 1000;
670                             nPointOffset++;
671                         }
672                     }
673                 }
674 
675                 if( bVertLines )
676                 {
677                     sal_uIntPtr nGridFlags = ( bVertSolid ? GRID_VERTLINES : GRID_DOTS );
678                     sal_uInt16 nSteps = sal_uInt16(ny1 / ny2);
679                     sal_uInt32 nRestPerStepMul1000 = nSteps ? ( ((ny1 * 1000L)/ nSteps) - (ny2 * 1000L) ) : 0;
680                     sal_uInt32 nStepOffset = 0;
681                     sal_uInt16 nPointOffset = 0;
682 
683                     for(sal_uInt16 a=0;a<nSteps;a++)
684                     {
685                         // Zeichnen
686                         rOut.DrawGrid(
687                             Rectangle( xBigOrg, yFinOrg + (a * ny2) + nPointOffset, x2, y2 ),
688                             Size( nx1, ny1 ), nGridFlags );
689 
690                         // Schritt machen
691                         nStepOffset += nRestPerStepMul1000;
692                         while(nStepOffset >= 1000)
693                         {
694                             nStepOffset -= 1000;
695                             nPointOffset++;
696                         }
697                     }
698 
699                     // rOut.DrawGrid( Rectangle( xo + xBigOrg, yo + yFinOrg, x2, y2 ), Size( nx1, ny2 ), nGridFlags );
700                 }
701             }
702         }
703 
704         rOut.EnableMapMode(bMap0);
705         rOut.SetLineColor(aColorMerk);
706     }
707 }
708 
709 void SdrPageView::AdjHdl()
710 {
711     GetView().AdjustMarkHdl();
712 }
713 
714 void SdrPageView::SetLayer(const XubString& rName, SetOfByte& rBS, sal_Bool bJa)
715 {
716     if(!GetPage())
717         return;
718 
719     SdrLayerID nID = GetPage()->GetLayerAdmin().GetLayerID(rName, sal_True);
720 
721     if(SDRLAYER_NOTFOUND != nID)
722         rBS.Set(nID, bJa);
723 }
724 
725 sal_Bool SdrPageView::IsLayer(const XubString& rName, const SetOfByte& rBS) const
726 {
727     if(!GetPage())
728         return sal_False;
729 
730     sal_Bool bRet(sal_False);
731 
732     if(rName.Len())
733     {
734         SdrLayerID nId = GetPage()->GetLayerAdmin().GetLayerID(rName, sal_True);
735 
736         if(SDRLAYER_NOTFOUND != nId)
737         {
738             bRet = rBS.IsSet(nId);
739         }
740     }
741 
742     return bRet;
743 }
744 
745 void SdrPageView::SetAllLayers(SetOfByte& rB, sal_Bool bJa)
746 {
747     if(bJa)
748     {
749         rB.SetAll();
750         rB.Clear(SDRLAYER_NOTFOUND);
751     }
752     else
753     {
754         rB.ClearAll();
755     }
756 }
757 
758 sal_Bool SdrPageView::IsObjMarkable(SdrObject* pObj) const
759 {
760     if(pObj)
761     {
762         // Vom Markieren ausgeschlossen?
763         if(pObj->IsMarkProtect())
764         {
765             return sal_False;
766         }
767 
768         // only visible are markable
769         if( !pObj->IsVisible() )
770         {
771             return sal_False;
772         }
773 
774         // #112440#
775         if(pObj->ISA(SdrObjGroup))
776         {
777             // If object is a Group object, visibility depends evtl. on
778             // multiple layers. If one object is markable, Group is markable.
779             SdrObjList* pObjList = ((SdrObjGroup*)pObj)->GetSubList();
780 
781             if(pObjList && pObjList->GetObjCount())
782             {
783                 sal_Bool bGroupIsMarkable(sal_False);
784 
785                 for(sal_uInt32 a(0L); !bGroupIsMarkable && a < pObjList->GetObjCount(); a++)
786                 {
787                     SdrObject* pCandidate = pObjList->GetObj(a);
788 
789                     // call recursively
790                     if(IsObjMarkable(pCandidate))
791                     {
792                         bGroupIsMarkable = sal_True;
793                     }
794                 }
795 
796                 return bGroupIsMarkable;
797             }
798             else
799             {
800                 // #i43302#
801                 // Allow empty groups to be selected to be able to delete them
802                 return sal_True;
803             }
804         }
805         else
806         {
807             // Der Layer muss sichtbar und darf nicht gesperrt sein
808             SdrLayerID nL = pObj->GetLayer();
809             return (aLayerVisi.IsSet(sal_uInt8(nL)) && !aLayerLock.IsSet(sal_uInt8(nL)));
810         }
811     }
812 
813     return sal_False;
814 }
815 
816 void SdrPageView::SetPageOrigin(const Point& rOrg)
817 {
818     if (rOrg!=aPgOrg) {
819         aPgOrg=rOrg;
820         if (GetView().IsGridVisible()) {
821             InvalidateAllWin();
822         }
823     }
824 }
825 
826 void SdrPageView::ImpInvalidateHelpLineArea(sal_uInt16 nNum) const
827 {
828     if (GetView().IsHlplVisible() && nNum<aHelpLines.GetCount()) {
829         const SdrHelpLine& rHL=aHelpLines[nNum];
830 
831         for(sal_uInt32 a(0L); a < GetView().PaintWindowCount(); a++)
832         {
833             SdrPaintWindow* pCandidate = GetView().GetPaintWindow(a);
834 
835             if(pCandidate->OutputToWindow())
836             {
837                 OutputDevice& rOutDev = pCandidate->GetOutputDevice();
838                 Rectangle aR(rHL.GetBoundRect(rOutDev));
839                 Size aSiz(rOutDev.PixelToLogic(Size(1,1)));
840                 aR.Left() -= aSiz.Width();
841                 aR.Right() += aSiz.Width();
842                 aR.Top() -= aSiz.Height();
843                 aR.Bottom() += aSiz.Height();
844                 ((SdrView&)GetView()).InvalidateOneWin((Window&)rOutDev, aR);
845             }
846         }
847     }
848 }
849 
850 void SdrPageView::SetHelpLines(const SdrHelpLineList& rHLL)
851 {
852     aHelpLines=rHLL;
853     InvalidateAllWin();
854 }
855 
856 void SdrPageView::SetHelpLine(sal_uInt16 nNum, const SdrHelpLine& rNewHelpLine)
857 {
858     if (nNum<aHelpLines.GetCount() && aHelpLines[nNum]!=rNewHelpLine) {
859         FASTBOOL bNeedRedraw=sal_True;
860         if (aHelpLines[nNum].GetKind()==rNewHelpLine.GetKind()) {
861             switch (rNewHelpLine.GetKind()) {
862                 case SDRHELPLINE_VERTICAL  : if (aHelpLines[nNum].GetPos().X()==rNewHelpLine.GetPos().X()) bNeedRedraw=sal_False; break;
863                 case SDRHELPLINE_HORIZONTAL: if (aHelpLines[nNum].GetPos().Y()==rNewHelpLine.GetPos().Y()) bNeedRedraw=sal_False; break;
864                 default: break;
865             } // switch
866         }
867         if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
868         aHelpLines[nNum]=rNewHelpLine;
869         if (bNeedRedraw) ImpInvalidateHelpLineArea(nNum);
870     }
871 }
872 
873 void SdrPageView::DeleteHelpLine(sal_uInt16 nNum)
874 {
875     if (nNum<aHelpLines.GetCount()) {
876         ImpInvalidateHelpLineArea(nNum);
877         aHelpLines.Delete(nNum);
878     }
879 }
880 
881 void SdrPageView::InsertHelpLine(const SdrHelpLine& rHL, sal_uInt16 nNum)
882 {
883     if (nNum>aHelpLines.GetCount()) nNum=aHelpLines.GetCount();
884     aHelpLines.Insert(rHL,nNum);
885     if (GetView().IsHlplVisible()) {
886         if (GetView().IsHlplFront()) {
887             // Hier optimieren ...
888             ImpInvalidateHelpLineArea(nNum);
889          } else {
890             ImpInvalidateHelpLineArea(nNum);
891         }
892     }
893 }
894 
895 // Betretene Gruppe und Liste setzen
896 void SdrPageView::SetAktGroupAndList(SdrObject* pNewGroup, SdrObjList* pNewList)
897 {
898     if(pAktGroup != pNewGroup)
899     {
900         pAktGroup = pNewGroup;
901     }
902     if(pAktList != pNewList)
903     {
904         pAktList = pNewList;
905     }
906 }
907 
908 sal_Bool SdrPageView::EnterGroup(SdrObject* pObj)
909 {
910     sal_Bool bRet(sal_False);
911 
912     if(pObj && pObj->IsGroupObject())
913     {
914         sal_Bool bGlueInvalidate(GetView().ImpIsGlueVisible());
915 
916         if(bGlueInvalidate)
917         {
918             GetView().GlueInvalidate();
919         }
920 
921         // deselect all
922         GetView().UnmarkAll();
923 
924         // set current group and list
925         SdrObjList* pNewObjList = pObj->GetSubList();
926         SetAktGroupAndList(pObj, pNewObjList);
927 
928         // select contained object if only one object is contained,
929         // else select nothing and let the user decide what to do next
930         if(pNewObjList && pNewObjList->GetObjCount() == 1)
931         {
932             SdrObject* pFirstObject = pNewObjList->GetObj(0L);
933 
934             if(GetView().GetSdrPageView())
935             {
936                 GetView().MarkObj(pFirstObject, GetView().GetSdrPageView());
937             }
938         }
939 
940         // build new handles
941         GetView().AdjustMarkHdl();
942 
943         // invalidate only when view wants to visualize group entering
944         if(GetView().DoVisualizeEnteredGroup())
945         {
946             InvalidateAllWin();
947         }
948 
949         if (bGlueInvalidate)
950         {
951             GetView().GlueInvalidate();
952         }
953 
954         bRet = sal_True;
955     }
956 
957     return bRet;
958 }
959 
960 void SdrPageView::LeaveOneGroup()
961 {
962     if(GetAktGroup())
963     {
964         sal_Bool bGlueInvalidate = (GetView().ImpIsGlueVisible());
965 
966         if(bGlueInvalidate)
967             GetView().GlueInvalidate();
968 
969         SdrObject* pLastGroup = GetAktGroup();
970         SdrObject* pParentGroup = GetAktGroup()->GetUpGroup();
971         SdrObjList* pParentList = GetPage();
972 
973         if(pParentGroup)
974             pParentList = pParentGroup->GetSubList();
975 
976         // Alles deselektieren
977         GetView().UnmarkAll();
978 
979         // Zuweisungen, pAktGroup und pAktList muessen gesetzt sein
980         SetAktGroupAndList(pParentGroup, pParentList);
981 
982         // gerade verlassene Gruppe selektieren
983         if(pLastGroup)
984             if(GetView().GetSdrPageView())
985                 GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
986 
987         GetView().AdjustMarkHdl();
988 
989         // invalidate only when view wants to visualize group entering
990         if(GetView().DoVisualizeEnteredGroup())
991             InvalidateAllWin();
992 
993         if(bGlueInvalidate)
994             GetView().GlueInvalidate();
995     }
996 }
997 
998 void SdrPageView::LeaveAllGroup()
999 {
1000     if(GetAktGroup())
1001     {
1002         sal_Bool bGlueInvalidate = (GetView().ImpIsGlueVisible());
1003 
1004         if(bGlueInvalidate)
1005             GetView().GlueInvalidate();
1006 
1007         SdrObject* pLastGroup = GetAktGroup();
1008 
1009         // Alles deselektieren
1010         GetView().UnmarkAll();
1011 
1012         // Zuweisungen, pAktGroup und pAktList muessen gesetzt sein
1013         SetAktGroupAndList(NULL, GetPage());
1014 
1015         // Oberste letzte Gruppe finden und selektieren
1016         if(pLastGroup)
1017         {
1018             while(pLastGroup->GetUpGroup())
1019                 pLastGroup = pLastGroup->GetUpGroup();
1020 
1021             if(GetView().GetSdrPageView())
1022                 GetView().MarkObj(pLastGroup, GetView().GetSdrPageView());
1023         }
1024 
1025         GetView().AdjustMarkHdl();
1026 
1027         // invalidate only when view wants to visualize group entering
1028         if(GetView().DoVisualizeEnteredGroup())
1029             InvalidateAllWin();
1030 
1031         if(bGlueInvalidate)
1032             GetView().GlueInvalidate();
1033     }
1034 }
1035 
1036 sal_uInt16 SdrPageView::GetEnteredLevel() const
1037 {
1038     sal_uInt16 nAnz=0;
1039     SdrObject* pGrp=GetAktGroup();
1040     while (pGrp!=NULL) {
1041         nAnz++;
1042         pGrp=pGrp->GetUpGroup();
1043     }
1044     return nAnz;
1045 }
1046 
1047 XubString SdrPageView::GetActualGroupName() const
1048 {
1049     if(GetAktGroup())
1050     {
1051         XubString aStr(GetAktGroup()->GetName());
1052 
1053         if(!aStr.Len())
1054             aStr += sal_Unicode('?');
1055 
1056         return aStr;
1057     }
1058     else
1059         return String();
1060 }
1061 
1062 XubString SdrPageView::GetActualPathName(sal_Unicode cSep) const
1063 {
1064     XubString aStr;
1065     sal_Bool bNamFnd(sal_False);
1066     SdrObject* pGrp = GetAktGroup();
1067 
1068     while(pGrp)
1069     {
1070         XubString aStr1(pGrp->GetName());
1071 
1072         if(!aStr1.Len())
1073             aStr1 += sal_Unicode('?');
1074         else
1075             bNamFnd = sal_True;
1076 
1077         aStr += aStr1;
1078         pGrp = pGrp->GetUpGroup();
1079 
1080         if(pGrp)
1081             aStr += cSep;
1082     }
1083 
1084     if(!bNamFnd && GetAktGroup())
1085     {
1086         aStr = String();
1087         aStr += sal_Unicode('(');
1088         aStr += String::CreateFromInt32( GetEnteredLevel() );
1089         aStr += sal_Unicode(')');
1090     }
1091 
1092     return aStr;
1093 }
1094 
1095 void SdrPageView::CheckAktGroup()
1096 {
1097     SdrObject* pGrp=GetAktGroup();
1098     while (pGrp!=NULL &&
1099            (!pGrp->IsInserted() || pGrp->GetObjList()==NULL ||
1100             pGrp->GetPage()==NULL || pGrp->GetModel()==NULL)) { // irgendwas daneben?
1101         pGrp=pGrp->GetUpGroup();
1102     }
1103     if (pGrp!=GetAktGroup()) {
1104         if (pGrp!=NULL) EnterGroup(pGrp);
1105         else LeaveAllGroup();
1106     }
1107 }
1108 
1109 // #103834# Set background color for svx at SdrPageViews
1110 void SdrPageView::SetApplicationBackgroundColor(Color aBackgroundColor)
1111 {
1112     maBackgroundColor = aBackgroundColor;
1113 }
1114 
1115 // #109585#
1116 Color SdrPageView::GetApplicationBackgroundColor() const
1117 {
1118     return maBackgroundColor;
1119 }
1120 
1121 // #103911# Set document color for svx at SdrPageViews
1122 void SdrPageView::SetApplicationDocumentColor(Color aDocumentColor)
1123 {
1124     maDocumentColor = aDocumentColor;
1125 }
1126 
1127 Color SdrPageView::GetApplicationDocumentColor() const
1128 {
1129     return maDocumentColor;
1130 }
1131 
1132 ////////////////////////////////////////////////////////////////////////////////////////////////////
1133 // eof
1134