xref: /aoo41x/main/svx/source/svdraw/svdcrtv.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 
31 #include <svx/svdcrtv.hxx>
32 #include "svx/xattr.hxx"
33 #include <svx/svdundo.hxx>
34 #include <svx/svdocapt.hxx> // Spezialbehandlung: Nach dem Create transparente Fuellung
35 #include <svx/svdoedge.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <svx/svdpage.hxx>
38 #include <svx/svdetc.hxx>
39 #include <svx/scene3d.hxx>
40 #include <svx/view3d.hxx>
41 #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx>
42 #include <svx/sdr/contact/displayinfo.hxx>
43 #include <svx/svdouno.hxx>
44 #define XOR_CREATE_PEN			PEN_SOLID
45 #include <svx/svdopath.hxx>
46 #include <svx/sdr/overlay/overlaypolypolygon.hxx>
47 #include <svx/sdr/overlay/overlaymanager.hxx>
48 #include <svx/sdrpaintwindow.hxx>
49 #include "fmobj.hxx"
50 #include <svx/svdocirc.hxx>
51 #include <svx/sdr/contact/viewcontact.hxx>
52 #include <svx/sdr/overlay/overlayprimitive2dsequenceobject.hxx>
53 #include <svx/sdr/overlay/overlaymanager.hxx>
54 
55 ////////////////////////////////////////////////////////////////////////////////////////////////////
56 
57 class ImplConnectMarkerOverlay
58 {
59 	// The OverlayObjects
60 	::sdr::overlay::OverlayObjectList				maObjects;
61 
62 	// The remembered target object
63 	const SdrObject&								mrObject;
64 
65 public:
66 	ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject& rObject);
67 	~ImplConnectMarkerOverlay();
68 
69 	const SdrObject& GetTargetObject() const { return mrObject; }
70 };
71 
72 ImplConnectMarkerOverlay::ImplConnectMarkerOverlay(const SdrCreateView& rView, SdrObject& rObject)
73 :	mrObject(rObject)
74 {
75 	basegfx::B2DPolyPolygon aB2DPolyPolygon(rObject.TakeXorPoly());
76 
77 	for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
78 	{
79 		SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
80 		::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
81 
82 		if(pTargetOverlay)
83 		{
84 			Size aHalfLogicSize(pTargetOverlay->getOutputDevice().PixelToLogic(Size(4, 4)));
85 
86 			// object
87 			::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aB2DPolyPolygon);
88 			pTargetOverlay->add(*pNew);
89 			maObjects.append(*pNew);
90 
91 			// gluepoints
92 			if(rView.IsAutoVertexConnectors())
93 			{
94 				for(sal_uInt16 i(0); i < 4; i++)
95 				{
96 					SdrGluePoint aGluePoint(rObject.GetVertexGluePoint(i));
97 					const Point& rPosition = aGluePoint.GetAbsolutePos(rObject);
98 
99 					basegfx::B2DPoint aTopLeft(rPosition.X() - aHalfLogicSize.Width(), rPosition.Y() - aHalfLogicSize.Height());
100 					basegfx::B2DPoint aBottomRight(rPosition.X() + aHalfLogicSize.Width(), rPosition.Y() + aHalfLogicSize.Height());
101 
102 					basegfx::B2DPolygon aTempPoly;
103 					aTempPoly.append(aTopLeft);
104 					aTempPoly.append(basegfx::B2DPoint(aBottomRight.getX(), aTopLeft.getY()));
105 					aTempPoly.append(aBottomRight);
106 					aTempPoly.append(basegfx::B2DPoint(aTopLeft.getX(), aBottomRight.getY()));
107 					aTempPoly.setClosed(true);
108 
109 					basegfx::B2DPolyPolygon aTempPolyPoly;
110 					aTempPolyPoly.append(aTempPoly);
111 
112 					pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(aTempPolyPoly);
113 					pTargetOverlay->add(*pNew);
114 					maObjects.append(*pNew);
115 				}
116 			}
117 		}
118 	}
119 }
120 
121 ImplConnectMarkerOverlay::~ImplConnectMarkerOverlay()
122 {
123 	// The OverlayObjects are cleared using the destructor of OverlayObjectList.
124 	// That destructor calls clear() at the list which removes all objects from the
125 	// OverlayManager and deletes them.
126 }
127 
128 ////////////////////////////////////////////////////////////////////////////////////////////////////
129 
130 class ImpSdrCreateViewExtraData
131 {
132 	// The OverlayObjects for XOR replacement
133 	::sdr::overlay::OverlayObjectList				maObjects;
134 
135 public:
136 	ImpSdrCreateViewExtraData();
137 	~ImpSdrCreateViewExtraData();
138 
139 	void CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly);
140 	void HideOverlay();
141 };
142 
143 ImpSdrCreateViewExtraData::ImpSdrCreateViewExtraData()
144 {
145 }
146 
147 ImpSdrCreateViewExtraData::~ImpSdrCreateViewExtraData()
148 {
149 	HideOverlay();
150 }
151 
152 void ImpSdrCreateViewExtraData::CreateAndShowOverlay(const SdrCreateView& rView, const SdrObject* pObject, const basegfx::B2DPolyPolygon& rPolyPoly)
153 {
154 	for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
155 	{
156 		SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
157 		::sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
158 
159 		if(pOverlayManager)
160 		{
161 			if(pObject)
162 			{
163 				const sdr::contact::ViewContact& rVC = pObject->GetViewContact();
164 				const drawinglayer::primitive2d::Primitive2DSequence aSequence = rVC.getViewIndependentPrimitive2DSequence();
165 				sdr::overlay::OverlayObject* pNew = new sdr::overlay::OverlayPrimitive2DSequenceObject(aSequence);
166 
167 				pOverlayManager->add(*pNew);
168 			    maObjects.append(*pNew);
169 			}
170 
171 			if(rPolyPoly.count())
172 			{
173 				::sdr::overlay::OverlayPolyPolygonStriped* pNew = new ::sdr::overlay::OverlayPolyPolygonStriped(rPolyPoly);
174 				pOverlayManager->add(*pNew);
175 				maObjects.append(*pNew);
176 			}
177 		}
178 	}
179 }
180 
181 void ImpSdrCreateViewExtraData::HideOverlay()
182 {
183 	// the clear() call at the list removes all objects from the
184 	// OverlayManager and deletes them.
185 	maObjects.clear();
186 }
187 
188 ////////////////////////////////////////////////////////////////////////////////////////////////////
189 ////////////////////////////////////////////////////////////////////////////////////////////////////
190 //
191 //   @@@@  @@@@@  @@@@@  @@@@  @@@@@@ @@@@@  @@ @@ @@ @@@@@ @@   @@
192 //  @@  @@ @@  @@ @@    @@  @@   @@   @@     @@ @@ @@ @@    @@   @@
193 //  @@     @@  @@ @@    @@  @@   @@   @@     @@ @@ @@ @@    @@ @ @@
194 //  @@     @@@@@  @@@@  @@@@@@   @@   @@@@   @@@@@ @@ @@@@  @@@@@@@
195 //  @@     @@  @@ @@    @@  @@   @@   @@      @@@  @@ @@    @@@@@@@
196 //  @@  @@ @@  @@ @@    @@  @@   @@   @@      @@@  @@ @@    @@@ @@@
197 //   @@@@  @@  @@ @@@@@ @@  @@   @@   @@@@@    @   @@ @@@@@ @@   @@
198 //
199 ////////////////////////////////////////////////////////////////////////////////////////////////////
200 ////////////////////////////////////////////////////////////////////////////////////////////////////
201 
202 void SdrCreateView::ImpClearConnectMarker()
203 {
204 	if(mpCoMaOverlay)
205 	{
206 		delete mpCoMaOverlay;
207 		mpCoMaOverlay = 0L;
208 	}
209 }
210 
211 void SdrCreateView::ImpClearVars()
212 {
213 	nAktInvent=SdrInventor;
214 	nAktIdent=OBJ_NONE;
215 	pAktCreate=NULL;
216 	pCreatePV=NULL;
217 	bAutoTextEdit=sal_False;
218 	b1stPointAsCenter=sal_False;
219 	aAktCreatePointer=Pointer(POINTER_CROSS);
220 	bUseIncompatiblePathCreateInterface=sal_False;
221 	bAutoClosePolys=sal_True;
222 	nAutoCloseDistPix=5;
223 	nFreeHandMinDistPix=10;
224 
225 	ImpClearConnectMarker();
226 }
227 
228 void SdrCreateView::ImpMakeCreateAttr()
229 {
230 }
231 
232 SdrCreateView::SdrCreateView(SdrModel* pModel1, OutputDevice* pOut)
233 :	SdrDragView(pModel1,pOut),
234 	mpCoMaOverlay(0L),
235 	mpCreateViewExtraData(new ImpSdrCreateViewExtraData())
236 {
237 	ImpClearVars();
238 	ImpMakeCreateAttr();
239 }
240 
241 SdrCreateView::~SdrCreateView()
242 {
243 	ImpClearConnectMarker();
244 	delete mpCreateViewExtraData;
245     SdrObject::Free( pAktCreate );
246 }
247 
248 void SdrCreateView::ImpDelCreateAttr()
249 {
250 }
251 
252 sal_Bool SdrCreateView::IsAction() const
253 {
254 	return SdrDragView::IsAction() || pAktCreate!=NULL;
255 }
256 
257 void SdrCreateView::MovAction(const Point& rPnt)
258 {
259 	SdrDragView::MovAction(rPnt);
260 	if (pAktCreate!=NULL) {
261 		MovCreateObj(rPnt);
262 	}
263 }
264 
265 void SdrCreateView::EndAction()
266 {
267 	if (pAktCreate!=NULL) EndCreateObj(SDRCREATE_FORCEEND);
268 	SdrDragView::EndAction();
269 }
270 
271 void SdrCreateView::BckAction()
272 {
273 	if (pAktCreate!=NULL) BckCreateObj();
274 	SdrDragView::BckAction();
275 }
276 
277 void SdrCreateView::BrkAction()
278 {
279 	SdrDragView::BrkAction();
280 	BrkCreateObj();
281 }
282 
283 void SdrCreateView::TakeActionRect(Rectangle& rRect) const
284 {
285 	if (pAktCreate!=NULL)
286 	{
287 		rRect=aDragStat.GetActionRect();
288 		if (rRect.IsEmpty())
289 		{
290 			rRect=Rectangle(aDragStat.GetPrev(),aDragStat.GetNow());
291 		}
292 	}
293 	else
294 	{
295 		SdrDragView::TakeActionRect(rRect);
296 	}
297 }
298 
299 sal_Bool SdrCreateView::CheckEdgeMode()
300 {
301 	sal_uInt32 nInv=nAktInvent;
302 	sal_uInt16 nIdn=nAktIdent;
303 	if (pAktCreate!=NULL)
304 	{
305 		nInv=pAktCreate->GetObjInventor();
306 		nIdn=pAktCreate->GetObjIdentifier();
307 		// wird vom EdgeObj gemanaged
308 		if (nAktInvent==SdrInventor && nAktIdent==OBJ_EDGE) return sal_False;
309 	}
310 
311 	if (!IsCreateMode() || nAktInvent!=SdrInventor || nAktIdent!=OBJ_EDGE)
312 	{
313 		ImpClearConnectMarker();
314 		return sal_False;
315 	}
316 	else
317 	{
318 		// sal_True heisst: MouseMove soll Connect checken
319 		return !IsAction();
320 	}
321 }
322 
323 void SdrCreateView::SetConnectMarker(const SdrObjConnection& rCon, const SdrPageView& /*rPV*/)
324 {
325 	SdrObject* pTargetObject = rCon.pObj;
326 
327 	if(pTargetObject)
328 	{
329 		// if target object changes, throw away overlay object to make room for changes
330 		if(mpCoMaOverlay && pTargetObject != &mpCoMaOverlay->GetTargetObject())
331 		{
332 			ImpClearConnectMarker();
333 		}
334 
335 		if(!mpCoMaOverlay)
336 		{
337 			mpCoMaOverlay = new ImplConnectMarkerOverlay(*this, *pTargetObject);
338 		}
339 	}
340 	else
341 	{
342 		ImpClearConnectMarker();
343 	}
344 }
345 
346 void SdrCreateView::HideConnectMarker()
347 {
348 	ImpClearConnectMarker();
349 }
350 
351 sal_Bool SdrCreateView::MouseMove(const MouseEvent& rMEvt, Window* pWin)
352 {
353 	if(CheckEdgeMode() && pWin)
354 	{
355 		SdrPageView* pPV = GetSdrPageView();
356 
357 		if(pPV)
358 		{
359 			// Defaultete Hit-Toleranz bei IsMarkedHit() mal aendern !!!!
360 			Point aPos(pWin->PixelToLogic(rMEvt.GetPosPixel()));
361 			sal_Bool bMarkHit=PickHandle(aPos)!=NULL || IsMarkedObjHit(aPos);
362 			SdrObjConnection aCon;
363 			if (!bMarkHit) SdrEdgeObj::ImpFindConnector(aPos,*pPV,aCon,NULL,pWin);
364 			SetConnectMarker(aCon,*pPV);
365 		}
366 	}
367 	return SdrDragView::MouseMove(rMEvt,pWin);
368 }
369 
370 sal_Bool SdrCreateView::IsTextTool() const
371 {
372 	return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_TEXT || nAktIdent==OBJ_TEXTEXT || nAktIdent==OBJ_TITLETEXT || nAktIdent==OBJ_OUTLINETEXT);
373 }
374 
375 sal_Bool SdrCreateView::IsEdgeTool() const
376 {
377 	return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_EDGE);
378 }
379 
380 sal_Bool SdrCreateView::IsMeasureTool() const
381 {
382 	return eEditMode==SDREDITMODE_CREATE && nAktInvent==SdrInventor && (nAktIdent==OBJ_MEASURE);
383 }
384 
385 void SdrCreateView::SetCurrentObj(sal_uInt16 nIdent, sal_uInt32 nInvent)
386 {
387 	if (nAktInvent!=nInvent || nAktIdent!=nIdent)
388 	{
389 		nAktInvent=nInvent;
390 		nAktIdent=nIdent;
391 		SdrObject* pObj = SdrObjFactory::MakeNewObject(nInvent,nIdent,NULL,NULL);
392 
393 		if(pObj)
394 		{
395 			// Auf pers. Wunsch von Marco:
396 			// Mauszeiger bei Textwerkzeug immer I-Beam. Fadenkreuz
397 			// mit kleinem I-Beam erst bai MouseButtonDown
398 			if(IsTextTool())
399 			{
400 				// #81944# AW: Here the correct pointer needs to be used
401 				// if the default is set to vertical writing
402 				aAktCreatePointer = POINTER_TEXT;
403 			}
404 			else
405 				aAktCreatePointer = pObj->GetCreatePointer();
406 
407 			SdrObject::Free( pObj );
408 		}
409 		else
410 		{
411 			aAktCreatePointer = Pointer(POINTER_CROSS);
412 		}
413 	}
414 
415 	CheckEdgeMode();
416 	ImpSetGlueVisible3(IsEdgeTool());
417 }
418 
419 sal_Bool SdrCreateView::ImpBegCreateObj(sal_uInt32 nInvent, sal_uInt16 nIdent, const Point& rPnt, OutputDevice* pOut,
420 	short nMinMov, SdrPageView* pPV, const Rectangle& rLogRect, SdrObject* pPreparedFactoryObject)
421 {
422 	sal_Bool bRet=sal_False;
423 	UnmarkAllObj();
424 	BrkAction();
425 
426 	ImpClearConnectMarker();
427 
428 	if (pPV!=NULL)
429 	{
430 		pCreatePV=pPV;
431 	}
432 	else
433 	{
434 		pCreatePV = GetSdrPageView();
435 	}
436 	if (pCreatePV!=NULL)
437 	{ // ansonsten keine Seite angemeldet!
438 		String aLay(aAktLayer);
439 
440 		if(nInvent == SdrInventor && nIdent == OBJ_MEASURE && aMeasureLayer.Len())
441 		{
442 			aLay = aMeasureLayer;
443 		}
444 
445 		SdrLayerID nLayer=pCreatePV->GetPage()->GetLayerAdmin().GetLayerID(aLay,sal_True);
446 		if (nLayer==SDRLAYER_NOTFOUND) nLayer=0;
447 		if (!pCreatePV->GetLockedLayers().IsSet(nLayer) && pCreatePV->GetVisibleLayers().IsSet(nLayer))
448 		{
449 			if(pPreparedFactoryObject)
450 			{
451 				pAktCreate = pPreparedFactoryObject;
452 
453 				if(pCreatePV->GetPage())
454 				{
455 					pAktCreate->SetPage(pCreatePV->GetPage());
456 				}
457 				else if (pMod)
458 				{
459 					pAktCreate->SetModel(pMod);
460 				}
461 			}
462 			else
463 			{
464 				pAktCreate = SdrObjFactory::MakeNewObject(nInvent, nIdent, pCreatePV->GetPage(), pMod);
465 			}
466 
467 			Point aPnt(rPnt);
468 			if (nAktInvent!=SdrInventor || (nAktIdent!=sal_uInt16(OBJ_EDGE) &&
469 											nAktIdent!=sal_uInt16(OBJ_FREELINE) &&
470 											nAktIdent!=sal_uInt16(OBJ_FREEFILL) )) { // Kein Fang fuer Edge und Freihand!
471 				aPnt=GetSnapPos(aPnt,pCreatePV);
472 			}
473 			if (pAktCreate!=NULL)
474 			{
475 				sal_Bool bStartEdit=sal_False; // nach Ende von Create automatisch TextEdit starten
476 				if (pDefaultStyleSheet!=NULL) pAktCreate->NbcSetStyleSheet(pDefaultStyleSheet, sal_False);
477 
478 				// #101618# SW uses a naked SdrObject for frame construction. Normally, such an
479 				// object should not be created. Since it is possible to use it as a helper
480 				// object (e.g. in letting the user define an area with the interactive
481 				// construction) at least no items should be set at that object.
482 				if(nInvent != SdrInventor || nIdent != OBJ_NONE)
483 				{
484 					pAktCreate->SetMergedItemSet(aDefaultAttr);
485 				}
486 
487 				if (HAS_BASE(SdrCaptionObj,pAktCreate))
488 				{
489 					SfxItemSet aSet(pMod->GetItemPool());
490 					aSet.Put(XFillColorItem(String(),Color(COL_WHITE))); // Falls einer auf Solid umschaltet
491 					aSet.Put(XFillStyleItem(XFILL_NONE));
492 
493 					pAktCreate->SetMergedItemSet(aSet);
494 
495 					bStartEdit=sal_True;
496 				}
497 				if (nInvent==SdrInventor && (nIdent==OBJ_TEXT || nIdent==OBJ_TEXTEXT ||
498 					nIdent==OBJ_TITLETEXT || nIdent==OBJ_OUTLINETEXT))
499 				{
500 					// Fuer alle Textrahmen default keinen Hintergrund und keine Umrandung
501 					SfxItemSet aSet(pMod->GetItemPool());
502 					aSet.Put(XFillColorItem(String(),Color(COL_WHITE))); // Falls einer auf Solid umschaltet
503 					aSet.Put(XFillStyleItem(XFILL_NONE));
504 					aSet.Put(XLineColorItem(String(),Color(COL_BLACK))); // Falls einer auf Solid umschaltet
505 					aSet.Put(XLineStyleItem(XLINE_NONE));
506 
507 					pAktCreate->SetMergedItemSet(aSet);
508 
509 					bStartEdit=sal_True;
510 				}
511 				if (!rLogRect.IsEmpty()) pAktCreate->NbcSetLogicRect(rLogRect);
512 
513 				// #90129# make sure drag start point is inside WorkArea
514 				const Rectangle& rWorkArea = ((SdrDragView*)this)->GetWorkArea();
515 
516 				if(!rWorkArea.IsEmpty())
517 				{
518 					if(aPnt.X() < rWorkArea.Left())
519 					{
520 						aPnt.X() = rWorkArea.Left();
521 					}
522 
523 					if(aPnt.X() > rWorkArea.Right())
524 					{
525 						aPnt.X() = rWorkArea.Right();
526 					}
527 
528 					if(aPnt.Y() < rWorkArea.Top())
529 					{
530 						aPnt.Y() = rWorkArea.Top();
531 					}
532 
533 					if(aPnt.Y() > rWorkArea.Bottom())
534 					{
535 						aPnt.Y() = rWorkArea.Bottom();
536 					}
537 				}
538 
539 				aDragStat.Reset(aPnt);
540 				aDragStat.SetView((SdrView*)this);
541 				aDragStat.SetPageView(pCreatePV);
542 				aDragStat.SetMinMove(ImpGetMinMovLogic(nMinMov,pOut));
543 				pDragWin=pOut;
544 				if (pAktCreate->BegCreate(aDragStat))
545 				{
546 					ShowCreateObj(/*pOut,sal_True*/);
547 					bRet=sal_True;
548 				}
549 				else
550 				{
551 					SdrObject::Free( pAktCreate );
552 					pAktCreate=NULL;
553 					pCreatePV=NULL;
554 				}
555 			}
556 		}
557 	}
558 	return bRet;
559 }
560 
561 sal_Bool SdrCreateView::BegCreateObj(const Point& rPnt, OutputDevice* pOut, short nMinMov, SdrPageView* pPV)
562 {
563 	return ImpBegCreateObj(nAktInvent,nAktIdent,rPnt,pOut,nMinMov,pPV,Rectangle(), 0L);
564 }
565 
566 sal_Bool SdrCreateView::BegCreatePreparedObject(const Point& rPnt, sal_Int16 nMinMov, SdrObject* pPreparedFactoryObject)
567 {
568 	sal_uInt32 nInvent(nAktInvent);
569 	sal_uInt16 nIdent(nAktIdent);
570 
571 	if(pPreparedFactoryObject)
572 	{
573 		nInvent = pPreparedFactoryObject->GetObjInventor();
574 		nIdent = pPreparedFactoryObject->GetObjIdentifier();
575 	}
576 
577 	return ImpBegCreateObj(nInvent, nIdent, rPnt, 0L, nMinMov, 0L, Rectangle(), pPreparedFactoryObject);
578 }
579 
580 sal_Bool SdrCreateView::BegCreateCaptionObj(const Point& rPnt, const Size& rObjSiz,
581 	OutputDevice* pOut, short nMinMov, SdrPageView* pPV)
582 {
583 	return ImpBegCreateObj(SdrInventor,OBJ_CAPTION,rPnt,pOut,nMinMov,pPV,
584 		Rectangle(rPnt,Size(rObjSiz.Width()+1,rObjSiz.Height()+1)), 0L);
585 }
586 
587 void SdrCreateView::MovCreateObj(const Point& rPnt)
588 {
589 	if (pAktCreate!=NULL) {
590 		Point aPnt(rPnt);
591 		if (!aDragStat.IsNoSnap())
592 		{
593 			aPnt=GetSnapPos(aPnt,pCreatePV);
594 		}
595 		if (IsOrtho())
596 		{
597 			if (aDragStat.IsOrtho8Possible()) OrthoDistance8(aDragStat.GetPrev(),aPnt,IsBigOrtho());
598 			else if (aDragStat.IsOrtho4Possible()) OrthoDistance4(aDragStat.GetPrev(),aPnt,IsBigOrtho());
599 		}
600 
601 		// #77734# If the drag point was limited and Ortho is active, do
602 		// the small ortho correction (reduction) -> last parameter to FALSE.
603 		sal_Bool bDidLimit(ImpLimitToWorkArea(aPnt));
604 		if(bDidLimit && IsOrtho())
605 		{
606 			if(aDragStat.IsOrtho8Possible())
607 				OrthoDistance8(aDragStat.GetPrev(), aPnt, sal_False);
608 			else if(aDragStat.IsOrtho4Possible())
609 				OrthoDistance4(aDragStat.GetPrev(), aPnt, sal_False);
610 		}
611 
612 		if (aPnt==aDragStat.GetNow()) return;
613 		bool bMerk(aDragStat.IsMinMoved());
614 		if (aDragStat.CheckMinMoved(aPnt))
615 		{
616 			Rectangle aBound;
617 			if (!bMerk) aDragStat.NextPoint();
618 			aDragStat.NextMove(aPnt);
619 			pAktCreate->MovCreate(aDragStat);
620 
621 			// MovCreate changes the object, so use ActionChanged() on it
622 			pAktCreate->ActionChanged();
623 
624 			// replace for DrawCreateObjDiff
625 			HideCreateObj();
626 			ShowCreateObj();
627 		}
628 	}
629 }
630 
631 sal_Bool SdrCreateView::EndCreateObj(SdrCreateCmd eCmd)
632 {
633 	sal_Bool bRet=sal_False;
634 	SdrObject* pObjMerk=pAktCreate;
635 	SdrPageView* pPVMerk=pCreatePV;
636 
637 	if (pAktCreate!=NULL)
638 	{
639 		sal_uIntPtr nAnz=aDragStat.GetPointAnz();
640 
641 		if (nAnz<=1 && eCmd==SDRCREATE_FORCEEND)
642 		{
643 			BrkCreateObj(); // Objekte mit nur einem Punkt gibt's nicht (zumindest noch nicht)
644 			return sal_False; // sal_False=Event nicht ausgewertet
645 		}
646 
647 		sal_Bool bPntsEq=nAnz>1;
648 		sal_uIntPtr i=1;
649 		Point aP0=aDragStat.GetPoint(0);
650 		while (bPntsEq && i<nAnz) { bPntsEq=aP0==aDragStat.GetPoint(i); i++; }
651 
652 		if (pAktCreate->EndCreate(aDragStat,eCmd))
653 		{
654 			HideCreateObj();
655 
656 			if (!bPntsEq)
657 			{
658 				// sonst Brk, weil alle Punkte gleich sind.
659 				SdrObject* pObj=pAktCreate;
660 				pAktCreate=NULL;
661 
662 				const SdrLayerAdmin& rAd = pCreatePV->GetPage()->GetLayerAdmin();
663 				SdrLayerID nLayer(0);
664 
665 				// #i72535#
666 				if(pObj->ISA(FmFormObj))
667 				{
668 					// for FormControls, force to form layer
669 					nLayer = rAd.GetLayerID(rAd.GetControlLayerName(), true);
670 				}
671 				else
672 				{
673 					nLayer = rAd.GetLayerID(aAktLayer, sal_True);
674 				}
675 
676 				if(SDRLAYER_NOTFOUND == nLayer)
677 				{
678 					nLayer=0;
679 				}
680 
681 				pObj->SetLayer(nLayer);
682 
683 				// #83403# recognize creation of a new 3D object inside a 3D scene
684 				sal_Bool bSceneIntoScene(sal_False);
685 
686 				if(pObjMerk
687 					&& pObjMerk->ISA(E3dScene)
688 					&& pCreatePV
689 					&& pCreatePV->GetAktGroup()
690 					&& pCreatePV->GetAktGroup()->ISA(E3dScene))
691 				{
692 					sal_Bool bDidInsert = ((E3dView*)this)->ImpCloneAll3DObjectsToDestScene(
693 						(E3dScene*)pObjMerk, (E3dScene*)pCreatePV->GetAktGroup(), Point(0, 0));
694 
695 					if(bDidInsert)
696 					{
697 						// delete object, it's content is cloned and inserted
698                         SdrObject::Free( pObjMerk );
699 						pObjMerk = 0L;
700 						bRet = sal_False;
701 						bSceneIntoScene = sal_True;
702 					}
703 				}
704 
705 				if(!bSceneIntoScene)
706 				{
707 					// do the same as before
708 					InsertObjectAtView(pObj, *pCreatePV);
709 				}
710 
711 				pCreatePV=NULL;
712 				bRet=sal_True; // sal_True=Event ausgewertet
713 			}
714 			else
715 			{
716 				BrkCreateObj();
717 			}
718 		}
719 		else
720 		{ // Mehr Punkte
721 			if (eCmd==SDRCREATE_FORCEEND || // nix da, Ende erzwungen
722 				nAnz==0 ||                             // keine Punkte da (kann eigentlich nicht vorkommen)
723 				(nAnz<=1 && !aDragStat.IsMinMoved())) { // MinMove nicht erfuellt
724 				BrkCreateObj();
725 			}
726 			else
727 			{
728 				// replace for DrawCreateObjDiff
729 				HideCreateObj();
730 				ShowCreateObj();
731 				aDragStat.ResetMinMoved(); // NextPoint gibt's bei MovCreateObj()
732 				bRet=sal_True;
733 			}
734 		}
735 		if (bRet && pObjMerk!=NULL && IsTextEditAfterCreate())
736 		{
737 			SdrTextObj* pText=PTR_CAST(SdrTextObj,pObjMerk);
738 			if (pText!=NULL && pText->IsTextFrame())
739 			{
740 				SdrBeginTextEdit(pText, pPVMerk, (Window*)0L, sal_True, (SdrOutliner*)0L, (OutlinerView*)0L);
741 			}
742 		}
743 	}
744 	return bRet;
745 }
746 
747 void SdrCreateView::BckCreateObj()
748 {
749 	if (pAktCreate!=NULL)
750 	{
751 		if (aDragStat.GetPointAnz()<=2 )
752 		{
753 			BrkCreateObj();
754 		}
755 		else
756 		{
757 			HideCreateObj();
758 			aDragStat.PrevPoint();
759 			if (pAktCreate->BckCreate(aDragStat))
760 			{
761 				ShowCreateObj();
762 			}
763 			else
764 			{
765 				BrkCreateObj();
766 			}
767 		}
768 	}
769 }
770 
771 void SdrCreateView::BrkCreateObj()
772 {
773 	if (pAktCreate!=NULL)
774 	{
775 		HideCreateObj();
776 		pAktCreate->BrkCreate(aDragStat);
777 		SdrObject::Free( pAktCreate );
778 		pAktCreate=NULL;
779 		pCreatePV=NULL;
780 	}
781 }
782 
783 void SdrCreateView::ShowCreateObj(/*OutputDevice* pOut, sal_Bool bFull*/)
784 {
785 	if(IsCreateObj() && !aDragStat.IsShown())
786 	{
787 		if(pAktCreate)
788 		{
789 			// for migration from XOR, replace DrawDragObj here to create
790 			// overlay objects instead.
791 			sal_Bool bUseSolidDragging(IsSolidDragging());
792 
793 			// #i101648# check if dragged object is a naked SdrObject (no
794 			// derivation of). This is e.g. used in SW Frame construction
795 			// as placeholder. Do not use SolidDragging for naked SDrObjects,
796 			// they cannot have a valid optical representation
797 			if(bUseSolidDragging && OBJ_NONE == pAktCreate->GetObjIdentifier())
798 			{
799 				bUseSolidDragging = false;
800 			}
801 
802 			// check for objects with no fill and no line
803 			if(bUseSolidDragging)
804 			{
805 				const SfxItemSet& rSet = pAktCreate->GetMergedItemSet();
806 				const XFillStyle eFill(((XFillStyleItem&)(rSet.Get(XATTR_FILLSTYLE))).GetValue());
807 				const XLineStyle eLine(((XLineStyleItem&)(rSet.Get(XATTR_LINESTYLE))).GetValue());
808 
809 				if(XLINE_NONE == eLine && XFILL_NONE == eFill)
810 				{
811 					bUseSolidDragging = sal_False;
812 				}
813 			}
814 
815 			// check for form controls
816 			if(bUseSolidDragging)
817 			{
818 				if(pAktCreate->ISA(SdrUnoObj))
819 				{
820 					bUseSolidDragging = sal_False;
821 				}
822 			}
823 
824   			// #i101781# force to non-solid dragging when not creating a full circle
825 			if(bUseSolidDragging)
826             {
827                 SdrCircObj* pCircObj = dynamic_cast< SdrCircObj* >(pAktCreate);
828 
829                 if(pCircObj && OBJ_CIRC != pCircObj->GetObjIdentifier())
830                 {
831                     // #i103058# Allow SolidDragging with four points
832                     if(aDragStat.GetPointAnz() < 4)
833                     {
834         				bUseSolidDragging = false;
835                     }
836                 }
837             }
838 
839 			if(bUseSolidDragging)
840 			{
841 				basegfx::B2DPolyPolygon aDragPolyPolygon;
842 
843 				if(pAktCreate->ISA(SdrRectObj))
844 				{
845 					// ensure object has some size, necessary for SdrTextObj because
846 					// there are still untested divisions by that sizes
847 					Rectangle aCurrentSnapRect(pAktCreate->GetSnapRect());
848 
849 					if(!(aCurrentSnapRect.GetWidth() > 1 && aCurrentSnapRect.GetHeight() > 1))
850 					{
851 						Rectangle aNewRect(aDragStat.GetStart(), aDragStat.GetStart() + Point(2, 2));
852 						pAktCreate->NbcSetSnapRect(aNewRect);
853 					}
854 				}
855 
856 				if(pAktCreate->ISA(SdrPathObj))
857 				{
858 					// The up-to-now created path needs to be set at the object to have something
859 					// that can be visualized
860 					SdrPathObj& rPathObj((SdrPathObj&)(*pAktCreate));
861 					const basegfx::B2DPolyPolygon aCurrentPolyPolygon(rPathObj.getObjectPolyPolygon(aDragStat));
862 
863 					if(aCurrentPolyPolygon.count())
864 					{
865 						rPathObj.NbcSetPathPoly(aCurrentPolyPolygon);
866 					}
867 
868 					aDragPolyPolygon = rPathObj.getDragPolyPolygon(aDragStat);
869 				}
870 
871 				// use directly the SdrObject for overlay
872 				mpCreateViewExtraData->CreateAndShowOverlay(*this, pAktCreate, aDragPolyPolygon);
873 			}
874 			else
875 			{
876 				mpCreateViewExtraData->CreateAndShowOverlay(*this, 0, pAktCreate->TakeCreatePoly(aDragStat));
877 			}
878 
879 			// #i101679# Force changed overlay to be shown
880 			for(sal_uInt32 a(0); a < PaintWindowCount(); a++)
881 			{
882 				SdrPaintWindow* pCandidate = GetPaintWindow(a);
883 				sdr::overlay::OverlayManager* pOverlayManager = pCandidate->GetOverlayManager();
884 
885 				if(pOverlayManager)
886 				{
887 					pOverlayManager->flush();
888 				}
889 			}
890 		}
891 
892 		aDragStat.SetShown(sal_True);
893 	}
894 }
895 
896 void SdrCreateView::HideCreateObj()
897 {
898 	if(IsCreateObj() && aDragStat.IsShown())
899 	{
900 		// for migration from XOR, replace DrawDragObj here to create
901 		// overlay objects instead.
902 		mpCreateViewExtraData->HideOverlay();
903 
904 		//DrawCreateObj(pOut,bFull);
905 		aDragStat.SetShown(sal_False);
906 	}
907 }
908 
909 ////////////////////////////////////////////////////////////////////////////////////////////////////
910 
911 /* new interface src537 */
912 sal_Bool SdrCreateView::GetAttributes(SfxItemSet& rTargetSet, sal_Bool bOnlyHardAttr) const
913 {
914 	if(pAktCreate)
915 	{
916 		rTargetSet.Put(pAktCreate->GetMergedItemSet());
917 		return sal_True;
918 	}
919 	else
920 	{
921 		return SdrDragView::GetAttributes(rTargetSet, bOnlyHardAttr);
922 	}
923 }
924 
925 sal_Bool SdrCreateView::SetAttributes(const SfxItemSet& rSet, sal_Bool bReplaceAll)
926 {
927 	if(pAktCreate)
928 	{
929 		pAktCreate->SetMergedItemSetAndBroadcast(rSet, bReplaceAll);
930 
931 		return sal_True;
932 	}
933 	else
934 	{
935 		return SdrDragView::SetAttributes(rSet,bReplaceAll);
936 	}
937 }
938 
939 SfxStyleSheet* SdrCreateView::GetStyleSheet() const // SfxStyleSheet* SdrCreateView::GetStyleSheet(sal_Bool& rOk) const
940 {
941 	if (pAktCreate!=NULL)
942 	{
943 		//rOk=sal_True;
944 		return pAktCreate->GetStyleSheet();
945 	}
946 	else
947 	{
948 		return SdrDragView::GetStyleSheet(); // SdrDragView::GetStyleSheet(rOk);
949 	}
950 }
951 
952 sal_Bool SdrCreateView::SetStyleSheet(SfxStyleSheet* pStyleSheet, sal_Bool bDontRemoveHardAttr)
953 {
954 	if (pAktCreate!=NULL)
955 	{
956 		pAktCreate->SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
957 		return sal_True;
958 	}
959 	else
960 	{
961 		return SdrDragView::SetStyleSheet(pStyleSheet,bDontRemoveHardAttr);
962 	}
963 }
964 
965