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