File: | home/maarten/src/libreoffice/core/sd/source/ui/func/fudraw.cxx |
Warning: | line 469, column 9 Called C++ object pointer is null |
Press '?' to see keyboard shortcuts
Keyboard shortcuts:
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 <sal/config.h> | |||
21 | ||||
22 | #include <vcl/svapp.hxx> | |||
23 | #include <vcl/ptrstyle.hxx> | |||
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 <svx/ImageMapInfo.hxx> | |||
32 | #include <sfx2/dispatch.hxx> | |||
33 | #include <sfx2/bindings.hxx> | |||
34 | #include <sfx2/sfxhelp.hxx> | |||
35 | #include <svx/svdpagv.hxx> | |||
36 | #include <vcl/imapobj.hxx> | |||
37 | #include <svx/svxids.hrc> | |||
38 | #include <svx/obj3d.hxx> | |||
39 | #include <svx/scene3d.hxx> | |||
40 | #include <sfx2/viewfrm.hxx> | |||
41 | ||||
42 | #include <strings.hrc> | |||
43 | ||||
44 | ||||
45 | #include <sdmod.hxx> | |||
46 | #include <fudraw.hxx> | |||
47 | #include <ViewShell.hxx> | |||
48 | #include <FrameView.hxx> | |||
49 | #include <View.hxx> | |||
50 | #include <Window.hxx> | |||
51 | #include <drawdoc.hxx> | |||
52 | #include <DrawDocShell.hxx> | |||
53 | #include <sdresid.hxx> | |||
54 | #include <fusel.hxx> | |||
55 | #include <vcl/weld.hxx> | |||
56 | #include <svx/sdrhittesthelper.hxx> | |||
57 | ||||
58 | using namespace ::com::sun::star; | |||
59 | ||||
60 | namespace sd { | |||
61 | ||||
62 | ||||
63 | /** | |||
64 | * Base-class for all drawmodul-specific functions | |||
65 | */ | |||
66 | FuDraw::FuDraw(ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, | |||
67 | SdDrawDocument* pDoc, SfxRequest& rReq) | |||
68 | : FuPoor(pViewSh, pWin, pView, pDoc, rReq) | |||
69 | , aNewPointer(PointerStyle::Arrow) | |||
70 | , aOldPointer(PointerStyle::Arrow) | |||
71 | , bMBDown(false) | |||
72 | , bDragHelpLine(false) | |||
73 | , nHelpLine(0) | |||
74 | , bPermanent(false) | |||
75 | { | |||
76 | } | |||
77 | ||||
78 | FuDraw::~FuDraw() | |||
79 | { | |||
80 | mpView->BrkAction(); | |||
81 | } | |||
82 | ||||
83 | ||||
84 | /** | |||
85 | * Code shared by MouseButtonDown and MouseMove | |||
86 | */ | |||
87 | void FuDraw::DoModifiers(const MouseEvent& rMEvt, bool bSnapModPressed) | |||
88 | { | |||
89 | FrameView* pFrameView = mpViewShell->GetFrameView(); | |||
90 | bool bGridSnap = pFrameView->IsGridSnap(); | |||
91 | bGridSnap = (bSnapModPressed != bGridSnap); | |||
92 | ||||
93 | if (mpView->IsGridSnap() != bGridSnap) | |||
94 | mpView->SetGridSnap(bGridSnap); | |||
95 | ||||
96 | bool bBordSnap = pFrameView->IsBordSnap(); | |||
97 | bBordSnap = (bSnapModPressed != bBordSnap); | |||
98 | ||||
99 | if (mpView->IsBordSnap() != bBordSnap) | |||
100 | mpView->SetBordSnap(bBordSnap); | |||
101 | ||||
102 | bool bHlplSnap = pFrameView->IsHlplSnap(); | |||
103 | bHlplSnap = (bSnapModPressed != bHlplSnap); | |||
104 | ||||
105 | if (mpView->IsHlplSnap() != bHlplSnap) | |||
106 | mpView->SetHlplSnap(bHlplSnap); | |||
107 | ||||
108 | bool bOFrmSnap = pFrameView->IsOFrmSnap(); | |||
109 | bOFrmSnap = (bSnapModPressed != bOFrmSnap); | |||
110 | ||||
111 | if (mpView->IsOFrmSnap() != bOFrmSnap) | |||
112 | mpView->SetOFrmSnap(bOFrmSnap); | |||
113 | ||||
114 | bool bOPntSnap = pFrameView->IsOPntSnap(); | |||
115 | bOPntSnap = (bSnapModPressed != bOPntSnap); | |||
116 | ||||
117 | if (mpView->IsOPntSnap() != bOPntSnap) | |||
118 | mpView->SetOPntSnap(bOPntSnap); | |||
119 | ||||
120 | bool bOConSnap = pFrameView->IsOConSnap(); | |||
121 | bOConSnap = (bSnapModPressed != bOConSnap); | |||
122 | ||||
123 | if (mpView->IsOConSnap() != bOConSnap) | |||
124 | mpView->SetOConSnap(bOConSnap); | |||
125 | ||||
126 | bool bAngleSnap = rMEvt.IsShift() == !pFrameView->IsAngleSnapEnabled(); | |||
127 | ||||
128 | if (mpView->IsAngleSnapEnabled() != bAngleSnap) | |||
129 | mpView->SetAngleSnapEnabled(bAngleSnap); | |||
130 | ||||
131 | bool bCenter = rMEvt.IsMod2(); | |||
132 | ||||
133 | if ( mpView->IsCreate1stPointAsCenter() != bCenter || | |||
134 | mpView->IsResizeAtCenter() != bCenter ) | |||
135 | { | |||
136 | mpView->SetCreate1stPointAsCenter(bCenter); | |||
137 | mpView->SetResizeAtCenter(bCenter); | |||
138 | } | |||
139 | } | |||
140 | ||||
141 | ||||
142 | bool FuDraw::MouseButtonDown(const MouseEvent& rMEvt) | |||
143 | { | |||
144 | // remember button state for creation of own MouseEvents | |||
145 | SetMouseButtonCode(rMEvt.GetButtons()); | |||
146 | ||||
147 | bool bReturn = false; | |||
148 | bDragHelpLine = false; | |||
149 | aMDPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() ); | |||
150 | ||||
151 | if ( rMEvt.IsLeft() ) | |||
152 | { | |||
153 | FrameView* pFrameView = mpViewShell->GetFrameView(); | |||
154 | ||||
155 | bool bOrtho = false; | |||
156 | ||||
157 | bool bRestricted = true; | |||
158 | ||||
159 | if (mpView->IsDragObj()) | |||
160 | { | |||
161 | // object is dragged (move, resize,...) | |||
162 | const SdrHdl* pHdl = mpView->GetDragStat().GetHdl(); | |||
163 | ||||
164 | if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl())) | |||
165 | { | |||
166 | // Move | |||
167 | bRestricted = false; | |||
168 | } | |||
169 | } | |||
170 | ||||
171 | // #i33136# | |||
172 | if(bRestricted && doConstructOrthogonal()) | |||
173 | { | |||
174 | // Restrict movement: | |||
175 | // rectangle->quadrat, ellipse->circle etc. | |||
176 | bOrtho = !rMEvt.IsShift(); | |||
177 | } | |||
178 | else | |||
179 | { | |||
180 | bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho(); | |||
181 | } | |||
182 | if (!mpView->IsSnapEnabled()) | |||
183 | mpView->SetSnapEnabled(true); | |||
184 | ||||
185 | bool bSnapModPressed = rMEvt.IsMod1(); | |||
186 | if (mpView->IsOrtho() != bOrtho) | |||
187 | mpView->SetOrtho(bOrtho); | |||
188 | ||||
189 | DoModifiers(rMEvt, bSnapModPressed); | |||
190 | ||||
191 | SdrPageView* pPV = nullptr; | |||
192 | sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); | |||
193 | ||||
194 | // look only for HelpLines when they are visible (!) | |||
195 | bool bHelpLine(false); | |||
196 | if(mpView->IsHlplVisible()) | |||
197 | bHelpLine = mpView->PickHelpLine(aMDPos, nHitLog, *mpWindow, nHelpLine, pPV); | |||
198 | bool bHitHdl = (mpView->PickHandle(aMDPos) != nullptr); | |||
199 | ||||
200 | if ( bHelpLine | |||
201 | && !mpView->IsCreateObj() | |||
202 | && ((mpView->GetEditMode() == SdrViewEditMode::Edit && !bHitHdl) || (rMEvt.IsShift() && bSnapModPressed)) ) | |||
203 | { | |||
204 | mpWindow->CaptureMouse(); | |||
205 | mpView->BegDragHelpLine(nHelpLine, pPV); | |||
206 | bDragHelpLine = mpView->IsDragHelpLine(); | |||
207 | bReturn = true; | |||
208 | } | |||
209 | } | |||
210 | ForcePointer(&rMEvt); | |||
211 | ||||
212 | return bReturn; | |||
213 | } | |||
214 | ||||
215 | bool FuDraw::MouseMove(const MouseEvent& rMEvt) | |||
216 | { | |||
217 | FrameView* pFrameView = mpViewShell->GetFrameView(); | |||
218 | Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() ); | |||
219 | ||||
220 | bool bOrtho = false; | |||
221 | bool bRestricted = true; | |||
222 | ||||
223 | if (mpView->IsDragObj()) | |||
224 | { | |||
225 | // object is dragged (move, resize, ...) | |||
226 | const SdrHdl* pHdl = mpView->GetDragStat().GetHdl(); | |||
227 | ||||
228 | if (!pHdl || (!pHdl->IsCornerHdl() && !pHdl->IsVertexHdl())) | |||
229 | { | |||
230 | // Move | |||
231 | bRestricted = false; | |||
232 | } | |||
233 | } | |||
234 | ||||
235 | if (mpView->IsAction()) | |||
236 | { | |||
237 | // #i33136# and fdo#88339 | |||
238 | if(bRestricted && doConstructOrthogonal()) | |||
239 | { | |||
240 | // Scale proportionally by default: | |||
241 | // rectangle->quadrat, ellipse->circle, Images etc. | |||
242 | bOrtho = !rMEvt.IsShift(); | |||
243 | } | |||
244 | else | |||
245 | { | |||
246 | bOrtho = rMEvt.IsShift() != pFrameView->IsOrtho(); | |||
247 | } | |||
248 | ||||
249 | bool bSnapModPressed = rMEvt.IsMod2(); | |||
250 | mpView->SetDragWithCopy(rMEvt.IsMod1() && pFrameView->IsDragWithCopy()); | |||
251 | ||||
252 | if (mpView->IsOrtho() != bOrtho) | |||
253 | mpView->SetOrtho(bOrtho); | |||
254 | DoModifiers(rMEvt, bSnapModPressed); | |||
255 | ||||
256 | ||||
257 | if ( mpView->IsDragHelpLine() ) | |||
258 | mpView->MovDragHelpLine(aPos); | |||
259 | } | |||
260 | ||||
261 | bool bReturn = mpView->MouseMove(rMEvt, mpWindow); | |||
262 | ||||
263 | if (mpView->IsAction()) | |||
264 | { | |||
265 | // Because the flag set back if necessary in MouseMove | |||
266 | if (mpView->IsOrtho() != bOrtho) | |||
267 | mpView->SetOrtho(bOrtho); | |||
268 | } | |||
269 | ||||
270 | ForcePointer(&rMEvt); | |||
271 | ||||
272 | return bReturn; | |||
273 | } | |||
274 | ||||
275 | bool FuDraw::MouseButtonUp(const MouseEvent& rMEvt) | |||
276 | { | |||
277 | if (mpView && mpView->IsDragHelpLine()) | |||
| ||||
278 | mpView->EndDragHelpLine(); | |||
279 | ||||
280 | if ( bDragHelpLine ) | |||
281 | { | |||
282 | ::tools::Rectangle aOutputArea(Point(0,0), mpWindow->GetOutputSizePixel()); | |||
283 | ||||
284 | if (mpView && !aOutputArea.IsInside(rMEvt.GetPosPixel())) | |||
285 | mpView->GetSdrPageView()->DeleteHelpLine(nHelpLine); | |||
286 | ||||
287 | mpWindow->ReleaseMouse(); | |||
288 | } | |||
289 | ||||
290 | if (mpView
| |||
291 | { | |||
292 | FrameView* pFrameView = mpViewShell->GetFrameView(); | |||
293 | mpView->SetOrtho( pFrameView->IsOrtho() ); | |||
294 | mpView->SetAngleSnapEnabled( pFrameView->IsAngleSnapEnabled() ); | |||
295 | mpView->SetSnapEnabled(true); | |||
296 | mpView->SetCreate1stPointAsCenter(false); | |||
297 | mpView->SetResizeAtCenter(false); | |||
298 | mpView->SetDragWithCopy(pFrameView->IsDragWithCopy()); | |||
299 | mpView->SetGridSnap(pFrameView->IsGridSnap()); | |||
300 | mpView->SetBordSnap(pFrameView->IsBordSnap()); | |||
301 | mpView->SetHlplSnap(pFrameView->IsHlplSnap()); | |||
302 | mpView->SetOFrmSnap(pFrameView->IsOFrmSnap()); | |||
303 | mpView->SetOPntSnap(pFrameView->IsOPntSnap()); | |||
304 | mpView->SetOConSnap(pFrameView->IsOConSnap()); | |||
305 | } | |||
306 | ||||
307 | bIsInDragMode = false; | |||
308 | ForcePointer(&rMEvt); | |||
309 | FuPoor::MouseButtonUp(rMEvt); | |||
310 | ||||
311 | return false; | |||
312 | } | |||
313 | ||||
314 | /** | |||
315 | * Process keyboard input | |||
316 | * @returns sal_True if a KeyEvent is being processed, sal_False otherwise | |||
317 | */ | |||
318 | bool FuDraw::KeyInput(const KeyEvent& rKEvt) | |||
319 | { | |||
320 | bool bReturn = false; | |||
321 | ||||
322 | switch ( rKEvt.GetKeyCode().GetCode() ) | |||
323 | { | |||
324 | case KEY_ESCAPE: | |||
325 | { | |||
326 | bReturn = FuDraw::cancel(); | |||
327 | } | |||
328 | break; | |||
329 | ||||
330 | case KEY_DELETE: | |||
331 | case KEY_BACKSPACE: | |||
332 | { | |||
333 | if (!mpDocSh->IsReadOnly()) | |||
334 | { | |||
335 | if (mpView->IsPresObjSelected(false, true, false, true)) | |||
336 | { | |||
337 | std::unique_ptr<weld::MessageDialog> xInfoBox(Application::CreateMessageDialog(mpWindow->GetFrameWeld(), | |||
338 | VclMessageType::Info, VclButtonsType::Ok, | |||
339 | SdResId(STR_ACTION_NOTPOSSIBLEreinterpret_cast<char const *>("STR_ACTION_NOTPOSSIBLE" "\004" u8"This function cannot be run \nwith the selected objects." )))); | |||
340 | xInfoBox->run(); | |||
341 | } | |||
342 | else | |||
343 | { | |||
344 | // wait-mousepointer while deleting object | |||
345 | weld::WaitObject aWait(mpViewShell->GetFrameWeld()); | |||
346 | // delete object | |||
347 | mpView->DeleteMarked(); | |||
348 | } | |||
349 | } | |||
350 | bReturn = true; | |||
351 | } | |||
352 | break; | |||
353 | ||||
354 | case KEY_TAB: | |||
355 | { | |||
356 | vcl::KeyCode aCode = rKEvt.GetKeyCode(); | |||
357 | ||||
358 | if ( !aCode.IsMod1() && !aCode.IsMod2() ) | |||
359 | { | |||
360 | // Moved next line which was a bugfix itself into | |||
361 | // the scope which really does the object selection travel | |||
362 | // and thus is allowed to call SelectionHasChanged(). | |||
363 | ||||
364 | // Switch to FuSelect. | |||
365 | mpViewShell->GetViewFrame()->GetDispatcher()->Execute( | |||
366 | SID_OBJECT_SELECT( 10000 + 128 ), | |||
367 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); | |||
368 | ||||
369 | // changeover to the next object | |||
370 | if(!mpView->MarkNextObj( !aCode.IsShift() )) | |||
371 | { | |||
372 | //If there is only one object, don't do the UnmarkAllObj() & MarkNextObj(). | |||
373 | if ( mpView->HasMultipleMarkableObjects() && mpView->AreObjectsMarked() ) | |||
374 | { | |||
375 | // No next object: go over open end and get first from | |||
376 | // the other side | |||
377 | mpView->UnmarkAllObj(); | |||
378 | mpView->MarkNextObj(!aCode.IsShift()); | |||
379 | } | |||
380 | } | |||
381 | ||||
382 | if(mpView->AreObjectsMarked()) | |||
383 | mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow); | |||
384 | ||||
385 | bReturn = true; | |||
386 | } | |||
387 | } | |||
388 | break; | |||
389 | ||||
390 | case KEY_END: | |||
391 | { | |||
392 | vcl::KeyCode aCode = rKEvt.GetKeyCode(); | |||
393 | ||||
394 | if ( aCode.IsMod1() ) | |||
395 | { | |||
396 | // mark last object | |||
397 | mpView->UnmarkAllObj(); | |||
398 | mpView->MarkNextObj(); | |||
399 | ||||
400 | if(mpView->AreObjectsMarked()) | |||
401 | mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow); | |||
402 | ||||
403 | bReturn = true; | |||
404 | } | |||
405 | } | |||
406 | break; | |||
407 | ||||
408 | case KEY_HOME: | |||
409 | { | |||
410 | vcl::KeyCode aCode = rKEvt.GetKeyCode(); | |||
411 | ||||
412 | if ( aCode.IsMod1() ) | |||
413 | { | |||
414 | // mark first object | |||
415 | mpView->UnmarkAllObj(); | |||
416 | mpView->MarkNextObj(true); | |||
417 | ||||
418 | if(mpView->AreObjectsMarked()) | |||
419 | mpView->MakeVisible(mpView->GetAllMarkedRect(), *mpWindow); | |||
420 | ||||
421 | bReturn = true; | |||
422 | } | |||
423 | } | |||
424 | break; | |||
425 | ||||
426 | default: | |||
427 | break; | |||
428 | } | |||
429 | ||||
430 | if (!bReturn) | |||
431 | { | |||
432 | bReturn = FuPoor::KeyInput(rKEvt); | |||
433 | } | |||
434 | else | |||
435 | { | |||
436 | mpWindow->ReleaseMouse(); | |||
437 | } | |||
438 | ||||
439 | return bReturn; | |||
440 | } | |||
441 | ||||
442 | void FuDraw::Activate() | |||
443 | { | |||
444 | FuPoor::Activate(); | |||
445 | ForcePointer(); | |||
446 | } | |||
447 | ||||
448 | /** | |||
449 | * Toggle mouse-pointer | |||
450 | */ | |||
451 | void FuDraw::ForcePointer(const MouseEvent* pMEvt) | |||
452 | { | |||
453 | Point aPnt; | |||
454 | sal_uInt16 nModifier = 0; | |||
455 | bool bLeftDown = false; | |||
456 | bool bDefPointer = true; | |||
457 | ||||
458 | if (pMEvt
| |||
459 | { | |||
460 | aPnt = mpWindow->PixelToLogic(pMEvt->GetPosPixel()); | |||
461 | nModifier = pMEvt->GetModifier(); | |||
462 | bLeftDown = pMEvt->IsLeft(); | |||
463 | } | |||
464 | else | |||
465 | { | |||
466 | aPnt = mpWindow->PixelToLogic(mpWindow->GetPointerPosPixel()); | |||
467 | } | |||
468 | ||||
469 | if (mpView->IsDragObj()) | |||
| ||||
470 | { | |||
471 | if (SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->GetWaterCan() && !mpView->PickHandle(aPnt)) | |||
472 | { | |||
473 | // water can mode | |||
474 | bDefPointer = false; | |||
475 | mpWindow->SetPointer(PointerStyle::Fill); | |||
476 | } | |||
477 | } | |||
478 | else | |||
479 | { | |||
480 | SdrHdl* pHdl = mpView->PickHandle(aPnt); | |||
481 | ||||
482 | if (SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->GetWaterCan() && !pHdl) | |||
483 | { | |||
484 | // water can mode | |||
485 | bDefPointer = false; | |||
486 | mpWindow->SetPointer(PointerStyle::Fill); | |||
487 | } | |||
488 | else if (!pHdl && | |||
489 | mpViewShell->GetViewFrame()->HasChildWindow(SvxBmpMaskChildWindow::GetChildWindowId())) | |||
490 | { | |||
491 | // pipette mode | |||
492 | SfxChildWindow* pWnd = mpViewShell->GetViewFrame()->GetChildWindow(SvxBmpMaskChildWindow::GetChildWindowId()); | |||
493 | SvxBmpMask* pMask = pWnd ? static_cast<SvxBmpMask*>(pWnd->GetWindow()) : nullptr; | |||
494 | if (pMask && pMask->IsEyedropping()) | |||
495 | { | |||
496 | bDefPointer = false; | |||
497 | mpWindow->SetPointer(PointerStyle::RefHand); | |||
498 | } | |||
499 | } | |||
500 | else if (!mpView->IsAction()) | |||
501 | { | |||
502 | SdrObject* pObj = nullptr; | |||
503 | SdrPageView* pPV = nullptr; | |||
504 | SdrViewEvent aVEvt; | |||
505 | SdrHitKind eHit = SdrHitKind::NONE; | |||
506 | SdrDragMode eDragMode = mpView->GetDragMode(); | |||
507 | ||||
508 | if (pMEvt) | |||
509 | { | |||
510 | eHit = mpView->PickAnything(*pMEvt, SdrMouseEventKind::MOVE, aVEvt); | |||
511 | } | |||
512 | ||||
513 | if ((eDragMode == SdrDragMode::Rotate) && (eHit == SdrHitKind::MarkedObject)) | |||
514 | { | |||
515 | // The goal of this request is show always the rotation arrow for 3D-objects at rotation mode | |||
516 | // Independent of the settings at Tools->Options->Draw "Objects always moveable" | |||
517 | // 2D-objects acquit in another way. Otherwise, the rotation of 3d-objects around any axes | |||
518 | // wouldn't be possible per default. | |||
519 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); | |||
520 | SdrObject* pObject = rMarkList.GetMark(0)->GetMarkedSdrObj(); | |||
521 | if ((dynamic_cast<const E3dObject* >(pObject) != nullptr) && (rMarkList.GetMarkCount() == 1)) | |||
522 | { | |||
523 | mpWindow->SetPointer(PointerStyle::Rotate); | |||
524 | bDefPointer = false; // Otherwise it'll be called Joe's routine and the mousepointer will reconfigurate again | |||
525 | } | |||
526 | } | |||
527 | ||||
528 | if (eHit == SdrHitKind::NONE) | |||
529 | { | |||
530 | // found nothing -> look after at the masterpage | |||
531 | pObj = mpView->PickObj(aPnt, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER); | |||
532 | } | |||
533 | else if (eHit == SdrHitKind::UnmarkedObject) | |||
534 | { | |||
535 | pObj = aVEvt.pObj; | |||
536 | } | |||
537 | else if (eHit == SdrHitKind::TextEditObj && dynamic_cast< const FuSelection *>( this ) != nullptr) | |||
538 | { | |||
539 | sal_uInt16 nSdrObjKind = aVEvt.pObj->GetObjIdentifier(); | |||
540 | ||||
541 | if ( nSdrObjKind != OBJ_TEXT && | |||
542 | nSdrObjKind != OBJ_TITLETEXT && | |||
543 | nSdrObjKind != OBJ_OUTLINETEXT && | |||
544 | aVEvt.pObj->IsEmptyPresObj() ) | |||
545 | { | |||
546 | pObj = nullptr; | |||
547 | bDefPointer = false; | |||
548 | mpWindow->SetPointer(PointerStyle::Arrow); | |||
549 | } | |||
550 | } | |||
551 | ||||
552 | if (pObj && pMEvt && !pMEvt->IsMod2() | |||
553 | && dynamic_cast<const FuSelection*>(this) != nullptr) | |||
554 | { | |||
555 | // test for ImageMap | |||
556 | bDefPointer = !SetPointer(pObj, aPnt); | |||
557 | ||||
558 | if (bDefPointer | |||
559 | && (dynamic_cast<const SdrObjGroup*>(pObj) != nullptr | |||
560 | || dynamic_cast<const E3dScene*>(pObj) != nullptr)) | |||
561 | { | |||
562 | // take a glance into the group | |||
563 | pObj = mpView->PickObj(aPnt, mpView->getHitTolLog(), pPV, | |||
564 | SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP); | |||
565 | if (pObj) | |||
566 | bDefPointer = !SetPointer(pObj, aPnt); | |||
567 | } | |||
568 | } | |||
569 | } | |||
570 | } | |||
571 | ||||
572 | if (bDefPointer) | |||
573 | { | |||
574 | mpWindow->SetPointer(mpView->GetPreferredPointer( | |||
575 | aPnt, mpWindow, nModifier, bLeftDown)); | |||
576 | } | |||
577 | } | |||
578 | ||||
579 | /** | |||
580 | * Set cursor to pointer when in clickable area of an ImageMap | |||
581 | * | |||
582 | * @return True when pointer was set | |||
583 | */ | |||
584 | bool FuDraw::SetPointer(const SdrObject* pObj, const Point& rPos) | |||
585 | { | |||
586 | bool bImageMapInfo = SvxIMapInfo::GetIMapInfo(pObj) != nullptr; | |||
587 | ||||
588 | if (!bImageMapInfo) | |||
589 | return false; | |||
590 | ||||
591 | const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers(); | |||
592 | sal_uInt16 nHitLog(sal_uInt16(mpWindow->PixelToLogic(Size(HITPIX, 0)).Width())); | |||
593 | long n2HitLog(nHitLog * 2); | |||
594 | Point aHitPosR(rPos); | |||
595 | Point aHitPosL(rPos); | |||
596 | Point aHitPosT(rPos); | |||
597 | Point aHitPosB(rPos); | |||
598 | ||||
599 | aHitPosR.AdjustX(n2HitLog); | |||
600 | aHitPosL.AdjustX(-n2HitLog); | |||
601 | aHitPosT.AdjustY(n2HitLog); | |||
602 | aHitPosB.AdjustY(-n2HitLog); | |||
603 | ||||
604 | if (!pObj->IsClosedObj() | |||
605 | || (SdrObjectPrimitiveHit(*pObj, aHitPosR, nHitLog, *mpView->GetSdrPageView(), pVisiLayer, | |||
606 | false) | |||
607 | && SdrObjectPrimitiveHit(*pObj, aHitPosL, nHitLog, *mpView->GetSdrPageView(), | |||
608 | pVisiLayer, false) | |||
609 | && SdrObjectPrimitiveHit(*pObj, aHitPosT, nHitLog, *mpView->GetSdrPageView(), | |||
610 | pVisiLayer, false) | |||
611 | && SdrObjectPrimitiveHit(*pObj, aHitPosB, nHitLog, *mpView->GetSdrPageView(), | |||
612 | pVisiLayer, false))) | |||
613 | { | |||
614 | // hit inside the object (without margin) or open object | |||
615 | if (SvxIMapInfo::GetHitIMapObject(pObj, rPos)) | |||
616 | { | |||
617 | mpWindow->SetPointer(PointerStyle::RefHand); | |||
618 | return true; | |||
619 | } | |||
620 | } | |||
621 | ||||
622 | return false; | |||
623 | } | |||
624 | ||||
625 | /** | |||
626 | * Response of doubleclick | |||
627 | */ | |||
628 | void FuDraw::DoubleClick(const MouseEvent& rMEvt) | |||
629 | { | |||
630 | sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); | |||
631 | ||||
632 | if ( mpView->AreObjectsMarked() ) | |||
633 | { | |||
634 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); | |||
635 | ||||
636 | if (rMarkList.GetMarkCount() == 1) | |||
637 | { | |||
638 | SdrMark* pMark = rMarkList.GetMark(0); | |||
639 | SdrObject* pObj = pMark->GetMarkedSdrObj(); | |||
640 | ||||
641 | SdrInventor nInv = pObj->GetObjInventor(); | |||
642 | sal_uInt16 nSdrObjKind = pObj->GetObjIdentifier(); | |||
643 | ||||
644 | if (nInv == SdrInventor::Default && nSdrObjKind == OBJ_OLE2) | |||
645 | { | |||
646 | // activate OLE-object | |||
647 | SfxInt16Item aItem(SID_OBJECT(5000 + 575), 0); | |||
648 | mpViewShell->GetViewFrame()-> | |||
649 | GetDispatcher()->ExecuteList(SID_OBJECT(5000 + 575), | |||
650 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, | |||
651 | { &aItem }); | |||
652 | } | |||
653 | else if (nInv == SdrInventor::Default && nSdrObjKind == OBJ_GRAF && pObj->IsEmptyPresObj() ) | |||
654 | { | |||
655 | mpViewShell->GetViewFrame()-> | |||
656 | GetDispatcher()->Execute( SID_INSERT_GRAPHICTypedWhichId<SfxStringItem>( 10000 + 241 ), | |||
657 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD ); | |||
658 | } | |||
659 | else if ( ( dynamic_cast< const SdrTextObj *>( pObj ) != nullptr || dynamic_cast< const SdrObjGroup *>( pObj ) != nullptr ) && | |||
660 | !SD_MOD()( static_cast<SdModule*>(SfxApplication::GetModule(SfxToolsModule ::Draw)) )->GetWaterCan() && | |||
661 | mpViewShell->GetFrameView()->IsDoubleClickTextEdit() && | |||
662 | !mpDocSh->IsReadOnly()) | |||
663 | { | |||
664 | SfxUInt16Item aItem(SID_TEXTEDIT(27000 +76), 2); | |||
665 | mpViewShell->GetViewFrame()->GetDispatcher()->ExecuteList( | |||
666 | SID_TEXTEDIT(27000 +76), | |||
667 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, | |||
668 | { &aItem }); | |||
669 | } | |||
670 | else if (nInv == SdrInventor::Default && nSdrObjKind == OBJ_GRUP) | |||
671 | { | |||
672 | // hit group -> select subobject | |||
673 | mpView->UnMarkAll(); | |||
674 | mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift(), true); | |||
675 | } | |||
676 | } | |||
677 | } | |||
678 | else | |||
679 | mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT( 10000 + 128 ), SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); | |||
680 | } | |||
681 | ||||
682 | bool FuDraw::RequestHelp(const HelpEvent& rHEvt) | |||
683 | { | |||
684 | bool bReturn = false; | |||
685 | ||||
686 | if (Help::IsBalloonHelpEnabled() || Help::IsQuickHelpEnabled()) | |||
687 | { | |||
688 | SdrViewEvent aVEvt; | |||
689 | ||||
690 | MouseEvent aMEvt(mpWindow->GetPointerPosPixel(), 1, MouseEventModifiers::NONE, MOUSE_LEFT(sal_uInt16(0x0001))); | |||
691 | ||||
692 | SdrHitKind eHit = mpView->PickAnything(aMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); | |||
693 | ||||
694 | SdrObject* pObj = aVEvt.pObj; | |||
695 | ||||
696 | if (eHit != SdrHitKind::NONE && pObj != nullptr) | |||
697 | { | |||
698 | Point aPosPixel = rHEvt.GetMousePosPixel(); | |||
699 | ||||
700 | bReturn = SetHelpText(pObj, aPosPixel, aVEvt); | |||
701 | ||||
702 | if (!bReturn && (dynamic_cast< const SdrObjGroup *>( pObj ) != nullptr || dynamic_cast< const E3dScene* >(pObj) != nullptr)) | |||
703 | { | |||
704 | // take a glance into the group | |||
705 | SdrPageView* pPV = nullptr; | |||
706 | ||||
707 | Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(aPosPixel))); | |||
708 | ||||
709 | pObj = mpView->PickObj(aPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::DEEP); | |||
710 | if (pObj) | |||
711 | bReturn = SetHelpText(pObj, aPosPixel, aVEvt); | |||
712 | } | |||
713 | } | |||
714 | } | |||
715 | ||||
716 | if (!bReturn) | |||
717 | { | |||
718 | bReturn = FuPoor::RequestHelp(rHEvt); | |||
719 | } | |||
720 | ||||
721 | if (!bReturn) | |||
722 | bReturn = mpView->RequestHelp(rHEvt); | |||
723 | ||||
724 | return bReturn; | |||
725 | } | |||
726 | ||||
727 | bool FuDraw::SetHelpText(const SdrObject* pObj, const Point& rPosPixel, const SdrViewEvent& rVEvt) | |||
728 | { | |||
729 | OUString aHelpText; | |||
730 | Point aPos(mpWindow->PixelToLogic(mpWindow->ScreenToOutputPixel(rPosPixel))); | |||
731 | IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject(pObj, aPos); | |||
732 | ||||
733 | if (!rVEvt.pURLField && !pIMapObj) | |||
734 | return false; | |||
735 | ||||
736 | OUString aURL; | |||
737 | if (rVEvt.pURLField) | |||
738 | aURL = INetURLObject::decode(rVEvt.pURLField->GetURL(), | |||
739 | INetURLObject::DecodeMechanism::WithCharset); | |||
740 | else if (pIMapObj) | |||
741 | { | |||
742 | aURL = pIMapObj->GetAltText() + | |||
743 | " (" + | |||
744 | INetURLObject::decode(pIMapObj->GetURL(), | |||
745 | INetURLObject::DecodeMechanism::WithCharset) + | |||
746 | ")"; | |||
747 | } | |||
748 | else | |||
749 | return false; | |||
750 | ||||
751 | aHelpText = SfxHelp::GetURLHelpText(aURL); | |||
752 | ||||
753 | if (aHelpText.isEmpty()) | |||
754 | return false; | |||
755 | ||||
756 | ::tools::Rectangle aLogicPix = mpWindow->LogicToPixel(pObj->GetLogicRect()); | |||
757 | ::tools::Rectangle aScreenRect(mpWindow->OutputToScreenPixel(aLogicPix.TopLeft()), | |||
758 | mpWindow->OutputToScreenPixel(aLogicPix.BottomRight())); | |||
759 | ||||
760 | if (Help::IsBalloonHelpEnabled()) | |||
761 | Help::ShowBalloon( static_cast<vcl::Window*>(mpWindow), rPosPixel, aScreenRect, aHelpText); | |||
762 | else if (Help::IsQuickHelpEnabled()) | |||
763 | Help::ShowQuickHelp( static_cast<vcl::Window*>(mpWindow), aScreenRect, aHelpText); | |||
764 | ||||
765 | return true; | |||
766 | } | |||
767 | ||||
768 | /** is called when the current function should be aborted. <p> | |||
769 | This is used when a function gets a KEY_ESCAPE but can also | |||
770 | be called directly. | |||
771 | ||||
772 | @returns true if an active function was aborted | |||
773 | */ | |||
774 | bool FuDraw::cancel() | |||
775 | { | |||
776 | bool bReturn = false; | |||
777 | ||||
778 | if ( mpView->IsAction() ) | |||
779 | { | |||
780 | mpView->BrkAction(); | |||
781 | bReturn = true; | |||
782 | } | |||
783 | else if ( mpView->IsTextEdit() ) | |||
784 | { | |||
785 | mpView->SdrEndTextEdit(); | |||
786 | bReturn = true; | |||
787 | ||||
788 | SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings(); | |||
789 | rBindings.Invalidate( SID_DEC_INDENT( 10000 + 461 ) ); | |||
790 | rBindings.Invalidate( SID_INC_INDENT( 10000 + 462 ) ); | |||
791 | rBindings.Invalidate( SID_PARASPACE_INCREASE( 10000 + 1145 ) ); | |||
792 | rBindings.Invalidate( SID_PARASPACE_DECREASE( 10000 + 1146 ) ); | |||
793 | } | |||
794 | else if ( mpView->AreObjectsMarked() ) | |||
795 | { | |||
796 | const SdrHdlList& rHdlList = mpView->GetHdlList(); | |||
797 | SdrHdl* pHdl = rHdlList.GetFocusHdl(); | |||
798 | ||||
799 | if(pHdl) | |||
800 | { | |||
801 | const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl(); | |||
802 | } | |||
803 | else | |||
804 | { | |||
805 | mpView->UnmarkAll(); | |||
806 | } | |||
807 | ||||
808 | // Switch to FuSelect. | |||
809 | mpViewShell->GetViewFrame()->GetDispatcher()->Execute( | |||
810 | SID_OBJECT_SELECT( 10000 + 128 ), | |||
811 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); | |||
812 | ||||
813 | bReturn = true; | |||
814 | } | |||
815 | ||||
816 | return bReturn; | |||
817 | } | |||
818 | ||||
819 | } // end of namespace sd | |||
820 | ||||
821 | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |