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