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 <fuediglu.hxx>
21 #include <svl/eitem.hxx>
22 #include <svx/svdglue.hxx>
23 #include <sfx2/request.hxx>
24 
25 #include <app.hrc>
26 
27 #include <Window.hxx>
28 #include <View.hxx>
29 #include <ViewShell.hxx>
30 #include <ViewShellBase.hxx>
31 #include <ToolBarManager.hxx>
32 
33 namespace sd {
34 
35 
FuEditGluePoints(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq)36 FuEditGluePoints::FuEditGluePoints (
37     ViewShell* pViewSh,
38     ::sd::Window* pWin,
39     ::sd::View* pView,
40     SdDrawDocument* pDoc,
41     SfxRequest& rReq)
42     : FuDraw(pViewSh, pWin, pView, pDoc, rReq)
43      //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
44      //and SHIFT+ENTER key to decide the position and draw the new insert point
45      ,bBeginInsertPoint(false),
46     oldPoint(0,0)
47 {
48 }
49 
Create(ViewShell * pViewSh,::sd::Window * pWin,::sd::View * pView,SdDrawDocument * pDoc,SfxRequest & rReq,bool bPermanent)50 rtl::Reference<FuPoor> FuEditGluePoints::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent )
51 {
52     FuEditGluePoints* pFunc;
53     rtl::Reference<FuPoor> xFunc( pFunc = new FuEditGluePoints( pViewSh, pWin, pView, pDoc, rReq ) );
54     xFunc->DoExecute(rReq);
55     pFunc->SetPermanent( bPermanent );
56     return xFunc;
57 }
58 
DoExecute(SfxRequest & rReq)59 void FuEditGluePoints::DoExecute( SfxRequest& rReq )
60 {
61     FuDraw::DoExecute( rReq );
62     mpView->SetInsGluePointMode(false);
63     mpViewShell->GetViewShellBase().GetToolBarManager()->AddToolBar(
64         ToolBarManager::ToolBarGroup::Function,
65         ToolBarManager::msGluePointsToolBar);
66 }
67 
~FuEditGluePoints()68 FuEditGluePoints::~FuEditGluePoints()
69 {
70     mpView->BrkAction();
71     mpView->UnmarkAllGluePoints();
72     mpView->SetInsGluePointMode(false);
73 }
74 
MouseButtonDown(const MouseEvent & rMEvt)75 bool FuEditGluePoints::MouseButtonDown(const MouseEvent& rMEvt)
76 {
77     mpView->SetActualWin( mpWindow->GetOutDev() );
78 
79     bool bReturn = FuDraw::MouseButtonDown(rMEvt);
80 
81     if (mpView->IsAction())
82     {
83         if (rMEvt.IsRight())
84             mpView->BckAction();
85 
86         return true;
87     }
88 
89     if (rMEvt.IsLeft())
90     {
91         bReturn = true;
92         sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
93         sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
94         mpWindow->CaptureMouse();
95 
96         SdrViewEvent aVEvt;
97         SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
98 
99         if (eHit == SdrHitKind::Handle)
100         {
101             // drag handle
102             SdrHdl* pHdl = aVEvt.pHdl;
103 
104             if (mpView->IsGluePointMarked(aVEvt.pObj, aVEvt.nGlueId) && rMEvt.IsShift())
105             {
106                 mpView->UnmarkGluePoint(aVEvt.pObj, aVEvt.nGlueId);
107                 pHdl = nullptr;
108             }
109 
110             if (pHdl)
111             {
112                 // drag handle
113                 mpView->BegDragObj(aMDPos, nullptr, aVEvt.pHdl, nDrgLog);
114             }
115         }
116         else if (eHit == SdrHitKind::MarkedObject && mpView->IsInsGluePointMode())
117         {
118             // insert glue points
119             mpView->BegInsGluePoint(aMDPos);
120         }
121         else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1())
122         {
123             // select glue points
124             if (!rMEvt.IsShift())
125                 mpView->UnmarkAllGluePoints();
126 
127             mpView->BegMarkGluePoints(aMDPos);
128         }
129         else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2())
130         {
131             // move object
132             mpView->BegDragObj(aMDPos, nullptr, nullptr, nDrgLog);
133         }
134         else if (eHit == SdrHitKind::Gluepoint)
135         {
136             // select glue points
137             if (!rMEvt.IsShift())
138                 mpView->UnmarkAllGluePoints();
139 
140             mpView->MarkGluePoint(aVEvt.pObj, aVEvt.nGlueId, false);
141             SdrHdl* pHdl = mpView->GetGluePointHdl(aVEvt.pObj, aVEvt.nGlueId);
142 
143             if (pHdl)
144             {
145                 mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog);
146             }
147         }
148         else
149         {
150             // select or drag object
151             if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SdrHitKind::UnmarkedObject)
152             {
153                mpView->UnmarkAllObj();
154             }
155 
156             bool bMarked = false;
157 
158             if (!rMEvt.IsMod1())
159             {
160                 if (rMEvt.IsMod2())
161                 {
162                     bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift());
163                 }
164                 else
165                 {
166                     bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift());
167                 }
168             }
169 
170             if (bMarked &&
171                 (!rMEvt.IsShift() || eHit == SdrHitKind::MarkedObject))
172             {
173                 // move object
174                 mpView->BegDragObj(aMDPos, nullptr, aVEvt.pHdl, nDrgLog);
175             }
176             else if (mpView->AreObjectsMarked())
177             {
178                 // select glue point
179                 if (!rMEvt.IsShift())
180                     mpView->UnmarkAllGluePoints();
181 
182                 mpView->BegMarkGluePoints(aMDPos);
183             }
184             else
185             {
186                 // select object
187                 mpView->BegMarkObj(aMDPos);
188             }
189         }
190 
191         ForcePointer(&rMEvt);
192     }
193 
194     return bReturn;
195 }
196 
MouseMove(const MouseEvent & rMEvt)197 bool FuEditGluePoints::MouseMove(const MouseEvent& rMEvt)
198 {
199     mpView->SetActualWin( mpWindow->GetOutDev() );
200 
201     FuDraw::MouseMove(rMEvt);
202 
203     if (mpView->IsAction())
204     {
205         Point aPix(rMEvt.GetPosPixel());
206         Point aPnt( mpWindow->PixelToLogic(aPix) );
207         ForceScroll(aPix);
208         mpView->MovAction(aPnt);
209     }
210 
211     ForcePointer(&rMEvt);
212 
213     return true;
214 }
215 
MouseButtonUp(const MouseEvent & rMEvt)216 bool FuEditGluePoints::MouseButtonUp(const MouseEvent& rMEvt)
217 {
218     mpView->SetActualWin( mpWindow->GetOutDev() );
219 
220     bool bReturn = false;
221 
222     if (mpView->IsAction())
223     {
224         bReturn = true;
225         mpView->EndAction();
226     }
227 
228     FuDraw::MouseButtonUp(rMEvt);
229 
230     sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(DRGPIX,0)).Width() );
231     Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
232 
233     if (std::abs(aMDPos.X() - aPos.X()) < nDrgLog &&
234         std::abs(aMDPos.Y() - aPos.Y()) < nDrgLog &&
235         !rMEvt.IsShift() && !rMEvt.IsMod2())
236     {
237         SdrViewEvent aVEvt;
238         SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
239 
240         if (eHit == SdrHitKind::NONE)
241         {
242             // click on position: deselect
243             mpView->UnmarkAllObj();
244         }
245     }
246 
247     mpWindow->ReleaseMouse();
248 
249     return bReturn;
250 }
251 
252 /**
253  * Process keyboard input
254  * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
255  */
KeyInput(const KeyEvent & rKEvt)256 bool FuEditGluePoints::KeyInput(const KeyEvent& rKEvt)
257 {
258     mpView->SetActualWin( mpWindow->GetOutDev() );
259 
260     //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point,
261     //and SHIFT+ENTER key to decide the position and draw the new insert point
262 
263     bool bReturn = false;
264 
265     switch (rKEvt.GetKeyCode().GetCode())
266     {
267         case KEY_UP:
268         case KEY_DOWN:
269         case KEY_LEFT:
270         case KEY_RIGHT:
271         {
272             if(rKEvt.GetKeyCode().IsShift()&& mpView->IsInsGluePointMode() ){
273                 ::tools::Long nX = 0;
274                 ::tools::Long nY = 0;
275                 sal_uInt16  nCode = rKEvt.GetKeyCode().GetCode();
276                 if (nCode == KEY_UP)
277                 {
278                     // scroll up
279                     nX = 0;
280                     nY =-1;
281                 }
282                 else if (nCode == KEY_DOWN)
283                 {
284                     // scroll down
285                     nX = 0;
286                     nY = 1;
287                 }
288                 else if (nCode == KEY_LEFT)
289                 {
290                     // scroll left
291                     nX =-1;
292                     nY = 0;
293                 }
294                 else if (nCode == KEY_RIGHT)
295                 {
296                     // scroll right
297                     nX = 1;
298                     nY = 0;
299                 }
300                 Point centerPoint;
301                 ::tools::Rectangle rect = mpView->GetMarkedObjRect();
302                 centerPoint = mpWindow->LogicToPixel(rect.Center());
303                 Point aPoint = bBeginInsertPoint? oldPoint:centerPoint;
304                 Point ePoint = aPoint + Point(nX,nY);
305                 mpWindow->SetPointerPosPixel(ePoint);
306                 //simulate mouse move action
307                 MouseEvent eMevt(ePoint, 1, MouseEventModifiers::DRAGMOVE, MOUSE_LEFT, 0);
308                 MouseMove(eMevt);
309                 oldPoint = ePoint;
310                 bBeginInsertPoint = true;
311                 bReturn = true;
312             }
313         }
314         break;
315         case KEY_RETURN:
316             if(rKEvt.GetKeyCode().IsShift() && mpView->IsInsGluePointMode() )
317             {
318                 if(bBeginInsertPoint)
319                 {
320                     mpWindow->SetPointerPosPixel(oldPoint);
321                     //simulate mouse button down action
322                     MouseEvent aMevt(oldPoint, 1,
323                                      MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::DRAGMOVE,
324                                      MOUSE_LEFT, KEY_SHIFT);
325                     // MT IA2: Not used?
326                     // sal_uInt16 ubuttons = aMevt.GetButtons();
327                     // sal_uInt16 uMod      = aMevt.GetModifier();
328                     MouseButtonDown(aMevt);
329                     mpWindow->CaptureMouse();
330                     //simulate mouse button up action
331                     MouseEvent rMEvt(oldPoint+Point(0,0), 1,
332                                      MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::ENTERWINDOW,
333                                      MOUSE_LEFT, KEY_SHIFT);
334                     MouseButtonUp(rMEvt);
335                     bReturn= true;
336                 }
337             }
338             break;
339     }
340 
341     if(!bReturn)
342         bReturn = FuDraw::KeyInput(rKEvt);
343 
344     return bReturn;
345 }
346 
347 //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point, and
348 //SHIFT+ENTER key to decide the position and draw the new insert point
ForcePointer(const MouseEvent * pMEvt)349 void FuEditGluePoints::ForcePointer(const MouseEvent* pMEvt)
350 {
351     if(bBeginInsertPoint && pMEvt)
352     {
353         MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(),
354             pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT);
355         FuDraw::ForcePointer(&aMEvt);
356     }
357     else
358     {
359         FuDraw::ForcePointer(pMEvt);
360     }
361 }
362 
Command(const CommandEvent & rCEvt)363 bool FuEditGluePoints::Command(const CommandEvent& rCEvt)
364 {
365     mpView->SetActualWin( mpWindow->GetOutDev() );
366     return FuPoor::Command( rCEvt );
367 }
368 
Activate()369 void FuEditGluePoints::Activate()
370 {
371     mpView->SetGluePointEditMode();
372     FuDraw::Activate();
373 }
374 
Deactivate()375 void FuEditGluePoints::Deactivate()
376 {
377     mpView->SetGluePointEditMode( false );
378     FuDraw::Deactivate();
379 }
380 
ReceiveRequest(SfxRequest & rReq)381 void FuEditGluePoints::ReceiveRequest(SfxRequest& rReq)
382 {
383     switch (rReq.GetSlot())
384     {
385         case SID_GLUE_INSERT_POINT:
386         {
387             mpView->SetInsGluePointMode(!mpView->IsInsGluePointMode());
388         }
389         break;
390 
391         case SID_GLUE_ESCDIR_LEFT:
392         {
393             mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::LEFT,
394                     !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::LEFT ) );
395         }
396         break;
397 
398         case SID_GLUE_ESCDIR_RIGHT:
399         {
400             mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::RIGHT,
401                     !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::RIGHT ) );
402         }
403         break;
404 
405         case SID_GLUE_ESCDIR_TOP:
406         {
407             mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::TOP,
408                     !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::TOP ) );
409         }
410         break;
411 
412         case SID_GLUE_ESCDIR_BOTTOM:
413         {
414             mpView->SetMarkedGluePointsEscDir( SdrEscapeDirection::BOTTOM,
415                     !mpView->IsMarkedGluePointsEscDir( SdrEscapeDirection::BOTTOM ) );
416         }
417         break;
418 
419         case SID_GLUE_PERCENT:
420         {
421             const SfxItemSet* pSet = rReq.GetArgs();
422             const SfxPoolItem& rItem = pSet->Get(SID_GLUE_PERCENT);
423             bool bPercent = static_cast<const SfxBoolItem&>(rItem).GetValue();
424             mpView->SetMarkedGluePointsPercent(bPercent);
425         }
426         break;
427 
428         case SID_GLUE_HORZALIGN_CENTER:
429         {
430             mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_CENTER);
431         }
432         break;
433 
434         case SID_GLUE_HORZALIGN_LEFT:
435         {
436             mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_LEFT);
437         }
438         break;
439 
440         case SID_GLUE_HORZALIGN_RIGHT:
441         {
442             mpView->SetMarkedGluePointsAlign(false, SdrAlign::HORZ_RIGHT);
443         }
444         break;
445 
446         case SID_GLUE_VERTALIGN_CENTER:
447         {
448             mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_CENTER);
449         }
450         break;
451 
452         case SID_GLUE_VERTALIGN_TOP:
453         {
454             mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_TOP);
455         }
456         break;
457 
458         case SID_GLUE_VERTALIGN_BOTTOM:
459         {
460             mpView->SetMarkedGluePointsAlign(true, SdrAlign::VERT_BOTTOM);
461         }
462         break;
463     }
464 
465     // at the end, call base class
466     FuPoor::ReceiveRequest(rReq);
467 }
468 
469 } // end of namespace sd
470 
471 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
472