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_sdext.hxx" 30 31 #include "PresenterSlideShowView.hxx" 32 33 #include "PresenterCanvasHelper.hxx" 34 #include "PresenterGeometryHelper.hxx" 35 #include "PresenterHelper.hxx" 36 #include "PresenterPaneContainer.hxx" 37 #include <com/sun/star/awt/InvalidateStyle.hpp> 38 #include <com/sun/star/awt/PosSize.hpp> 39 #include <com/sun/star/awt/WindowAttribute.hpp> 40 #include <com/sun/star/awt/XWindow.hpp> 41 #include <com/sun/star/awt/XWindow2.hpp> 42 #include <com/sun/star/awt/XWindowPeer.hpp> 43 #include <com/sun/star/beans/XPropertySet.hpp> 44 #include <com/sun/star/drawing/CanvasFeature.hpp> 45 #include <com/sun/star/drawing/XPresenterHelper.hpp> 46 #include <com/sun/star/drawing/framework/XControllerManager.hpp> 47 #include <com/sun/star/drawing/framework/XConfigurationController.hpp> 48 #include <com/sun/star/rendering/CompositeOperation.hpp> 49 #include <com/sun/star/rendering/TextDirection.hpp> 50 #include <com/sun/star/rendering/TexturingMode.hpp> 51 #include <osl/mutex.hxx> 52 53 using namespace ::com::sun::star; 54 using namespace ::com::sun::star::uno; 55 using namespace ::com::sun::star::drawing::framework; 56 using ::rtl::OUString; 57 58 #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) 59 60 namespace sdext { namespace presenter { 61 62 //===== PresenterSlideShowView ================================================ 63 64 PresenterSlideShowView::PresenterSlideShowView ( 65 const css::uno::Reference<css::uno::XComponentContext>& rxContext, 66 const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, 67 const css::uno::Reference<css::frame::XController>& rxController, 68 const ::rtl::Reference<PresenterController>& rpPresenterController) 69 : PresenterSlideShowViewInterfaceBase(m_aMutex), 70 mxComponentContext(rxContext), 71 mpPresenterController(rpPresenterController), 72 mxViewId(rxViewId), 73 mxController(rxController), 74 mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)), 75 mxSlideShow(), 76 mxCanvas(), 77 mxViewCanvas(), 78 mxPointer(), 79 mxWindow(), 80 mxViewWindow(), 81 mxTopPane(), 82 mxPresenterHelper(), 83 mxBackgroundPolygon1(), 84 mxBackgroundPolygon2(), 85 mbIsViewAdded(false), 86 mnPageAspectRatio(28.0/21.0), 87 maBroadcaster(m_aMutex), 88 mpBackground(), 89 mbIsInModifyNotification(false), 90 mbIsForcedPaintPending(false), 91 mbIsPaintPending(true), 92 msClickToExitPresentationText(), 93 msClickToExitPresentationTitle(), 94 msTitleTemplate(), 95 mbIsEndSlideVisible(false), 96 mxCurrentSlide() 97 { 98 if (mpPresenterController.get() != NULL) 99 { 100 mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio(); 101 mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL()); 102 } 103 } 104 105 106 107 void PresenterSlideShowView::LateInit (void) 108 { 109 mxSlideShow = Reference<presentation::XSlideShow> ( 110 mxSlideShowController->getSlideShow(), UNO_QUERY_THROW); 111 Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY); 112 if (xSlideShowComponent.is()) 113 xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this)); 114 115 Reference<lang::XMultiComponentFactory> xFactory ( 116 mxComponentContext->getServiceManager(), UNO_QUERY_THROW); 117 mxPresenterHelper.set (xFactory->createInstanceWithContext( 118 OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), 119 mxComponentContext), 120 UNO_QUERY_THROW); 121 122 // Use view id and controller to retrieve window and canvas from 123 // configuration controller. 124 Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW); 125 Reference<XConfigurationController> xCC (xCM->getConfigurationController()); 126 127 if (xCC.is()) 128 { 129 mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY); 130 131 Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW); 132 133 mxWindow = xPane->getWindow(); 134 mxCanvas = xPane->getCanvas(); 135 136 if (mxWindow.is()) 137 { 138 mxWindow->addPaintListener(this); 139 mxWindow->addWindowListener(this); 140 } 141 142 // The window does not have to paint a background. We do 143 // that ourself. 144 Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); 145 if (xPeer.is()) 146 xPeer->setBackground(util::Color(0xff000000)); 147 } 148 149 // Create a window for the actual slide show view. It is places 150 // centered and with maximal size inside the pane. 151 mxViewWindow = CreateViewWindow(mxWindow); 152 153 mxViewCanvas = CreateViewCanvas(mxViewWindow); 154 155 if (mxViewWindow.is()) 156 { 157 // Register listeners at window. 158 mxViewWindow->addPaintListener(this); 159 mxViewWindow->addMouseListener(this); 160 mxViewWindow->addMouseMotionListener(this); 161 } 162 163 if (mxViewWindow.is()) 164 Resize(); 165 166 if (mxWindow.is()) 167 mxWindow->setVisible(sal_True); 168 169 // Add the new slide show view to the slide show. 170 if (mxSlideShow.is() && ! mbIsViewAdded) 171 { 172 Reference<presentation::XSlideShowView> xView (this); 173 mxSlideShow->addView(xView); 174 // Prevent embeded sounds being played twice at the same time by 175 // disabling sound for the new slide show view. 176 beans::PropertyValue aProperty; 177 aProperty.Name = A2S("IsSoundEnabled"); 178 Sequence<Any> aValues (2); 179 aValues[0] <<= xView; 180 aValues[1] <<= sal_False; 181 aProperty.Value <<= aValues; 182 mxSlideShow->setProperty(aProperty); 183 mbIsViewAdded = true; 184 } 185 186 // Read text for one past last slide. 187 PresenterConfigurationAccess aConfiguration ( 188 mxComponentContext, 189 PresenterConfigurationAccess::msPresenterScreenRootName, 190 PresenterConfigurationAccess::READ_ONLY); 191 aConfiguration.GetConfigurationNode( 192 A2S("Presenter/Views/CurrentSlidePreview/" 193 "Strings/ClickToExitPresentationText/String")) 194 >>= msClickToExitPresentationText; 195 aConfiguration.GetConfigurationNode( 196 A2S("Presenter/Views/CurrentSlidePreview/" 197 "Strings/ClickToExitPresentationTitle/String")) 198 >>= msClickToExitPresentationTitle; 199 } 200 201 202 203 204 PresenterSlideShowView::~PresenterSlideShowView (void) 205 { 206 } 207 208 209 210 211 void PresenterSlideShowView::disposing (void) 212 { 213 // Tell all listeners that we are disposed. 214 lang::EventObject aEvent; 215 aEvent.Source = static_cast<XWeak*>(this); 216 217 ::cppu::OInterfaceContainerHelper* pIterator 218 = maBroadcaster.getContainer(getCppuType((Reference<lang::XEventListener>*)NULL)); 219 if (pIterator != NULL) 220 pIterator->disposeAndClear(aEvent); 221 222 // Do this for 223 // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener? 224 225 if (mxWindow.is()) 226 { 227 mxWindow->removePaintListener(this); 228 mxWindow->removeMouseListener(this); 229 mxWindow->removeMouseMotionListener(this); 230 mxWindow->removeWindowListener(this); 231 mxWindow = NULL; 232 } 233 mxSlideShowController = NULL; 234 mxSlideShow = NULL; 235 if (mxViewCanvas.is()) 236 { 237 Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY); 238 mxViewCanvas = NULL; 239 if (xComponent.is()) 240 xComponent->dispose(); 241 } 242 if (mxViewWindow.is()) 243 { 244 Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY); 245 mxViewWindow = NULL; 246 if (xComponent.is()) 247 xComponent->dispose(); 248 } 249 if (mxPointer.is()) 250 { 251 Reference<XComponent> xComponent (mxPointer, UNO_QUERY); 252 mxPointer = NULL; 253 if (xComponent.is()) 254 xComponent->dispose(); 255 } 256 if (mxBackgroundPolygon1.is()) 257 { 258 Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY); 259 mxBackgroundPolygon1 = NULL; 260 if (xComponent.is()) 261 xComponent->dispose(); 262 } 263 if (mxBackgroundPolygon2.is()) 264 { 265 Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY); 266 mxBackgroundPolygon2 = NULL; 267 if (xComponent.is()) 268 xComponent->dispose(); 269 } 270 271 mxComponentContext = NULL; 272 mpPresenterController = NULL; 273 mxViewId = NULL; 274 mxController = NULL; 275 mxCanvas = NULL; 276 mpBackground.reset(); 277 msClickToExitPresentationText = OUString(); 278 msClickToExitPresentationTitle = OUString(); 279 msTitleTemplate = OUString(); 280 mxCurrentSlide = NULL; 281 } 282 283 284 285 286 //----- XDrawView ------------------------------------------------------------- 287 288 void SAL_CALL PresenterSlideShowView::setCurrentPage ( 289 const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) 290 throw (css::uno::RuntimeException) 291 { 292 mxCurrentSlide = rxSlide; 293 if (mpPresenterController.get() != NULL 294 && mxSlideShowController.is() 295 && ! mpPresenterController->GetCurrentSlide().is() 296 && ! mxSlideShowController->isPaused()) 297 { 298 mbIsEndSlideVisible = true; 299 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); 300 if (xPeer.is()) 301 xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT); 302 303 // For the end slide we use a special title, without the (n of m) 304 // part. Save the title template for the case that the user goes 305 // backwards. 306 PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( 307 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); 308 if (pDescriptor.get() != NULL) 309 { 310 msTitleTemplate = pDescriptor->msTitleTemplate; 311 pDescriptor->msTitleTemplate = msClickToExitPresentationTitle; 312 mpPresenterController->UpdatePaneTitles(); 313 } 314 } 315 else if (mbIsEndSlideVisible) 316 { 317 mbIsEndSlideVisible = false; 318 319 // Restore the title template. 320 PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( 321 mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); 322 if (pDescriptor.get() != NULL) 323 { 324 pDescriptor->msTitleTemplate = msTitleTemplate; 325 pDescriptor->msTitle = OUString(); 326 mpPresenterController->UpdatePaneTitles(); 327 } 328 } 329 } 330 331 332 333 334 css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage (void) 335 throw (css::uno::RuntimeException) 336 { 337 return mxCurrentSlide; 338 } 339 340 341 342 343 //----- CachablePresenterView ------------------------------------------------- 344 345 void PresenterSlideShowView::ReleaseView (void) 346 { 347 if (mxSlideShow.is() && mbIsViewAdded) 348 { 349 mxSlideShow->removeView(this); 350 mbIsViewAdded = false; 351 } 352 } 353 354 355 356 357 //----- XSlideShowView -------------------------------------------------------- 358 359 Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas (void) 360 throw (RuntimeException) 361 { 362 ThrowIfDisposed(); 363 364 return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY); 365 } 366 367 368 369 370 void SAL_CALL PresenterSlideShowView::clear (void) 371 throw (RuntimeException) 372 { 373 ThrowIfDisposed(); 374 mbIsForcedPaintPending = false; 375 mbIsPaintPending = false; 376 377 if (mxViewCanvas.is() && mxViewWindow.is()) 378 { 379 // Create a polygon for the window outline. 380 awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); 381 Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon( 382 awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height), 383 mxViewCanvas->getDevice())); 384 385 rendering::ViewState aViewState ( 386 geometry::AffineMatrix2D(1,0,0, 0,1,0), 387 NULL); 388 double aColor[3] = {0,0,0}; 389 rendering::RenderState aRenderState( 390 geometry::AffineMatrix2D(1,0,0, 0,1,0), 391 NULL, 392 Sequence<double>(aColor,4), 393 rendering::CompositeOperation::SOURCE); 394 mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState); 395 } 396 } 397 398 399 400 401 geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation (void) 402 throw (RuntimeException) 403 { 404 ThrowIfDisposed(); 405 406 if (mxViewWindow.is()) 407 { 408 // When the mbIsInModifyNotification is set then a slightly modifed 409 // version of the transformation is returned in order to get past 410 // optimizations the avoid updates when the transformation is 411 // unchanged (when the window size changes then due to the constant 412 // aspect ratio the size of the preview may remain the same while 413 // the position changes. The position, however, is repesented by 414 // the position of the view window. This transformation is given 415 // relative to the view window and therefore does not contain the 416 // position.) 417 const awt::Rectangle aWindowBox = mxViewWindow->getPosSize(); 418 return geometry::AffineMatrix2D( 419 aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0), 420 0, aWindowBox.Height-1, 0); 421 } 422 else 423 { 424 return geometry::AffineMatrix2D(1,0,0, 0,1,0); 425 } 426 } 427 428 429 430 431 void SAL_CALL PresenterSlideShowView::addTransformationChangedListener( 432 const Reference<util::XModifyListener>& rxListener) 433 throw (RuntimeException) 434 { 435 ThrowIfDisposed(); 436 maBroadcaster.addListener( 437 getCppuType((Reference<util::XModifyListener>*)NULL), 438 rxListener); 439 } 440 441 442 443 444 void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener( 445 const Reference<util::XModifyListener>& rxListener) 446 throw (RuntimeException) 447 { 448 ThrowIfDisposed(); 449 maBroadcaster.removeListener( 450 getCppuType((Reference<util::XModifyListener>*)NULL), 451 rxListener); 452 } 453 454 455 456 457 void SAL_CALL PresenterSlideShowView::addPaintListener( 458 const Reference<awt::XPaintListener>& rxListener) 459 throw (RuntimeException) 460 { 461 ThrowIfDisposed(); 462 maBroadcaster.addListener( 463 getCppuType((Reference<awt::XPaintListener>*)NULL), 464 rxListener); 465 } 466 467 468 469 470 void SAL_CALL PresenterSlideShowView::removePaintListener( 471 const Reference<awt::XPaintListener>& rxListener) 472 throw (RuntimeException) 473 { 474 ThrowIfDisposed(); 475 maBroadcaster.removeListener( 476 getCppuType((Reference<awt::XPaintListener>*)NULL), 477 rxListener); 478 } 479 480 481 482 483 void SAL_CALL PresenterSlideShowView::addMouseListener( 484 const Reference<awt::XMouseListener>& rxListener) 485 throw (RuntimeException) 486 { 487 ThrowIfDisposed(); 488 maBroadcaster.addListener( 489 getCppuType((Reference<awt::XMouseListener>*)NULL), 490 rxListener); 491 } 492 493 494 495 496 void SAL_CALL PresenterSlideShowView::removeMouseListener( 497 const Reference<awt::XMouseListener>& rxListener) 498 throw (RuntimeException) 499 { 500 ThrowIfDisposed(); 501 maBroadcaster.removeListener( 502 getCppuType((Reference<awt::XMouseListener>*)NULL), 503 rxListener); 504 } 505 506 507 508 509 void SAL_CALL PresenterSlideShowView::addMouseMotionListener( 510 const Reference<awt::XMouseMotionListener>& rxListener) 511 throw (RuntimeException) 512 { 513 ThrowIfDisposed(); 514 maBroadcaster.addListener( 515 getCppuType((Reference<awt::XMouseMotionListener>*)NULL), 516 rxListener); 517 } 518 519 520 521 522 void SAL_CALL PresenterSlideShowView::removeMouseMotionListener( 523 const Reference<awt::XMouseMotionListener>& rxListener) 524 throw (RuntimeException) 525 { 526 ThrowIfDisposed(); 527 maBroadcaster.removeListener( 528 getCppuType((Reference<awt::XMouseMotionListener>*)NULL), 529 rxListener); 530 } 531 532 533 534 535 void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape) 536 throw (RuntimeException) 537 { 538 ThrowIfDisposed(); 539 540 // Create a pointer when it does not yet exist. 541 if ( ! mxPointer.is()) 542 { 543 Reference<lang::XMultiServiceFactory> xFactory ( 544 mxComponentContext, UNO_QUERY); 545 if (xFactory.is()) 546 mxPointer = Reference<awt::XPointer>( 547 xFactory->createInstance(OUString::createFromAscii("com.sun.star.awt.Pointer")), 548 UNO_QUERY); 549 } 550 551 // Set the pointer to the given shape and the window(peer) to the 552 // pointer. 553 Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); 554 if (mxPointer.is() && xPeer.is()) 555 { 556 mxPointer->setType(nPointerShape); 557 xPeer->setPointer(mxPointer); 558 } 559 } 560 561 562 563 awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException) 564 { 565 if( mxViewWindow.is() && mxTopPane.is() ) 566 return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() ); 567 568 awt::Rectangle aRectangle; 569 570 aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0; 571 572 return aRectangle; 573 } 574 575 576 577 //----- lang::XEventListener -------------------------------------------------- 578 579 void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent) 580 throw (RuntimeException) 581 { 582 if (rEvent.Source == mxViewWindow) 583 mxViewWindow = NULL; 584 else if (rEvent.Source == mxSlideShow) 585 mxSlideShow = NULL; 586 } 587 588 589 590 591 //----- XPaintListener -------------------------------------------------------- 592 593 void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent) 594 throw (RuntimeException) 595 { 596 // Deactivated views must not be painted. 597 if ( ! mbIsPresenterViewActive) 598 return; 599 600 awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); 601 if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0) 602 return; 603 604 if (rEvent.Source == mxWindow) 605 PaintOuterWindow(rEvent.UpdateRect); 606 else if (mbIsEndSlideVisible) 607 PaintEndSlide(rEvent.UpdateRect); 608 else 609 PaintInnerWindow(rEvent); 610 } 611 612 613 614 615 //----- XMouseListener -------------------------------------------------------- 616 617 void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent) 618 throw (RuntimeException) 619 { 620 awt::MouseEvent aEvent (rEvent); 621 aEvent.Source = static_cast<XWeak*>(this); 622 ::cppu::OInterfaceContainerHelper* pIterator 623 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); 624 if (pIterator != NULL) 625 { 626 pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent); 627 } 628 629 // Only when the end slide is displayed we forward the mouse event to 630 // the PresenterController so that it switches to the next slide and 631 // ends the presentation. 632 if (mbIsEndSlideVisible) 633 if (mpPresenterController.get() != NULL) 634 mpPresenterController->HandleMouseClick(rEvent); 635 } 636 637 638 639 640 void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent) 641 throw (RuntimeException) 642 { 643 awt::MouseEvent aEvent (rEvent); 644 aEvent.Source = static_cast<XWeak*>(this); 645 ::cppu::OInterfaceContainerHelper* pIterator 646 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); 647 if (pIterator != NULL) 648 { 649 pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent); 650 } 651 } 652 653 654 655 656 void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent) 657 throw (RuntimeException) 658 { 659 awt::MouseEvent aEvent (rEvent); 660 aEvent.Source = static_cast<XWeak*>(this); 661 ::cppu::OInterfaceContainerHelper* pIterator 662 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); 663 if (pIterator != NULL) 664 { 665 pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent); 666 } 667 } 668 669 670 671 672 void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent) 673 throw (RuntimeException) 674 { 675 awt::MouseEvent aEvent (rEvent); 676 aEvent.Source = static_cast<XWeak*>(this); 677 ::cppu::OInterfaceContainerHelper* pIterator 678 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); 679 if (pIterator != NULL) 680 { 681 pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent); 682 } 683 } 684 685 686 687 688 //----- XMouseMotionListener -------------------------------------------------- 689 690 void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent) 691 throw (RuntimeException) 692 { 693 awt::MouseEvent aEvent (rEvent); 694 aEvent.Source = static_cast<XWeak*>(this); 695 ::cppu::OInterfaceContainerHelper* pIterator 696 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL)); 697 if (pIterator != NULL) 698 { 699 pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent); 700 } 701 } 702 703 704 705 706 void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent) 707 throw (RuntimeException) 708 { 709 awt::MouseEvent aEvent (rEvent); 710 aEvent.Source = static_cast<XWeak*>(this); 711 ::cppu::OInterfaceContainerHelper* pIterator 712 = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL)); 713 if (pIterator != NULL) 714 { 715 pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent); 716 } 717 } 718 719 720 721 722 //----- XWindowListener ------------------------------------------------------- 723 724 void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent) 725 throw (RuntimeException) 726 { 727 (void)rEvent; 728 729 ThrowIfDisposed(); 730 ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); 731 732 Resize(); 733 } 734 735 736 737 738 739 void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent) 740 throw (RuntimeException) 741 { 742 (void)rEvent; 743 if ( ! mbIsPaintPending) 744 mbIsForcedPaintPending = true; 745 } 746 747 748 749 750 void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent) 751 throw (RuntimeException) 752 { 753 (void)rEvent; 754 Resize(); 755 } 756 757 758 759 760 void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject& rEvent) 761 throw (RuntimeException) 762 { 763 (void)rEvent; 764 } 765 766 767 768 769 //----- XView ----------------------------------------------------------------- 770 771 Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId (void) 772 throw(RuntimeException) 773 { 774 return mxViewId; 775 } 776 777 778 779 780 sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly (void) 781 throw (RuntimeException) 782 { 783 return false; 784 } 785 786 787 788 789 //----- CachablePresenterView ------------------------------------------------- 790 791 void PresenterSlideShowView::ActivatePresenterView (void) 792 { 793 if (mxSlideShow.is() && ! mbIsViewAdded) 794 { 795 mxSlideShow->addView(this); 796 mbIsViewAdded = true; 797 } 798 } 799 800 801 802 803 void PresenterSlideShowView::DeactivatePresenterView (void) 804 { 805 if (mxSlideShow.is() && mbIsViewAdded) 806 { 807 mxSlideShow->removeView(this); 808 mbIsViewAdded = false; 809 } 810 } 811 812 813 814 815 //----------------------------------------------------------------------------- 816 817 void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox) 818 { 819 if ( ! mxCanvas.is()) 820 return; 821 822 if (mpBackground.get() == NULL) 823 return; 824 825 const rendering::ViewState aViewState( 826 geometry::AffineMatrix2D(1,0,0, 0,1,0), 827 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); 828 829 rendering::RenderState aRenderState ( 830 geometry::AffineMatrix2D(1,0,0, 0,1,0), 831 NULL, 832 Sequence<double>(4), 833 rendering::CompositeOperation::SOURCE); 834 835 Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap()); 836 if (xBackgroundBitmap.is()) 837 { 838 Sequence<rendering::Texture> aTextures (1); 839 const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize()); 840 aTextures[0] = rendering::Texture ( 841 geometry::AffineMatrix2D( 842 aBitmapSize.Width,0,0, 843 0,aBitmapSize.Height,0), 844 1, 845 0, 846 xBackgroundBitmap, 847 NULL, 848 NULL, 849 rendering::StrokeAttributes(), 850 rendering::TexturingMode::REPEAT, 851 rendering::TexturingMode::REPEAT); 852 853 if (mxBackgroundPolygon1.is()) 854 mxCanvas->fillTexturedPolyPolygon( 855 mxBackgroundPolygon1, 856 aViewState, 857 aRenderState, 858 aTextures); 859 if (mxBackgroundPolygon2.is()) 860 mxCanvas->fillTexturedPolyPolygon( 861 mxBackgroundPolygon2, 862 aViewState, 863 aRenderState, 864 aTextures); 865 } 866 else 867 { 868 PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor); 869 870 if (mxBackgroundPolygon1.is()) 871 mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState); 872 if (mxBackgroundPolygon2.is()) 873 mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState); 874 } 875 } 876 877 878 879 880 void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox) 881 { 882 if ( ! mxCanvas.is()) 883 return; 884 885 const rendering::ViewState aViewState( 886 geometry::AffineMatrix2D(1,0,0, 0,1,0), 887 PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); 888 889 rendering::RenderState aRenderState ( 890 geometry::AffineMatrix2D(1,0,0, 0,1,0), 891 NULL, 892 Sequence<double>(4), 893 rendering::CompositeOperation::SOURCE); 894 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000)); 895 mxCanvas->fillPolyPolygon( 896 PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()), 897 aViewState, 898 aRenderState); 899 900 do 901 { 902 if (mpPresenterController.get() == NULL) 903 break; 904 ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme()); 905 if (pTheme.get() == NULL) 906 break; 907 908 const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL())); 909 PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle)); 910 if (pFont.get() == NULL) 911 break; 912 913 PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff)); 914 aRenderState.AffineTransform.m02 = 20; 915 aRenderState.AffineTransform.m12 = 40; 916 const rendering::StringContext aContext ( 917 msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength()); 918 pFont->PrepareFont(mxCanvas); 919 mxCanvas->drawText( 920 aContext, 921 pFont->mxFont, 922 aViewState, 923 aRenderState, 924 rendering::TextDirection::WEAK_LEFT_TO_RIGHT); 925 } 926 while (false); 927 928 // Finally, in double buffered environments, request the changes to be 929 // made visible. 930 Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY); 931 if (mxSpriteCanvas.is()) 932 mxSpriteCanvas->updateScreen(sal_True); 933 } 934 935 936 937 938 void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent) 939 { 940 // Forward window paint to listeners. 941 awt::PaintEvent aEvent (rEvent); 942 aEvent.Source = static_cast<XWeak*>(this); 943 ::cppu::OInterfaceContainerHelper* pIterator 944 = maBroadcaster.getContainer(getCppuType((Reference<awt::XPaintListener>*)NULL)); 945 if (pIterator != NULL) 946 { 947 pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent); 948 } 949 950 if (mbIsForcedPaintPending) 951 ForceRepaint(); 952 953 // Finally, in double buffered environments, request the changes to be 954 // made visible. 955 Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY); 956 if (mxSpriteCanvas.is()) 957 mxSpriteCanvas->updateScreen(sal_True); 958 } 959 960 961 962 963 Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow ( 964 const Reference<awt::XWindow>& rxParentWindow) const 965 { 966 Reference<awt::XWindow> xViewWindow; 967 try 968 { 969 Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager()); 970 if ( ! xFactory.is()) 971 return xViewWindow; 972 973 Reference<awt::XToolkit> xToolkit ( 974 xFactory->createInstanceWithContext( 975 OUString::createFromAscii("com.sun.star.awt.Toolkit"), 976 mxComponentContext), 977 UNO_QUERY_THROW); 978 awt::WindowDescriptor aWindowDescriptor ( 979 awt::WindowClass_CONTAINER, 980 OUString(), 981 Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW), 982 -1, // parent index not available 983 awt::Rectangle(0,0,10,10), 984 awt::WindowAttribute::SIZEABLE 985 | awt::WindowAttribute::MOVEABLE 986 | awt::WindowAttribute::NODECORATION); 987 xViewWindow = Reference<awt::XWindow>( 988 xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW); 989 990 // Make the background transparent. The slide show paints its own background. 991 Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW); 992 if (xPeer.is()) 993 { 994 xPeer->setBackground(0xff000000); 995 } 996 997 xViewWindow->setVisible(sal_True); 998 } 999 catch (RuntimeException&) 1000 { 1001 } 1002 return xViewWindow; 1003 } 1004 1005 1006 1007 1008 Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas ( 1009 const Reference<awt::XWindow>& rxViewWindow) const 1010 { 1011 // Create a canvas for the view window. 1012 return mxPresenterHelper->createSharedCanvas( 1013 Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY), 1014 mxTopPane->getWindow(), 1015 mxTopPane->getCanvas(), 1016 mxTopPane->getWindow(), 1017 rxViewWindow); 1018 } 1019 1020 1021 1022 1023 void PresenterSlideShowView::Resize (void) 1024 { 1025 if ( ! mxWindow.is() || ! mxViewWindow.is()) 1026 return; 1027 1028 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1029 awt::Rectangle aViewWindowBox; 1030 if (aWindowBox.Height > 0) 1031 { 1032 const double nWindowAspectRatio ( 1033 double(aWindowBox.Width) / double(aWindowBox.Height)); 1034 if (nWindowAspectRatio > mnPageAspectRatio) 1035 { 1036 // Slides will be painted with the full parent window height. 1037 aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5); 1038 aViewWindowBox.Height = aWindowBox.Height; 1039 aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2; 1040 aViewWindowBox.Y = 0; 1041 } 1042 else 1043 { 1044 // Slides will be painted with the full parent window width. 1045 aViewWindowBox.Width = aWindowBox.Width; 1046 aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5); 1047 aViewWindowBox.X = 0; 1048 aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2; 1049 } 1050 mxViewWindow->setPosSize( 1051 aViewWindowBox.X, 1052 aViewWindowBox.Y, 1053 aViewWindowBox.Width, 1054 aViewWindowBox.Height, 1055 awt::PosSize::POSSIZE); 1056 } 1057 1058 // Clear the background polygon so that on the next paint it is created 1059 // for the new size. 1060 CreateBackgroundPolygons(); 1061 1062 // Notify listeners that the transformation that maps the view into the 1063 // window has changed. 1064 lang::EventObject aEvent (static_cast<XWeak*>(this)); 1065 ::cppu::OInterfaceContainerHelper* pIterator 1066 = maBroadcaster.getContainer(getCppuType((Reference<util::XModifyListener>*)NULL)); 1067 if (pIterator != NULL) 1068 { 1069 pIterator->notifyEach(&util::XModifyListener::modified, aEvent); 1070 } 1071 1072 // Due to constant aspect ratio resizing may lead a preview that changes 1073 // its position but not its size. This invalidates the back buffer and 1074 // we have to enforce a complete repaint. 1075 if ( ! mbIsPaintPending) 1076 mbIsForcedPaintPending = true; 1077 } 1078 1079 1080 1081 1082 void PresenterSlideShowView::ForceRepaint (void) 1083 { 1084 if (mxSlideShow.is() && mbIsViewAdded) 1085 { 1086 mxSlideShow->removeView(this); 1087 mxSlideShow->addView(this); 1088 } 1089 } 1090 1091 1092 1093 1094 void PresenterSlideShowView::CreateBackgroundPolygons (void) 1095 { 1096 const awt::Rectangle aWindowBox (mxWindow->getPosSize()); 1097 const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); 1098 if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width) 1099 { 1100 mxBackgroundPolygon1 = NULL; 1101 mxBackgroundPolygon2 = NULL; 1102 } 1103 else if (aWindowBox.Height == aViewWindowBox.Height) 1104 { 1105 // Paint two boxes to the left and right of the view window. 1106 mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( 1107 awt::Rectangle( 1108 0, 1109 0, 1110 aViewWindowBox.X, 1111 aWindowBox.Height), 1112 mxCanvas->getDevice()); 1113 mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( 1114 awt::Rectangle( 1115 aViewWindowBox.X + aViewWindowBox.Width, 1116 0, 1117 aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width, 1118 aWindowBox.Height), 1119 mxCanvas->getDevice()); 1120 } 1121 else 1122 { 1123 // Paint two boxes above and below the view window. 1124 mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( 1125 awt::Rectangle( 1126 0, 1127 0, 1128 aWindowBox.Width, 1129 aViewWindowBox.Y), 1130 mxCanvas->getDevice()); 1131 mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( 1132 awt::Rectangle( 1133 0, 1134 aViewWindowBox.Y + aViewWindowBox.Height, 1135 aWindowBox.Width, 1136 aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height), 1137 mxCanvas->getDevice()); 1138 } 1139 } 1140 1141 1142 1143 1144 void PresenterSlideShowView::ThrowIfDisposed (void) 1145 throw (::com::sun::star::lang::DisposedException) 1146 { 1147 if (rBHelper.bDisposed || rBHelper.bInDispose) 1148 { 1149 throw lang::DisposedException ( 1150 OUString::createFromAscii("PresenterSlideShowView object has already been disposed"), 1151 static_cast<uno::XWeak*>(this)); 1152 } 1153 } 1154 1155 1156 } } // end of namespace ::sd::presenter 1157