1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sd.hxx" 30 31 #include <com/sun/star/presentation/EffectNodeType.hpp> 32 33 #include "fuconbez.hxx" 34 #include <svl/aeitem.hxx> 35 #include <svx/svdopath.hxx> 36 #include <svl/intitem.hxx> 37 #include <sfx2/dispatch.hxx> 38 #include <svx/svdobj.hxx> 39 #include <sfx2/bindings.hxx> 40 #include <sfx2/request.hxx> 41 #include <sfx2/viewfrm.hxx> 42 43 44 #include <svx/svxids.hrc> 45 #include <svx/svdpagv.hxx> 46 47 #include "app.hrc" 48 #include "ViewShell.hxx" 49 #include "ViewShellBase.hxx" 50 #include "View.hxx" 51 #include "Window.hxx" 52 #include "ToolBarManager.hxx" 53 #include "drawdoc.hxx" 54 #include "res_bmp.hrc" 55 #include <basegfx/polygon/b2dpolygon.hxx> 56 #include <basegfx/polygon/b2dpolygontools.hxx> 57 58 #include "CustomAnimationEffect.hxx" 59 60 using namespace ::com::sun::star::uno; 61 62 namespace sd { 63 64 TYPEINIT1( FuConstructBezierPolygon, FuConstruct ); 65 66 67 /************************************************************************* 68 |* 69 |* Konstruktor 70 |* 71 \************************************************************************/ 72 73 FuConstructBezierPolygon::FuConstructBezierPolygon ( 74 ViewShell* pViewSh, 75 ::sd::Window* pWin, 76 ::sd::View* pView, 77 SdDrawDocument* pDoc, 78 SfxRequest& rReq) 79 : FuConstruct(pViewSh, pWin, pView, pDoc, rReq), 80 nEditMode(SID_BEZIER_MOVE) 81 { 82 } 83 84 FunctionReference FuConstructBezierPolygon::Create( ViewShell* pViewSh, ::sd::Window* pWin, ::sd::View* pView, SdDrawDocument* pDoc, SfxRequest& rReq, bool bPermanent ) 85 { 86 FuConstructBezierPolygon* pFunc; 87 FunctionReference xFunc( pFunc = new FuConstructBezierPolygon( pViewSh, pWin, pView, pDoc, rReq ) ); 88 xFunc->DoExecute(rReq); 89 pFunc->SetPermanent(bPermanent); 90 return xFunc; 91 } 92 93 void FuConstructBezierPolygon::DoExecute( SfxRequest& rReq ) 94 { 95 FuConstruct::DoExecute( rReq ); 96 97 const SfxItemSet* pArgs = rReq.GetArgs(); 98 if( pArgs ) 99 { 100 const SfxPoolItem* pPoolItem = NULL; 101 if( SFX_ITEM_SET == pArgs->GetItemState( SID_ADD_MOTION_PATH, sal_True, &pPoolItem ) ) 102 maTargets = ( ( const SfxUnoAnyItem* ) pPoolItem )->GetValue(); 103 } 104 } 105 106 /************************************************************************* 107 |* 108 |* MouseButtonDown-event 109 |* 110 \************************************************************************/ 111 112 sal_Bool FuConstructBezierPolygon::MouseButtonDown(const MouseEvent& rMEvt) 113 { 114 sal_Bool bReturn = FuConstruct::MouseButtonDown(rMEvt); 115 116 SdrViewEvent aVEvt; 117 SdrHitKind eHit = mpView->PickAnything(rMEvt, SDRMOUSEBUTTONDOWN, aVEvt); 118 119 if (eHit == SDRHIT_HANDLE || rMEvt.IsMod1()) 120 { 121 mpView->SetEditMode(SDREDITMODE_EDIT); 122 } 123 else 124 { 125 mpView->SetEditMode(SDREDITMODE_CREATE); 126 } 127 128 if (aVEvt.eEvent == SDREVENT_BEGTEXTEDIT) 129 { 130 // Texteingabe hier nicht zulassen 131 aVEvt.eEvent = SDREVENT_BEGDRAGOBJ; 132 mpView->EnableExtendedMouseEventDispatcher(sal_False); 133 } 134 else 135 { 136 mpView->EnableExtendedMouseEventDispatcher(sal_True); 137 } 138 139 if (eHit == SDRHIT_MARKEDOBJECT && nEditMode == SID_BEZIER_INSERT) 140 { 141 /****************************************************************** 142 * Klebepunkt einfuegen 143 ******************************************************************/ 144 mpView->BegInsObjPoint(aMDPos, rMEvt.IsMod1()); 145 } 146 else 147 { 148 mpView->MouseButtonDown(rMEvt, mpWindow); 149 150 SdrObject* pObj = mpView->GetCreateObj(); 151 152 if (pObj) 153 { 154 SfxItemSet aAttr(mpDoc->GetPool()); 155 SetStyleSheet(aAttr, pObj); 156 pObj->SetMergedItemSet(aAttr); 157 } 158 } 159 160 return(bReturn); 161 } 162 163 /************************************************************************* 164 |* 165 |* MouseMove-event 166 |* 167 \************************************************************************/ 168 169 sal_Bool FuConstructBezierPolygon::MouseMove(const MouseEvent& rMEvt) 170 { 171 sal_Bool bReturn = FuConstruct::MouseMove(rMEvt); 172 return(bReturn); 173 } 174 175 /************************************************************************* 176 |* 177 |* MouseButtonUp-event 178 |* 179 \************************************************************************/ 180 181 sal_Bool FuConstructBezierPolygon::MouseButtonUp(const MouseEvent& rMEvt ) 182 { 183 sal_Bool bReturn = sal_False; 184 sal_Bool bCreated = sal_False; 185 186 SdrViewEvent aVEvt; 187 mpView->PickAnything(rMEvt, SDRMOUSEBUTTONUP, aVEvt); 188 189 sal_uLong nCount = mpView->GetSdrPageView()->GetObjList()->GetObjCount(); 190 191 if (mpView->IsInsObjPoint()) 192 { 193 mpView->EndInsObjPoint(SDRCREATE_FORCEEND); 194 } 195 else 196 { 197 mpView->MouseButtonUp(rMEvt, mpWindow); 198 } 199 200 if (aVEvt.eEvent == SDREVENT_ENDCREATE) 201 { 202 bReturn = sal_True; 203 204 if (nCount == (mpView->GetSdrPageView()->GetObjList()->GetObjCount() - 1)) 205 { 206 bCreated = sal_True; 207 } 208 209 // Trick, um FuDraw::DoubleClick nicht auszuloesen 210 bMBDown = sal_False; 211 212 } 213 214 bReturn = FuConstruct::MouseButtonUp(rMEvt) || bReturn; 215 216 bool bDeleted = false; 217 if( bCreated && maTargets.hasValue() ) 218 { 219 SdrPathObj* pPathObj = dynamic_cast< SdrPathObj* >( mpView->GetSdrPageView()->GetObjList()->GetObj( nCount ) ); 220 SdPage* pPage = dynamic_cast< SdPage* >( pPathObj ? pPathObj->GetPage() : 0 ); 221 if( pPage ) 222 { 223 boost::shared_ptr< sd::MainSequence > pMainSequence( pPage->getMainSequence() ); 224 if( pMainSequence.get() ) 225 { 226 Sequence< Any > aTargets; 227 maTargets >>= aTargets; 228 229 sal_Int32 nTCount = aTargets.getLength(); 230 if( nTCount > 1 ) 231 { 232 const Any* pTarget = aTargets.getConstArray(); 233 double fDuration = 0.0; 234 *pTarget++ >>= fDuration; 235 bool bFirst = true; 236 while( --nTCount ) 237 { 238 CustomAnimationEffectPtr pCreated( pMainSequence->append( *pPathObj, *pTarget++, fDuration ) ); 239 if( bFirst ) 240 bFirst = false; 241 else 242 pCreated->setNodeType( ::com::sun::star::presentation::EffectNodeType::WITH_PREVIOUS ); 243 } 244 } 245 } 246 } 247 mpView->DeleteMarked(); 248 bDeleted = true; 249 } 250 251 if ((!bPermanent && bCreated) || bDeleted) 252 { 253 mpViewShell->GetViewFrame()->GetDispatcher()->Execute(SID_OBJECT_SELECT, SFX_CALLMODE_ASYNCHRON); 254 } 255 256 return(bReturn); 257 } 258 259 /************************************************************************* 260 |* 261 |* Tastaturereignisse bearbeiten 262 |* 263 |* Wird ein KeyEvent bearbeitet, so ist der Return-Wert sal_True, andernfalls 264 |* sal_False. 265 |* 266 \************************************************************************/ 267 268 sal_Bool FuConstructBezierPolygon::KeyInput(const KeyEvent& rKEvt) 269 { 270 sal_Bool bReturn = FuConstruct::KeyInput(rKEvt); 271 272 return(bReturn); 273 } 274 275 /************************************************************************* 276 |* 277 |* Function aktivieren 278 |* 279 \************************************************************************/ 280 281 void FuConstructBezierPolygon::Activate() 282 { 283 mpView->EnableExtendedMouseEventDispatcher(sal_True); 284 285 SdrObjKind eKind; 286 287 switch (nSlotId) 288 { 289 case SID_DRAW_POLYGON_NOFILL: 290 case SID_DRAW_XPOLYGON_NOFILL: 291 { 292 eKind = OBJ_PLIN; 293 } 294 break; 295 296 case SID_DRAW_POLYGON: 297 case SID_DRAW_XPOLYGON: 298 { 299 eKind = OBJ_POLY; 300 } 301 break; 302 303 case SID_DRAW_BEZIER_NOFILL: 304 { 305 eKind = OBJ_PATHLINE; 306 } 307 break; 308 309 case SID_DRAW_BEZIER_FILL: 310 { 311 eKind = OBJ_PATHFILL; 312 } 313 break; 314 315 case SID_DRAW_FREELINE_NOFILL: 316 { 317 eKind = OBJ_FREELINE; 318 } 319 break; 320 321 case SID_DRAW_FREELINE: 322 { 323 eKind = OBJ_FREEFILL; 324 } 325 break; 326 327 default: 328 { 329 eKind = OBJ_PATHLINE; 330 } 331 break; 332 } 333 334 mpView->SetCurrentObj((sal_uInt16)eKind); 335 336 FuConstruct::Activate(); 337 } 338 339 /************************************************************************* 340 |* 341 |* Function deaktivieren 342 |* 343 \************************************************************************/ 344 345 void FuConstructBezierPolygon::Deactivate() 346 { 347 mpView->EnableExtendedMouseEventDispatcher(sal_False); 348 349 FuConstruct::Deactivate(); 350 } 351 352 353 /************************************************************************* 354 |* 355 |* Selektion hat sich geaendert 356 |* 357 \************************************************************************/ 358 359 void FuConstructBezierPolygon::SelectionHasChanged() 360 { 361 FuDraw::SelectionHasChanged(); 362 363 mpViewShell->GetViewShellBase().GetToolBarManager()->SelectionHasChanged( 364 *mpViewShell, 365 *mpView); 366 } 367 368 369 370 /************************************************************************* 371 |* 372 |* Aktuellen Bezier-Editmodus setzen 373 |* 374 \************************************************************************/ 375 376 void FuConstructBezierPolygon::SetEditMode(sal_uInt16 nMode) 377 { 378 nEditMode = nMode; 379 ForcePointer(); 380 381 SfxBindings& rBindings = mpViewShell->GetViewFrame()->GetBindings(); 382 rBindings.Invalidate(SID_BEZIER_MOVE); 383 rBindings.Invalidate(SID_BEZIER_INSERT); 384 } 385 386 // #97016# 387 SdrObject* FuConstructBezierPolygon::CreateDefaultObject(const sal_uInt16 nID, const Rectangle& rRectangle) 388 { 389 // case SID_DRAW_POLYGON: 390 // case SID_DRAW_POLYGON_NOFILL: 391 // case SID_DRAW_XPOLYGON: 392 // case SID_DRAW_XPOLYGON_NOFILL: 393 // case SID_DRAW_FREELINE: 394 // case SID_DRAW_FREELINE_NOFILL: 395 // case SID_DRAW_BEZIER_FILL: // BASIC 396 // case SID_DRAW_BEZIER_NOFILL: // BASIC 397 398 SdrObject* pObj = SdrObjFactory::MakeNewObject( 399 mpView->GetCurrentObjInventor(), mpView->GetCurrentObjIdentifier(), 400 0L, mpDoc); 401 402 if(pObj) 403 { 404 if(pObj->ISA(SdrPathObj)) 405 { 406 basegfx::B2DPolyPolygon aPoly; 407 408 switch(nID) 409 { 410 case SID_DRAW_BEZIER_FILL: 411 { 412 const sal_Int32 nWdt(rRectangle.GetWidth() / 2); 413 const sal_Int32 nHgt(rRectangle.GetHeight() / 2); 414 const basegfx::B2DPolygon aInnerPoly(basegfx::tools::createPolygonFromEllipse(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y()), nWdt, nHgt)); 415 416 aPoly.append(aInnerPoly); 417 break; 418 } 419 case SID_DRAW_BEZIER_NOFILL: 420 { 421 basegfx::B2DPolygon aInnerPoly; 422 423 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom())); 424 425 const basegfx::B2DPoint aCenterBottom(rRectangle.Center().X(), rRectangle.Bottom()); 426 aInnerPoly.appendBezierSegment( 427 aCenterBottom, 428 aCenterBottom, 429 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y())); 430 431 const basegfx::B2DPoint aCenterTop(rRectangle.Center().X(), rRectangle.Top()); 432 aInnerPoly.appendBezierSegment( 433 aCenterTop, 434 aCenterTop, 435 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top())); 436 437 aPoly.append(aInnerPoly); 438 break; 439 } 440 case SID_DRAW_FREELINE: 441 case SID_DRAW_FREELINE_NOFILL: 442 { 443 basegfx::B2DPolygon aInnerPoly; 444 445 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom())); 446 447 aInnerPoly.appendBezierSegment( 448 basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top()), 449 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top()), 450 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y())); 451 452 aInnerPoly.appendBezierSegment( 453 basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom()), 454 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom()), 455 basegfx::B2DPoint(rRectangle.Right(), rRectangle.Top())); 456 457 if(SID_DRAW_FREELINE == nID) 458 { 459 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom())); 460 } 461 else 462 { 463 aInnerPoly.setClosed(true); 464 } 465 466 aPoly.append(aInnerPoly); 467 break; 468 } 469 case SID_DRAW_XPOLYGON: 470 case SID_DRAW_XPOLYGON_NOFILL: 471 { 472 basegfx::B2DPolygon aInnerPoly; 473 474 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom())); 475 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top())); 476 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Top())); 477 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Center().Y())); 478 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Center().Y())); 479 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Right(), rRectangle.Bottom())); 480 481 if(SID_DRAW_XPOLYGON_NOFILL == nID) 482 { 483 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom())); 484 } 485 else 486 { 487 aInnerPoly.setClosed(true); 488 } 489 490 aPoly.append(aInnerPoly); 491 break; 492 } 493 case SID_DRAW_POLYGON: 494 case SID_DRAW_POLYGON_NOFILL: 495 { 496 basegfx::B2DPolygon aInnerPoly; 497 const sal_Int32 nWdt(rRectangle.GetWidth()); 498 const sal_Int32 nHgt(rRectangle.GetHeight()); 499 500 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Bottom())); 501 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 30) / 100, rRectangle.Top() + (nHgt * 70) / 100)); 502 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left(), rRectangle.Top() + (nHgt * 15) / 100)); 503 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 65) / 100, rRectangle.Top())); 504 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + nWdt, rRectangle.Top() + (nHgt * 30) / 100)); 505 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 50) / 100)); 506 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Left() + (nWdt * 80) / 100, rRectangle.Top() + (nHgt * 75) / 100)); 507 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Bottom(), rRectangle.Right())); 508 509 if(SID_DRAW_POLYGON_NOFILL == nID) 510 { 511 aInnerPoly.append(basegfx::B2DPoint(rRectangle.Center().X(), rRectangle.Bottom())); 512 } 513 else 514 { 515 aInnerPoly.setClosed(true); 516 } 517 518 aPoly.append(aInnerPoly); 519 break; 520 } 521 } 522 523 ((SdrPathObj*)pObj)->SetPathPoly(aPoly); 524 } 525 else 526 { 527 DBG_ERROR("Object is NO path object"); 528 } 529 530 pObj->SetLogicRect(rRectangle); 531 } 532 533 return pObj; 534 } 535 536 } // end of namespace sd 537 538 // eof 539