Line data Source code
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 <sot/object.hxx>
21 : #include <editeng/eeitem.hxx>
22 : #include <vcl/waitobj.hxx>
23 :
24 : #include <editeng/flditem.hxx>
25 : #include <svx/svdogrp.hxx>
26 : #include <svx/svdoole2.hxx>
27 : #include <tools/urlobj.hxx>
28 : #include <vcl/help.hxx>
29 : #include <svx/bmpmask.hxx>
30 : #include <svx/svdotext.hxx>
31 : #include <sfx2/app.hxx>
32 : #include <sfx2/dispatch.hxx>
33 : #include <sfx2/bindings.hxx>
34 : #include <svx/svdpagv.hxx>
35 : #include <svtools/imapobj.hxx>
36 : #include <svx/svxids.hrc>
37 : #include <svx/obj3d.hxx>
38 : #include <svx/polysc3d.hxx>
39 :
40 : #include <sfx2/viewfrm.hxx>
41 :
42 : #include "anminfo.hxx"
43 : #include "imapinfo.hxx"
44 : #include "app.hrc"
45 : #include "glob.hrc"
46 : #include "strings.hrc"
47 : #include "res_bmp.hrc"
48 :
49 : #include "sdmod.hxx"
50 : #include "GraphicDocShell.hxx"
51 : #include "fudraw.hxx"
52 : #include "ViewShell.hxx"
53 : #include "FrameView.hxx"
54 : #include "View.hxx"
55 : #include "Window.hxx"
56 : #include "drawdoc.hxx"
57 : #include "DrawDocShell.hxx"
58 : #include "Client.hxx"
59 : #include "sdresid.hxx"
60 : #include "drawview.hxx"
61 : #include "fusel.hxx"
62 : #include <svl/aeitem.hxx>
63 : #include <vcl/msgbox.hxx>
64 : #include "slideshow.hxx"
65 : #include <svx/sdrhittesthelper.hxx>
66 :
67 : using namespace ::com::sun::star;
68 :
69 : namespace sd {
70 :
71 0 : TYPEINIT1( FuDraw, FuPoor );
72 :
73 : /**
74 : * Base-class for all drawmodul-specific functions
75 : */
76 138 : FuDraw::FuDraw(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView,
77 : SdDrawDocument* pDoc, SfxRequest& rReq)
78 : : FuPoor(pViewSh, pWin, pView, pDoc, rReq)
79 : , bMBDown(false)
80 : , bDragHelpLine(false)
81 : , nHelpLine(0)
82 : , bPermanent(false)
83 138 : , bIsImageSelected(false)
84 : {
85 138 : }
86 :
87 276 : FuDraw::~FuDraw()
88 : {
89 138 : mpView->BrkAction();
90 138 : }
91 :
92 :
93 : /**
94 : * Code shared by MouseButtonDown and MouseMove
95 : */
96 4 : void FuDraw::DoModifiers(const MouseEvent& rMEvt, bool bSnapModPressed)
97 : {
98 4 : FrameView* pFrameView = mpViewShell->GetFrameView();
99 4 : bool bGridSnap = pFrameView->IsGridSnap();
100 4 : bGridSnap = (bSnapModPressed != bGridSnap);
101 :
102 4 : if (mpView->IsGridSnap() != bGridSnap)
103 0 : mpView->SetGridSnap(bGridSnap);
104 :
105 4 : bool bBordSnap = pFrameView->IsBordSnap();
106 4 : bBordSnap = (bSnapModPressed != bBordSnap);
107 :
108 4 : if (mpView->IsBordSnap() != bBordSnap)
109 0 : mpView->SetBordSnap(bBordSnap);
110 :
111 4 : bool bHlplSnap = pFrameView->IsHlplSnap();
112 4 : bHlplSnap = (bSnapModPressed != bHlplSnap);
113 :
114 4 : if (mpView->IsHlplSnap() != bHlplSnap)
115 0 : mpView->SetHlplSnap(bHlplSnap);
116 :
117 4 : bool bOFrmSnap = pFrameView->IsOFrmSnap();
118 4 : bOFrmSnap = (bSnapModPressed != bOFrmSnap);
119 :
120 4 : if (mpView->IsOFrmSnap() != bOFrmSnap)
121 0 : mpView->SetOFrmSnap(bOFrmSnap);
122 :
123 4 : bool bOPntSnap = pFrameView->IsOPntSnap();
124 4 : bOPntSnap = (bSnapModPressed != bOPntSnap);
125 :
126 4 : if (mpView->IsOPntSnap() != bOPntSnap)
127 0 : mpView->SetOPntSnap(bOPntSnap);
128 :
129 4 : bool bOConSnap = pFrameView->IsOConSnap();
130 4 : bOConSnap = (bSnapModPressed != bOConSnap);
131 :
132 4 : if (mpView->IsOConSnap() != bOConSnap)
133 0 : mpView->SetOConSnap(bOConSnap);
134 :
135 4 : bool bAngleSnap = rMEvt.IsShift() == !pFrameView->IsAngleSnapEnabled();
136 :
137 4 : if (mpView->IsAngleSnapEnabled() != bAngleSnap)
138 0 : mpView->SetAngleSnapEnabled(bAngleSnap);
139 :
140 4 : bool bCenter = rMEvt.IsMod2();
141 :
142 8 : if ( mpView->IsCreate1stPointAsCenter() != bCenter ||
143 4 : mpView->IsResizeAtCenter() != bCenter )
144 : {
145 0 : mpView->SetCreate1stPointAsCenter(bCenter);
146 0 : mpView->SetResizeAtCenter(bCenter);
147 : }
148 4 : }
149 :
150 :
151 2 : bool FuDraw::MouseButtonDown(const MouseEvent& rMEvt)
152 : {
153 : // remember button state for creation of own MouseEvents
154 2 : SetMouseButtonCode(rMEvt.GetButtons());
155 :
156 2 : bool bReturn = false;
157 2 : bDragHelpLine = false;
158 2 : aMDPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
159 :
160 : // Check whether an image is selected
161 2 : bIsImageSelected = false;
162 2 : if (mpView->AreObjectsMarked())
163 : {
164 1 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
165 1 : if (rMarkList.GetMarkCount() == 1)
166 : {
167 1 : SdrMark* pMark = rMarkList.GetMark(0);
168 : // tdf#89758 Extra check to avoid interactive crop preview from being
169 : // proportionally scaled by default.
170 1 : if (mpView->GetDragMode() != SDRDRAG_CROP)
171 : {
172 1 : bIsImageSelected = pMark->GetMarkedSdrObj()->GetObjIdentifier() == OBJ_GRAF;
173 : }
174 : }
175 : }
176 :
177 2 : if ( rMEvt.IsLeft() )
178 : {
179 2 : FrameView* pFrameView = mpViewShell->GetFrameView();
180 :
181 2 : bool bOrtho = false;
182 :
183 2 : bool bRestricted = true;
184 :
185 2 : if (mpView->IsDragObj())
186 : {
187 : // object is dragged (move, resize,...)
188 0 : const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
189 :
190 0 : if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
191 : {
192 : // Move
193 0 : bRestricted = false;
194 : }
195 : }
196 :
197 : // #i33136#
198 2 : if(bRestricted && doConstructOrthogonal())
199 : {
200 : // Restrict movement:
201 : // rectangle->quadrat, ellipse->circle etc.
202 0 : bOrtho = !rMEvt.IsShift();
203 : }
204 : else
205 : {
206 2 : bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
207 : }
208 2 : if (!mpView->IsSnapEnabled())
209 0 : mpView->SetSnapEnabled(true);
210 :
211 2 : bool bSnapModPressed = rMEvt.IsMod1();
212 2 : if (mpView->IsOrtho() != bOrtho)
213 0 : mpView->SetOrtho(bOrtho);
214 :
215 2 : DoModifiers(rMEvt, bSnapModPressed);
216 :
217 2 : SdrPageView* pPV = 0;
218 2 : sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
219 :
220 : // look only for HelpLines when they are visible (!)
221 2 : bool bHelpLine(false);
222 2 : if(mpView->IsHlplVisible())
223 0 : bHelpLine = mpView->PickHelpLine(aMDPos, nHitLog, *mpWindow, nHelpLine, pPV);
224 2 : bool bHitHdl = (mpView->PickHandle(aMDPos) != NULL);
225 :
226 2 : if ( bHelpLine
227 0 : && !mpView->IsCreateObj()
228 2 : && ((mpView->GetEditMode() == SDREDITMODE_EDIT && !bHitHdl) || (rMEvt.IsShift() && bSnapModPressed)) )
229 : {
230 0 : mpWindow->CaptureMouse();
231 0 : mpView->BegDragHelpLine(nHelpLine, pPV);
232 0 : bDragHelpLine = mpView->IsDragHelpLine();
233 0 : bReturn = true;
234 : }
235 : }
236 2 : ForcePointer(&rMEvt);
237 :
238 2 : return bReturn;
239 : }
240 :
241 2 : bool FuDraw::MouseMove(const MouseEvent& rMEvt)
242 : {
243 2 : FrameView* pFrameView = mpViewShell->GetFrameView();
244 2 : Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() );
245 :
246 2 : bool bOrtho = false;
247 2 : bool bRestricted = true;
248 :
249 2 : if (mpView->IsDragObj())
250 : {
251 : // object is dragged (move, resize, ...)
252 2 : const SdrHdl* pHdl = mpView->GetDragStat().GetHdl();
253 :
254 2 : if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl()))
255 : {
256 : // Move
257 0 : bRestricted = false;
258 : }
259 : }
260 :
261 2 : if (mpView->IsAction())
262 : {
263 : // #i33136# and fdo#88339
264 2 : if(bRestricted && (bIsImageSelected || doConstructOrthogonal()))
265 : {
266 : // Scale proportionally by default:
267 : // rectangle->quadrat, ellipse->circle, Images etc.
268 0 : bOrtho = !rMEvt.IsShift();
269 : }
270 : else
271 : {
272 2 : bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho();
273 : }
274 :
275 2 : bool bSnapModPressed = rMEvt.IsMod2();
276 2 : mpView->SetDragWithCopy(rMEvt.IsMod1() && pFrameView->IsDragWithCopy());
277 :
278 2 : if (mpView->IsOrtho() != bOrtho)
279 0 : mpView->SetOrtho(bOrtho);
280 2 : DoModifiers(rMEvt, bSnapModPressed);
281 :
282 :
283 2 : if ( mpView->IsDragHelpLine() )
284 0 : mpView->MovDragHelpLine(aPos);
285 : }
286 :
287 2 : bool bReturn = mpView->MouseMove(rMEvt, mpWindow);
288 :
289 2 : if (mpView->IsAction())
290 : {
291 : // Because the flag set back if necessary in MouseMove
292 2 : if (mpView->IsOrtho() != bOrtho)
293 0 : mpView->SetOrtho(bOrtho);
294 : }
295 :
296 2 : ForcePointer(&rMEvt);
297 :
298 2 : return bReturn;
299 : }
300 :
301 1 : bool FuDraw::MouseButtonUp(const MouseEvent& rMEvt)
302 : {
303 1 : if (mpView && mpView->IsDragHelpLine())
304 0 : mpView->EndDragHelpLine();
305 :
306 1 : if ( bDragHelpLine )
307 : {
308 0 : Rectangle aOutputArea(Point(0,0), mpWindow->GetOutputSizePixel());
309 :
310 0 : if (mpView && !aOutputArea.IsInside(rMEvt.GetPosPixel()))
311 0 : mpView->GetSdrPageView()->DeleteHelpLine(nHelpLine);
312 :
313 0 : mpWindow->ReleaseMouse();
314 : }
315 :
316 1 : if (mpView)
317 : {
318 1 : FrameView* pFrameView = mpViewShell->GetFrameView();
319 1 : mpView->SetOrtho( pFrameView->IsOrtho() );
320 1 : mpView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() );
321 1 : mpView->SetSnapEnabled(true);
322 1 : mpView->SetCreate1stPointAsCenter(false);
323 1 : mpView->SetResizeAtCenter(false);
324 1 : mpView->SetDragWithCopy(pFrameView->IsDragWithCopy());
325 1 : mpView->SetGridSnap(pFrameView->IsGridSnap());
326 1 : mpView->SetBordSnap(pFrameView->IsBordSnap());
327 1 : mpView->SetHlplSnap(pFrameView->IsHlplSnap());
328 1 : mpView->SetOFrmSnap(pFrameView->IsOFrmSnap());
329 1 : mpView->SetOPntSnap(pFrameView->IsOPntSnap());
330 1 : mpView->SetOConSnap(pFrameView->IsOConSnap());
331 : }
332 :
333 1 : bIsInDragMode = false;
334 1 : ForcePointer(&rMEvt);
335 1 : FuPoor::MouseButtonUp(rMEvt);
336 :
337 1 : return false;
338 : }
339 :
340 : /**
341 : * Process keyboard input
342 : * @returns sal_True if a KeyEvent is being processed, sal_False otherwise
343 : */
344 0 : bool FuDraw::KeyInput(const KeyEvent& rKEvt)
345 : {
346 0 : bool bReturn = false;
347 :
348 0 : switch ( rKEvt.GetKeyCode().GetCode() )
349 : {
350 : case KEY_ESCAPE:
351 : {
352 0 : bReturn = FuDraw::cancel();
353 : }
354 0 : break;
355 :
356 : case KEY_DELETE:
357 : case KEY_BACKSPACE:
358 : {
359 0 : if (!mpDocSh->IsReadOnly())
360 : {
361 0 : if (mpView->IsPresObjSelected(false, true, false, true))
362 : {
363 0 : ScopedVclPtr<InfoBox>::Create(mpWindow, SD_RESSTR(STR_ACTION_NOTPOSSIBLE) )->Execute();
364 : }
365 : else
366 : {
367 : /* If IP-Client active, we reset the pointer to the OLE- and
368 : to the old graphic object of SdClient. With this, we
369 : avoid the restoration of an no more existing object in
370 : ::SelectionHasChanged after deletion. All other OLE
371 : objects are not affected. */
372 : OSL_ASSERT (mpViewShell->GetViewShell()!=NULL);
373 : Client* pIPClient = static_cast<Client*>(
374 0 : mpViewShell->GetViewShell()->GetIPClient());
375 0 : if (pIPClient && pIPClient->IsObjectInPlaceActive())
376 0 : pIPClient->SetSdrGrafObj(NULL);
377 :
378 : // wait-mousepointer while deleting object
379 0 : WaitObject aWait( static_cast<vcl::Window*>(mpViewShell->GetActiveWindow()) );
380 : // delete object
381 0 : mpView->DeleteMarked();
382 : }
383 : }
384 0 : bReturn = true;
385 : }
386 0 : break;
387 :
388 : case KEY_TAB:
389 : {
390 0 : vcl::KeyCode aCode = rKEvt.GetKeyCode();
391 :
392 0 : if ( !aCode.IsMod1() && !aCode.IsMod2() )
393 : {
394 : // Moved next line which was a bugfix itself into
395 : // the scope which really does the object selection travel
396 : // and thus is allowed to call SelectionHasChanged().
397 :
398 : // Switch to FuSelect.
399 : mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
400 : SID_OBJECT_SELECT,
401 0 : SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
402 :
403 : // changeover to the next object
404 0 : if(!mpView->MarkNextObj( !aCode.IsShift() ))
405 : {
406 : //If there is only one object, don't do the UnmarkAlllObj() & MarkNextObj().
407 0 : if ( mpView->GetMarkableObjCount() > 1 && mpView->AreObjectsMarked() )
408 : {
409 : // No next object: go over open end and get first from
410 : // the other side
411 0 : mpView->UnmarkAllObj();
412 0 : mpView->MarkNextObj(!aCode.IsShift());
413 : }
414 : }
415 :
416 0 : if(mpView->AreObjectsMarked())
417 0 : mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
418 :
419 0 : bReturn = true;
420 : }
421 : }
422 0 : break;
423 :
424 : case KEY_END:
425 : {
426 0 : vcl::KeyCode aCode = rKEvt.GetKeyCode();
427 :
428 0 : if ( aCode.IsMod1() )
429 : {
430 : // mark last object
431 0 : mpView->UnmarkAllObj();
432 0 : mpView->MarkNextObj(false);
433 :
434 0 : if(mpView->AreObjectsMarked())
435 0 : mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
436 :
437 0 : bReturn = true;
438 : }
439 : }
440 0 : break;
441 :
442 : case KEY_HOME:
443 : {
444 0 : vcl::KeyCode aCode = rKEvt.GetKeyCode();
445 :
446 0 : if ( aCode.IsMod1() )
447 : {
448 : // mark first object
449 0 : mpView->UnmarkAllObj();
450 0 : mpView->MarkNextObj(true);
451 :
452 0 : if(mpView->AreObjectsMarked())
453 0 : mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow);
454 :
455 0 : bReturn = true;
456 : }
457 : }
458 0 : break;
459 :
460 : default:
461 0 : break;
462 : }
463 :
464 0 : if (!bReturn)
465 : {
466 0 : bReturn = FuPoor::KeyInput(rKEvt);
467 : }
468 : else
469 : {
470 0 : mpWindow->ReleaseMouse();
471 : }
472 :
473 0 : return bReturn;
474 : }
475 :
476 340 : void FuDraw::Activate()
477 : {
478 340 : FuPoor::Activate();
479 340 : ForcePointer();
480 340 : }
481 :
482 299 : void FuDraw::Deactivate()
483 : {
484 299 : FuPoor::Deactivate();
485 299 : }
486 :
487 : /**
488 : * Toggle mouse-pointer
489 : */
490 349 : void FuDraw::ForcePointer(const MouseEvent* pMEvt)
491 : {
492 349 : Point aPnt;
493 349 : sal_uInt16 nModifier = 0;
494 349 : bool bLeftDown = false;
495 349 : bool bDefPointer = true;
496 :
497 349 : if (pMEvt)
498 : {
499 9 : aPnt = mpWindow->PixelToLogic(pMEvt->GetPosPixel());
500 9 : nModifier = pMEvt->GetModifier();
501 9 : bLeftDown = pMEvt->IsLeft();
502 : }
503 : else
504 : {
505 340 : aPnt = mpWindow->PixelToLogic(mpWindow->GetPointerPosPixel());
506 : }
507 :
508 349 : if (mpView->IsDragObj())
509 : {
510 5 : if (SD_MOD()->GetWaterCan() && !mpView->PickHandle(aPnt))
511 : {
512 : // water can mode
513 0 : bDefPointer = false;
514 0 : mpWindow->SetPointer(Pointer(PointerStyle::Fill));
515 : }
516 : }
517 : else
518 : {
519 344 : SdrHdl* pHdl = mpView->PickHandle(aPnt);
520 :
521 344 : if (SD_MOD()->GetWaterCan() && !pHdl)
522 : {
523 : // water can mode
524 0 : bDefPointer = false;
525 0 : mpWindow->SetPointer(Pointer(PointerStyle::Fill));
526 : }
527 686 : else if (!pHdl &&
528 342 : mpViewShell->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()))
529 : {
530 : // pipette mode
531 0 : SfxChildWindow* pWnd = mpViewShell->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId());
532 0 : SvxBmpMask* pMask = pWnd ? static_cast<SvxBmpMask*>(pWnd->GetWindow()) : NULL;
533 0 : if (pMask && pMask->IsEyedropping())
534 : {
535 0 : bDefPointer = false;
536 0 : mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
537 : }
538 : }
539 344 : else if (!mpView->IsAction())
540 : {
541 344 : SdrObject* pObj = NULL;
542 344 : SdrPageView* pPV = NULL;
543 344 : SdrViewEvent aVEvt;
544 344 : SdrHitKind eHit = SDRHIT_NONE;
545 344 : SdrDragMode eDragMode = mpView->GetDragMode();
546 :
547 344 : if (pMEvt)
548 : {
549 4 : eHit = mpView->PickAnything(*pMEvt, SdrMouseEventKind::MOVE, aVEvt);
550 : }
551 :
552 344 : if ((eDragMode == SDRDRAG_ROTATE) && (eHit == SDRHIT_MARKEDOBJECT))
553 : {
554 : // The goal of this request is show always the rotation-arrow for 3D-objects at rotation-modus
555 : // Independent of the settings at Extras->Optionen->Grafik "Objekte immer verschieben"
556 : // 2D-objects acquit in an other way. Otherwise, the rotation of 3d-objects around any axises
557 : // wouldn't be possible per default.
558 0 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
559 0 : SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj();
560 0 : if ((pObject->ISA(E3dObject)) && (rMarkList.GetMarkCount() == 1))
561 : {
562 0 : mpWindow->SetPointer(Pointer(PointerStyle::Rotate));
563 0 : bDefPointer = false; // Otherwise it'll be calles Joes routine and the mousepointer will reconfigurate again
564 : }
565 : }
566 :
567 344 : if (eHit == SDRHIT_NONE)
568 : {
569 : // found nothing -> look after at the masterpage
570 340 : mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER);
571 : }
572 4 : else if (eHit == SDRHIT_UNMARKEDOBJECT)
573 : {
574 1 : pObj = aVEvt.pObj;
575 : }
576 3 : else if (eHit == SDRHIT_TEXTEDITOBJ && this->ISA(FuSelection))
577 : {
578 0 : sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier();
579 :
580 0 : if ( nSdrObjKind != OBJ_TEXT &&
581 0 : nSdrObjKind != OBJ_TITLETEXT &&
582 0 : nSdrObjKind != OBJ_OUTLINETEXT &&
583 0 : aVEvt.pObj->IsEmptyPresObj() )
584 : {
585 0 : pObj = NULL;
586 0 : bDefPointer = false;
587 0 : mpWindow->SetPointer(Pointer(PointerStyle::Arrow));
588 : }
589 : }
590 :
591 344 : if (pObj && pMEvt && !pMEvt->IsMod2() && this->ISA(FuSelection))
592 : {
593 : // test for animation or ImageMap
594 1 : bDefPointer = !SetPointer(pObj, aPnt);
595 :
596 1 : if (bDefPointer && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
597 : {
598 : // take a glance into the group
599 0 : if (mpView->PickObj(aPnt, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP))
600 0 : bDefPointer = !SetPointer(pObj, aPnt);
601 : }
602 344 : }
603 : }
604 : }
605 :
606 349 : if (bDefPointer)
607 : {
608 349 : mpWindow->SetPointer(mpView->GetPreferredPointer(
609 698 : aPnt, mpWindow, nModifier, bLeftDown));
610 : }
611 349 : }
612 :
613 : /**
614 : * Set cursor for animaton or imagemap
615 : */
616 1 : bool FuDraw::SetPointer(SdrObject* pObj, const Point& rPos)
617 : {
618 1 : bool bSet = false;
619 :
620 2 : bool bAnimationInfo = !mpDocSh->ISA(GraphicDocShell) &&
621 2 : mpDoc->GetAnimationInfo(pObj);
622 :
623 1 : bool bImageMapInfo = false;
624 :
625 1 : if (!bAnimationInfo)
626 0 : bImageMapInfo = mpDoc->GetIMapInfo(pObj) != nullptr;
627 :
628 1 : if (bAnimationInfo || bImageMapInfo)
629 : {
630 1 : const SetOfByte* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers();
631 1 : sal_uInt16 nHitLog(sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()));
632 1 : long n2HitLog(nHitLog * 2);
633 1 : Point aHitPosR(rPos);
634 1 : Point aHitPosL(rPos);
635 1 : Point aHitPosT(rPos);
636 1 : Point aHitPosB(rPos);
637 :
638 1 : aHitPosR.X() += n2HitLog;
639 1 : aHitPosL.X() -= n2HitLog;
640 1 : aHitPosT.Y() += n2HitLog;
641 1 : aHitPosB.Y() -= n2HitLog;
642 :
643 2 : if ( !pObj->IsClosedObj() ||
644 2 : ( SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
645 2 : SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
646 1 : SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false) &&
647 0 : SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, false)))
648 : {
649 : /**********************************************************
650 : * hit inside the object (without margin) or open object
651 : ********************************************************/
652 :
653 0 : if (bAnimationInfo)
654 : {
655 : /******************************************************
656 : * Click-Action
657 : ******************************************************/
658 0 : SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
659 :
660 0 : if ((mpView->ISA(DrawView) &&
661 0 : (pInfo->meClickAction == presentation::ClickAction_BOOKMARK ||
662 0 : pInfo->meClickAction == presentation::ClickAction_DOCUMENT ||
663 0 : pInfo->meClickAction == presentation::ClickAction_PREVPAGE ||
664 0 : pInfo->meClickAction == presentation::ClickAction_NEXTPAGE ||
665 0 : pInfo->meClickAction == presentation::ClickAction_FIRSTPAGE ||
666 0 : pInfo->meClickAction == presentation::ClickAction_LASTPAGE ||
667 0 : pInfo->meClickAction == presentation::ClickAction_VERB ||
668 0 : pInfo->meClickAction == presentation::ClickAction_PROGRAM ||
669 0 : pInfo->meClickAction == presentation::ClickAction_MACRO ||
670 0 : pInfo->meClickAction == presentation::ClickAction_SOUND))
671 0 : ||
672 0 : (mpView->ISA(DrawView) &&
673 0 : SlideShow::IsRunning( mpViewShell->GetViewShellBase() ) &&
674 0 : (pInfo->meClickAction == presentation::ClickAction_VANISH ||
675 0 : pInfo->meClickAction == presentation::ClickAction_INVISIBLE ||
676 0 : pInfo->meClickAction == presentation::ClickAction_STOPPRESENTATION ||
677 0 : (pInfo->mbActive &&
678 0 : ( pInfo->meEffect != presentation::AnimationEffect_NONE ||
679 0 : pInfo->meTextEffect != presentation::AnimationEffect_NONE )))))
680 : {
681 : // Animation object
682 0 : bSet = true;
683 0 : mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
684 : }
685 : }
686 0 : else if (bImageMapInfo &&
687 0 : mpDoc->GetHitIMapObject(pObj, rPos, *mpWindow))
688 : {
689 : /******************************************************
690 : * ImageMap
691 : ******************************************************/
692 0 : bSet = true;
693 0 : mpWindow->SetPointer(Pointer(PointerStyle::RefHand));
694 : }
695 : }
696 : }
697 :
698 1 : return bSet;
699 : }
700 :
701 : /**
702 : * Response of doubleclick
703 : */
704 0 : void FuDraw::DoubleClick(const MouseEvent& rMEvt)
705 : {
706 0 : sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() );
707 :
708 0 : if ( mpView->AreObjectsMarked() )
709 : {
710 0 : const SdrMarkList& rMarkList = mpView->GetMarkedObjectList();
711 :
712 0 : if (rMarkList.GetMarkCount() == 1)
713 : {
714 0 : SdrMark* pMark = rMarkList.GetMark(0);
715 0 : SdrObject* pObj = pMark->GetMarkedSdrObj();
716 :
717 0 : sal_uInt32 nInv = pObj->GetObjInventor();
718 0 : sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier();
719 :
720 0 : if (nInv == SdrInventor && nSdrObjKind == OBJ_OLE2)
721 : {
722 0 : DrawDocShell* pDocSh = mpDoc->GetDocSh();
723 :
724 0 : if ( !pDocSh->IsUIActive() )
725 : {
726 : /**********************************************************
727 : * activate OLE-object
728 : **********************************************************/
729 0 : mpViewShell->ActivateObject( static_cast<SdrOle2Obj*>(pObj), 0);
730 0 : }
731 : }
732 0 : else if (nInv == SdrInventor && nSdrObjKind == OBJ_GRAF && pObj->IsEmptyPresObj() )
733 : {
734 : mpViewShell->GetViewFrame()->
735 : GetDispatcher()->Execute( SID_INSERT_GRAPHIC,
736 0 : SfxCallMode::ASYNCHRON | SfxCallMode::RECORD );
737 : }
738 0 : else if ( ( pObj->ISA(SdrTextObj) || pObj->ISA(SdrObjGroup) ) &&
739 0 : !SD_MOD()->GetWaterCan() &&
740 0 : mpViewShell->GetFrameView()->IsDoubleClickTextEdit() &&
741 0 : !mpDocSh->IsReadOnly())
742 : {
743 0 : SfxUInt16Item aItem(SID_TEXTEDIT, 2);
744 : mpViewShell->GetViewFrame()->GetDispatcher()->
745 : Execute(SID_TEXTEDIT, SfxCallMode::ASYNCHRON |
746 0 : SfxCallMode::RECORD, &aItem, 0L);
747 : }
748 0 : else if (nInv == SdrInventor && nSdrObjKind == OBJ_GRUP)
749 : {
750 : // hit group -> select subobject
751 0 : mpView->UnMarkAll();
752 0 : mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), true);
753 : }
754 : }
755 : }
756 : else
757 0 : mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
758 0 : }
759 :
760 0 : bool FuDraw::RequestHelp(const HelpEvent& rHEvt)
761 : {
762 0 : bool bReturn = false;
763 :
764 0 : if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled())
765 : {
766 0 : SdrViewEvent aVEvt;
767 :
768 0 : MouseEvent aMEvt(mpWindow->GetPointerPosPixel(), 1, MouseEventModifiers::NONE, MOUSE_LEFT);
769 :
770 0 : SdrHitKind eHit = mpView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt);
771 :
772 0 : SdrObject* pObj = aVEvt.pObj;
773 :
774 0 : if (eHit != SDRHIT_NONE && pObj != NULL)
775 : {
776 0 : Point aPosPixel = rHEvt.GetMousePosPixel();
777 :
778 0 : bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
779 :
780 0 : if (!bReturn && (pObj->ISA(SdrObjGroup) || pObj->ISA(E3dPolyScene)))
781 : {
782 : // take a glance into the group
783 0 : SdrPageView* pPV = NULL;
784 :
785 0 : Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(aPosPixel)));
786 :
787 0 : if (mpView->PickObj(aPos, mpView->getHitTolLog(), pObj, pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP))
788 0 : bReturn = SetHelpText(pObj, aPosPixel, aVEvt);
789 : }
790 0 : }
791 : }
792 :
793 0 : if (!bReturn)
794 : {
795 0 : bReturn = FuPoor::RequestHelp(rHEvt);
796 : }
797 :
798 0 : return bReturn;
799 : }
800 :
801 0 : bool FuDraw::SetHelpText(SdrObject* pObj, const Point& rPosPixel, const SdrViewEvent& rVEvt)
802 : {
803 0 : bool bSet = false;
804 0 : OUString aHelpText;
805 0 : Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(rPosPixel)));
806 :
807 : // URL for IMapObject underneath pointer is help text
808 0 : if ( mpDoc->GetIMapInfo(pObj) )
809 : {
810 0 : IMapObject* pIMapObj = mpDoc->GetHitIMapObject(pObj, aPos, *mpWindow );
811 :
812 0 : if ( pIMapObj )
813 : {
814 : // show name
815 0 : aHelpText = pIMapObj->GetAltText();
816 :
817 0 : if (aHelpText.isEmpty())
818 : {
819 : // show url if no name is available
820 0 : aHelpText = INetURLObject::decode( pIMapObj->GetURL(), INetURLObject::DECODE_WITH_CHARSET );
821 : }
822 : }
823 : }
824 0 : else if (!mpDocSh->ISA(GraphicDocShell) && mpDoc->GetAnimationInfo(pObj))
825 : {
826 0 : SdAnimationInfo* pInfo = mpDoc->GetAnimationInfo(pObj);
827 :
828 0 : switch (pInfo->meClickAction)
829 : {
830 : case presentation::ClickAction_PREVPAGE:
831 : {
832 : // jump to the prior page
833 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_PREVPAGE);
834 : }
835 0 : break;
836 :
837 : case presentation::ClickAction_NEXTPAGE:
838 : {
839 : // jump to the next page
840 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_NEXTPAGE);
841 : }
842 0 : break;
843 :
844 : case presentation::ClickAction_FIRSTPAGE:
845 : {
846 : // jump to the first page
847 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_FIRSTPAGE);
848 : }
849 0 : break;
850 :
851 : case presentation::ClickAction_LASTPAGE:
852 : {
853 : // jump to the last page
854 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_LASTPAGE);
855 : }
856 0 : break;
857 :
858 : case presentation::ClickAction_BOOKMARK:
859 : {
860 : // jump to object/page
861 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_BOOKMARK);
862 0 : aHelpText += ": ";
863 0 : aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
864 : }
865 0 : break;
866 :
867 : case presentation::ClickAction_DOCUMENT:
868 : {
869 : // jump to document (object/page)
870 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_DOCUMENT);
871 0 : aHelpText += ": ";
872 0 : aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
873 : }
874 0 : break;
875 :
876 : case presentation::ClickAction_PROGRAM:
877 : {
878 : // execute program
879 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_PROGRAM);
880 0 : aHelpText += ": ";
881 0 : aHelpText += INetURLObject::decode( pInfo->GetBookmark(), INetURLObject::DECODE_WITH_CHARSET );
882 : }
883 0 : break;
884 :
885 : case presentation::ClickAction_MACRO:
886 : {
887 : // execute program
888 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_MACRO);
889 0 : aHelpText += ": ";
890 :
891 0 : if ( SfxApplication::IsXScriptURL( pInfo->GetBookmark() ) )
892 : {
893 0 : aHelpText += pInfo->GetBookmark();
894 : }
895 : else
896 : {
897 0 : OUString sBookmark( pInfo->GetBookmark() );
898 0 : aHelpText += sBookmark.getToken( 2, '.' );
899 0 : aHelpText += ".";
900 0 : aHelpText += sBookmark.getToken( 1, '.' );
901 0 : aHelpText += ".";
902 0 : aHelpText += sBookmark.getToken( 0, '.' );
903 : }
904 : }
905 0 : break;
906 :
907 : case presentation::ClickAction_SOUND:
908 : {
909 : // play-back sound
910 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_SOUND);
911 : }
912 0 : break;
913 :
914 : case presentation::ClickAction_VERB:
915 : {
916 : // execute OLE-verb
917 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_VERB);
918 : }
919 0 : break;
920 :
921 : case presentation::ClickAction_STOPPRESENTATION:
922 : {
923 : // quit presentation
924 0 : aHelpText = SD_RESSTR(STR_CLICK_ACTION_STOPPRESENTATION);
925 : }
926 0 : break;
927 : default:
928 0 : break;
929 : }
930 : }
931 0 : else if (rVEvt.pURLField)
932 : {
933 : /**************************************************************
934 : * URL-Field
935 : **************************************************************/
936 0 : aHelpText = INetURLObject::decode( rVEvt.pURLField->GetURL(), INetURLObject::DECODE_WITH_CHARSET );
937 : }
938 :
939 0 : if (!aHelpText.isEmpty())
940 : {
941 0 : bSet = true;
942 0 : Rectangle aLogicPix = mpWindow->LogicToPixel(pObj->GetLogicRect());
943 0 : Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()),
944 0 : mpWindow->OutputToScreenPixel(aLogicPix.BottomRight()));
945 :
946 0 : if (Help::IsBalloonHelpEnabled())
947 0 : Help::ShowBalloon( static_cast<vcl::Window*>(mpWindow), rPosPixel, aScreenRect, aHelpText);
948 0 : else if (Help::IsQuickHelpEnabled())
949 0 : Help::ShowQuickHelp( static_cast<vcl::Window*>(mpWindow), aScreenRect, aHelpText);
950 : }
951 :
952 0 : return bSet;
953 : }
954 :
955 : /** is called when the current function should be aborted. <p>
956 : This is used when a function gets a KEY_ESCAPE but can also
957 : be called directly.
958 :
959 : @returns true if a active function was aborted
960 : */
961 0 : bool FuDraw::cancel()
962 : {
963 0 : bool bReturn = false;
964 :
965 0 : if ( mpView->IsAction() )
966 : {
967 0 : mpView->BrkAction();
968 0 : bReturn = true;
969 : }
970 0 : else if ( mpView->IsTextEdit() )
971 : {
972 0 : mpView->SdrEndTextEdit();
973 0 : bReturn = true;
974 :
975 0 : SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings();
976 0 : rBindings.Invalidate( SID_PARASPACE_INCREASE );
977 0 : rBindings.Invalidate( SID_PARASPACE_DECREASE );
978 : }
979 0 : else if ( mpView->AreObjectsMarked() )
980 : {
981 0 : const SdrHdlList& rHdlList = mpView->GetHdlList();
982 0 : SdrHdl* pHdl = rHdlList.GetFocusHdl();
983 :
984 0 : if(pHdl)
985 : {
986 0 : ((SdrHdlList&)rHdlList).ResetFocusHdl();
987 : }
988 : else
989 : {
990 0 : mpView->UnmarkAll();
991 : }
992 :
993 : // Switch to FuSelect.
994 : mpViewShell->GetViewFrame()->GetDispatcher()->Execute(
995 : SID_OBJECT_SELECT,
996 0 : SfxCallMode::ASYNCHRON | SfxCallMode::RECORD);
997 :
998 0 : bReturn = true;
999 : }
1000 :
1001 0 : return bReturn;
1002 : }
1003 :
1004 66 : } // end of namespace sd
1005 :
1006 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|