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