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