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