/src/libreoffice/sd/source/ui/func/fusel.cxx
Line | Count | Source |
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 <fusel.hxx> |
21 | | #include <svx/svddrgmt.hxx> |
22 | | #include <svx/svdpagv.hxx> |
23 | | #include <svx/svdopage.hxx> |
24 | | #include <svx/svdogrp.hxx> |
25 | | #include <svx/scene3d.hxx> |
26 | | #include <vcl/imapobj.hxx> |
27 | | #include <unotools/securityoptions.hxx> |
28 | | #include <svx/svxids.hrc> |
29 | | #include <svx/xfillit0.hxx> |
30 | | #include <svx/ImageMapInfo.hxx> |
31 | | #include <sfx2/viewfrm.hxx> |
32 | | #include <svl/stritem.hxx> |
33 | | #include <svl/intitem.hxx> |
34 | | #include <sfx2/dispatch.hxx> |
35 | | #include <sfx2/docfile.hxx> |
36 | | #include <editeng/flditem.hxx> |
37 | | |
38 | | #include <svx/svdotable.hxx> |
39 | | |
40 | | #include <app.hrc> |
41 | | |
42 | | #include <sdmod.hxx> |
43 | | #include <DrawDocShell.hxx> |
44 | | #include <stlpool.hxx> |
45 | | #include <fudraw.hxx> |
46 | | #include <ViewShell.hxx> |
47 | | #include <ViewShellBase.hxx> |
48 | | #include <FrameView.hxx> |
49 | | #include <View.hxx> |
50 | | #include <Window.hxx> |
51 | | #include <drawdoc.hxx> |
52 | | #include <DrawViewShell.hxx> |
53 | | #include <ToolBarManager.hxx> |
54 | | #include <Client.hxx> |
55 | | #include <annotationmanager.hxx> |
56 | | |
57 | | #include <svx/svdundo.hxx> |
58 | | |
59 | | #include <svx/sdrhittesthelper.hxx> |
60 | | #include <svx/diagram/DiagramHelper_svx.hxx> |
61 | | #include <svx/annotation/ObjectAnnotationData.hxx> |
62 | | |
63 | | #include <LibreOfficeKit/LibreOfficeKitEnums.h> |
64 | | #include <comphelper/lok.hxx> |
65 | | #include <svl/cryptosign.hxx> |
66 | | |
67 | | using namespace ::com::sun::star; |
68 | | |
69 | | namespace sd { |
70 | | |
71 | | FuSelection::FuSelection ( |
72 | | ViewShell& rViewSh, |
73 | | ::sd::Window* pWin, |
74 | | ::sd::View* pView, |
75 | | SdDrawDocument& rDoc, |
76 | | SfxRequest& rReq) |
77 | 0 | : FuDraw(rViewSh, pWin, pView, rDoc, rReq), |
78 | 0 | bTempRotation(false), |
79 | 0 | bSelectionChanged(false), |
80 | 0 | pHdl(nullptr), |
81 | 0 | bSuppressChangesOfSelection(false), |
82 | 0 | bMirrorSide0(false), |
83 | 0 | nEditMode(SID_BEZIER_MOVE), |
84 | 0 | pWaterCanCandidate(nullptr) |
85 | | //Add Shift+UP/DOWN/LEFT/RIGHT key to move the position of insert point, |
86 | | //and SHIFT+ENTER key to decide the position and draw the new insert point |
87 | 0 | ,bBeginInsertPoint(false), |
88 | 0 | oldPoint(0,0) |
89 | 0 | ,bMovedToCenterPoint(false) |
90 | 0 | { |
91 | 0 | } |
92 | | |
93 | | rtl::Reference<FuPoor> FuSelection::Create( ViewShell& rViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument& rDoc, SfxRequest& rReq ) |
94 | 0 | { |
95 | 0 | rtl::Reference<FuPoor> xFunc( new FuSelection( rViewSh, pWin, pView, rDoc, rReq ) ); |
96 | 0 | xFunc->DoExecute(rReq); |
97 | 0 | return xFunc; |
98 | 0 | } |
99 | | |
100 | | void FuSelection::DoExecute( SfxRequest& rReq ) |
101 | 0 | { |
102 | 0 | FuDraw::DoExecute( rReq ); |
103 | | |
104 | | // Select object bar |
105 | 0 | SelectionHasChanged(); |
106 | 0 | } |
107 | | |
108 | | FuSelection::~FuSelection() |
109 | 0 | { |
110 | 0 | mpView->UnmarkAllPoints(); |
111 | 0 | mpView->ResetCreationActive(); |
112 | |
|
113 | 0 | if ( mpView->GetDragMode() != SdrDragMode::Move ) |
114 | 0 | { |
115 | 0 | mpView->SetDragMode(SdrDragMode::Move); |
116 | 0 | } |
117 | 0 | } |
118 | | |
119 | | namespace { |
120 | 0 | bool lcl_followHyperlinkAllowed(const MouseEvent& rMEvt) { |
121 | 0 | if (!rMEvt.IsMod1() && SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink)) |
122 | 0 | return false; |
123 | 0 | if (rMEvt.IsMod1() && !SvtSecurityOptions::IsOptionSet(SvtSecurityOptions::EOption::CtrlClickHyperlink)) |
124 | 0 | return false; |
125 | 0 | return true; |
126 | 0 | } |
127 | | } |
128 | | |
129 | | bool FuSelection::MouseButtonDown(const MouseEvent& rMEvt) |
130 | 0 | { |
131 | 0 | pHdl = nullptr; |
132 | 0 | bool bReturn = FuDraw::MouseButtonDown(rMEvt); |
133 | 0 | bool bWaterCan = SdModule::get()->GetWaterCan(); |
134 | 0 | const bool bReadOnly = mpDocSh->IsReadOnly(); |
135 | | // When the right mouse button is pressed then only select objects |
136 | | // (and deselect others) as a preparation for showing the context |
137 | | // menu. |
138 | 0 | const bool bSelectionOnly = rMEvt.IsRight(); |
139 | |
|
140 | 0 | bMBDown = true; |
141 | 0 | bSelectionChanged = false; |
142 | |
|
143 | 0 | if ( mpView->IsAction() ) |
144 | 0 | { |
145 | 0 | if ( rMEvt.IsRight() ) |
146 | 0 | mpView->BckAction(); |
147 | 0 | return true; |
148 | 0 | } |
149 | | |
150 | 0 | sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() ); |
151 | 0 | sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); |
152 | |
|
153 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
154 | 0 | { |
155 | | // When tiled rendering, we always work in logic units, use the non-pixel constants. |
156 | 0 | nDrgLog = DRGLOG; |
157 | 0 | nHitLog = HITLOG; |
158 | 0 | } |
159 | | |
160 | | // The following code is executed for right clicks as well as for left |
161 | | // clicks in order to modify the selection for the right button as a |
162 | | // preparation for the context menu. The functions BegMarkObject() and |
163 | | // BegDragObject(), however, are not called for right clicks because a) |
164 | | // it makes no sense and b) to have IsAction() return sal_False when called |
165 | | // from Command() which is a prerequisite for the context menu. |
166 | 0 | if ((rMEvt.IsLeft() || rMEvt.IsRight()) |
167 | 0 | && !mpView->IsAction() |
168 | 0 | && (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints())) |
169 | 0 | { |
170 | | /****************************************************************** |
171 | | * NO BEZIER_EDITOR |
172 | | ******************************************************************/ |
173 | 0 | mpWindow->CaptureMouse(); |
174 | 0 | pHdl = mpView->PickHandle(aMDPos); |
175 | |
|
176 | 0 | Degree100 nAngle0 = GetAngle(aMDPos - mpView->GetRef1()); |
177 | 0 | nAngle0 -= 27000_deg100; |
178 | 0 | nAngle0 = NormAngle36000(nAngle0); |
179 | 0 | bMirrorSide0 = nAngle0 < 18000_deg100; |
180 | |
|
181 | 0 | if (!pHdl && mpView->Is3DRotationCreationActive()) |
182 | 0 | { |
183 | | /****************************************************************** |
184 | | * If 3D-rotation bodies are about to be created, |
185 | | * end creation now. |
186 | | ******************************************************************/ |
187 | 0 | bSuppressChangesOfSelection = true; |
188 | 0 | mpWindow->EnterWait(); |
189 | 0 | mpView->End3DCreation(); |
190 | 0 | bSuppressChangesOfSelection = false; |
191 | 0 | mpView->ResetCreationActive(); |
192 | 0 | mpWindow->LeaveWait(); |
193 | 0 | } |
194 | |
|
195 | 0 | bool bTextEdit = false; |
196 | 0 | SdrViewEvent aVEvt; |
197 | 0 | SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); |
198 | |
|
199 | 0 | if (eHit == SdrHitKind::TextEditObj && (mrViewShell.GetFrameView()->IsQuickEdit() || dynamic_cast< sdr::table::SdrTableObj* >(aVEvt.mpObj) != nullptr)) |
200 | 0 | { |
201 | 0 | bTextEdit = true; |
202 | 0 | } |
203 | | |
204 | | // When clicking into a URl field, also go to text edit mode (when not following the link) |
205 | 0 | if (!bTextEdit && eHit == SdrHitKind::UrlField && !rMEvt.IsMod2() && !lcl_followHyperlinkAllowed(rMEvt)) |
206 | 0 | bTextEdit = true; |
207 | |
|
208 | 0 | bool bPreventModify = mpDocSh->IsReadOnly(); |
209 | 0 | SfxViewShell* pViewShell = mrViewShell.GetViewShell(); |
210 | 0 | if (bPreventModify && pViewShell && pViewShell->GetSignPDFCertificate().Is()) |
211 | 0 | { |
212 | | // If the just added signature line shape is selected, allow moving / resizing it. |
213 | 0 | bPreventModify = false; |
214 | 0 | } |
215 | |
|
216 | 0 | if(!bTextEdit |
217 | 0 | && !bPreventModify |
218 | 0 | && ((mpView->IsMarkedHit(aMDPos, nHitLog) && !rMEvt.IsShift() && !rMEvt.IsMod2()) || pHdl != nullptr) |
219 | 0 | && (rMEvt.GetClicks() != 2) |
220 | 0 | ) |
221 | 0 | { |
222 | 0 | if (!pHdl && mpView->Is3DRotationCreationActive()) |
223 | 0 | { |
224 | | // Switch between 3D-rotation body -> selection |
225 | 0 | mpView->ResetCreationActive(); |
226 | 0 | } |
227 | 0 | else if (bWaterCan) |
228 | 0 | { |
229 | | // Remember the selected object for proper handling in |
230 | | // MouseButtonUp(). |
231 | 0 | pWaterCanCandidate = pickObject (aMDPos); |
232 | 0 | } |
233 | 0 | else |
234 | 0 | { |
235 | | // hit handle or marked object |
236 | 0 | bFirstMouseMove = true; |
237 | 0 | aDragTimer.Start(); |
238 | 0 | } |
239 | |
|
240 | 0 | if ( ! rMEvt.IsRight()) |
241 | 0 | if (mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog)) |
242 | 0 | mpView->GetDragMethod()->SetShiftPressed( rMEvt.IsShift() ); |
243 | 0 | bReturn = true; |
244 | 0 | } |
245 | 0 | else |
246 | 0 | { |
247 | 0 | SdrPageView* pPV = nullptr; |
248 | 0 | SdrObject* pObj = !rMEvt.IsMod2() ? mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::PICKMACRO) : nullptr; |
249 | 0 | if (pObj) |
250 | 0 | { |
251 | 0 | mpView->BegMacroObj(aMDPos, nHitLog, pObj, pPV, mpWindow); |
252 | 0 | bReturn = true; |
253 | 0 | } |
254 | 0 | else if ( bTextEdit ) |
255 | 0 | { |
256 | 0 | SdrObjKind nSdrObjKind = aVEvt.mpObj->GetObjIdentifier(); |
257 | |
|
258 | 0 | if (aVEvt.mpObj->GetObjInventor() == SdrInventor::Default && |
259 | 0 | (nSdrObjKind == SdrObjKind::Text || |
260 | 0 | nSdrObjKind == SdrObjKind::TitleText || |
261 | 0 | nSdrObjKind == SdrObjKind::OutlineText || |
262 | 0 | !aVEvt.mpObj->IsEmptyPresObj())) |
263 | 0 | { |
264 | | // Seamless Editing: branch to text input |
265 | 0 | if (!rMEvt.IsShift()) |
266 | 0 | mpView->UnmarkAll(); |
267 | |
|
268 | 0 | SfxUInt16Item aItem(SID_TEXTEDIT, 1); |
269 | 0 | mrViewShell.GetViewFrame()->GetDispatcher()-> |
270 | 0 | ExecuteList(SID_TEXTEDIT, |
271 | 0 | SfxCallMode::SYNCHRON | SfxCallMode::RECORD, |
272 | 0 | { &aItem }); |
273 | 0 | return bReturn; // CAUTION, due to the synchronous slot the object is deleted now |
274 | 0 | } |
275 | 0 | } |
276 | 0 | else if ( !rMEvt.IsMod2() && rMEvt.GetClicks() == 1 && |
277 | 0 | aVEvt.meEvent == SdrEventKind::ExecuteUrl ) |
278 | 0 | { |
279 | 0 | mpWindow->ReleaseMouse(); |
280 | |
|
281 | 0 | if (!aVEvt.mpURLField) |
282 | 0 | return true; |
283 | | |
284 | | // If tiled rendering, let client handles URL execution and early returns. |
285 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
286 | 0 | { |
287 | 0 | SfxViewShell& rSfxViewShell = mrViewShell.GetViewShellBase(); |
288 | 0 | rSfxViewShell.libreOfficeKitViewCallback(LOK_CALLBACK_HYPERLINK_CLICKED, aVEvt.mpURLField->GetURL().toUtf8()); |
289 | 0 | return true; |
290 | 0 | } |
291 | | |
292 | 0 | if (!lcl_followHyperlinkAllowed(rMEvt)) |
293 | 0 | return true; |
294 | | |
295 | 0 | SfxStringItem aStrItem(SID_FILE_NAME, aVEvt.mpURLField->GetURL()); |
296 | 0 | SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName()); |
297 | 0 | SfxBoolItem aBrowseItem( SID_BROWSE, true ); |
298 | 0 | SfxViewFrame* pFrame = mrViewShell.GetViewFrame(); |
299 | 0 | mpWindow->ReleaseMouse(); |
300 | |
|
301 | 0 | if (rMEvt.IsMod1()) |
302 | 0 | { |
303 | | // Open in new frame |
304 | 0 | pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC, |
305 | 0 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, |
306 | 0 | { &aStrItem, &aBrowseItem, &aReferer }); |
307 | 0 | } |
308 | 0 | else |
309 | 0 | { |
310 | | // Open in current frame |
311 | 0 | SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame); |
312 | 0 | pFrame->GetDispatcher()->ExecuteList(SID_OPENDOC, |
313 | 0 | SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, |
314 | 0 | { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer }); |
315 | 0 | } |
316 | |
|
317 | 0 | bReturn = true; |
318 | 0 | } |
319 | 0 | else if(!rMEvt.IsMod2() |
320 | 0 | && dynamic_cast< const DrawViewShell *>( &mrViewShell ) != nullptr |
321 | 0 | ) |
322 | 0 | { |
323 | 0 | pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER); |
324 | 0 | if (pObj) |
325 | 0 | { |
326 | | // Handle ImageMap click when not just selecting |
327 | 0 | if (!bSelectionOnly) |
328 | 0 | { |
329 | 0 | if (lcl_followHyperlinkAllowed(rMEvt)) |
330 | 0 | bReturn = HandleImageMapClick(pObj, aMDPos); |
331 | 0 | } |
332 | |
|
333 | 0 | if (!bReturn |
334 | 0 | && (dynamic_cast<const SdrObjGroup*>(pObj) != nullptr |
335 | 0 | || DynCastE3dScene(pObj))) |
336 | 0 | { |
337 | 0 | if (rMEvt.GetClicks() == 1) |
338 | 0 | { |
339 | | // Look into the group |
340 | 0 | pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, |
341 | 0 | SdrSearchOptions::ALSOONMASTER |
342 | 0 | | SdrSearchOptions::DEEP); |
343 | 0 | if (pObj && lcl_followHyperlinkAllowed(rMEvt)) |
344 | 0 | bReturn = HandleImageMapClick(pObj, aMDPos); |
345 | 0 | } |
346 | 0 | else if (!bReadOnly && rMEvt.GetClicks() == 2) |
347 | 0 | { |
348 | | // New: double click on selected Group object |
349 | | // enter group |
350 | 0 | if (!bSelectionOnly |
351 | 0 | && pObj->getSdrPageFromSdrObject() == pPV->GetPage()) |
352 | 0 | bReturn = pPV->EnterGroup(pObj); |
353 | 0 | } |
354 | 0 | } |
355 | 0 | else if (pObj->GetObjIdentifier() == SdrObjKind::Page) |
356 | 0 | { |
357 | 0 | if (rMEvt.GetClicks() == 2) |
358 | 0 | { |
359 | 0 | if (DrawViewShell* pDrawViewShell = dynamic_cast<DrawViewShell*>(&mrViewShell)) |
360 | 0 | { |
361 | 0 | SdrPageObj* pPageObj = static_cast<SdrPageObj*>(pObj); |
362 | 0 | sal_uInt16 nPageNum = (pPageObj->GetReferencedPage()->GetPageNum() - 1) / 2; |
363 | 0 | pDrawViewShell->SwitchPage(nPageNum); |
364 | 0 | } |
365 | 0 | } |
366 | 0 | } |
367 | 0 | } |
368 | | |
369 | | // #i71727# replaced else here with two possibilities, once the original else (!pObj) |
370 | | // and also ignoring the found object when it's on a masterpage |
371 | 0 | if(!pObj || (pObj->getSdrPageFromSdrObject() && pObj->getSdrPageFromSdrObject()->IsMasterPage())) |
372 | 0 | { |
373 | 0 | if(mpView->IsGroupEntered() && 2 == rMEvt.GetClicks()) |
374 | 0 | { |
375 | | // New: double click on empty space/on obj on MasterPage, leave group |
376 | 0 | mpView->LeaveOneGroup(); |
377 | 0 | bReturn = true; |
378 | 0 | } |
379 | 0 | } |
380 | 0 | } |
381 | | |
382 | 0 | if (!bReturn) |
383 | 0 | { |
384 | 0 | if (bWaterCan) |
385 | 0 | { |
386 | 0 | if ( ! (rMEvt.IsShift() || rMEvt.IsMod2())) |
387 | 0 | { |
388 | | // Find the object under the current mouse position |
389 | | // and store it for the MouseButtonUp() method to |
390 | | // evaluate. |
391 | 0 | pWaterCanCandidate = pickObject (aMDPos); |
392 | 0 | } |
393 | 0 | } |
394 | 0 | else |
395 | 0 | { |
396 | 0 | bReturn = true; |
397 | 0 | bool bDeactivateOLE = false; |
398 | |
|
399 | 0 | if ( !rMEvt.IsShift() && !rMEvt.IsMod2() ) |
400 | 0 | { |
401 | 0 | OSL_ASSERT (mrViewShell.GetViewShell()!=nullptr); |
402 | 0 | Client* pIPClient = static_cast<Client*>( |
403 | 0 | mrViewShell.GetViewShell()->GetIPClient()); |
404 | |
|
405 | 0 | if (pIPClient && pIPClient->IsObjectInPlaceActive()) |
406 | 0 | { |
407 | | // OLE-object gets deactivated in subsequent UnmarkAll() |
408 | 0 | bDeactivateOLE = true; |
409 | 0 | } |
410 | |
|
411 | 0 | mpView->UnmarkAll(); |
412 | 0 | } |
413 | |
|
414 | 0 | bool bMarked = false; |
415 | |
|
416 | 0 | if ( !rMEvt.IsMod1() && !bDeactivateOLE) |
417 | 0 | { |
418 | 0 | if ( rMEvt.IsMod2() ) |
419 | 0 | { |
420 | 0 | bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift() ); |
421 | 0 | } |
422 | 0 | else |
423 | 0 | { |
424 | 0 | bool bToggle = false; |
425 | |
|
426 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
427 | 0 | if (rMEvt.IsShift() && rMarkList.GetMarkCount() > 1) |
428 | 0 | { |
429 | | // No Toggle on single selection |
430 | 0 | bToggle = true; |
431 | 0 | } |
432 | |
|
433 | 0 | bMarked = mpView->MarkObj(aMDPos, nHitLog, bToggle); |
434 | 0 | } |
435 | 0 | } |
436 | |
|
437 | 0 | if( !bDeactivateOLE ) |
438 | 0 | { |
439 | 0 | if ( !bReadOnly && |
440 | 0 | bMarked && |
441 | 0 | (!rMEvt.IsShift() || mpView->IsMarkedHit(aMDPos, nHitLog))) |
442 | 0 | { |
443 | | /********************************************************** |
444 | | * Move object |
445 | | **********************************************************/ |
446 | 0 | aDragTimer.Start(); |
447 | |
|
448 | 0 | pHdl=mpView->PickHandle(aMDPos); |
449 | 0 | if ( ! rMEvt.IsRight()) |
450 | 0 | mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog); |
451 | |
|
452 | 0 | if (comphelper::LibreOfficeKit::isActive()) |
453 | 0 | { |
454 | 0 | if (pObj->GetObjIdentifier() == SdrObjKind::Page) |
455 | 0 | { |
456 | 0 | SdPage* pPage = mrViewShell.GetActualPage(); |
457 | 0 | if (pPage->IsCanvasPage()) |
458 | 0 | { |
459 | 0 | ::tools::JsonWriter jsonWriter; |
460 | 0 | jsonWriter.put("commandName", "ReshufflePagePopup"); |
461 | 0 | { |
462 | 0 | auto jsonState = jsonWriter.startNode("state"); |
463 | 0 | } |
464 | |
|
465 | 0 | OString aPayload = jsonWriter.finishAndGetAsOString(); |
466 | 0 | if (pViewShell) |
467 | 0 | pViewShell->libreOfficeKitViewCallback(LOK_CALLBACK_STATE_CHANGED, aPayload); |
468 | |
|
469 | 0 | } |
470 | 0 | } |
471 | 0 | } |
472 | 0 | } |
473 | 0 | else |
474 | 0 | { |
475 | | /********************************************************** |
476 | | * Select object |
477 | | **********************************************************/ |
478 | 0 | if ( ! rMEvt.IsRight()) |
479 | 0 | mpView->BegMarkObj(aMDPos); |
480 | 0 | } |
481 | 0 | } |
482 | |
|
483 | 0 | if( bMarked && bTempRotation && (nSlotId == SID_OBJECT_ROTATE) && !rMEvt.IsShift() && (rMEvt.GetClicks() != 2) ) |
484 | 0 | { |
485 | 0 | nSlotId = SID_OBJECT_SELECT; |
486 | 0 | Activate(); |
487 | 0 | } |
488 | 0 | } |
489 | 0 | } |
490 | 0 | } |
491 | 0 | } |
492 | 0 | else if ( !bReadOnly |
493 | 0 | && (rMEvt.IsLeft() || rMEvt.IsRight()) |
494 | 0 | && !mpView->IsAction()) |
495 | 0 | { |
496 | | /********************************************************************** |
497 | | * BEZIER-EDITOR |
498 | | **********************************************************************/ |
499 | 0 | mpWindow->CaptureMouse(); |
500 | 0 | SdrViewEvent aVEvt; |
501 | 0 | SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); |
502 | |
|
503 | 0 | if (eHit == SdrHitKind::Handle && aVEvt.mpHdl->GetKind() == SdrHdlKind::BezierWeight) |
504 | 0 | { |
505 | | /****************************************************************** |
506 | | * Drag Handle |
507 | | ******************************************************************/ |
508 | 0 | if ( ! rMEvt.IsRight()) |
509 | 0 | mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog); |
510 | 0 | } |
511 | 0 | else if (eHit == SdrHitKind::MarkedObject && nEditMode == SID_BEZIER_INSERT) |
512 | 0 | { |
513 | | /****************************************************************** |
514 | | * Insert gluepoint |
515 | | ******************************************************************/ |
516 | 0 | mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1()); |
517 | 0 | } |
518 | 0 | else if (eHit == SdrHitKind::MarkedObject && rMEvt.IsMod1()) |
519 | 0 | { |
520 | | /****************************************************************** |
521 | | * Select gluepoint |
522 | | ******************************************************************/ |
523 | 0 | if (!rMEvt.IsShift()) |
524 | 0 | mpView->UnmarkAllPoints(); |
525 | |
|
526 | 0 | if ( ! rMEvt.IsRight()) |
527 | 0 | mpView->BegMarkPoints(aMDPos); |
528 | 0 | } |
529 | 0 | else if (eHit == SdrHitKind::MarkedObject && !rMEvt.IsShift() && !rMEvt.IsMod2()) |
530 | 0 | { |
531 | | /****************************************************************** |
532 | | * Move object |
533 | | ******************************************************************/ |
534 | 0 | if ( ! rMEvt.IsRight()) |
535 | 0 | mpView->BegDragObj(aMDPos, nullptr, nullptr, nDrgLog); |
536 | 0 | } |
537 | 0 | else if (eHit == SdrHitKind::Handle) |
538 | 0 | { |
539 | | /****************************************************************** |
540 | | * Select gluepoint |
541 | | ******************************************************************/ |
542 | 0 | if (!mpView->IsPointMarked(*aVEvt.mpHdl) || rMEvt.IsShift()) |
543 | 0 | { |
544 | 0 | if (!rMEvt.IsShift()) |
545 | 0 | { |
546 | 0 | mpView->UnmarkAllPoints(); |
547 | 0 | pHdl = mpView->PickHandle(aMDPos); |
548 | 0 | } |
549 | 0 | else |
550 | 0 | { |
551 | 0 | if (mpView->IsPointMarked(*aVEvt.mpHdl)) |
552 | 0 | { |
553 | 0 | mpView->UnmarkPoint(*aVEvt.mpHdl); |
554 | 0 | pHdl = nullptr; |
555 | 0 | } |
556 | 0 | else |
557 | 0 | { |
558 | 0 | pHdl = mpView->PickHandle(aMDPos); |
559 | 0 | } |
560 | 0 | } |
561 | |
|
562 | 0 | if (pHdl) |
563 | 0 | { |
564 | 0 | mpView->MarkPoint(*pHdl); |
565 | 0 | if ( ! rMEvt.IsRight()) |
566 | 0 | mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog); |
567 | |
|
568 | 0 | } |
569 | 0 | } |
570 | 0 | else |
571 | 0 | { |
572 | | // Point IS marked and NO shift is pressed. Start |
573 | | // dragging of selected point(s) |
574 | 0 | pHdl = mpView->PickHandle(aMDPos); |
575 | 0 | if(pHdl && ! rMEvt.IsRight()) |
576 | 0 | mpView->BegDragObj(aMDPos, nullptr, pHdl, nDrgLog); |
577 | 0 | } |
578 | 0 | } |
579 | 0 | else |
580 | 0 | { |
581 | | /****************************************************************** |
582 | | * Select or drag object |
583 | | ******************************************************************/ |
584 | 0 | if (!rMEvt.IsShift() && !rMEvt.IsMod2() && eHit == SdrHitKind::UnmarkedObject) |
585 | 0 | { |
586 | 0 | mpView->UnmarkAllObj(); |
587 | 0 | } |
588 | |
|
589 | 0 | bool bMarked = false; |
590 | |
|
591 | 0 | if (!rMEvt.IsMod1()) |
592 | 0 | { |
593 | 0 | if (rMEvt.IsMod2()) |
594 | 0 | { |
595 | 0 | bMarked = mpView->MarkNextObj(aMDPos, nHitLog, rMEvt.IsShift()); |
596 | 0 | } |
597 | 0 | else |
598 | 0 | { |
599 | 0 | bMarked = mpView->MarkObj(aMDPos, nHitLog, rMEvt.IsShift()); |
600 | 0 | } |
601 | 0 | } |
602 | |
|
603 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
604 | 0 | if (bMarked && |
605 | 0 | (!rMEvt.IsShift() || eHit == SdrHitKind::MarkedObject)) |
606 | 0 | { |
607 | | // Move object |
608 | 0 | if ( ! rMEvt.IsRight()) |
609 | 0 | mpView->BegDragObj(aMDPos, nullptr, aVEvt.mpHdl, nDrgLog); |
610 | 0 | } |
611 | 0 | else if (rMarkList.GetMarkCount() != 0) |
612 | 0 | { |
613 | | /************************************************************** |
614 | | * Select gluepoint |
615 | | **************************************************************/ |
616 | 0 | if (!rMEvt.IsShift()) |
617 | 0 | mpView->UnmarkAllPoints(); |
618 | |
|
619 | 0 | if ( ! rMEvt.IsRight()) |
620 | 0 | mpView->BegMarkPoints(aMDPos); |
621 | 0 | } |
622 | 0 | else |
623 | 0 | { |
624 | | /************************************************************** |
625 | | * Select object |
626 | | **************************************************************/ |
627 | 0 | if ( ! rMEvt.IsRight()) |
628 | 0 | mpView->BegMarkObj(aMDPos); |
629 | 0 | } |
630 | |
|
631 | 0 | ForcePointer(&rMEvt); |
632 | 0 | } |
633 | 0 | } |
634 | | |
635 | 0 | if (!bIsInDragMode) |
636 | 0 | { |
637 | 0 | ForcePointer(&rMEvt); |
638 | 0 | } |
639 | |
|
640 | 0 | return bReturn; |
641 | 0 | } |
642 | | |
643 | | bool FuSelection::MouseMove(const MouseEvent& rMEvt) |
644 | 0 | { |
645 | 0 | bool bReturn = FuDraw::MouseMove(rMEvt); |
646 | |
|
647 | 0 | if (aDragTimer.IsActive()) |
648 | 0 | { |
649 | 0 | if(bFirstMouseMove) |
650 | 0 | { |
651 | 0 | bFirstMouseMove = false; |
652 | 0 | } |
653 | 0 | else |
654 | 0 | { |
655 | 0 | aDragTimer.Stop(); |
656 | 0 | } |
657 | 0 | } |
658 | |
|
659 | 0 | if (mpView->IsAction()) |
660 | 0 | { |
661 | 0 | Point aPix(rMEvt.GetPosPixel()); |
662 | 0 | Point aPnt(mpWindow->PixelToLogic(aPix)); |
663 | |
|
664 | 0 | ForceScroll(aPix); |
665 | |
|
666 | 0 | if (mpView->IsInsObjPoint()) |
667 | 0 | { |
668 | 0 | mpView->MovInsObjPoint(aPnt); |
669 | 0 | } |
670 | 0 | else |
671 | 0 | { |
672 | 0 | mpView->MovAction(aPnt); |
673 | 0 | } |
674 | 0 | } |
675 | |
|
676 | 0 | ForcePointer(&rMEvt); |
677 | |
|
678 | 0 | return bReturn; |
679 | 0 | } |
680 | | |
681 | | bool FuSelection::MouseButtonUp(const MouseEvent& rMEvt) |
682 | 0 | { |
683 | 0 | bool bReturn = false; |
684 | | // When the right mouse button is pressed then only select objects |
685 | | // (and deselect others) as a preparation for showing the context |
686 | | // menu. |
687 | 0 | const bool bSelectionOnly = rMEvt.IsRight(); |
688 | |
|
689 | 0 | if (aDragTimer.IsActive() ) |
690 | 0 | { |
691 | 0 | aDragTimer.Stop(); |
692 | 0 | bIsInDragMode = false; |
693 | 0 | } |
694 | |
|
695 | 0 | if( !mpView ) |
696 | 0 | return false; |
697 | | |
698 | 0 | Point aPnt( mpWindow->PixelToLogic( rMEvt.GetPosPixel() ) ); |
699 | 0 | sal_uInt16 nHitLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(HITPIX,0)).Width() ); |
700 | 0 | sal_uInt16 nDrgLog = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() ); |
701 | 0 | svx::diagram::DiagramFrameHdl* pDiagramFrameHdl(dynamic_cast<svx::diagram::DiagramFrameHdl*>(pHdl)); |
702 | |
|
703 | 0 | bool bWasDragged = false; |
704 | 0 | if (mpView->IsFrameDragSingles() || !mpView->HasMarkablePoints()) |
705 | 0 | { |
706 | | /********************************************************************** |
707 | | * NO BEZIER_EDITOR |
708 | | **********************************************************************/ |
709 | 0 | if ( mpView->IsDragObj() ) |
710 | 0 | { |
711 | | /****************************************************************** |
712 | | * Object was moved |
713 | | ******************************************************************/ |
714 | 0 | FrameView* pFrameView = mrViewShell.GetFrameView(); |
715 | 0 | bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy()); |
716 | |
|
717 | 0 | if (bDragWithCopy) |
718 | 0 | { |
719 | 0 | bDragWithCopy = !mpView->IsPresObjSelected(false); |
720 | 0 | } |
721 | |
|
722 | 0 | mpView->SetDragWithCopy(bDragWithCopy); |
723 | 0 | bWasDragged = mpView->EndDragObj(mpView->IsDragWithCopy()); |
724 | |
|
725 | 0 | mpView->ForceMarkedToAnotherPage(); |
726 | |
|
727 | 0 | if (!rMEvt.IsShift() && !rMEvt.IsMod1() && !rMEvt.IsMod2() && |
728 | 0 | !bSelectionChanged && |
729 | 0 | std::abs(aPnt.X() - aMDPos.X()) < nDrgLog && |
730 | 0 | std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) |
731 | 0 | { |
732 | | /************************************************************* |
733 | | * If a user wants to click on an object in front of a marked |
734 | | * one, he releases the mouse button immediately |
735 | | **************************************************************/ |
736 | 0 | SdrPageView* pPV; |
737 | 0 | SdrObject* pObj = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::ALSOONMASTER | SdrSearchOptions::BEFOREMARK); |
738 | |
|
739 | 0 | if (pObj && pPV->IsObjMarkable(pObj)) |
740 | 0 | { |
741 | 0 | mpView->UnmarkAllObj(); |
742 | 0 | mpView->MarkObj(pObj,pPV); |
743 | 0 | return true; |
744 | 0 | } |
745 | | |
746 | | // check for single object selected |
747 | 0 | SdrObject* pSingleObj = nullptr; |
748 | |
|
749 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
750 | 0 | if (rMarkList.GetMarkCount()==1) |
751 | 0 | { |
752 | 0 | pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
753 | 0 | } |
754 | | |
755 | | /************************************************************** |
756 | | * Toggle between selection and rotation |
757 | | **************************************************************/ |
758 | 0 | if (nSlotId == SID_OBJECT_SELECT |
759 | 0 | && !comphelper::LibreOfficeKit::isActive() |
760 | 0 | && mpView->IsRotateAllowed() |
761 | | |
762 | 0 | && (rMEvt.GetClicks() != 2) |
763 | 0 | && (mrViewShell.GetFrameView()->IsClickChangeRotation() |
764 | 0 | || (pSingleObj |
765 | 0 | && pSingleObj->GetObjInventor()==SdrInventor::E3d)) |
766 | 0 | && ! bSelectionOnly) |
767 | | |
768 | 0 | { |
769 | 0 | bTempRotation = true; |
770 | 0 | nSlotId = SID_OBJECT_ROTATE; |
771 | 0 | Activate(); |
772 | 0 | } |
773 | 0 | else if (nSlotId == SID_OBJECT_ROTATE) |
774 | 0 | { |
775 | 0 | nSlotId = SID_OBJECT_SELECT; |
776 | 0 | Activate(); |
777 | 0 | } |
778 | 0 | } |
779 | 0 | else if (nSlotId == SID_CONVERT_TO_3D_LATHE) |
780 | 0 | { |
781 | 0 | if (!pHdl) |
782 | 0 | { |
783 | 0 | bSuppressChangesOfSelection = true; |
784 | 0 | mpView->Start3DCreation(); |
785 | 0 | bSuppressChangesOfSelection = false; |
786 | 0 | } |
787 | 0 | else if (pHdl->GetKind() != SdrHdlKind::MirrorAxis && |
788 | 0 | pHdl->GetKind() != SdrHdlKind::Ref1 && |
789 | 0 | pHdl->GetKind() != SdrHdlKind::Ref2 && mpView->Is3DRotationCreationActive()) |
790 | 0 | { |
791 | | /********************************************************* |
792 | | * If 3D-rotation bodies are about to be created, |
793 | | * end creation now |
794 | | **********************************************************/ |
795 | 0 | Degree100 nAngle1 = GetAngle(aPnt - mpView->GetRef1()); |
796 | 0 | nAngle1 -= 27000_deg100; |
797 | 0 | nAngle1 = NormAngle36000(nAngle1); |
798 | 0 | bool bMirrorSide1 = nAngle1 < 18000_deg100; |
799 | |
|
800 | 0 | if (bMirrorSide0 != bMirrorSide1) |
801 | 0 | { |
802 | 0 | bSuppressChangesOfSelection = true; |
803 | 0 | mpWindow->EnterWait(); |
804 | 0 | mpView->End3DCreation(); |
805 | 0 | bSuppressChangesOfSelection = false; |
806 | 0 | nSlotId = SID_OBJECT_SELECT; |
807 | 0 | mpWindow->LeaveWait(); |
808 | 0 | Activate(); |
809 | 0 | } |
810 | 0 | } |
811 | 0 | } |
812 | 0 | } |
813 | 0 | else if (rMEvt.IsMod1() |
814 | 0 | && !rMEvt.IsMod2() |
815 | 0 | && std::abs(aPnt.X() - aMDPos.X()) < nDrgLog |
816 | 0 | && std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) |
817 | 0 | { |
818 | | // Enter group |
819 | 0 | mpView->MarkObj(aPnt, nHitLog, rMEvt.IsShift(), rMEvt.IsMod1()); |
820 | 0 | } |
821 | | |
822 | 0 | if (mpView->IsAction() ) |
823 | 0 | { |
824 | 0 | mpView->EndAction(); |
825 | 0 | } |
826 | |
|
827 | 0 | if (SdModule::get()->GetWaterCan()) |
828 | 0 | { |
829 | 0 | if( rMEvt.IsRight() ) |
830 | 0 | { |
831 | | // In watering-can mode, on press onto right mouse button, an undo is executed |
832 | 0 | mrViewShell.GetViewFrame()->GetDispatcher()->Execute( SID_UNDO, SfxCallMode::ASYNCHRON ); |
833 | 0 | } |
834 | 0 | else if (pWaterCanCandidate != nullptr) |
835 | 0 | { |
836 | | // Is the candidate object still under the mouse? |
837 | 0 | if (pickObject (aPnt) == pWaterCanCandidate) |
838 | 0 | { |
839 | 0 | SdStyleSheetPool* pPool = static_cast<SdStyleSheetPool*>( |
840 | 0 | mpDocSh->GetStyleSheetPool()); |
841 | 0 | if (pPool != nullptr) |
842 | 0 | { |
843 | 0 | SfxStyleSheet* pStyleSheet = static_cast<SfxStyleSheet*>( |
844 | 0 | pPool->GetActualStyleSheet()); |
845 | 0 | if (pStyleSheet != nullptr && mpView->IsUndoEnabled() ) |
846 | 0 | { |
847 | | // Added UNDOs for the WaterCan mode. This was never done in |
848 | | // the past, thus it was missing all the time. |
849 | 0 | std::unique_ptr<SdrUndoAction> pUndoAttr = mrDoc.GetSdrUndoFactory().CreateUndoAttrObject(*pWaterCanCandidate, true, true); |
850 | 0 | mpView->BegUndo(pUndoAttr->GetComment()); |
851 | 0 | mpView->AddUndo(mrDoc.GetSdrUndoFactory().CreateUndoGeoObject(*pWaterCanCandidate)); |
852 | 0 | mpView->AddUndo(std::move(pUndoAttr)); |
853 | |
|
854 | 0 | pWaterCanCandidate->SetStyleSheet (pStyleSheet, false); |
855 | |
|
856 | 0 | mpView->EndUndo(); |
857 | 0 | } |
858 | 0 | } |
859 | 0 | } |
860 | 0 | } |
861 | | // else when there has been no object under the mouse when the |
862 | | // button was pressed then nothing happens even when there is |
863 | | // one now. |
864 | 0 | } |
865 | |
|
866 | 0 | sal_uInt16 nClicks = rMEvt.GetClicks(); |
867 | |
|
868 | 0 | if (nClicks == 2 && rMEvt.IsLeft() && bMBDown && |
869 | 0 | !rMEvt.IsMod1() && !rMEvt.IsShift() ) |
870 | 0 | { |
871 | 0 | DoubleClick(rMEvt); |
872 | 0 | } |
873 | |
|
874 | 0 | bMBDown = false; |
875 | |
|
876 | 0 | ForcePointer(&rMEvt); |
877 | 0 | pHdl = nullptr; |
878 | 0 | mpWindow->ReleaseMouse(); |
879 | 0 | SdrObject* pSingleObj = nullptr; |
880 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
881 | 0 | const size_t nMarkCount = rMarkList.GetMarkCount(); |
882 | |
|
883 | 0 | if (nMarkCount==1) |
884 | 0 | { |
885 | 0 | pSingleObj = rMarkList.GetMark(0)->GetMarkedSdrObj(); |
886 | 0 | } |
887 | |
|
888 | 0 | if (!bWasDragged && pSingleObj && pSingleObj->isAnnotationObject() && rMEvt.IsLeft()) |
889 | 0 | { |
890 | 0 | auto& pAnnotationData = pSingleObj->getAnnotationData(); |
891 | 0 | if (pAnnotationData) |
892 | 0 | { |
893 | 0 | auto* pDrawViewShell = dynamic_cast<DrawViewShell*>(&mrViewShell); |
894 | 0 | if (pDrawViewShell && pDrawViewShell->getAnnotationManagerPtr()) |
895 | 0 | pDrawViewShell->getAnnotationManagerPtr()->SelectAnnotation(pAnnotationData->mxAnnotation, true); |
896 | 0 | } |
897 | 0 | return true; |
898 | 0 | } |
899 | | |
900 | 0 | if(!bWasDragged && nullptr != pSingleObj && pSingleObj->isDiagram()) |
901 | 0 | { |
902 | 0 | if(nullptr != pDiagramFrameHdl) |
903 | 0 | { |
904 | | // Check for click on svx::diagram::DiagramFrameHdl |
905 | | // - if we hit a SdrHdl |
906 | | // - if it was not moved |
907 | | // - if single object is selected and it is a Diagram |
908 | | // let the DiagramFrameHdl decide what to do |
909 | 0 | svx::diagram::DiagramFrameHdl::clicked(aPnt); |
910 | 0 | return true; |
911 | 0 | } |
912 | 0 | else |
913 | 0 | { |
914 | 0 | const std::shared_ptr< svx::diagram::DiagramHelper_svx >& rDiagramHelper(pSingleObj->getDiagramHelper()); |
915 | 0 | if (rDiagramHelper) |
916 | 0 | { |
917 | 0 | SdrPageView* pPV; |
918 | 0 | SdrObject* pCandidate = mpView->PickObj(aMDPos, mpView->getHitTolLog(), pPV, SdrSearchOptions::DEEP); |
919 | 0 | if (pCandidate && !pCandidate->isDiagram()) |
920 | 0 | { |
921 | 0 | rDiagramHelper->markDirectDiagramSubSelection(*pCandidate); |
922 | 0 | mpView->UnmarkAllObj(); |
923 | 0 | mpView->MarkObj(pSingleObj,pPV); |
924 | 0 | return true; |
925 | 0 | } |
926 | 0 | } |
927 | 0 | } |
928 | 0 | } |
929 | | |
930 | 0 | if ( (nSlotId != SID_OBJECT_SELECT && nMarkCount==0) || |
931 | 0 | ( mpView->GetDragMode() == SdrDragMode::Crook && |
932 | 0 | !mpView->IsCrookAllowed( mpView->IsCrookNoContortion() ) ) || |
933 | 0 | ( mpView->GetDragMode() == SdrDragMode::Shear && |
934 | 0 | !mpView->IsShearAllowed() && !mpView->IsDistortAllowed() ) || |
935 | 0 | ( nSlotId==SID_CONVERT_TO_3D_LATHE && pSingleObj && |
936 | 0 | (pSingleObj->GetObjInventor() != SdrInventor::Default || |
937 | 0 | pSingleObj->GetObjIdentifier() == SdrObjKind::Measure) ) ) |
938 | 0 | { |
939 | 0 | bReturn = true; |
940 | 0 | ForcePointer(&rMEvt); |
941 | 0 | pHdl = nullptr; |
942 | 0 | mpWindow->ReleaseMouse(); |
943 | 0 | FuDraw::MouseButtonUp(rMEvt); |
944 | 0 | mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::SYNCHRON); |
945 | 0 | return bReturn; // CAUTION, due to the synchronous slot, the object is deleted now. |
946 | 0 | } |
947 | | |
948 | 0 | FuDraw::MouseButtonUp(rMEvt); |
949 | 0 | } |
950 | 0 | else |
951 | 0 | { |
952 | | /********************************************************************** |
953 | | * BEZIER_EDITOR |
954 | | **********************************************************************/ |
955 | 0 | if ( mpView->IsAction() ) |
956 | 0 | { |
957 | 0 | if ( mpView->IsInsObjPoint() ) |
958 | 0 | { |
959 | 0 | mpView->EndInsObjPoint(SdrCreateCmd::ForceEnd); |
960 | 0 | } |
961 | 0 | else if ( mpView->IsDragObj() ) |
962 | 0 | { |
963 | 0 | FrameView* pFrameView = mrViewShell.GetFrameView(); |
964 | 0 | bool bDragWithCopy = (rMEvt.IsMod1() && pFrameView->IsDragWithCopy()); |
965 | |
|
966 | 0 | if (bDragWithCopy) |
967 | 0 | { |
968 | 0 | bDragWithCopy = !mpView->IsPresObjSelected(false); |
969 | 0 | } |
970 | |
|
971 | 0 | mpView->SetDragWithCopy(bDragWithCopy); |
972 | 0 | mpView->EndDragObj( mpView->IsDragWithCopy() ); |
973 | 0 | } |
974 | 0 | else |
975 | 0 | { |
976 | 0 | mpView->EndAction(); |
977 | |
|
978 | 0 | sal_uInt16 nDrgLog2 = sal_uInt16 ( mpWindow->PixelToLogic(Size(mpView->GetDragThresholdPixels(),0)).Width() ); |
979 | 0 | Point aPos = mpWindow->PixelToLogic( rMEvt.GetPosPixel() ); |
980 | |
|
981 | 0 | if (std::abs(aMDPos.X() - aPos.X()) < nDrgLog2 && |
982 | 0 | std::abs(aMDPos.Y() - aPos.Y()) < nDrgLog2 && |
983 | 0 | !rMEvt.IsShift() && !rMEvt.IsMod2()) |
984 | 0 | { |
985 | 0 | SdrViewEvent aVEvt; |
986 | 0 | SdrHitKind eHit = mpView->PickAnything(rMEvt, SdrMouseEventKind::BUTTONDOWN, aVEvt); |
987 | |
|
988 | 0 | if (eHit == SdrHitKind::NONE) |
989 | 0 | { |
990 | | // Click on the same place - unselect |
991 | 0 | mpView->UnmarkAllObj(); |
992 | 0 | } |
993 | 0 | } |
994 | 0 | } |
995 | 0 | } |
996 | 0 | else if (!rMEvt.IsShift() && rMEvt.IsMod1() && !rMEvt.IsMod2() && |
997 | 0 | std::abs(aPnt.X() - aMDPos.X()) < nDrgLog && |
998 | 0 | std::abs(aPnt.Y() - aMDPos.Y()) < nDrgLog) |
999 | 0 | { |
1000 | | // Enter group |
1001 | 0 | mpView->MarkObj(aPnt, nHitLog, false, rMEvt.IsMod1()); |
1002 | 0 | } |
1003 | |
|
1004 | 0 | ForcePointer(&rMEvt); |
1005 | 0 | pHdl = nullptr; |
1006 | 0 | mpWindow->ReleaseMouse(); |
1007 | |
|
1008 | 0 | FuDraw::MouseButtonUp(rMEvt); |
1009 | 0 | } |
1010 | | |
1011 | 0 | return bReturn; |
1012 | 0 | } |
1013 | | |
1014 | | /** |
1015 | | * Process keyboard input |
1016 | | * @returns sal_True if a KeyEvent is being processed, sal_False otherwise |
1017 | | */ |
1018 | | bool FuSelection::KeyInput(const KeyEvent& rKEvt) |
1019 | 0 | { |
1020 | 0 | bool bReturn = false; |
1021 | |
|
1022 | 0 | switch (rKEvt.GetKeyCode().GetCode()) |
1023 | 0 | { |
1024 | 0 | case KEY_ESCAPE: |
1025 | 0 | { |
1026 | 0 | bReturn = FuSelection::cancel(); |
1027 | 0 | } |
1028 | 0 | break; |
1029 | | //add keyboard operation for insert points in drawing curve |
1030 | 0 | case KEY_UP: |
1031 | 0 | case KEY_DOWN: |
1032 | 0 | case KEY_LEFT: |
1033 | 0 | case KEY_RIGHT: |
1034 | 0 | { |
1035 | 0 | if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)){ |
1036 | 0 | ::tools::Long nX = 0; |
1037 | 0 | ::tools::Long nY = 0; |
1038 | 0 | sal_uInt16 nCode = rKEvt.GetKeyCode().GetCode(); |
1039 | 0 | if (nCode == KEY_UP) |
1040 | 0 | { |
1041 | | // scroll up |
1042 | 0 | nX = 0; |
1043 | 0 | nY =-1; |
1044 | 0 | } |
1045 | 0 | else if (nCode == KEY_DOWN) |
1046 | 0 | { |
1047 | | // scroll down |
1048 | 0 | nX = 0; |
1049 | 0 | nY = 1; |
1050 | 0 | } |
1051 | 0 | else if (nCode == KEY_LEFT) |
1052 | 0 | { |
1053 | | // scroll left |
1054 | 0 | nX =-1; |
1055 | 0 | nY = 0; |
1056 | 0 | } |
1057 | 0 | else if (nCode == KEY_RIGHT) |
1058 | 0 | { |
1059 | | // scroll right |
1060 | 0 | nX = 1; |
1061 | 0 | nY = 0; |
1062 | 0 | } |
1063 | |
|
1064 | 0 | Point centerPoint; |
1065 | 0 | ::tools::Rectangle rect = mpView->GetMarkedObjRect(); |
1066 | 0 | centerPoint = mpWindow->LogicToPixel(rect.Center()); |
1067 | 0 | Point aPoint = bMovedToCenterPoint? oldPoint:centerPoint; |
1068 | 0 | Point ePoint = aPoint + Point(nX,nY); |
1069 | 0 | mpWindow->SetPointerPosPixel(ePoint); |
1070 | | //simulate mouse move action |
1071 | 0 | MouseEvent eMevt(ePoint, 1, MouseEventModifiers::DRAGMOVE, MOUSE_LEFT, 0); |
1072 | 0 | MouseMove(eMevt); |
1073 | 0 | oldPoint = ePoint; |
1074 | 0 | bMovedToCenterPoint = true; |
1075 | 0 | bReturn = true; |
1076 | 0 | } |
1077 | 0 | } |
1078 | 0 | break; |
1079 | 0 | case KEY_RETURN: |
1080 | 0 | if(rKEvt.GetKeyCode().IsShift()&&(nEditMode == SID_BEZIER_INSERT)) |
1081 | 0 | { |
1082 | 0 | if(!bBeginInsertPoint) |
1083 | 0 | { |
1084 | | //simulate mouse button down action |
1085 | 0 | MouseEvent aMevt(oldPoint, 1, |
1086 | 0 | MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::DRAGMOVE, |
1087 | 0 | MOUSE_LEFT, KEY_SHIFT); |
1088 | 0 | MouseButtonDown(aMevt); |
1089 | 0 | mpWindow->CaptureMouse(); |
1090 | 0 | bBeginInsertPoint = true; |
1091 | 0 | } |
1092 | 0 | else |
1093 | 0 | { |
1094 | | //simulate mouse button up action |
1095 | 0 | MouseEvent rMEvt(oldPoint, 1, |
1096 | 0 | MouseEventModifiers::SIMPLEMOVE | MouseEventModifiers::ENTERWINDOW, |
1097 | 0 | MOUSE_LEFT, KEY_SHIFT); |
1098 | 0 | MouseButtonUp(rMEvt); |
1099 | 0 | bBeginInsertPoint = false; |
1100 | 0 | } |
1101 | 0 | bReturn= true; |
1102 | 0 | } |
1103 | 0 | break; |
1104 | 0 | } |
1105 | 0 | if (!bReturn) |
1106 | 0 | { |
1107 | 0 | bReturn = FuDraw::KeyInput(rKEvt); |
1108 | |
|
1109 | 0 | const SdrMarkList& rMarkList = mpView->GetMarkedObjectList(); |
1110 | 0 | if(rMarkList.GetMarkCount() == 0) |
1111 | 0 | { |
1112 | 0 | mpView->ResetCreationActive(); |
1113 | |
|
1114 | 0 | mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); |
1115 | 0 | } |
1116 | 0 | } |
1117 | |
|
1118 | 0 | return bReturn; |
1119 | |
|
1120 | 0 | } |
1121 | | |
1122 | | void FuSelection::Activate() |
1123 | 0 | { |
1124 | 0 | SdrDragMode eMode; |
1125 | 0 | mpView->ResetCreationActive(); |
1126 | 0 | mpView->SetEditMode(SdrViewEditMode::Edit); |
1127 | |
|
1128 | 0 | switch( nSlotId ) |
1129 | 0 | { |
1130 | 0 | case SID_OBJECT_ROTATE: |
1131 | 0 | { |
1132 | 0 | eMode = SdrDragMode::Rotate; |
1133 | |
|
1134 | 0 | if ( mpView->GetDragMode() != eMode ) |
1135 | 0 | mpView->SetDragMode(eMode); |
1136 | 0 | } |
1137 | 0 | break; |
1138 | | |
1139 | 0 | case SID_OBJECT_MIRROR: |
1140 | 0 | { |
1141 | 0 | eMode = SdrDragMode::Mirror; |
1142 | |
|
1143 | 0 | if ( mpView->GetDragMode() != eMode ) |
1144 | 0 | mpView->SetDragMode(eMode); |
1145 | 0 | } |
1146 | 0 | break; |
1147 | | |
1148 | 0 | case SID_OBJECT_CROP: |
1149 | 0 | { |
1150 | 0 | eMode = SdrDragMode::Crop; |
1151 | |
|
1152 | 0 | if ( mpView->GetDragMode() != eMode ) |
1153 | 0 | mpView->SetDragMode(eMode); |
1154 | 0 | } |
1155 | 0 | break; |
1156 | | |
1157 | 0 | case SID_OBJECT_TRANSPARENCE: |
1158 | 0 | { |
1159 | 0 | eMode = SdrDragMode::Transparence; |
1160 | |
|
1161 | 0 | if ( mpView->GetDragMode() != eMode ) |
1162 | 0 | mpView->SetDragMode(eMode); |
1163 | 0 | } |
1164 | 0 | break; |
1165 | | |
1166 | 0 | case SID_OBJECT_GRADIENT: |
1167 | 0 | { |
1168 | 0 | eMode = SdrDragMode::Gradient; |
1169 | |
|
1170 | 0 | if ( mpView->GetDragMode() != eMode ) |
1171 | 0 | mpView->SetDragMode(eMode); |
1172 | 0 | } |
1173 | 0 | break; |
1174 | | |
1175 | 0 | case SID_OBJECT_SHEAR: |
1176 | 0 | { |
1177 | 0 | eMode = SdrDragMode::Shear; |
1178 | |
|
1179 | 0 | if ( mpView->GetDragMode() != eMode ) |
1180 | 0 | mpView->SetDragMode(eMode); |
1181 | 0 | } |
1182 | 0 | break; |
1183 | | |
1184 | 0 | case SID_OBJECT_CROOK_ROTATE: |
1185 | 0 | { |
1186 | 0 | eMode = SdrDragMode::Crook; |
1187 | |
|
1188 | 0 | if ( mpView->GetDragMode() != eMode ) |
1189 | 0 | { |
1190 | 0 | mpView->SetDragMode(eMode); |
1191 | 0 | mpView->SetCrookMode(SdrCrookMode::Rotate); |
1192 | 0 | } |
1193 | 0 | } |
1194 | 0 | break; |
1195 | | |
1196 | 0 | case SID_OBJECT_CROOK_SLANT: |
1197 | 0 | { |
1198 | 0 | eMode = SdrDragMode::Crook; |
1199 | |
|
1200 | 0 | if ( mpView->GetDragMode() != eMode ) |
1201 | 0 | { |
1202 | 0 | mpView->SetDragMode(eMode); |
1203 | 0 | mpView->SetCrookMode(SdrCrookMode::Slant); |
1204 | 0 | } |
1205 | 0 | } |
1206 | 0 | break; |
1207 | | |
1208 | 0 | case SID_OBJECT_CROOK_STRETCH: |
1209 | 0 | { |
1210 | 0 | eMode = SdrDragMode::Crook; |
1211 | |
|
1212 | 0 | if ( mpView->GetDragMode() != eMode ) |
1213 | 0 | { |
1214 | 0 | mpView->SetDragMode(eMode); |
1215 | 0 | mpView->SetCrookMode(SdrCrookMode::Stretch); |
1216 | 0 | } |
1217 | 0 | } |
1218 | 0 | break; |
1219 | | |
1220 | 0 | case SID_CONVERT_TO_3D_LATHE: |
1221 | 0 | { |
1222 | 0 | eMode = SdrDragMode::Mirror; |
1223 | 0 | bSuppressChangesOfSelection = true; |
1224 | |
|
1225 | 0 | if ( mpView->GetDragMode() != eMode ) |
1226 | 0 | mpView->SetDragMode(eMode); |
1227 | |
|
1228 | 0 | if (!mpView->Is3DRotationCreationActive()) |
1229 | 0 | mpView->Start3DCreation(); |
1230 | |
|
1231 | 0 | bSuppressChangesOfSelection = false; |
1232 | 0 | } |
1233 | 0 | break; |
1234 | | |
1235 | 0 | default: |
1236 | 0 | { |
1237 | 0 | eMode = SdrDragMode::Move; |
1238 | |
|
1239 | 0 | if ( mpView->GetDragMode() != eMode ) |
1240 | 0 | mpView->SetDragMode(eMode); |
1241 | 0 | } |
1242 | 0 | break; |
1243 | 0 | } |
1244 | | |
1245 | 0 | if (nSlotId != SID_OBJECT_ROTATE) |
1246 | 0 | { |
1247 | 0 | bTempRotation = false; |
1248 | 0 | } |
1249 | |
|
1250 | 0 | FuDraw::Activate(); |
1251 | 0 | } |
1252 | | |
1253 | | void FuSelection::SelectionHasChanged() |
1254 | 0 | { |
1255 | 0 | bSelectionChanged = true; |
1256 | |
|
1257 | 0 | FuDraw::SelectionHasChanged(); |
1258 | |
|
1259 | 0 | if (mpView->Is3DRotationCreationActive() && !bSuppressChangesOfSelection) |
1260 | 0 | { |
1261 | | // Switch rotation body -> selection |
1262 | 0 | mpView->ResetCreationActive(); |
1263 | 0 | nSlotId = SID_OBJECT_SELECT; |
1264 | 0 | Activate(); |
1265 | 0 | } |
1266 | | |
1267 | | // Activate the right tool bar for the current context of the view. |
1268 | 0 | mrViewShell.GetViewShellBase().GetToolBarManager()->SelectionHasChanged(mrViewShell, *mpView); |
1269 | 0 | } |
1270 | | |
1271 | | /** |
1272 | | * Set current bezier edit mode |
1273 | | */ |
1274 | | void FuSelection::SetEditMode(sal_uInt16 nMode) |
1275 | 0 | { |
1276 | 0 | nEditMode = nMode; |
1277 | |
|
1278 | 0 | if (nEditMode == SID_BEZIER_INSERT) |
1279 | 0 | { |
1280 | 0 | mpView->SetInsObjPointMode(true); |
1281 | 0 | } |
1282 | 0 | else |
1283 | 0 | { |
1284 | 0 | mpView->SetInsObjPointMode(false); |
1285 | 0 | } |
1286 | |
|
1287 | 0 | ForcePointer(); |
1288 | |
|
1289 | 0 | SfxBindings& rBindings = mrViewShell.GetViewFrame()->GetBindings(); |
1290 | 0 | rBindings.Invalidate(SID_BEZIER_MOVE); |
1291 | 0 | rBindings.Invalidate(SID_BEZIER_INSERT); |
1292 | 0 | } |
1293 | | |
1294 | | /** |
1295 | | * Execute ImageMap interaction |
1296 | | */ |
1297 | | bool FuSelection::HandleImageMapClick(const SdrObject* pObj, const Point& rPos) |
1298 | 0 | { |
1299 | 0 | bool bClosed = pObj->IsClosedObj(); |
1300 | 0 | bool bFilled = false; |
1301 | |
|
1302 | 0 | if (bClosed) |
1303 | 0 | { |
1304 | 0 | SfxItemSet aSet(mrDoc.GetPool()); |
1305 | |
|
1306 | 0 | aSet.Put(pObj->GetMergedItemSet()); |
1307 | |
|
1308 | 0 | const XFillStyleItem& rFillStyle = aSet.Get(XATTR_FILLSTYLE); |
1309 | 0 | bFilled = rFillStyle.GetValue() != drawing::FillStyle_NONE; |
1310 | 0 | } |
1311 | |
|
1312 | 0 | const SdrLayerIDSet* pVisiLayer = &mpView->GetSdrPageView()->GetVisibleLayers(); |
1313 | 0 | double fHitLog = mpWindow->PixelToLogic(Size(HITPIX, 0)).Width(); |
1314 | 0 | const ::tools::Long n2HitLog = fHitLog * 2; |
1315 | 0 | Point aHitPosR(rPos); |
1316 | 0 | Point aHitPosL(rPos); |
1317 | 0 | Point aHitPosT(rPos); |
1318 | 0 | Point aHitPosB(rPos); |
1319 | |
|
1320 | 0 | aHitPosR.AdjustX(n2HitLog); |
1321 | 0 | aHitPosL.AdjustX(-n2HitLog); |
1322 | 0 | aHitPosT.AdjustY(n2HitLog); |
1323 | 0 | aHitPosB.AdjustY(-n2HitLog); |
1324 | |
|
1325 | 0 | if (!bClosed || !bFilled |
1326 | 0 | || (SdrObjectPrimitiveHit(*pObj, aHitPosR, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), pVisiLayer, |
1327 | 0 | false) |
1328 | 0 | && SdrObjectPrimitiveHit(*pObj, aHitPosL, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), |
1329 | 0 | pVisiLayer, false) |
1330 | 0 | && SdrObjectPrimitiveHit(*pObj, aHitPosT, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), |
1331 | 0 | pVisiLayer, false) |
1332 | 0 | && SdrObjectPrimitiveHit(*pObj, aHitPosB, {fHitLog, fHitLog}, *mpView->GetSdrPageView(), |
1333 | 0 | pVisiLayer, false))) |
1334 | 0 | { |
1335 | 0 | if (SvxIMapInfo::GetIMapInfo(pObj)) |
1336 | 0 | { |
1337 | 0 | const IMapObject* pIMapObj = SvxIMapInfo::GetHitIMapObject(pObj, rPos); |
1338 | |
|
1339 | 0 | if (pIMapObj && !pIMapObj->GetURL().isEmpty()) |
1340 | 0 | { |
1341 | | // Jump to Document |
1342 | 0 | mpWindow->ReleaseMouse(); |
1343 | 0 | SfxStringItem aStrItem(SID_FILE_NAME, pIMapObj->GetURL()); |
1344 | 0 | SfxStringItem aReferer(SID_REFERER, mpDocSh->GetMedium()->GetName()); |
1345 | 0 | SfxViewFrame* pFrame = mrViewShell.GetViewFrame(); |
1346 | 0 | SfxFrameItem aFrameItem(SID_DOCFRAME, pFrame); |
1347 | 0 | SfxBoolItem aBrowseItem(SID_BROWSE, true); |
1348 | 0 | mpWindow->ReleaseMouse(); |
1349 | 0 | pFrame->GetDispatcher()->ExecuteList( |
1350 | 0 | SID_OPENDOC, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD, |
1351 | 0 | { &aStrItem, &aFrameItem, &aBrowseItem, &aReferer }); |
1352 | |
|
1353 | 0 | return true; |
1354 | 0 | } |
1355 | 0 | } |
1356 | 0 | } |
1357 | | |
1358 | 0 | return false; |
1359 | 0 | } |
1360 | | |
1361 | | /** is called when the current function should be aborted. <p> |
1362 | | This is used when a function gets a KEY_ESCAPE but can also |
1363 | | be called directly. |
1364 | | |
1365 | | @returns true if an active function was aborted |
1366 | | */ |
1367 | | bool FuSelection::cancel() |
1368 | 0 | { |
1369 | 0 | if (mpView->Is3DRotationCreationActive()) |
1370 | 0 | { |
1371 | 0 | mpView->ResetCreationActive(); |
1372 | 0 | mrViewShell.GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SfxCallMode::ASYNCHRON | SfxCallMode::RECORD); |
1373 | 0 | return true; |
1374 | 0 | } |
1375 | 0 | else |
1376 | 0 | { |
1377 | 0 | return false; |
1378 | 0 | } |
1379 | 0 | } |
1380 | | |
1381 | | SdrObject* FuSelection::pickObject (const Point& rTestPoint) |
1382 | 0 | { |
1383 | 0 | SdrPageView* pPageView; |
1384 | 0 | sal_uInt16 nHitLog = sal_uInt16 (mpWindow->PixelToLogic(Size(HITPIX,0)).Width()); |
1385 | 0 | return mpView->PickObj(rTestPoint, nHitLog, pPageView, SdrSearchOptions::PICKMARKABLE); |
1386 | 0 | } |
1387 | | |
1388 | | void FuSelection::ForcePointer(const MouseEvent* pMEvt) |
1389 | 0 | { |
1390 | 0 | if(bMovedToCenterPoint && !bBeginInsertPoint && pMEvt) |
1391 | 0 | { |
1392 | 0 | MouseEvent aMEvt(pMEvt->GetPosPixel(), pMEvt->GetClicks(), |
1393 | 0 | pMEvt->GetMode(), pMEvt->GetButtons(), pMEvt->GetModifier() & ~KEY_SHIFT); |
1394 | 0 | FuDraw::ForcePointer(&aMEvt); |
1395 | 0 | } |
1396 | 0 | else |
1397 | 0 | { |
1398 | 0 | FuDraw::ForcePointer(pMEvt); |
1399 | 0 | } |
1400 | 0 | } |
1401 | | |
1402 | | } // end of namespace sd |
1403 | | |
1404 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |