xref: /aoo41x/main/svx/source/svdraw/svdpagv.cxx (revision cdf0e10c)
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