xref: /trunk/main/basctl/source/dlged/dlgedfunc.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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_basctl.hxx"
30 #include <vcl/scrbar.hxx>
31 #include <svx/svdview.hxx>
32 #include "dlgedfunc.hxx"
33 #include "dlged.hxx"
34 #include "dlgedview.hxx"
35 #include <vcl/seleng.hxx>
36 
37 
38 //----------------------------------------------------------------------------
39 
40 IMPL_LINK_INLINE_START( DlgEdFunc, ScrollTimeout, Timer *, pTimer )
41 {
42     (void)pTimer;
43     Window* pWindow = pParent->GetWindow();
44     Point aPos = pWindow->ScreenToOutputPixel( pWindow->GetPointerPosPixel() );
45     aPos = pWindow->PixelToLogic( aPos );
46     ForceScroll( aPos );
47     return 0;
48 }
49 IMPL_LINK_INLINE_END( DlgEdFunc, ScrollTimeout, Timer *, pTimer )
50 
51 //----------------------------------------------------------------------------
52 
53 void DlgEdFunc::ForceScroll( const Point& rPos )
54 {
55     aScrollTimer.Stop();
56 
57     Window* pWindow  = pParent->GetWindow();
58 
59     static Point aDefPoint;
60     Rectangle aOutRect( aDefPoint, pWindow->GetOutputSizePixel() );
61     aOutRect = pWindow->PixelToLogic( aOutRect );
62 
63     ScrollBar* pHScroll = pParent->GetHScroll();
64     ScrollBar* pVScroll = pParent->GetVScroll();
65     long nDeltaX = pHScroll->GetLineSize();
66     long nDeltaY = pVScroll->GetLineSize();
67 
68     if( !aOutRect.IsInside( rPos ) )
69     {
70         if( rPos.X() < aOutRect.Left() )
71             nDeltaX = -nDeltaX;
72         else
73         if( rPos.X() <= aOutRect.Right() )
74             nDeltaX = 0;
75 
76         if( rPos.Y() < aOutRect.Top() )
77             nDeltaY = -nDeltaY;
78         else
79         if( rPos.Y() <= aOutRect.Bottom() )
80             nDeltaY = 0;
81 
82         if( nDeltaX )
83             pHScroll->SetThumbPos( pHScroll->GetThumbPos() + nDeltaX );
84         if( nDeltaY )
85             pVScroll->SetThumbPos( pVScroll->GetThumbPos() + nDeltaY );
86 
87         if( nDeltaX )
88             pParent->DoScroll( pHScroll );
89         if( nDeltaY )
90             pParent->DoScroll( pVScroll );
91     }
92 
93     aScrollTimer.Start();
94 }
95 
96 //----------------------------------------------------------------------------
97 
98 DlgEdFunc::DlgEdFunc( DlgEditor* pParent_ )
99 {
100     DlgEdFunc::pParent = pParent_;
101     aScrollTimer.SetTimeoutHdl( LINK( this, DlgEdFunc, ScrollTimeout ) );
102     aScrollTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL );
103 }
104 
105 //----------------------------------------------------------------------------
106 
107 DlgEdFunc::~DlgEdFunc()
108 {
109 }
110 
111 //----------------------------------------------------------------------------
112 
113 sal_Bool DlgEdFunc::MouseButtonDown( const MouseEvent& )
114 {
115     return sal_True;
116 }
117 
118 //----------------------------------------------------------------------------
119 
120 sal_Bool DlgEdFunc::MouseButtonUp( const MouseEvent& )
121 {
122     aScrollTimer.Stop();
123     return sal_True;
124 }
125 
126 //----------------------------------------------------------------------------
127 
128 sal_Bool DlgEdFunc::MouseMove( const MouseEvent& )
129 {
130     return sal_True;
131 }
132 
133 //----------------------------------------------------------------------------
134 
135 sal_Bool DlgEdFunc::KeyInput( const KeyEvent& rKEvt )
136 {
137     sal_Bool bReturn = sal_False;
138 
139     SdrView* pView = pParent->GetView();
140     Window* pWindow = pParent->GetWindow();
141 
142     KeyCode aCode = rKEvt.GetKeyCode();
143     sal_uInt16 nCode = aCode.GetCode();
144 
145     switch ( nCode )
146     {
147         case KEY_ESCAPE:
148         {
149             if ( pView->IsAction() )
150             {
151                 pView->BrkAction();
152                 bReturn = sal_True;
153             }
154             else if ( pView->AreObjectsMarked() )
155             {
156                 const SdrHdlList& rHdlList = pView->GetHdlList();
157                 SdrHdl* pHdl = rHdlList.GetFocusHdl();
158                 if ( pHdl )
159                     ((SdrHdlList&)rHdlList).ResetFocusHdl();
160                 else
161                     pView->UnmarkAll();
162 
163                 bReturn = sal_True;
164             }
165         }
166         break;
167         case KEY_TAB:
168         {
169             if ( !aCode.IsMod1() && !aCode.IsMod2() )
170             {
171                 // mark next object
172                 if ( !pView->MarkNextObj( !aCode.IsShift() ) )
173                 {
174                     // if no next object, mark first/last
175                     pView->UnmarkAllObj();
176                     pView->MarkNextObj( !aCode.IsShift() );
177                 }
178 
179                 if ( pView->AreObjectsMarked() )
180                     pView->MakeVisible( pView->GetAllMarkedRect(), *pWindow );
181 
182                 bReturn = sal_True;
183             }
184             else if ( aCode.IsMod1() )
185             {
186                 // selected handle
187                 const SdrHdlList& rHdlList = pView->GetHdlList();
188                 ((SdrHdlList&)rHdlList).TravelFocusHdl( !aCode.IsShift() );
189 
190                 // guarantee visibility of focused handle
191                 SdrHdl* pHdl = rHdlList.GetFocusHdl();
192                 if ( pHdl )
193                 {
194                     Point aHdlPosition( pHdl->GetPos() );
195                     Rectangle aVisRect( aHdlPosition - Point( 100, 100 ), Size( 200, 200 ) );
196                     pView->MakeVisible( aVisRect, *pWindow );
197                 }
198 
199                 bReturn = sal_True;
200             }
201         }
202         break;
203         case KEY_UP:
204         case KEY_DOWN:
205         case KEY_LEFT:
206         case KEY_RIGHT:
207         {
208             long nX = 0;
209             long nY = 0;
210 
211             if ( nCode == KEY_UP )
212             {
213                 // scroll up
214                 nX =  0;
215                 nY = -1;
216             }
217             else if ( nCode == KEY_DOWN )
218             {
219                 // scroll down
220                 nX =  0;
221                 nY =  1;
222             }
223             else if ( nCode == KEY_LEFT )
224             {
225                 // scroll left
226                 nX = -1;
227                 nY =  0;
228             }
229             else if ( nCode == KEY_RIGHT )
230             {
231                 // scroll right
232                 nX =  1;
233                 nY =  0;
234             }
235 
236             if ( pView->AreObjectsMarked() && !aCode.IsMod1() )
237             {
238                 if ( aCode.IsMod2() )
239                 {
240                     // move in 1 pixel distance
241                     Size aPixelSize = pWindow ? pWindow->PixelToLogic( Size( 1, 1 ) ) : Size( 100, 100 );
242                     nX *= aPixelSize.Width();
243                     nY *= aPixelSize.Height();
244                 }
245                 else
246                 {
247                     // move in 1 mm distance
248                     nX *= 100;
249                     nY *= 100;
250                 }
251 
252                 const SdrHdlList& rHdlList = pView->GetHdlList();
253                 SdrHdl* pHdl = rHdlList.GetFocusHdl();
254 
255                 if ( pHdl == 0 )
256                 {
257                     // no handle selected
258                     if ( pView->IsMoveAllowed() )
259                     {
260                         // restrict movement to work area
261                         const Rectangle& rWorkArea = pView->GetWorkArea();
262 
263                         if ( !rWorkArea.IsEmpty() )
264                         {
265                             Rectangle aMarkRect( pView->GetMarkedObjRect() );
266                             aMarkRect.Move( nX, nY );
267 
268                             if ( !rWorkArea.IsInside( aMarkRect ) )
269                             {
270                                 if ( aMarkRect.Left() < rWorkArea.Left() )
271                                     nX += rWorkArea.Left() - aMarkRect.Left();
272 
273                                 if ( aMarkRect.Right() > rWorkArea.Right() )
274                                     nX -= aMarkRect.Right() - rWorkArea.Right();
275 
276                                 if ( aMarkRect.Top() < rWorkArea.Top() )
277                                     nY += rWorkArea.Top() - aMarkRect.Top();
278 
279                                 if ( aMarkRect.Bottom() > rWorkArea.Bottom() )
280                                     nY -= aMarkRect.Bottom() - rWorkArea.Bottom();
281                             }
282                         }
283 
284                         if ( nX != 0 || nY != 0 )
285                         {
286                             pView->MoveAllMarked( Size( nX, nY ) );
287                             pView->MakeVisible( pView->GetAllMarkedRect(), *pWindow );
288                         }
289                     }
290                 }
291                 else
292                 {
293                     // move the handle
294                     if ( pHdl && ( nX || nY ) )
295                     {
296                         Point aStartPoint( pHdl->GetPos() );
297                         Point aEndPoint( pHdl->GetPos() + Point( nX, nY ) );
298                         const SdrDragStat& rDragStat = pView->GetDragStat();
299 
300                         // start dragging
301                         pView->BegDragObj( aStartPoint, 0, pHdl, 0 );
302 
303                         if ( pView->IsDragObj() )
304                         {
305                             FASTBOOL bWasNoSnap = rDragStat.IsNoSnap();
306                             sal_Bool bWasSnapEnabled = pView->IsSnapEnabled();
307 
308                             // switch snapping off
309                             if ( !bWasNoSnap )
310                                 ((SdrDragStat&)rDragStat).SetNoSnap( sal_True );
311                             if ( bWasSnapEnabled )
312                                 pView->SetSnapEnabled( sal_False );
313 
314                             pView->MovAction( aEndPoint );
315                             pView->EndDragObj();
316 
317                             // restore snap
318                             if ( !bWasNoSnap )
319                                 ((SdrDragStat&)rDragStat).SetNoSnap( bWasNoSnap );
320                             if ( bWasSnapEnabled )
321                                 pView->SetSnapEnabled( bWasSnapEnabled );
322                         }
323 
324                         // make moved handle visible
325                         Rectangle aVisRect( aEndPoint - Point( 100, 100 ), Size( 200, 200 ) );
326                         pView->MakeVisible( aVisRect, *pWindow );
327                     }
328                 }
329             }
330             else
331             {
332                 // scroll page
333                 ScrollBar* pScrollBar = ( nX != 0 ) ? pParent->GetHScroll() : pParent->GetVScroll();
334                 if ( pScrollBar )
335                 {
336                     long nRangeMin = pScrollBar->GetRangeMin();
337                     long nRangeMax = pScrollBar->GetRangeMax();
338                     long nThumbPos = pScrollBar->GetThumbPos() + ( ( nX != 0 ) ? nX : nY ) * pScrollBar->GetLineSize();
339                     if ( nThumbPos < nRangeMin )
340                         nThumbPos = nRangeMin;
341                     if ( nThumbPos > nRangeMax )
342                         nThumbPos = nRangeMax;
343                     pScrollBar->SetThumbPos( nThumbPos );
344                     pParent->DoScroll( pScrollBar );
345                 }
346             }
347 
348             bReturn = sal_True;
349         }
350         break;
351         default:
352         {
353         }
354         break;
355     }
356 
357     if ( bReturn )
358         pWindow->ReleaseMouse();
359 
360     return bReturn;
361 }
362 
363 //----------------------------------------------------------------------------
364 
365 DlgEdFuncInsert::DlgEdFuncInsert( DlgEditor* pParent_ ) :
366     DlgEdFunc( pParent_ )
367 {
368     pParent_->GetView()->SetCreateMode( sal_True );
369 }
370 
371 //----------------------------------------------------------------------------
372 
373 DlgEdFuncInsert::~DlgEdFuncInsert()
374 {
375     pParent->GetView()->SetEditMode( sal_True );
376 }
377 
378 //----------------------------------------------------------------------------
379 
380 sal_Bool DlgEdFuncInsert::MouseButtonDown( const MouseEvent& rMEvt )
381 {
382     if( !rMEvt.IsLeft() )
383         return sal_True;
384 
385     SdrView* pView  = pParent->GetView();
386     Window*  pWindow= pParent->GetWindow();
387     pView->SetActualWin( pWindow );
388 
389     Point aPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
390     sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
391     sal_uInt16 nDrgLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
392 
393     pWindow->CaptureMouse();
394 
395     if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 )
396     {
397         SdrHdl* pHdl = pView->PickHandle(aPos);
398 
399         // if selected object was hit, drag object
400         if ( pHdl!=NULL || pView->IsMarkedHit(aPos, nHitLog) )
401             pView->BegDragObj(aPos, (OutputDevice*) NULL, pHdl, nDrgLog);
402         else if ( pView->AreObjectsMarked() )
403             pView->UnmarkAll();
404 
405         // if no action, create object
406         if ( !pView->IsAction() )
407             pView->BegCreateObj(aPos);
408     }
409     else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 )
410     {
411         // if object was hit, show property browser
412         if ( pView->IsMarkedHit(aPos, nHitLog) && pParent->GetMode() != DLGED_READONLY )
413             pParent->ShowProperties();
414     }
415 
416     return sal_True;
417 }
418 
419 //----------------------------------------------------------------------------
420 
421 sal_Bool DlgEdFuncInsert::MouseButtonUp( const MouseEvent& rMEvt )
422 {
423     DlgEdFunc::MouseButtonUp( rMEvt );
424 
425     SdrView* pView  = pParent->GetView();
426     Window*  pWindow= pParent->GetWindow();
427     pView->SetActualWin( pWindow );
428 
429     pWindow->ReleaseMouse();
430 
431     // object creation active?
432     if ( pView->IsCreateObj() )
433     {
434         pView->EndCreateObj(SDRCREATE_FORCEEND);
435 
436         if ( !pView->AreObjectsMarked() )
437         {
438             sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
439             Point aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
440             pView->MarkObj(aPos, nHitLog);
441         }
442 
443         if( pView->AreObjectsMarked() )
444             return sal_True;
445         else
446             return sal_False;
447     }
448     else
449     {
450         if ( pView->IsDragObj() )
451              pView->EndDragObj( rMEvt.IsMod1() );
452         return sal_True;
453     }
454 }
455 
456 //----------------------------------------------------------------------------
457 
458 sal_Bool DlgEdFuncInsert::MouseMove( const MouseEvent& rMEvt )
459 {
460     SdrView* pView  = pParent->GetView();
461     Window*  pWindow= pParent->GetWindow();
462     pView->SetActualWin( pWindow );
463 
464     Point   aPos( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
465     sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
466 
467     if ( pView->IsAction() )
468     {
469         ForceScroll(aPos);
470         pView->MovAction(aPos);
471     }
472 
473     pWindow->SetPointer( pView->GetPreferedPointer( aPos, pWindow, nHitLog ) );
474 
475     return sal_True;
476 }
477 
478 //----------------------------------------------------------------------------
479 
480 DlgEdFuncSelect::DlgEdFuncSelect( DlgEditor* pParent_ ) :
481     DlgEdFunc( pParent_ ),
482     bMarkAction(sal_False)
483 {
484 }
485 
486 //----------------------------------------------------------------------------
487 
488 DlgEdFuncSelect::~DlgEdFuncSelect()
489 {
490 }
491 
492 //----------------------------------------------------------------------------
493 
494 sal_Bool DlgEdFuncSelect::MouseButtonDown( const MouseEvent& rMEvt )
495 {
496     // get view from parent
497     SdrView* pView   = pParent->GetView();
498     Window*  pWindow = pParent->GetWindow();
499     pView->SetActualWin( pWindow );
500 
501     sal_uInt16 nDrgLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
502     sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
503     Point  aMDPos = pWindow->PixelToLogic( rMEvt.GetPosPixel() );
504 
505     if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 )
506     {
507         SdrHdl* pHdl = pView->PickHandle(aMDPos);
508         SdrObject* pObj;
509         SdrPageView* pPV;
510 
511         // hit selected object?
512         if ( pHdl!=NULL || pView->IsMarkedHit(aMDPos, nHitLog) )
513         {
514             pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, nDrgLog);
515         }
516         else
517         {
518             // if not multi selection, unmark all
519             if ( !rMEvt.IsShift() )
520                 pView->UnmarkAll();
521             else
522             {
523                 if( pView->PickObj( aMDPos, nHitLog, pObj, pPV ) )
524                 {
525                     //if( pObj->ISA( DlgEdForm ) )
526                     //  pView->UnmarkAll();
527                     //else
528                     //  pParent->UnmarkDialog();
529                 }
530             }
531 
532             if ( pView->MarkObj(aMDPos, nHitLog) )
533             {
534                 // drag object
535                 pHdl=pView->PickHandle(aMDPos);
536                 pView->BegDragObj(aMDPos, (OutputDevice*) NULL, pHdl, nDrgLog);
537             }
538             else
539             {
540                 // select object
541                 pView->BegMarkObj(aMDPos);
542                 bMarkAction = sal_True;
543             }
544         }
545     }
546     else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 )
547     {
548         // if object was hit, show property browser
549         if ( pView->IsMarkedHit(aMDPos, nHitLog) && pParent->GetMode() != DLGED_READONLY )
550             pParent->ShowProperties();
551     }
552 
553     return sal_True;
554 }
555 
556 //----------------------------------------------------------------------------
557 
558 sal_Bool DlgEdFuncSelect::MouseButtonUp( const MouseEvent& rMEvt )
559 {
560     DlgEdFunc::MouseButtonUp( rMEvt );
561 
562     // get view from parent
563     SdrView* pView  = pParent->GetView();
564     Window*  pWindow= pParent->GetWindow();
565     pView->SetActualWin( pWindow );
566 
567     Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
568     sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
569 
570     if ( rMEvt.IsLeft() )
571     {
572         if ( pView->IsDragObj() )
573         {
574             // object was dragged
575             pView->EndDragObj( rMEvt.IsMod1() );
576             pView->ForceMarkedToAnotherPage();
577         }
578         else
579         if (pView->IsAction() )
580         {
581             pView->EndAction();
582             //if( bMarkAction )
583                 //pParent->UnmarkDialog();
584         }
585     }
586 
587 //  sal_uInt16 nClicks = rMEvt.GetClicks();
588 //  if (nClicks == 2)
589 //  {
590 //      if ( pView->AreObjectsMarked() )
591 //      {
592 //          const SdrMarkList& rMarkList = pView->GetMarkedObjectList();
593 //
594 //          if (rMarkList.GetMarkCount() == 1)
595 //          {
596 //              SdrMark* pMark = rMarkList.GetMark(0);
597 //              SdrObject* pObj = pMark->GetMarkedSdrObj();
598 //
599 //              // edit objects here
600 //          }
601 //      }
602 //  }
603 
604     bMarkAction = sal_False;
605 
606     pWindow->SetPointer( pView->GetPreferedPointer( aPnt, pWindow, nHitLog ) );
607     pWindow->ReleaseMouse();
608 
609     return sal_True;
610 }
611 
612 //----------------------------------------------------------------------------
613 
614 sal_Bool DlgEdFuncSelect::MouseMove( const MouseEvent& rMEvt )
615 {
616     SdrView* pView  = pParent->GetView();
617     Window*  pWindow= pParent->GetWindow();
618     pView->SetActualWin( pWindow );
619 
620     Point aPnt( pWindow->PixelToLogic( rMEvt.GetPosPixel() ) );
621     sal_uInt16 nHitLog = sal_uInt16 ( pWindow->PixelToLogic(Size(3,0)).Width() );
622 
623     if ( pView->IsAction() )
624     {
625         Point aPix(rMEvt.GetPosPixel());
626         Point aPnt_(pWindow->PixelToLogic(aPix));
627 
628         ForceScroll(aPnt_);
629         pView->MovAction(aPnt_);
630     }
631 
632     pWindow->SetPointer( pView->GetPreferedPointer( aPnt, pWindow, nHitLog ) );
633 
634     return sal_True;
635 }
636 
637 //----------------------------------------------------------------------------
638