Bug Summary

File:home/maarten/src/libreoffice/core/sd/source/ui/func/fusel.cxx
Warning:line 381, column 25
Called C++ object pointer is null

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name fusel.cxx -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=cplusplus -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mframe-pointer=all -fmath-errno -fno-rounding-math -mconstructor-aliases -munwind-tables -target-cpu x86-64 -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/11.0.0 -isystem /usr/include/libxml2 -isystem /usr/include/dbus-1.0 -isystem /usr/lib64/dbus-1.0/include -D BOOST_ERROR_CODE_HEADER_ONLY -D BOOST_SYSTEM_NO_DEPRECATED -D CPPU_ENV=gcc3 -D LINUX -D OSL_DEBUG_LEVEL=1 -D SAL_LOG_INFO -D SAL_LOG_WARN -D UNIX -D UNX -D X86_64 -D _PTHREADS -D _REENTRANT -D SD_DLLIMPLEMENTATION -D SDUI_DLL_NAME="libsduilo.so" -D SYSTEM_LIBXML -D ENABLE_SDREMOTE -D ENABLE_SDREMOTE_BLUETOOTH -D EXCEPTIONS_ON -D LIBO_INTERNAL_ONLY -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/i18n -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/icu/source/common -I /home/maarten/src/libreoffice/core/external/boost/include -I /home/maarten/src/libreoffice/core/workdir/UnpackedTarball/boost -I /home/maarten/src/libreoffice/core/external/bluez_bluetooth/inc -I /home/maarten/src/libreoffice/core/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include -I /usr/lib/jvm/java-11-openjdk-11.0.9.10-0.0.ea.fc33.x86_64/include/linux -I /home/maarten/src/libreoffice/core/config_host -I /home/maarten/src/libreoffice/core/sd/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/inc -I /home/maarten/src/libreoffice/core/sd/source/ui/slidesorter/inc -I /home/maarten/src/libreoffice/core/workdir/SdiTarget/sd/sdi -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/officecfg/registry -I /home/maarten/src/libreoffice/core/workdir/CustomTarget/oox/generated -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/udkapi/normal -I /home/maarten/src/libreoffice/core/workdir/UnoApiHeadersTarget/offapi/normal -I /usr/include/glib-2.0 -I /usr/lib64/glib-2.0/include -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10 -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/x86_64-redhat-linux -internal-isystem /usr/bin/../lib/gcc/x86_64-redhat-linux/10/../../../../include/c++/10/backward -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/11.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -O0 -Wno-missing-braces -std=c++17 -fdeprecated-macro -fdebug-compilation-dir /home/maarten/src/libreoffice/core -ferror-limit 19 -fvisibility hidden -fvisibility-inlines-hidden -stack-protector 2 -fgnuc-version=4.2.1 -fcxx-exceptions -fexceptions -debug-info-kind=constructor -analyzer-output=html -faddrsig -o /home/maarten/tmp/wis/scan-build-libreoffice/output/report/2020-10-07-141433-9725-1 -x c++ /home/maarten/src/libreoffice/core/sd/source/ui/func/fusel.cxx

/home/maarten/src/libreoffice/core/sd/source/ui/func/fusel.cxx

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

/home/maarten/src/libreoffice/core/include/vcl/event.hxx

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#ifndef INCLUDED_VCL_EVENT_HXX
21#define INCLUDED_VCL_EVENT_HXX
22
23#include <vcl/dllapi.h>
24#include <tools/gen.hxx>
25#include <vcl/keycod.hxx>
26#include <vcl/settings.hxx>
27#include <vcl/vclptr.hxx>
28#include <vcl/outdev.hxx>
29#include <vcl/window.hxx>
30#include <optional>
31
32class CommandEvent;
33
34enum class TextDirectionality {
35 LeftToRight_TopToBottom,
36 RightToLeft_TopToBottom,
37 TopToBottom_RightToLeft,
38 BottomToTop_LeftToRight
39};
40
41class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) KeyEvent
42{
43private:
44 vcl::KeyCode maKeyCode;
45 sal_uInt16 mnRepeat;
46 sal_Unicode mnCharCode;
47
48public:
49 KeyEvent();
50 KeyEvent( sal_Unicode nChar, const vcl::KeyCode& rKeyCode,
51 sal_uInt16 nRepeat = 0 );
52
53 sal_Unicode GetCharCode() const { return mnCharCode; }
54 const vcl::KeyCode& GetKeyCode() const { return maKeyCode; }
55 sal_uInt16 GetRepeat() const { return mnRepeat; }
56
57 KeyEvent LogicalTextDirectionality (TextDirectionality eMode) const;
58};
59
60inline KeyEvent::KeyEvent()
61{
62 mnCharCode = 0;
63 mnRepeat = 0;
64}
65
66inline KeyEvent::KeyEvent( sal_Unicode nChar, const vcl::KeyCode& rKeyCode,
67 sal_uInt16 nRepeat ) :
68 maKeyCode( rKeyCode )
69
70{
71 mnCharCode = nChar;
72 mnRepeat = nRepeat;
73}
74
75
76enum class MouseEventModifiers
77{
78 NONE = 0,
79 // mouse move modifiers
80 SIMPLEMOVE = 0x0001,
81 DRAGMOVE = 0x0002,
82 DRAGCOPY = 0x0004,
83 ENTERWINDOW = 0x0010,
84 LEAVEWINDOW = 0x0020,
85 SYNTHETIC = 0x0040,
86 MODIFIERCHANGED = 0x0080,
87 // mouse up/down-button modifiers
88 SIMPLECLICK = 0x0100,
89 SELECT = 0x0200,
90 MULTISELECT = 0x0400,
91 RANGESELECT = 0x0800
92};
93namespace o3tl
94{
95 template<> struct typed_flags<MouseEventModifiers> : is_typed_flags<MouseEventModifiers, 0xff7> {};
96}
97
98// Mouse buttons
99#define MOUSE_LEFT(sal_uInt16(0x0001)) (sal_uInt16(0x0001))
100#define MOUSE_MIDDLE(sal_uInt16(0x0002)) (sal_uInt16(0x0002))
101#define MOUSE_RIGHT(sal_uInt16(0x0004)) (sal_uInt16(0x0004))
102
103class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) MouseEvent
104{
105private:
106 Point maPos;
107 MouseEventModifiers mnMode;
108 sal_uInt16 mnClicks;
109 sal_uInt16 mnCode;
110
111 // Set, if the document relative logic position are available
112 std::optional<Point> maLogicPosition;
113
114public:
115 explicit MouseEvent();
116 explicit MouseEvent( const Point& rPos, sal_uInt16 nClicks = 1,
117 MouseEventModifiers nMode = MouseEventModifiers::NONE, sal_uInt16 nButtons = 0,
118 sal_uInt16 nModifier = 0 );
119
120 const Point& GetPosPixel() const { return maPos; }
121 MouseEventModifiers GetMode() const { return mnMode; }
122
123 sal_uInt16 GetClicks() const { return mnClicks; }
124
125 void setLogicPosition(Point aLogicPosition)
126 {
127 maLogicPosition = aLogicPosition;
128 }
129
130 std::optional<Point> getLogicPosition() const
131 {
132 return maLogicPosition;
133 }
134
135 bool IsEnterWindow() const
136 { return bool(mnMode & MouseEventModifiers::ENTERWINDOW); }
137 bool IsLeaveWindow() const
138 { return bool(mnMode & MouseEventModifiers::LEAVEWINDOW); }
139 bool IsSynthetic() const
140 { return bool(mnMode & MouseEventModifiers::SYNTHETIC); }
141 bool IsModifierChanged() const
142 { return bool(mnMode & MouseEventModifiers::MODIFIERCHANGED); }
143
144 sal_uInt16 GetButtons() const
145 { return (mnCode & (MOUSE_LEFT(sal_uInt16(0x0001)) | MOUSE_MIDDLE(sal_uInt16(0x0002)) | MOUSE_RIGHT(sal_uInt16(0x0004)))); }
146 bool IsLeft() const
147 { return ((mnCode & MOUSE_LEFT(sal_uInt16(0x0001))) != 0); }
7
Assuming the condition is true
8
Returning the value 1, which participates in a condition later
148 bool IsMiddle() const
149 { return ((mnCode & MOUSE_MIDDLE(sal_uInt16(0x0002))) != 0); }
150 bool IsRight() const
151 { return ((mnCode & MOUSE_RIGHT(sal_uInt16(0x0004))) != 0); }
152
153 sal_uInt16 GetModifier() const
154 { return (mnCode & (KEY_SHIFT | KEY_MOD1 | KEY_MOD2)); }
155 bool IsShift() const
156 { return ((mnCode & KEY_SHIFT) != 0); }
35
Assuming the condition is false
36
Returning zero, which participates in a condition later
157 bool IsMod1() const
158 { return ((mnCode & KEY_MOD1) != 0); }
159 bool IsMod2() const
160 { return ((mnCode & KEY_MOD2) != 0); }
25
Returning zero, which participates in a condition later
39
Returning zero, which participates in a condition later
161 bool IsMod3() const
162 { return ((mnCode & KEY_MOD3) != 0); }
163};
164
165inline MouseEvent::MouseEvent()
166{
167 mnMode = MouseEventModifiers::NONE;
168 mnClicks = 0;
169 mnCode = 0;
170}
171
172inline MouseEvent::MouseEvent( const Point& rPos, sal_uInt16 nClicks,
173 MouseEventModifiers nMode,
174 sal_uInt16 nButtons, sal_uInt16 nModifier ) :
175 maPos( rPos )
176{
177 mnClicks = nClicks;
178 mnMode = nMode;
179 mnCode = nButtons | nModifier;
180}
181
182enum class HelpEventMode
183{
184 NONE = 0x0000,
185 CONTEXT = 0x0001,
186 BALLOON = 0x0002,
187 QUICK = 0x0004
188};
189namespace o3tl
190{
191 template<> struct typed_flags<HelpEventMode> : is_typed_flags<HelpEventMode, 0x07> {};
192}
193
194class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) HelpEvent
195{
196private:
197 Point maPos;
198 HelpEventMode mnMode;
199 bool mbKeyboardActivated;
200
201public:
202 explicit HelpEvent( const Point& rMousePos, HelpEventMode nHelpMode );
203
204 const Point& GetMousePosPixel() const { return maPos; }
205 HelpEventMode GetMode() const { return mnMode; }
206 bool KeyboardActivated() const { return mbKeyboardActivated; }
207 void SetKeyboardActivated( bool bKeyboard ) { mbKeyboardActivated = bKeyboard; }
208};
209
210inline HelpEvent::HelpEvent( const Point& rMousePos, HelpEventMode nHelpMode ) :
211 maPos( rMousePos )
212{
213 mnMode = nHelpMode;
214 mbKeyboardActivated = false;
215}
216
217/// Event to pass information for UserDraw() handling eg. in comboboxes.
218class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) UserDrawEvent
219{
220private:
221 /// Window that owns the user draw.
222 VclPtr<vcl::Window> mpWindow;
223
224 /// RenderContext to which we should draw - can be a VirtualDevice or anything.
225 VclPtr<vcl::RenderContext> mpRenderContext;
226
227 tools::Rectangle maOutRect;
228 sal_uInt16 mnItemId;
229 bool mbSelected;
230
231public:
232 UserDrawEvent(vcl::Window* pWindow, vcl::RenderContext* pRenderContext,
233 const tools::Rectangle& rOutRect, sal_uInt16 nId, bool bSelected = false)
234 : mpWindow(pWindow)
235 , mpRenderContext(pRenderContext)
236 , maOutRect( rOutRect )
237 , mnItemId(nId)
238 , mbSelected(bSelected)
239 {
240 }
241
242 vcl::Window* GetWindow() const { return mpWindow; }
243 vcl::RenderContext* GetRenderContext() const { return mpRenderContext; }
244 const tools::Rectangle& GetRect() const { return maOutRect; }
245 sal_uInt16 GetItemId() const { return mnItemId; }
246 bool IsSelected() const { return mbSelected; }
247};
248
249class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) TrackingEvent
250{
251private:
252 MouseEvent maMEvt;
253 TrackingEventFlags mnFlags;
254
255public:
256 explicit TrackingEvent( const MouseEvent&,
257 TrackingEventFlags nTrackFlags = TrackingEventFlags::NONE );
258
259 const MouseEvent& GetMouseEvent() const { return maMEvt; }
260
261 bool IsTrackingRepeat() const
262 { return bool(mnFlags & TrackingEventFlags::Repeat); }
263 bool IsTrackingEnded() const
264 { return bool(mnFlags & TrackingEventFlags::End); }
265 bool IsTrackingCanceled() const
266 { return bool(mnFlags & TrackingEventFlags::Cancel); }
267};
268
269inline TrackingEvent::TrackingEvent( const MouseEvent& rMEvt,
270 TrackingEventFlags nTrackFlags ) :
271 maMEvt( rMEvt )
272{
273 mnFlags = nTrackFlags;
274}
275
276
277enum class MouseNotifyEvent
278{
279 NONE = 0,
280 MOUSEBUTTONDOWN = 1,
281 MOUSEBUTTONUP = 2,
282 MOUSEMOVE = 3,
283 KEYINPUT = 4,
284 KEYUP = 5,
285 GETFOCUS = 6,
286 LOSEFOCUS = 7,
287 COMMAND = 8,
288 INPUTENABLE = 10
289};
290
291class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) NotifyEvent
292{
293private:
294 VclPtr<vcl::Window> mpWindow;
295 void* mpData;
296 MouseNotifyEvent mnEventType;
297
298public:
299 NotifyEvent( MouseNotifyEvent nEventType,
300 vcl::Window* pWindow,
301 const void* pEvent = nullptr );
302
303 MouseNotifyEvent GetType() const { return mnEventType; }
304 vcl::Window* GetWindow() const { return mpWindow; }
305 void* GetData() const { return mpData; }
306 const KeyEvent* GetKeyEvent() const;
307 const MouseEvent* GetMouseEvent() const;
308 const CommandEvent* GetCommandEvent() const;
309};
310
311inline const KeyEvent* NotifyEvent::GetKeyEvent() const
312{
313 if ( (mnEventType == MouseNotifyEvent::KEYINPUT) || (mnEventType == MouseNotifyEvent::KEYUP) )
314 return static_cast<const KeyEvent*>(mpData);
315 else
316 return nullptr;
317}
318
319inline const MouseEvent* NotifyEvent::GetMouseEvent() const
320{
321 if ( (mnEventType >= MouseNotifyEvent::MOUSEBUTTONDOWN) && (mnEventType <= MouseNotifyEvent::MOUSEMOVE) )
322 return static_cast<const MouseEvent*>(mpData);
323 else
324 return nullptr;
325}
326
327inline const CommandEvent* NotifyEvent::GetCommandEvent() const
328{
329 if ( mnEventType == MouseNotifyEvent::COMMAND )
330 return static_cast<const CommandEvent*>(mpData);
331 else
332 return nullptr;
333}
334
335
336enum class DataChangedEventType {
337 NONE = 0,
338 SETTINGS = 1,
339 DISPLAY = 2,
340 FONTS = 4,
341 PRINTER = 5,
342 FONTSUBSTITUTION = 6
343};
344
345class VCL_DLLPUBLIC__attribute__ ((visibility("default"))) DataChangedEvent
346{
347private:
348 void* mpData;
349 AllSettingsFlags mnFlags;
350 DataChangedEventType mnType;
351
352public:
353 explicit DataChangedEvent( DataChangedEventType nType,
354 const void* pData = nullptr,
355 AllSettingsFlags nFlags = AllSettingsFlags::NONE );
356
357 DataChangedEventType GetType() const { return mnType; }
358 AllSettingsFlags GetFlags() const { return mnFlags; }
359
360 const AllSettings* GetOldSettings() const;
361};
362
363inline DataChangedEvent::DataChangedEvent( DataChangedEventType nType,
364 const void* pData,
365 AllSettingsFlags nChangeFlags )
366{
367 mpData = const_cast<void*>(pData);
368 mnFlags = nChangeFlags;
369 mnType = nType;
370}
371
372inline const AllSettings* DataChangedEvent::GetOldSettings() const
373{
374 if ( mnType == DataChangedEventType::SETTINGS )
375 return static_cast<const AllSettings*>(mpData);
376 else
377 return nullptr;
378}
379
380#endif // INCLUDED_VCL_EVENT_HXX
381
382/* vim:set shiftwidth=4 softtabstop=4 expandtab: */