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