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