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