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