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 <svtools/scrolladaptor.hxx> 21 #include <svx/svdview.hxx> 22 #include <dlgedfunc.hxx> 23 #include <dlged.hxx> 24 #include <dlgedview.hxx> 25 #include <vcl/seleng.hxx> 26 27 namespace basctl 28 { 29 30 IMPL_LINK_NOARG( DlgEdFunc, ScrollTimeout, Timer *, void ) 31 { 32 vcl::Window& rWindow = rParent.GetWindow(); 33 Point aPos = rWindow.ScreenToOutputPixel( rWindow.GetPointerPosPixel() ); 34 aPos = rWindow.PixelToLogic( aPos ); 35 ForceScroll( aPos ); 36 } 37 38 void DlgEdFunc::ForceScroll( const Point& rPos ) 39 { 40 aScrollTimer.Stop(); 41 42 vcl::Window& rWindow = rParent.GetWindow(); 43 44 static const Point aDefPoint; 45 tools::Rectangle aOutRect( aDefPoint, rWindow.GetOutputSizePixel() ); 46 aOutRect = rWindow.PixelToLogic( aOutRect ); 47 48 ScrollAdaptor* pHScroll = rParent.GetHScroll(); 49 ScrollAdaptor* pVScroll = rParent.GetVScroll(); 50 tools::Long nDeltaX = pHScroll->GetLineSize(); 51 tools::Long nDeltaY = pVScroll->GetLineSize(); 52 53 if( !aOutRect.Contains( rPos ) ) 54 { 55 if( rPos.X() < aOutRect.Left() ) 56 nDeltaX = -nDeltaX; 57 else if( rPos.X() <= aOutRect.Right() ) 58 nDeltaX = 0; 59 60 if( rPos.Y() < aOutRect.Top() ) 61 nDeltaY = -nDeltaY; 62 else if( rPos.Y() <= aOutRect.Bottom() ) 63 nDeltaY = 0; 64 65 if( nDeltaX ) 66 pHScroll->SetThumbPos( pHScroll->GetThumbPos() + nDeltaX ); 67 if( nDeltaY ) 68 pVScroll->SetThumbPos( pVScroll->GetThumbPos() + nDeltaY ); 69 70 if( nDeltaX ) 71 rParent.DoScroll(); 72 if( nDeltaY ) 73 rParent.DoScroll(); 74 } 75 76 aScrollTimer.Start(); 77 } 78 79 DlgEdFunc::DlgEdFunc (DlgEditor& rParent_) : 80 rParent(rParent_), aScrollTimer("basctl DlgEdFunc aScrollTimer") 81 { 82 aScrollTimer.SetInvokeHandler( LINK( this, DlgEdFunc, ScrollTimeout ) ); 83 aScrollTimer.SetTimeout( SELENG_AUTOREPEAT_INTERVAL ); 84 } 85 86 DlgEdFunc::~DlgEdFunc() 87 { 88 } 89 90 void DlgEdFunc::MouseButtonDown( const MouseEvent& ) 91 { 92 } 93 94 bool DlgEdFunc::MouseButtonUp( const MouseEvent& ) 95 { 96 aScrollTimer.Stop(); 97 return true; 98 } 99 100 void DlgEdFunc::MouseMove( const MouseEvent& ) 101 { 102 } 103 104 bool DlgEdFunc::KeyInput( const KeyEvent& rKEvt ) 105 { 106 bool bReturn = false; 107 108 SdrView& rView = rParent.GetView(); 109 vcl::Window& rWindow = rParent.GetWindow(); 110 111 vcl::KeyCode aCode = rKEvt.GetKeyCode(); 112 sal_uInt16 nCode = aCode.GetCode(); 113 114 switch ( nCode ) 115 { 116 case KEY_ESCAPE: 117 { 118 if ( rView.IsAction() ) 119 { 120 rView.BrkAction(); 121 bReturn = true; 122 } 123 else if ( rView.AreObjectsMarked() ) 124 { 125 const SdrHdlList& rHdlList = rView.GetHdlList(); 126 SdrHdl* pHdl = rHdlList.GetFocusHdl(); 127 if ( pHdl ) 128 const_cast<SdrHdlList&>(rHdlList).ResetFocusHdl(); 129 else 130 rView.UnmarkAll(); 131 132 bReturn = true; 133 } 134 } 135 break; 136 case KEY_TAB: 137 { 138 if ( !aCode.IsMod1() && !aCode.IsMod2() ) 139 { 140 // mark next object 141 if ( !rView.MarkNextObj( !aCode.IsShift() ) ) 142 { 143 // if no next object, mark first/last 144 rView.UnmarkAllObj(); 145 rView.MarkNextObj( !aCode.IsShift() ); 146 } 147 148 if ( rView.AreObjectsMarked() ) 149 rView.MakeVisible( rView.GetAllMarkedRect(), rWindow ); 150 151 bReturn = true; 152 } 153 else if ( aCode.IsMod1() ) 154 { 155 // selected handle 156 const SdrHdlList& rHdlList = rView.GetHdlList(); 157 const_cast<SdrHdlList&>(rHdlList).TravelFocusHdl( !aCode.IsShift() ); 158 159 // guarantee visibility of focused handle 160 if (SdrHdl* pHdl = rHdlList.GetFocusHdl()) 161 { 162 Point aHdlPosition( pHdl->GetPos() ); 163 tools::Rectangle aVisRect( aHdlPosition - Point( 100, 100 ), Size( 200, 200 ) ); 164 rView.MakeVisible( aVisRect, rWindow ); 165 } 166 167 bReturn = true; 168 } 169 } 170 break; 171 case KEY_UP: 172 case KEY_DOWN: 173 case KEY_LEFT: 174 case KEY_RIGHT: 175 { 176 tools::Long nX = 0; 177 tools::Long nY = 0; 178 179 if ( nCode == KEY_UP ) 180 { 181 // scroll up 182 nX = 0; 183 nY = -1; 184 } 185 else if ( nCode == KEY_DOWN ) 186 { 187 // scroll down 188 nX = 0; 189 nY = 1; 190 } 191 else if ( nCode == KEY_LEFT ) 192 { 193 // scroll left 194 nX = -1; 195 nY = 0; 196 } 197 else if ( nCode == KEY_RIGHT ) 198 { 199 // scroll right 200 nX = 1; 201 nY = 0; 202 } 203 204 if ( rView.AreObjectsMarked() && !aCode.IsMod1() ) 205 { 206 if ( aCode.IsMod2() ) 207 { 208 // move in 1 pixel distance 209 Size aPixelSize = rWindow.PixelToLogic(Size(1, 1)); 210 nX *= aPixelSize.Width(); 211 nY *= aPixelSize.Height(); 212 } 213 else 214 { 215 // move in 1 mm distance 216 nX *= 100; 217 nY *= 100; 218 } 219 220 const SdrHdlList& rHdlList = rView.GetHdlList(); 221 SdrHdl* pHdl = rHdlList.GetFocusHdl(); 222 223 if ( pHdl == nullptr ) 224 { 225 // no handle selected 226 if ( rView.IsMoveAllowed() ) 227 { 228 // restrict movement to work area 229 const tools::Rectangle& rWorkArea = rView.GetWorkArea(); 230 231 if ( !rWorkArea.IsEmpty() ) 232 { 233 tools::Rectangle aMarkRect( rView.GetMarkedObjRect() ); 234 aMarkRect.Move( nX, nY ); 235 236 if ( !rWorkArea.Contains( aMarkRect ) ) 237 { 238 if ( aMarkRect.Left() < rWorkArea.Left() ) 239 nX += rWorkArea.Left() - aMarkRect.Left(); 240 241 if ( aMarkRect.Right() > rWorkArea.Right() ) 242 nX -= aMarkRect.Right() - rWorkArea.Right(); 243 244 if ( aMarkRect.Top() < rWorkArea.Top() ) 245 nY += rWorkArea.Top() - aMarkRect.Top(); 246 247 if ( aMarkRect.Bottom() > rWorkArea.Bottom() ) 248 nY -= aMarkRect.Bottom() - rWorkArea.Bottom(); 249 } 250 } 251 252 if ( nX != 0 || nY != 0 ) 253 { 254 rView.MoveAllMarked( Size( nX, nY ) ); 255 rView.MakeVisible( rView.GetAllMarkedRect(), rWindow ); 256 } 257 } 258 } 259 else if (nX || nY) 260 { 261 Point aStartPoint(pHdl->GetPos()); 262 Point aEndPoint(pHdl->GetPos() + Point(nX, nY)); 263 const SdrDragStat& rDragStat = rView.GetDragStat(); 264 265 // start dragging 266 rView.BegDragObj(aStartPoint, nullptr, pHdl, 0); 267 268 if (rView.IsDragObj()) 269 { 270 bool const bWasNoSnap = rDragStat.IsNoSnap(); 271 bool const bWasSnapEnabled = rView.IsSnapEnabled(); 272 273 // switch snapping off 274 if (!bWasNoSnap) 275 const_cast<SdrDragStat&>(rDragStat).SetNoSnap(); 276 if (bWasSnapEnabled) 277 rView.SetSnapEnabled(false); 278 279 rView.MovAction(aEndPoint); 280 rView.EndDragObj(); 281 282 // restore snap 283 if (!bWasNoSnap) 284 const_cast<SdrDragStat&>(rDragStat).SetNoSnap(bWasNoSnap); 285 if (bWasSnapEnabled) 286 rView.SetSnapEnabled(bWasSnapEnabled); 287 } 288 289 // make moved handle visible 290 tools::Rectangle aVisRect(aEndPoint - Point(100, 100), Size(200, 200)); 291 rView.MakeVisible(aVisRect, rWindow); 292 } 293 } 294 else 295 { 296 // scroll page 297 ScrollAdaptor* pScrollBar = ( nX != 0 ) ? rParent.GetHScroll() : rParent.GetVScroll(); 298 if ( pScrollBar ) 299 { 300 tools::Long nRangeMin = pScrollBar->GetRangeMin(); 301 tools::Long nRangeMax = pScrollBar->GetRangeMax(); 302 tools::Long nThumbPos = pScrollBar->GetThumbPos() + ( ( nX != 0 ) ? nX : nY ) * pScrollBar->GetLineSize(); 303 if ( nThumbPos < nRangeMin ) 304 nThumbPos = nRangeMin; 305 if ( nThumbPos > nRangeMax ) 306 nThumbPos = nRangeMax; 307 pScrollBar->SetThumbPos( nThumbPos ); 308 rParent.DoScroll(); 309 } 310 } 311 312 bReturn = true; 313 } 314 break; 315 default: 316 { 317 } 318 break; 319 } 320 321 if ( bReturn ) 322 rWindow.ReleaseMouse(); 323 324 return bReturn; 325 } 326 327 DlgEdFuncInsert::DlgEdFuncInsert (DlgEditor& rParent_) : 328 DlgEdFunc(rParent_) 329 { 330 rParent.GetView().SetCreateMode(); 331 } 332 333 DlgEdFuncInsert::~DlgEdFuncInsert() 334 { 335 rParent.GetView().SetEditMode(); 336 } 337 338 void DlgEdFuncInsert::MouseButtonDown( const MouseEvent& rMEvt ) 339 { 340 if( !rMEvt.IsLeft() ) 341 return; 342 343 SdrView& rView = rParent.GetView(); 344 vcl::Window& rWindow = rParent.GetWindow(); 345 rView.SetActualWin(rWindow.GetOutDev()); 346 347 Point aPos = rWindow.PixelToLogic( rMEvt.GetPosPixel() ); 348 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 349 sal_uInt16 nDrgLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 350 351 rWindow.CaptureMouse(); 352 353 if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 ) 354 { 355 SdrHdl* pHdl = rView.PickHandle(aPos); 356 357 // if selected object was hit, drag object 358 if ( pHdl!=nullptr || rView.IsMarkedHit(aPos, nHitLog) ) 359 rView.BegDragObj(aPos, nullptr, pHdl, nDrgLog); 360 else if ( rView.AreObjectsMarked() ) 361 rView.UnmarkAll(); 362 363 // if no action, create object 364 if ( !rView.IsAction() ) 365 rView.BegCreateObj(aPos); 366 } 367 else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 ) 368 { 369 // if object was hit, show property browser 370 if ( rView.IsMarkedHit(aPos, nHitLog) && rParent.GetMode() != DlgEditor::READONLY ) 371 rParent.ShowProperties(); 372 } 373 } 374 375 bool DlgEdFuncInsert::MouseButtonUp( const MouseEvent& rMEvt ) 376 { 377 DlgEdFunc::MouseButtonUp( rMEvt ); 378 379 SdrView& rView = rParent.GetView(); 380 vcl::Window& rWindow = rParent.GetWindow(); 381 rView.SetActualWin(rWindow.GetOutDev()); 382 383 rWindow.ReleaseMouse(); 384 385 // object creation active? 386 if ( rView.IsCreateObj() ) 387 { 388 rView.EndCreateObj(SdrCreateCmd::ForceEnd); 389 390 if ( !rView.AreObjectsMarked() ) 391 { 392 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 393 Point aPos( rWindow.PixelToLogic( rMEvt.GetPosPixel() ) ); 394 rView.MarkObj(aPos, nHitLog); 395 } 396 397 return rView.AreObjectsMarked(); 398 } 399 else 400 { 401 if ( rView.IsDragObj() ) 402 rView.EndDragObj( rMEvt.IsMod1() ); 403 return true; 404 } 405 } 406 407 void DlgEdFuncInsert::MouseMove( const MouseEvent& rMEvt ) 408 { 409 SdrView& rView = rParent.GetView(); 410 vcl::Window& rWindow = rParent.GetWindow(); 411 rView.SetActualWin(rWindow.GetOutDev()); 412 413 Point aPos = rWindow.PixelToLogic(rMEvt.GetPosPixel()); 414 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 415 416 if (rView.IsAction()) 417 { 418 ForceScroll(aPos); 419 rView.MovAction(aPos); 420 } 421 422 rWindow.SetPointer( rView.GetPreferredPointer( aPos, rWindow.GetOutDev(), nHitLog ) ); 423 } 424 425 DlgEdFuncSelect::DlgEdFuncSelect (DlgEditor& rParent_) : 426 DlgEdFunc(rParent_) 427 { 428 } 429 430 DlgEdFuncSelect::~DlgEdFuncSelect() 431 { 432 } 433 434 void DlgEdFuncSelect::MouseButtonDown( const MouseEvent& rMEvt ) 435 { 436 // get view from parent 437 SdrView& rView = rParent.GetView(); 438 vcl::Window& rWindow = rParent.GetWindow(); 439 rView.SetActualWin(rWindow.GetOutDev()); 440 441 sal_uInt16 nDrgLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 442 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 443 Point aMDPos = rWindow.PixelToLogic(rMEvt.GetPosPixel()); 444 445 if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 1 ) 446 { 447 SdrHdl* pHdl = rView.PickHandle(aMDPos); 448 449 // hit selected object? 450 if ( pHdl!=nullptr || rView.IsMarkedHit(aMDPos, nHitLog) ) 451 { 452 rView.BegDragObj(aMDPos, nullptr, pHdl, nDrgLog); 453 } 454 else 455 { 456 // if not multi selection, unmark all 457 if ( !rMEvt.IsShift() ) 458 rView.UnmarkAll(); 459 else 460 { 461 SdrPageView* pPV; 462 SdrObject* pObj = rView.PickObj(aMDPos, nHitLog, pPV); 463 if (pObj) 464 { 465 //if (dynamic_cast<DlgEdForm*>(pObj)) 466 // rView.UnmarkAll(); 467 //else 468 // rParent.UnmarkDialog(); 469 } 470 } 471 472 if ( rView.MarkObj(aMDPos, nHitLog) ) 473 { 474 // drag object 475 pHdl = rView.PickHandle(aMDPos); 476 rView.BegDragObj(aMDPos, nullptr, pHdl, nDrgLog); 477 } 478 else 479 { 480 // select object 481 rView.BegMarkObj(aMDPos); 482 } 483 } 484 } 485 else if ( rMEvt.IsLeft() && rMEvt.GetClicks() == 2 ) 486 { 487 // if object was hit, show property browser 488 if ( rView.IsMarkedHit(aMDPos, nHitLog) && rParent.GetMode() != DlgEditor::READONLY ) 489 rParent.ShowProperties(); 490 } 491 } 492 493 bool DlgEdFuncSelect::MouseButtonUp( const MouseEvent& rMEvt ) 494 { 495 DlgEdFunc::MouseButtonUp( rMEvt ); 496 497 // get view from parent 498 SdrView& rView = rParent.GetView(); 499 vcl::Window& rWindow = rParent.GetWindow(); 500 rView.SetActualWin(rWindow.GetOutDev()); 501 502 Point aPnt = rWindow.PixelToLogic(rMEvt.GetPosPixel()); 503 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 504 505 if ( rMEvt.IsLeft() ) 506 { 507 if (rView.IsDragObj()) 508 { 509 // object was dragged 510 rView.EndDragObj( rMEvt.IsMod1() ); 511 rView.ForceMarkedToAnotherPage(); 512 } 513 else if (rView.IsAction()) 514 { 515 rView.EndAction(); 516 } 517 } 518 519 rWindow.SetPointer( rView.GetPreferredPointer( aPnt, rWindow.GetOutDev(), nHitLog ) ); 520 rWindow.ReleaseMouse(); 521 522 return true; 523 } 524 525 void DlgEdFuncSelect::MouseMove( const MouseEvent& rMEvt ) 526 { 527 SdrView& rView = rParent.GetView(); 528 vcl::Window& rWindow = rParent.GetWindow(); 529 rView.SetActualWin(rWindow.GetOutDev()); 530 531 Point aPnt = rWindow.PixelToLogic(rMEvt.GetPosPixel()); 532 sal_uInt16 nHitLog = static_cast<sal_uInt16>(rWindow.PixelToLogic(Size(3, 0)).Width()); 533 534 if ( rView.IsAction() ) 535 { 536 Point aPix = rMEvt.GetPosPixel(); 537 Point aPnt_ = rWindow.PixelToLogic(aPix); 538 539 ForceScroll(aPnt_); 540 rView.MovAction(aPnt_); 541 } 542 543 rWindow.SetPointer( rView.GetPreferredPointer( aPnt, rWindow.GetOutDev(), nHitLog ) ); 544 } 545 546 } // namespace basctl 547 548 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 549
