xref: /trunk/main/svx/source/svdraw/svdsnpv.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_svx.hxx"
30 
31 #include <svx/svdsnpv.hxx>
32 #include <math.h>
33 
34 #include <svx/svdetc.hxx>
35 #include <svx/svdobj.hxx>
36 #include <svx/svdpagv.hxx>
37 #include <svx/svdpage.hxx>
38 #include "svx/svditer.hxx"
39 #include <svx/sdr/overlay/overlayobjectlist.hxx>
40 #include <svx/sdr/overlay/overlaycrosshair.hxx>
41 #include <svx/sdr/overlay/overlayhelpline.hxx>
42 #include <svx/sdr/overlay/overlaymanager.hxx>
43 #include <basegfx/matrix/b2dhommatrix.hxx>
44 #include <svx/sdrpaintwindow.hxx>
45 
46 ////////////////////////////////////////////////////////////////////////////////////////////////////
47 // #114409#-1 Migrate PageOrigin
48 class ImplPageOriginOverlay
49 {
50     // The OverlayObjects
51     ::sdr::overlay::OverlayObjectList               maObjects;
52 
53     // The current position in logical coodinates
54     basegfx::B2DPoint                               maPosition;
55 
56 public:
57     ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos);
58     ~ImplPageOriginOverlay();
59 
60     void SetPosition(const basegfx::B2DPoint& rNewPosition);
61 };
62 
63 ImplPageOriginOverlay::ImplPageOriginOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos)
64 :   maPosition(rStartPos)
65 {
66     for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
67     {
68         SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
69         ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
70 
71         if(pTargetOverlay)
72         {
73             ::sdr::overlay::OverlayCrosshairStriped* aNew = new ::sdr::overlay::OverlayCrosshairStriped(
74                 maPosition);
75             pTargetOverlay->add(*aNew);
76             maObjects.append(*aNew);
77         }
78     }
79 }
80 
81 ImplPageOriginOverlay::~ImplPageOriginOverlay()
82 {
83     // The OverlayObjects are cleared using the destructor of OverlayObjectList.
84     // That destructor calls clear() at the list which removes all objects from the
85     // OverlayManager and deletes them.
86 }
87 
88 void ImplPageOriginOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
89 {
90     if(rNewPosition != maPosition)
91     {
92         // apply to OverlayObjects
93         for(sal_uInt32 a(0); a < maObjects.count(); a++)
94         {
95             sdr::overlay::OverlayCrosshairStriped* pCandidate =
96                 static_cast< sdr::overlay::OverlayCrosshairStriped* >(&maObjects.getOverlayObject(a));
97 
98             if(pCandidate)
99             {
100                 pCandidate->setBasePosition(rNewPosition);
101             }
102         }
103 
104         // remember new position
105         maPosition = rNewPosition;
106     }
107 }
108 
109 ////////////////////////////////////////////////////////////////////////////////////////////////////
110 // #114409#-2 Migrate HelpLine
111 class ImplHelpLineOverlay
112 {
113     // The OverlayObjects
114     ::sdr::overlay::OverlayObjectList               maObjects;
115 
116     // The current position in logical coodinates
117     basegfx::B2DPoint                               maPosition;
118 
119     // HelpLine specific stuff
120     SdrPageView*                                    mpPageView;
121     sal_uInt16                                      mnHelpLineNumber;
122     SdrHelpLineKind                                 meHelpLineKind;
123 
124 public:
125     ImplHelpLineOverlay(const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
126         SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind);
127     ~ImplHelpLineOverlay();
128 
129     void SetPosition(const basegfx::B2DPoint& rNewPosition);
130 
131     // access to HelpLine specific stuff
132     SdrPageView* GetPageView() const { return mpPageView; }
133     sal_uInt16 GetHelpLineNumber() const { return mnHelpLineNumber; }
134     SdrHelpLineKind GetHelpLineKind() const { return meHelpLineKind; }
135 };
136 
137 ImplHelpLineOverlay::ImplHelpLineOverlay(
138     const SdrPaintView& rView, const basegfx::B2DPoint& rStartPos,
139     SdrPageView* pPageView, sal_uInt16 nHelpLineNumber, SdrHelpLineKind eKind)
140 :   maPosition(rStartPos),
141     mpPageView(pPageView),
142     mnHelpLineNumber(nHelpLineNumber),
143     meHelpLineKind(eKind)
144 {
145     for(sal_uInt32 a(0L); a < rView.PaintWindowCount(); a++)
146     {
147         SdrPaintWindow* pCandidate = rView.GetPaintWindow(a);
148         ::sdr::overlay::OverlayManager* pTargetOverlay = pCandidate->GetOverlayManager();
149 
150         if(pTargetOverlay)
151         {
152             ::sdr::overlay::OverlayHelplineStriped* aNew = new ::sdr::overlay::OverlayHelplineStriped(
153                 maPosition, meHelpLineKind);
154             pTargetOverlay->add(*aNew);
155             maObjects.append(*aNew);
156         }
157     }
158 }
159 
160 ImplHelpLineOverlay::~ImplHelpLineOverlay()
161 {
162     // The OverlayObjects are cleared using the destructor of OverlayObjectList.
163     // That destructor calls clear() at the list which removes all objects from the
164     // OverlayManager and deletes them.
165 }
166 
167 void ImplHelpLineOverlay::SetPosition(const basegfx::B2DPoint& rNewPosition)
168 {
169     if(rNewPosition != maPosition)
170     {
171         // apply to OverlayObjects
172         // apply to OverlayObjects
173         for(sal_uInt32 a(0); a < maObjects.count(); a++)
174         {
175             sdr::overlay::OverlayHelplineStriped* pCandidate =
176                 static_cast< sdr::overlay::OverlayHelplineStriped* >(&maObjects.getOverlayObject(a));
177 
178             if(pCandidate)
179             {
180                 pCandidate->setBasePosition(rNewPosition);
181             }
182         }
183 
184         // remember new position
185         maPosition = rNewPosition;
186     }
187 }
188 
189 ////////////////////////////////////////////////////////////////////////////////////////////////////
190 ////////////////////////////////////////////////////////////////////////////////////////////////////
191 //
192 //  @@@@  @@  @@  @@@@  @@@@@   @@ @@ @@ @@@@@ @@   @@
193 // @@  @@ @@@ @@ @@  @@ @@  @@  @@ @@ @@ @@    @@   @@
194 // @@     @@@@@@ @@  @@ @@  @@  @@ @@ @@ @@    @@ @ @@
195 //  @@@@  @@@@@@ @@@@@@ @@@@@   @@@@@ @@ @@@@  @@@@@@@
196 //     @@ @@ @@@ @@  @@ @@       @@@  @@ @@    @@@@@@@
197 // @@  @@ @@  @@ @@  @@ @@       @@@  @@ @@    @@@ @@@
198 //  @@@@  @@  @@ @@  @@ @@        @   @@ @@@@@ @@   @@
199 //
200 ////////////////////////////////////////////////////////////////////////////////////////////////////
201 ////////////////////////////////////////////////////////////////////////////////////////////////////
202 
203 void SdrSnapView::ClearVars()
204 {
205     nMagnSizPix=4;
206     bSnapEnab=sal_True;
207     bGridSnap=sal_True;
208     bSnapTo1Pix=sal_True;
209     bBordSnap=sal_True;
210     bHlplSnap=sal_True;
211     bOFrmSnap=sal_True;
212     bOPntSnap=sal_False;
213     bOConSnap=sal_True;
214     bMoveMFrmSnap=sal_True;
215     bMoveOFrmSnap=sal_True;
216     bMoveOPntSnap=sal_True;
217     bMoveOConSnap=sal_True;
218     bMoveSnapOnlyTopLeft=sal_False;
219     bOrtho=sal_False;
220     bBigOrtho=sal_True;
221     nSnapAngle=1500;
222     bAngleSnapEnab=sal_False;
223     bMoveOnlyDragging=sal_False;
224     bSlantButShear=sal_False;
225     bCrookNoContortion=sal_False;
226     eCrookMode=SDRCROOK_ROTATE;
227     bHlplFixed=sal_False;
228     bEliminatePolyPoints=sal_False;
229     nEliminatePolyPointLimitAngle=0;
230 
231     // #114409#-1 Migrate PageOrigin
232     BrkSetPageOrg();
233 
234     // #114409#-2 Migrate HelpLine
235     BrkDragHelpLine();
236 }
237 
238 SdrSnapView::SdrSnapView(SdrModel* pModel1, OutputDevice* pOut):
239     SdrPaintView(pModel1,pOut),
240     // #114409#-1 Migrate PageOrigin
241     mpPageOriginOverlay(0L),
242     // #114409#-2 Migrate HelpLine
243     mpHelpLineOverlay(0L)
244 {
245     ClearVars();
246 }
247 
248 // #114409#-1 Migrate PageOrigin
249 SdrSnapView::~SdrSnapView()
250 {
251     // #114409#-1 Migrate PageOrigin
252     BrkSetPageOrg();
253 
254     // #114409#-2 Migrate HelpLine
255     BrkDragHelpLine();
256 }
257 
258 ////////////////////////////////////////////////////////////////////////////////////////////////////
259 
260 sal_Bool SdrSnapView::IsAction() const
261 {
262     return IsSetPageOrg() || IsDragHelpLine() || SdrPaintView::IsAction();
263 }
264 
265 void SdrSnapView::MovAction(const Point& rPnt)
266 {
267     SdrPaintView::MovAction(rPnt);
268     if (IsSetPageOrg()) {
269         MovSetPageOrg(rPnt);
270     }
271     if (IsDragHelpLine()) {
272         MovDragHelpLine(rPnt);
273     }
274 }
275 
276 void SdrSnapView::EndAction()
277 {
278     if (IsSetPageOrg()) {
279         EndSetPageOrg();
280     }
281     if (IsDragHelpLine()) {
282         EndDragHelpLine();
283     }
284     SdrPaintView::EndAction();
285 }
286 
287 void SdrSnapView::BckAction()
288 {
289     BrkSetPageOrg();
290     BrkDragHelpLine();
291     SdrPaintView::BckAction();
292 }
293 
294 void SdrSnapView::BrkAction()
295 {
296     BrkSetPageOrg();
297     BrkDragHelpLine();
298     SdrPaintView::BrkAction();
299 }
300 
301 void SdrSnapView::TakeActionRect(Rectangle& rRect) const
302 {
303     if (IsSetPageOrg() || IsDragHelpLine()) {
304         rRect=Rectangle(aDragStat.GetNow(),aDragStat.GetNow());
305     } else {
306         SdrPaintView::TakeActionRect(rRect);
307     }
308 }
309 
310 ////////////////////////////////////////////////////////////////////////////////////////////////////
311 
312 Point SdrSnapView::GetSnapPos(const Point& rPnt, const SdrPageView* pPV) const
313 {
314     Point aPt(rPnt);
315     SnapPos(aPt,pPV);
316     return aPt;
317 }
318 
319 #define NOT_SNAPPED 0x7FFFFFFF
320 sal_uInt16 SdrSnapView::SnapPos(Point& rPnt, const SdrPageView* pPV) const
321 {
322     if (!bSnapEnab) return SDRSNAP_NOTSNAPPED;
323     sal_Bool bPVOfs=sal_False;
324     long x=rPnt.X();
325     long y=rPnt.Y();
326     if (pPV==NULL) {
327         bPVOfs=sal_True;
328         pPV=GetSdrPageView();
329         if (pPV==NULL) return SDRSNAP_NOTSNAPPED;
330     }
331 
332     long dx=NOT_SNAPPED;
333     long dy=NOT_SNAPPED;
334     long dx1,dy1;
335     long mx=aMagnSiz.Width();
336     long my=aMagnSiz.Height();
337     if (bHlplVisible && bHlplSnap && !IsDragHelpLine())
338     {
339         const SdrHelpLineList& rHLL=pPV->GetHelpLines();
340         sal_uInt16 nAnz=rHLL.GetCount();
341         for (sal_uInt16 i=nAnz; i>0;) {
342             i--;
343             const SdrHelpLine& rHL=rHLL[i];
344             const Point& rPos=rHL.GetPos();
345             switch (rHL.GetKind()) {
346                 case SDRHELPLINE_VERTICAL: {
347                     long a=x-rPos.X();
348                     if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; }
349                 } break;
350                 case SDRHELPLINE_HORIZONTAL: {
351                     long b=y-rPos.Y();
352                     if (Abs(b)<=my) { dy1=-b; if (Abs(dy1)<Abs(dy)) dy=dy1; }
353                 } break;
354                 case SDRHELPLINE_POINT: {
355                     long a=x-rPos.X();
356                     long b=y-rPos.Y();
357                     if (Abs(a)<=mx && Abs(b)<=my) {
358                         dx1=-a; dy1=-b;
359                         if (Abs(dx1)<Abs(dx) && Abs(dy1)<Abs(dy)) { dx=dx1; dy=dy1; }
360                     }
361                 } break;
362             } // switch
363         }
364     }
365     if (bBordVisible && bBordSnap) {
366         SdrPage* pPage=pPV->GetPage();
367         long xs=pPage->GetWdt();
368         long ys=pPage->GetHgt();
369         long lft=pPage->GetLftBorder();
370         long rgt=pPage->GetRgtBorder();
371         long upp=pPage->GetUppBorder();
372         long lwr=pPage->GetLwrBorder();
373         long a;
374         a=x- lft    ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // linker Rand
375         a=x-(xs-rgt); if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // rechter Rand
376         a=x         ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // linke Papierkante
377         a=x- xs     ; if (Abs(a)<=mx) { dx1=-a; if (Abs(dx1)<Abs(dx)) dx=dx1; } // rechte Papierkante
378         a=y- upp    ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // linker Rand
379         a=y-(ys-lwr); if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // rechter Rand
380         a=y         ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // linke Papierkante
381         a=y- ys     ; if (Abs(a)<=my) { dy1=-a; if (Abs(dy1)<Abs(dy)) dy=dy1; } // rechte Papierkante
382     }
383     if (bOFrmSnap || bOPntSnap /*|| (bConnVisible && bOConSnap)*/) {
384         sal_uIntPtr nMaxPointSnapCount=200;
385         sal_uIntPtr nMaxFrameSnapCount=200;
386 
387         // #97981# go back to IM_DEEPNOGROUPS runthrough for snap to object comparisons
388         SdrObjListIter aIter(*pPV->GetPage(),/*IM_FLAT*/IM_DEEPNOGROUPS,sal_True);
389 
390         while (aIter.IsMore() && (nMaxPointSnapCount>0 || nMaxFrameSnapCount>0)) {
391             SdrObject* pO=aIter.Next();
392             Rectangle aRect(pO->GetCurrentBoundRect());
393             aRect.Left  ()-=mx;
394             aRect.Right ()+=mx;
395             aRect.Top   ()-=my;
396             aRect.Bottom()+=my;
397             if (aRect.IsInside(rPnt)) {
398                 if (bOPntSnap && nMaxPointSnapCount>0)
399                 {
400                     sal_uInt32 nAnz(pO->GetSnapPointCount());
401                     for (sal_uInt32 i(0L); i < nAnz && nMaxPointSnapCount > 0L; i++)
402                     {
403                         Point aP(pO->GetSnapPoint(i));
404                         dx1=x-aP.X();
405                         dy1=y-aP.Y();
406                         if (Abs(dx1)<=mx && Abs(dy1)<=my && Abs(dx1)<Abs(dx) && Abs(dy1)<Abs(dy)) {
407                             dx=-dx1;
408                             dy=-dy1;
409                         }
410                         nMaxPointSnapCount--;
411                     }
412                 }
413                 if (bOFrmSnap && nMaxFrameSnapCount>0) {
414                     Rectangle aLog(pO->GetSnapRect());
415                     Rectangle aR1(aLog);
416                     aR1.Left  ()-=mx;
417                     aR1.Right ()+=mx;
418                     aR1.Top   ()-=my;
419                     aR1.Bottom()+=my;
420                     if (aR1.IsInside(rPnt)) {
421                         if (Abs(x-aLog.Left  ())<=mx) { dx1=-(x-aLog.Left  ()); if (Abs(dx1)<Abs(dx)) dx=dx1; }
422                         if (Abs(x-aLog.Right ())<=mx) { dx1=-(x-aLog.Right ()); if (Abs(dx1)<Abs(dx)) dx=dx1; }
423                         if (Abs(y-aLog.Top   ())<=my) { dy1=-(y-aLog.Top   ()); if (Abs(dy1)<Abs(dy)) dy=dy1; }
424                         if (Abs(y-aLog.Bottom())<=my) { dy1=-(y-aLog.Bottom()); if (Abs(dy1)<Abs(dy)) dy=dy1; }
425                     }
426                     nMaxFrameSnapCount--;
427                 }
428             }
429         }
430     }
431     if(bGridSnap)
432     {
433         double fSnapWidth = aSnapWdtX;
434         if(dx == NOT_SNAPPED && fSnapWidth != 0.0)
435         {
436             double fx = (double)x;
437 
438             // round statt trunc
439             if(fx - (double)pPV->GetPageOrigin().X() >= 0.0)
440                 fx += fSnapWidth / 2.0;
441             else
442                 fx -= fSnapWidth / 2.0;
443 
444             x = (long)((fx - (double)pPV->GetPageOrigin().X()) / fSnapWidth);
445             x = (long)((double)x * fSnapWidth + (double)pPV->GetPageOrigin().X());
446             dx = 0;
447         }
448         fSnapWidth = aSnapWdtY;
449         if(dy == NOT_SNAPPED && fSnapWidth)
450         {
451             double fy = (double)y;
452 
453             // round statt trunc
454             if(fy - (double)pPV->GetPageOrigin().Y() >= 0.0)
455                 fy += fSnapWidth / 2.0;
456             else
457                 fy -= fSnapWidth / 2.0;
458 
459             y = (long)((fy - (double)pPV->GetPageOrigin().Y()) / fSnapWidth);
460             y = (long)((double)y * fSnapWidth + (double)pPV->GetPageOrigin().Y());
461             dy = 0;
462         }
463     }
464     sal_Bool bRet=SDRSNAP_NOTSNAPPED;
465     if (dx==NOT_SNAPPED) dx=0; else bRet|=SDRSNAP_XSNAPPED;
466     if (dy==NOT_SNAPPED) dy=0; else bRet|=SDRSNAP_YSNAPPED;
467     rPnt.X()=x+dx;
468     rPnt.Y()=y+dy;
469     return bRet;
470 }
471 
472 void SdrSnapView::CheckSnap(const Point& rPt, const SdrPageView* pPV, long& nBestXSnap, long& nBestYSnap, bool& bXSnapped, bool& bYSnapped) const
473 {
474     Point aPt(rPt);
475     sal_uInt16 nRet=SnapPos(aPt,pPV);
476     aPt-=rPt;
477     if ((nRet & SDRSNAP_XSNAPPED) !=0) {
478         if (bXSnapped) {
479             if (Abs(aPt.X())<Abs(nBestXSnap)) {
480                 nBestXSnap=aPt.X();
481             }
482         } else {
483             nBestXSnap=aPt.X();
484             bXSnapped=sal_True;
485         }
486     }
487     if ((nRet & SDRSNAP_YSNAPPED) !=0) {
488         if (bYSnapped) {
489             if (Abs(aPt.Y())<Abs(nBestYSnap)) {
490                 nBestYSnap=aPt.Y();
491             }
492         } else {
493             nBestYSnap=aPt.Y();
494             bYSnapped=sal_True;
495         }
496     }
497 }
498 
499 sal_uInt16 SdrSnapView::SnapRect(const Rectangle& rRect, const SdrPageView* pPV, long& rDX, long& rDY) const
500 {
501     long nBestXSnap=0;
502     long nBestYSnap=0;
503     bool bXSnapped=sal_False;
504     bool bYSnapped=sal_False;
505     CheckSnap(rRect.TopLeft()    ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
506     if (!bMoveSnapOnlyTopLeft) {
507         CheckSnap(rRect.TopRight()   ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
508         CheckSnap(rRect.BottomLeft() ,pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
509         CheckSnap(rRect.BottomRight(),pPV,nBestXSnap,nBestYSnap,bXSnapped,bYSnapped);
510     }
511     rDX=nBestXSnap;
512     rDY=nBestYSnap;
513     sal_uInt16 nRet=0;
514     if (bXSnapped) nRet+=SDRSNAP_XSNAPPED;
515     if (bYSnapped) nRet+=SDRSNAP_YSNAPPED;
516     return nRet;
517 }
518 
519 ////////////////////////////////////////////////////////////////////////////////////////////////////
520 
521 sal_Bool SdrSnapView::BegSetPageOrg(const Point& rPnt)
522 {
523     BrkAction();
524 
525     DBG_ASSERT(0L == mpPageOriginOverlay, "SdrSnapView::BegSetPageOrg: There exists a ImplPageOriginOverlay (!)");
526     basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
527     mpPageOriginOverlay = new ImplPageOriginOverlay(*this, aStartPos);
528     aDragStat.Reset(GetSnapPos(rPnt,NULL));
529 
530     return sal_True;
531 }
532 
533 void SdrSnapView::MovSetPageOrg(const Point& rPnt)
534 {
535     if(IsSetPageOrg())
536     {
537         aDragStat.NextMove(GetSnapPos(rPnt,NULL));
538         DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
539         basegfx::B2DPoint aNewPos(aDragStat.GetNow().X(), aDragStat.GetNow().Y());
540         mpPageOriginOverlay->SetPosition(aNewPos);
541     }
542 }
543 
544 sal_Bool SdrSnapView::EndSetPageOrg()
545 {
546     sal_Bool bRet(sal_False);
547 
548     if(IsSetPageOrg())
549     {
550         SdrPageView* pPV = GetSdrPageView();
551 
552         if(pPV)
553         {
554             Point aPnt(aDragStat.GetNow());
555             pPV->SetPageOrigin(aPnt);
556             bRet = sal_True;
557         }
558 
559         // cleanup
560         BrkSetPageOrg();
561     }
562 
563     return bRet;
564 }
565 
566 void SdrSnapView::BrkSetPageOrg()
567 {
568     if(IsSetPageOrg())
569     {
570         DBG_ASSERT(mpPageOriginOverlay, "SdrSnapView::MovSetPageOrg: no ImplPageOriginOverlay (!)");
571         delete mpPageOriginOverlay;
572         mpPageOriginOverlay = 0L;
573     }
574 }
575 
576 ////////////////////////////////////////////////////////////////////////////////////////////////////
577 
578 sal_Bool SdrSnapView::PickHelpLine(const Point& rPnt, short nTol, const OutputDevice& rOut, sal_uInt16& rnHelpLineNum, SdrPageView*& rpPV) const
579 {
580     rpPV=NULL;
581     nTol=ImpGetHitTolLogic(nTol,&rOut);
582     SdrPageView* pPV = GetSdrPageView();
583 
584     if(pPV)
585     {
586         Point aPnt(rPnt);
587         sal_uInt16 nIndex=pPV->GetHelpLines().HitTest(aPnt,sal_uInt16(nTol),rOut);
588         if (nIndex!=SDRHELPLINE_NOTFOUND) {
589             rpPV=pPV;
590             rnHelpLineNum=nIndex;
591             return sal_True;
592         }
593     }
594     return sal_False;
595 }
596 
597 // start HelpLine drag for new HelpLine
598 sal_Bool SdrSnapView::BegDragHelpLine(sal_uInt16 nHelpLineNum, SdrPageView* pPV)
599 {
600     sal_Bool bRet(sal_False);
601 
602     if(!bHlplFixed)
603     {
604         BrkAction();
605 
606         if(pPV && nHelpLineNum < pPV->GetHelpLines().GetCount())
607         {
608             const SdrHelpLineList& rHelpLines = pPV->GetHelpLines();
609             const SdrHelpLine& rHelpLine = rHelpLines[nHelpLineNum];
610             Point aHelpLinePos = rHelpLine.GetPos(); // + pPV->GetOffset();
611             basegfx::B2DPoint aStartPos(aHelpLinePos.X(), aHelpLinePos.Y());
612 
613             DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)");
614             mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, pPV, nHelpLineNum, rHelpLine.GetKind());
615 
616             aDragStat.Reset(GetSnapPos(aHelpLinePos, pPV));
617             aDragStat.SetMinMove(ImpGetMinMovLogic(-3, 0L));
618 
619             bRet = sal_True;
620         }
621     }
622 
623     return bRet;
624 }
625 
626 // start HelpLine drag with existing HelpLine
627 sal_Bool SdrSnapView::BegDragHelpLine(const Point& rPnt, SdrHelpLineKind eNewKind)
628 {
629     sal_Bool bRet(sal_False);
630 
631     BrkAction();
632 
633     if(GetSdrPageView())
634     {
635         DBG_ASSERT(0L == mpHelpLineOverlay, "SdrSnapView::BegDragHelpLine: There exists a ImplHelpLineOverlay (!)");
636         basegfx::B2DPoint aStartPos(rPnt.X(), rPnt.Y());
637         mpHelpLineOverlay = new ImplHelpLineOverlay(*this, aStartPos, 0L, 0, eNewKind);
638         aDragStat.Reset(GetSnapPos(rPnt, 0L));
639         bRet = sal_True;
640     }
641 
642     return bRet;
643 }
644 
645 Pointer SdrSnapView::GetDraggedHelpLinePointer() const
646 {
647     if(IsDragHelpLine())
648     {
649         switch(mpHelpLineOverlay->GetHelpLineKind())
650         {
651             case SDRHELPLINE_VERTICAL  : return Pointer(POINTER_ESIZE);
652             case SDRHELPLINE_HORIZONTAL: return Pointer(POINTER_SSIZE);
653             default                    : return Pointer(POINTER_MOVE);
654         }
655     }
656 
657     return Pointer(POINTER_MOVE);
658 }
659 
660 void SdrSnapView::MovDragHelpLine(const Point& rPnt)
661 {
662     if(IsDragHelpLine() && aDragStat.CheckMinMoved(rPnt))
663     {
664         Point aPnt(GetSnapPos(rPnt, 0L));
665 
666         if(aPnt != aDragStat.GetNow())
667         {
668             aDragStat.NextMove(aPnt);
669             DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::MovDragHelpLine: no ImplHelpLineOverlay (!)");
670             basegfx::B2DPoint aNewPos(aDragStat.GetNow().X(), aDragStat.GetNow().Y());
671             mpHelpLineOverlay->SetPosition(aNewPos);
672         }
673     }
674 }
675 
676 sal_Bool SdrSnapView::EndDragHelpLine()
677 {
678     sal_Bool bRet(sal_False);
679 
680     if(IsDragHelpLine())
681     {
682         if(aDragStat.IsMinMoved())
683         {
684             SdrPageView* pPageView = mpHelpLineOverlay->GetPageView();
685 
686             if(pPageView)
687             {
688                 // moved existing one
689                 Point aPnt(aDragStat.GetNow());
690                 const SdrHelpLineList& rHelpLines = pPageView->GetHelpLines();
691                 SdrHelpLine aChangedHelpLine = rHelpLines[mpHelpLineOverlay->GetHelpLineNumber()];
692                 aChangedHelpLine.SetPos(aPnt);
693                 pPageView->SetHelpLine(mpHelpLineOverlay->GetHelpLineNumber(), aChangedHelpLine);
694 
695                 bRet = sal_True;
696             }
697             else
698             {
699                 // create new one
700                 pPageView = GetSdrPageView();
701 
702                 if(pPageView)
703                 {
704                     Point aPnt(aDragStat.GetNow());
705                     SdrHelpLine aNewHelpLine(mpHelpLineOverlay->GetHelpLineKind(), aPnt);
706                     pPageView->InsertHelpLine(aNewHelpLine);
707 
708                     bRet = sal_True;
709                 }
710             }
711         }
712 
713         // cleanup
714         BrkDragHelpLine();
715     }
716 
717     return bRet;
718 }
719 
720 void SdrSnapView::BrkDragHelpLine()
721 {
722     if(IsDragHelpLine())
723     {
724         DBG_ASSERT(mpHelpLineOverlay, "SdrSnapView::EndDragHelpLine: no ImplHelpLineOverlay (!)");
725         delete mpHelpLineOverlay;
726         mpHelpLineOverlay = 0L;
727     }
728 }
729 
730 // eof
731