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