| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_sdext.hxx" |
| |
| #include "PresenterSlideShowView.hxx" |
| |
| #include "PresenterCanvasHelper.hxx" |
| #include "PresenterGeometryHelper.hxx" |
| #include "PresenterHelper.hxx" |
| #include "PresenterPaneContainer.hxx" |
| #include <com/sun/star/awt/InvalidateStyle.hpp> |
| #include <com/sun/star/awt/PosSize.hpp> |
| #include <com/sun/star/awt/WindowAttribute.hpp> |
| #include <com/sun/star/awt/XWindow.hpp> |
| #include <com/sun/star/awt/XWindow2.hpp> |
| #include <com/sun/star/awt/XWindowPeer.hpp> |
| #include <com/sun/star/beans/XPropertySet.hpp> |
| #include <com/sun/star/drawing/CanvasFeature.hpp> |
| #include <com/sun/star/drawing/XPresenterHelper.hpp> |
| #include <com/sun/star/drawing/framework/XControllerManager.hpp> |
| #include <com/sun/star/drawing/framework/XConfigurationController.hpp> |
| #include <com/sun/star/rendering/CompositeOperation.hpp> |
| #include <com/sun/star/rendering/TextDirection.hpp> |
| #include <com/sun/star/rendering/TexturingMode.hpp> |
| #include <osl/mutex.hxx> |
| |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::drawing::framework; |
| using ::rtl::OUString; |
| |
| #define A2S(pString) (::rtl::OUString(RTL_CONSTASCII_USTRINGPARAM(pString))) |
| |
| namespace sdext { namespace presenter { |
| |
| //===== PresenterSlideShowView ================================================ |
| |
| PresenterSlideShowView::PresenterSlideShowView ( |
| const css::uno::Reference<css::uno::XComponentContext>& rxContext, |
| const css::uno::Reference<css::drawing::framework::XResourceId>& rxViewId, |
| const css::uno::Reference<css::frame::XController>& rxController, |
| const ::rtl::Reference<PresenterController>& rpPresenterController) |
| : PresenterSlideShowViewInterfaceBase(m_aMutex), |
| mxComponentContext(rxContext), |
| mpPresenterController(rpPresenterController), |
| mxViewId(rxViewId), |
| mxController(rxController), |
| mxSlideShowController(PresenterHelper::GetSlideShowController(rxController)), |
| mxSlideShow(), |
| mxCanvas(), |
| mxViewCanvas(), |
| mxPointer(), |
| mxWindow(), |
| mxViewWindow(), |
| mxTopPane(), |
| mxPresenterHelper(), |
| mxBackgroundPolygon1(), |
| mxBackgroundPolygon2(), |
| mbIsViewAdded(false), |
| mnPageAspectRatio(28.0/21.0), |
| maBroadcaster(m_aMutex), |
| mpBackground(), |
| mbIsInModifyNotification(false), |
| mbIsForcedPaintPending(false), |
| mbIsPaintPending(true), |
| msClickToExitPresentationText(), |
| msClickToExitPresentationTitle(), |
| msTitleTemplate(), |
| mbIsEndSlideVisible(false), |
| mxCurrentSlide() |
| { |
| if (mpPresenterController.get() != NULL) |
| { |
| mnPageAspectRatio = mpPresenterController->GetSlideAspectRatio(); |
| mpBackground = mpPresenterController->GetViewBackground(mxViewId->getResourceURL()); |
| } |
| } |
| |
| |
| |
| void PresenterSlideShowView::LateInit (void) |
| { |
| mxSlideShow = Reference<presentation::XSlideShow> ( |
| mxSlideShowController->getSlideShow(), UNO_QUERY_THROW); |
| Reference<lang::XComponent> xSlideShowComponent (mxSlideShow, UNO_QUERY); |
| if (xSlideShowComponent.is()) |
| xSlideShowComponent->addEventListener(static_cast<awt::XWindowListener*>(this)); |
| |
| Reference<lang::XMultiComponentFactory> xFactory ( |
| mxComponentContext->getServiceManager(), UNO_QUERY_THROW); |
| mxPresenterHelper.set (xFactory->createInstanceWithContext( |
| OUString::createFromAscii("com.sun.star.comp.Draw.PresenterHelper"), |
| mxComponentContext), |
| UNO_QUERY_THROW); |
| |
| // Use view id and controller to retrieve window and canvas from |
| // configuration controller. |
| Reference<XControllerManager> xCM (mxController, UNO_QUERY_THROW); |
| Reference<XConfigurationController> xCC (xCM->getConfigurationController()); |
| |
| if (xCC.is()) |
| { |
| mxTopPane.set(xCC->getResource(mxViewId->getAnchor()->getAnchor()), UNO_QUERY); |
| |
| Reference<XPane> xPane (xCC->getResource(mxViewId->getAnchor()), UNO_QUERY_THROW); |
| |
| mxWindow = xPane->getWindow(); |
| mxCanvas = xPane->getCanvas(); |
| |
| if (mxWindow.is()) |
| { |
| mxWindow->addPaintListener(this); |
| mxWindow->addWindowListener(this); |
| } |
| |
| // The window does not have to paint a background. We do |
| // that ourself. |
| Reference<awt::XWindowPeer> xPeer (mxWindow, UNO_QUERY); |
| if (xPeer.is()) |
| xPeer->setBackground(util::Color(0xff000000)); |
| } |
| |
| // Create a window for the actual slide show view. It is places |
| // centered and with maximal size inside the pane. |
| mxViewWindow = CreateViewWindow(mxWindow); |
| |
| mxViewCanvas = CreateViewCanvas(mxViewWindow); |
| |
| if (mxViewWindow.is()) |
| { |
| // Register listeners at window. |
| mxViewWindow->addPaintListener(this); |
| mxViewWindow->addMouseListener(this); |
| mxViewWindow->addMouseMotionListener(this); |
| } |
| |
| if (mxViewWindow.is()) |
| Resize(); |
| |
| if (mxWindow.is()) |
| mxWindow->setVisible(sal_True); |
| |
| // Add the new slide show view to the slide show. |
| if (mxSlideShow.is() && ! mbIsViewAdded) |
| { |
| Reference<presentation::XSlideShowView> xView (this); |
| mxSlideShow->addView(xView); |
| // Prevent embeded sounds being played twice at the same time by |
| // disabling sound for the new slide show view. |
| beans::PropertyValue aProperty; |
| aProperty.Name = A2S("IsSoundEnabled"); |
| Sequence<Any> aValues (2); |
| aValues[0] <<= xView; |
| aValues[1] <<= sal_False; |
| aProperty.Value <<= aValues; |
| mxSlideShow->setProperty(aProperty); |
| mbIsViewAdded = true; |
| } |
| |
| // Read text for one past last slide. |
| PresenterConfigurationAccess aConfiguration ( |
| mxComponentContext, |
| PresenterConfigurationAccess::msPresenterScreenRootName, |
| PresenterConfigurationAccess::READ_ONLY); |
| aConfiguration.GetConfigurationNode( |
| A2S("Presenter/Views/CurrentSlidePreview/" |
| "Strings/ClickToExitPresentationText/String")) |
| >>= msClickToExitPresentationText; |
| aConfiguration.GetConfigurationNode( |
| A2S("Presenter/Views/CurrentSlidePreview/" |
| "Strings/ClickToExitPresentationTitle/String")) |
| >>= msClickToExitPresentationTitle; |
| } |
| |
| |
| |
| |
| PresenterSlideShowView::~PresenterSlideShowView (void) |
| { |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::disposing (void) |
| { |
| // Tell all listeners that we are disposed. |
| lang::EventObject aEvent; |
| aEvent.Source = static_cast<XWeak*>(this); |
| |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<lang::XEventListener>*)NULL)); |
| if (pIterator != NULL) |
| pIterator->disposeAndClear(aEvent); |
| |
| // Do this for |
| // XPaintListener, XModifyListener,XMouseListener,XMouseMotionListener,XWindowListener? |
| |
| if (mxWindow.is()) |
| { |
| mxWindow->removePaintListener(this); |
| mxWindow->removeMouseListener(this); |
| mxWindow->removeMouseMotionListener(this); |
| mxWindow->removeWindowListener(this); |
| mxWindow = NULL; |
| } |
| mxSlideShowController = NULL; |
| mxSlideShow = NULL; |
| if (mxViewCanvas.is()) |
| { |
| Reference<XComponent> xComponent (mxViewCanvas, UNO_QUERY); |
| mxViewCanvas = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| if (mxViewWindow.is()) |
| { |
| Reference<XComponent> xComponent (mxViewWindow, UNO_QUERY); |
| mxViewWindow = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| if (mxPointer.is()) |
| { |
| Reference<XComponent> xComponent (mxPointer, UNO_QUERY); |
| mxPointer = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| if (mxBackgroundPolygon1.is()) |
| { |
| Reference<XComponent> xComponent (mxBackgroundPolygon1, UNO_QUERY); |
| mxBackgroundPolygon1 = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| if (mxBackgroundPolygon2.is()) |
| { |
| Reference<XComponent> xComponent (mxBackgroundPolygon2, UNO_QUERY); |
| mxBackgroundPolygon2 = NULL; |
| if (xComponent.is()) |
| xComponent->dispose(); |
| } |
| |
| mxComponentContext = NULL; |
| mpPresenterController = NULL; |
| mxViewId = NULL; |
| mxController = NULL; |
| mxCanvas = NULL; |
| mpBackground.reset(); |
| msClickToExitPresentationText = OUString(); |
| msClickToExitPresentationTitle = OUString(); |
| msTitleTemplate = OUString(); |
| mxCurrentSlide = NULL; |
| } |
| |
| |
| |
| |
| //----- XDrawView ------------------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::setCurrentPage ( |
| const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) |
| throw (css::uno::RuntimeException) |
| { |
| mxCurrentSlide = rxSlide; |
| if (mpPresenterController.get() != NULL |
| && mxSlideShowController.is() |
| && ! mpPresenterController->GetCurrentSlide().is() |
| && ! mxSlideShowController->isPaused()) |
| { |
| mbIsEndSlideVisible = true; |
| Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); |
| if (xPeer.is()) |
| xPeer->invalidate(awt::InvalidateStyle::NOTRANSPARENT); |
| |
| // For the end slide we use a special title, without the (n of m) |
| // part. Save the title template for the case that the user goes |
| // backwards. |
| PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( |
| mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); |
| if (pDescriptor.get() != NULL) |
| { |
| msTitleTemplate = pDescriptor->msTitleTemplate; |
| pDescriptor->msTitleTemplate = msClickToExitPresentationTitle; |
| mpPresenterController->UpdatePaneTitles(); |
| } |
| } |
| else if (mbIsEndSlideVisible) |
| { |
| mbIsEndSlideVisible = false; |
| |
| // Restore the title template. |
| PresenterPaneContainer::SharedPaneDescriptor pDescriptor ( |
| mpPresenterController->GetPaneContainer()->FindViewURL(mxViewId->getResourceURL())); |
| if (pDescriptor.get() != NULL) |
| { |
| pDescriptor->msTitleTemplate = msTitleTemplate; |
| pDescriptor->msTitle = OUString(); |
| mpPresenterController->UpdatePaneTitles(); |
| } |
| } |
| } |
| |
| |
| |
| |
| css::uno::Reference<css::drawing::XDrawPage> SAL_CALL PresenterSlideShowView::getCurrentPage (void) |
| throw (css::uno::RuntimeException) |
| { |
| return mxCurrentSlide; |
| } |
| |
| |
| |
| |
| //----- CachablePresenterView ------------------------------------------------- |
| |
| void PresenterSlideShowView::ReleaseView (void) |
| { |
| if (mxSlideShow.is() && mbIsViewAdded) |
| { |
| mxSlideShow->removeView(this); |
| mbIsViewAdded = false; |
| } |
| } |
| |
| |
| |
| |
| //----- XSlideShowView -------------------------------------------------------- |
| |
| Reference<rendering::XSpriteCanvas> SAL_CALL PresenterSlideShowView::getCanvas (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| return Reference<rendering::XSpriteCanvas>(mxViewCanvas, UNO_QUERY); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::clear (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| mbIsForcedPaintPending = false; |
| mbIsPaintPending = false; |
| |
| if (mxViewCanvas.is() && mxViewWindow.is()) |
| { |
| // Create a polygon for the window outline. |
| awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); |
| Reference<rendering::XPolyPolygon2D> xPolygon (PresenterGeometryHelper::CreatePolygon( |
| awt::Rectangle(0,0, aViewWindowBox.Width,aViewWindowBox.Height), |
| mxViewCanvas->getDevice())); |
| |
| rendering::ViewState aViewState ( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| NULL); |
| double aColor[3] = {0,0,0}; |
| rendering::RenderState aRenderState( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| NULL, |
| Sequence<double>(aColor,4), |
| rendering::CompositeOperation::SOURCE); |
| mxViewCanvas->fillPolyPolygon(xPolygon, aViewState, aRenderState); |
| } |
| } |
| |
| |
| |
| |
| geometry::AffineMatrix2D SAL_CALL PresenterSlideShowView::getTransformation (void) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| if (mxViewWindow.is()) |
| { |
| // When the mbIsInModifyNotification is set then a slightly modifed |
| // version of the transformation is returned in order to get past |
| // optimizations the avoid updates when the transformation is |
| // unchanged (when the window size changes then due to the constant |
| // aspect ratio the size of the preview may remain the same while |
| // the position changes. The position, however, is repesented by |
| // the position of the view window. This transformation is given |
| // relative to the view window and therefore does not contain the |
| // position.) |
| const awt::Rectangle aWindowBox = mxViewWindow->getPosSize(); |
| return geometry::AffineMatrix2D( |
| aWindowBox.Width-1, 0, (mbIsInModifyNotification ? 1 : 0), |
| 0, aWindowBox.Height-1, 0); |
| } |
| else |
| { |
| return geometry::AffineMatrix2D(1,0,0, 0,1,0); |
| } |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::addTransformationChangedListener( |
| const Reference<util::XModifyListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.addListener( |
| getCppuType((Reference<util::XModifyListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::removeTransformationChangedListener( |
| const Reference<util::XModifyListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.removeListener( |
| getCppuType((Reference<util::XModifyListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::addPaintListener( |
| const Reference<awt::XPaintListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.addListener( |
| getCppuType((Reference<awt::XPaintListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::removePaintListener( |
| const Reference<awt::XPaintListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.removeListener( |
| getCppuType((Reference<awt::XPaintListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::addMouseListener( |
| const Reference<awt::XMouseListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.addListener( |
| getCppuType((Reference<awt::XMouseListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::removeMouseListener( |
| const Reference<awt::XMouseListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.removeListener( |
| getCppuType((Reference<awt::XMouseListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::addMouseMotionListener( |
| const Reference<awt::XMouseMotionListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.addListener( |
| getCppuType((Reference<awt::XMouseMotionListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::removeMouseMotionListener( |
| const Reference<awt::XMouseMotionListener>& rxListener) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| maBroadcaster.removeListener( |
| getCppuType((Reference<awt::XMouseMotionListener>*)NULL), |
| rxListener); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::setMouseCursor(::sal_Int16 nPointerShape) |
| throw (RuntimeException) |
| { |
| ThrowIfDisposed(); |
| |
| // Create a pointer when it does not yet exist. |
| if ( ! mxPointer.is()) |
| { |
| Reference<lang::XMultiServiceFactory> xFactory ( |
| mxComponentContext, UNO_QUERY); |
| if (xFactory.is()) |
| mxPointer = Reference<awt::XPointer>( |
| xFactory->createInstance(OUString::createFromAscii("com.sun.star.awt.Pointer")), |
| UNO_QUERY); |
| } |
| |
| // Set the pointer to the given shape and the window(peer) to the |
| // pointer. |
| Reference<awt::XWindowPeer> xPeer (mxViewWindow, UNO_QUERY); |
| if (mxPointer.is() && xPeer.is()) |
| { |
| mxPointer->setType(nPointerShape); |
| xPeer->setPointer(mxPointer); |
| } |
| } |
| |
| |
| |
| awt::Rectangle SAL_CALL PresenterSlideShowView::getCanvasArea( ) throw (RuntimeException) |
| { |
| if( mxViewWindow.is() && mxTopPane.is() ) |
| return mxPresenterHelper->getWindowExtentsRelative( mxViewWindow, mxTopPane->getWindow() ); |
| |
| awt::Rectangle aRectangle; |
| |
| aRectangle.X = aRectangle.Y = aRectangle.Width = aRectangle.Height = 0; |
| |
| return aRectangle; |
| } |
| |
| |
| |
| //----- lang::XEventListener -------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::disposing (const lang::EventObject& rEvent) |
| throw (RuntimeException) |
| { |
| if (rEvent.Source == mxViewWindow) |
| mxViewWindow = NULL; |
| else if (rEvent.Source == mxSlideShow) |
| mxSlideShow = NULL; |
| } |
| |
| |
| |
| |
| //----- XPaintListener -------------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::windowPaint (const awt::PaintEvent& rEvent) |
| throw (RuntimeException) |
| { |
| // Deactivated views must not be painted. |
| if ( ! mbIsPresenterViewActive) |
| return; |
| |
| awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); |
| if (aViewWindowBox.Width <= 0 || aViewWindowBox.Height <= 0) |
| return; |
| |
| if (rEvent.Source == mxWindow) |
| PaintOuterWindow(rEvent.UpdateRect); |
| else if (mbIsEndSlideVisible) |
| PaintEndSlide(rEvent.UpdateRect); |
| else |
| PaintInnerWindow(rEvent); |
| } |
| |
| |
| |
| |
| //----- XMouseListener -------------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::mousePressed (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseListener::mousePressed, aEvent); |
| } |
| |
| // Only when the end slide is displayed we forward the mouse event to |
| // the PresenterController so that it switches to the next slide and |
| // ends the presentation. |
| if (mbIsEndSlideVisible) |
| if (mpPresenterController.get() != NULL) |
| mpPresenterController->HandleMouseClick(rEvent); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::mouseReleased (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseListener::mouseReleased, aEvent); |
| } |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::mouseEntered (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseListener::mouseEntered, aEvent); |
| } |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::mouseExited (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseListener::mouseExited, aEvent); |
| } |
| } |
| |
| |
| |
| |
| //----- XMouseMotionListener -------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::mouseDragged (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseMotionListener::mouseDragged, aEvent); |
| } |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::mouseMoved (const awt::MouseEvent& rEvent) |
| throw (RuntimeException) |
| { |
| awt::MouseEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XMouseMotionListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XMouseMotionListener::mouseMoved, aEvent); |
| } |
| } |
| |
| |
| |
| |
| //----- XWindowListener ------------------------------------------------------- |
| |
| void SAL_CALL PresenterSlideShowView::windowResized (const awt::WindowEvent& rEvent) |
| throw (RuntimeException) |
| { |
| (void)rEvent; |
| |
| ThrowIfDisposed(); |
| ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex()); |
| |
| Resize(); |
| } |
| |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::windowMoved (const awt::WindowEvent& rEvent) |
| throw (RuntimeException) |
| { |
| (void)rEvent; |
| if ( ! mbIsPaintPending) |
| mbIsForcedPaintPending = true; |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::windowShown (const lang::EventObject& rEvent) |
| throw (RuntimeException) |
| { |
| (void)rEvent; |
| Resize(); |
| } |
| |
| |
| |
| |
| void SAL_CALL PresenterSlideShowView::windowHidden (const lang::EventObject& rEvent) |
| throw (RuntimeException) |
| { |
| (void)rEvent; |
| } |
| |
| |
| |
| |
| //----- XView ----------------------------------------------------------------- |
| |
| Reference<XResourceId> SAL_CALL PresenterSlideShowView::getResourceId (void) |
| throw(RuntimeException) |
| { |
| return mxViewId; |
| } |
| |
| |
| |
| |
| sal_Bool SAL_CALL PresenterSlideShowView::isAnchorOnly (void) |
| throw (RuntimeException) |
| { |
| return false; |
| } |
| |
| |
| |
| |
| //----- CachablePresenterView ------------------------------------------------- |
| |
| void PresenterSlideShowView::ActivatePresenterView (void) |
| { |
| if (mxSlideShow.is() && ! mbIsViewAdded) |
| { |
| mxSlideShow->addView(this); |
| mbIsViewAdded = true; |
| } |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::DeactivatePresenterView (void) |
| { |
| if (mxSlideShow.is() && mbIsViewAdded) |
| { |
| mxSlideShow->removeView(this); |
| mbIsViewAdded = false; |
| } |
| } |
| |
| |
| |
| |
| //----------------------------------------------------------------------------- |
| |
| void PresenterSlideShowView::PaintOuterWindow (const awt::Rectangle& rRepaintBox) |
| { |
| if ( ! mxCanvas.is()) |
| return; |
| |
| if (mpBackground.get() == NULL) |
| return; |
| |
| const rendering::ViewState aViewState( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); |
| |
| rendering::RenderState aRenderState ( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| NULL, |
| Sequence<double>(4), |
| rendering::CompositeOperation::SOURCE); |
| |
| Reference<rendering::XBitmap> xBackgroundBitmap (mpBackground->GetNormalBitmap()); |
| if (xBackgroundBitmap.is()) |
| { |
| Sequence<rendering::Texture> aTextures (1); |
| const geometry::IntegerSize2D aBitmapSize(xBackgroundBitmap->getSize()); |
| aTextures[0] = rendering::Texture ( |
| geometry::AffineMatrix2D( |
| aBitmapSize.Width,0,0, |
| 0,aBitmapSize.Height,0), |
| 1, |
| 0, |
| xBackgroundBitmap, |
| NULL, |
| NULL, |
| rendering::StrokeAttributes(), |
| rendering::TexturingMode::REPEAT, |
| rendering::TexturingMode::REPEAT); |
| |
| if (mxBackgroundPolygon1.is()) |
| mxCanvas->fillTexturedPolyPolygon( |
| mxBackgroundPolygon1, |
| aViewState, |
| aRenderState, |
| aTextures); |
| if (mxBackgroundPolygon2.is()) |
| mxCanvas->fillTexturedPolyPolygon( |
| mxBackgroundPolygon2, |
| aViewState, |
| aRenderState, |
| aTextures); |
| } |
| else |
| { |
| PresenterCanvasHelper::SetDeviceColor(aRenderState, mpBackground->maReplacementColor); |
| |
| if (mxBackgroundPolygon1.is()) |
| mxCanvas->fillPolyPolygon(mxBackgroundPolygon1, aViewState, aRenderState); |
| if (mxBackgroundPolygon2.is()) |
| mxCanvas->fillPolyPolygon(mxBackgroundPolygon2, aViewState, aRenderState); |
| } |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::PaintEndSlide (const awt::Rectangle& rRepaintBox) |
| { |
| if ( ! mxCanvas.is()) |
| return; |
| |
| const rendering::ViewState aViewState( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| PresenterGeometryHelper::CreatePolygon(rRepaintBox, mxCanvas->getDevice())); |
| |
| rendering::RenderState aRenderState ( |
| geometry::AffineMatrix2D(1,0,0, 0,1,0), |
| NULL, |
| Sequence<double>(4), |
| rendering::CompositeOperation::SOURCE); |
| PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00000000)); |
| mxCanvas->fillPolyPolygon( |
| PresenterGeometryHelper::CreatePolygon(mxViewWindow->getPosSize(), mxCanvas->getDevice()), |
| aViewState, |
| aRenderState); |
| |
| do |
| { |
| if (mpPresenterController.get() == NULL) |
| break; |
| ::boost::shared_ptr<PresenterTheme> pTheme (mpPresenterController->GetTheme()); |
| if (pTheme.get() == NULL) |
| break; |
| |
| const OUString sViewStyle (pTheme->GetStyleName(mxViewId->getResourceURL())); |
| PresenterTheme::SharedFontDescriptor pFont (pTheme->GetFont(sViewStyle)); |
| if (pFont.get() == NULL) |
| break; |
| |
| PresenterCanvasHelper::SetDeviceColor(aRenderState, util::Color(0x00ffffff)); |
| aRenderState.AffineTransform.m02 = 20; |
| aRenderState.AffineTransform.m12 = 40; |
| const rendering::StringContext aContext ( |
| msClickToExitPresentationText, 0, msClickToExitPresentationText.getLength()); |
| pFont->PrepareFont(mxCanvas); |
| mxCanvas->drawText( |
| aContext, |
| pFont->mxFont, |
| aViewState, |
| aRenderState, |
| rendering::TextDirection::WEAK_LEFT_TO_RIGHT); |
| } |
| while (false); |
| |
| // Finally, in double buffered environments, request the changes to be |
| // made visible. |
| Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY); |
| if (mxSpriteCanvas.is()) |
| mxSpriteCanvas->updateScreen(sal_True); |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::PaintInnerWindow (const awt::PaintEvent& rEvent) |
| { |
| // Forward window paint to listeners. |
| awt::PaintEvent aEvent (rEvent); |
| aEvent.Source = static_cast<XWeak*>(this); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<awt::XPaintListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&awt::XPaintListener::windowPaint, aEvent); |
| } |
| |
| if (mbIsForcedPaintPending) |
| ForceRepaint(); |
| |
| // Finally, in double buffered environments, request the changes to be |
| // made visible. |
| Reference<rendering::XSpriteCanvas> mxSpriteCanvas (mxCanvas, UNO_QUERY); |
| if (mxSpriteCanvas.is()) |
| mxSpriteCanvas->updateScreen(sal_True); |
| } |
| |
| |
| |
| |
| Reference<awt::XWindow> PresenterSlideShowView::CreateViewWindow ( |
| const Reference<awt::XWindow>& rxParentWindow) const |
| { |
| Reference<awt::XWindow> xViewWindow; |
| try |
| { |
| Reference<lang::XMultiComponentFactory> xFactory (mxComponentContext->getServiceManager()); |
| if ( ! xFactory.is()) |
| return xViewWindow; |
| |
| Reference<awt::XToolkit> xToolkit ( |
| xFactory->createInstanceWithContext( |
| OUString::createFromAscii("com.sun.star.awt.Toolkit"), |
| mxComponentContext), |
| UNO_QUERY_THROW); |
| awt::WindowDescriptor aWindowDescriptor ( |
| awt::WindowClass_CONTAINER, |
| OUString(), |
| Reference<awt::XWindowPeer>(rxParentWindow,UNO_QUERY_THROW), |
| -1, // parent index not available |
| awt::Rectangle(0,0,10,10), |
| awt::WindowAttribute::SIZEABLE |
| | awt::WindowAttribute::MOVEABLE |
| | awt::WindowAttribute::NODECORATION); |
| xViewWindow = Reference<awt::XWindow>( |
| xToolkit->createWindow(aWindowDescriptor),UNO_QUERY_THROW); |
| |
| // Make the background transparent. The slide show paints its own background. |
| Reference<awt::XWindowPeer> xPeer (xViewWindow, UNO_QUERY_THROW); |
| if (xPeer.is()) |
| { |
| xPeer->setBackground(0xff000000); |
| } |
| |
| xViewWindow->setVisible(sal_True); |
| } |
| catch (RuntimeException&) |
| { |
| } |
| return xViewWindow; |
| } |
| |
| |
| |
| |
| Reference<rendering::XCanvas> PresenterSlideShowView::CreateViewCanvas ( |
| const Reference<awt::XWindow>& rxViewWindow) const |
| { |
| // Create a canvas for the view window. |
| return mxPresenterHelper->createSharedCanvas( |
| Reference<rendering::XSpriteCanvas>(mxTopPane->getCanvas(), UNO_QUERY), |
| mxTopPane->getWindow(), |
| mxTopPane->getCanvas(), |
| mxTopPane->getWindow(), |
| rxViewWindow); |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::Resize (void) |
| { |
| if ( ! mxWindow.is() || ! mxViewWindow.is()) |
| return; |
| |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| awt::Rectangle aViewWindowBox; |
| if (aWindowBox.Height > 0) |
| { |
| const double nWindowAspectRatio ( |
| double(aWindowBox.Width) / double(aWindowBox.Height)); |
| if (nWindowAspectRatio > mnPageAspectRatio) |
| { |
| // Slides will be painted with the full parent window height. |
| aViewWindowBox.Width = sal_Int32(aWindowBox.Height * mnPageAspectRatio + 0.5); |
| aViewWindowBox.Height = aWindowBox.Height; |
| aViewWindowBox.X = (aWindowBox.Width - aViewWindowBox.Width) / 2; |
| aViewWindowBox.Y = 0; |
| } |
| else |
| { |
| // Slides will be painted with the full parent window width. |
| aViewWindowBox.Width = aWindowBox.Width; |
| aViewWindowBox.Height = sal_Int32(aWindowBox.Width / mnPageAspectRatio + 0.5); |
| aViewWindowBox.X = 0; |
| aViewWindowBox.Y = (aWindowBox.Height - aViewWindowBox.Height) / 2; |
| } |
| mxViewWindow->setPosSize( |
| aViewWindowBox.X, |
| aViewWindowBox.Y, |
| aViewWindowBox.Width, |
| aViewWindowBox.Height, |
| awt::PosSize::POSSIZE); |
| } |
| |
| // Clear the background polygon so that on the next paint it is created |
| // for the new size. |
| CreateBackgroundPolygons(); |
| |
| // Notify listeners that the transformation that maps the view into the |
| // window has changed. |
| lang::EventObject aEvent (static_cast<XWeak*>(this)); |
| ::cppu::OInterfaceContainerHelper* pIterator |
| = maBroadcaster.getContainer(getCppuType((Reference<util::XModifyListener>*)NULL)); |
| if (pIterator != NULL) |
| { |
| pIterator->notifyEach(&util::XModifyListener::modified, aEvent); |
| } |
| |
| // Due to constant aspect ratio resizing may lead a preview that changes |
| // its position but not its size. This invalidates the back buffer and |
| // we have to enforce a complete repaint. |
| if ( ! mbIsPaintPending) |
| mbIsForcedPaintPending = true; |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::ForceRepaint (void) |
| { |
| if (mxSlideShow.is() && mbIsViewAdded) |
| { |
| mxSlideShow->removeView(this); |
| mxSlideShow->addView(this); |
| } |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::CreateBackgroundPolygons (void) |
| { |
| const awt::Rectangle aWindowBox (mxWindow->getPosSize()); |
| const awt::Rectangle aViewWindowBox (mxViewWindow->getPosSize()); |
| if (aWindowBox.Height == aViewWindowBox.Height && aWindowBox.Width == aViewWindowBox.Width) |
| { |
| mxBackgroundPolygon1 = NULL; |
| mxBackgroundPolygon2 = NULL; |
| } |
| else if (aWindowBox.Height == aViewWindowBox.Height) |
| { |
| // Paint two boxes to the left and right of the view window. |
| mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( |
| awt::Rectangle( |
| 0, |
| 0, |
| aViewWindowBox.X, |
| aWindowBox.Height), |
| mxCanvas->getDevice()); |
| mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( |
| awt::Rectangle( |
| aViewWindowBox.X + aViewWindowBox.Width, |
| 0, |
| aWindowBox.Width - aViewWindowBox.X - aViewWindowBox.Width, |
| aWindowBox.Height), |
| mxCanvas->getDevice()); |
| } |
| else |
| { |
| // Paint two boxes above and below the view window. |
| mxBackgroundPolygon1 = PresenterGeometryHelper::CreatePolygon( |
| awt::Rectangle( |
| 0, |
| 0, |
| aWindowBox.Width, |
| aViewWindowBox.Y), |
| mxCanvas->getDevice()); |
| mxBackgroundPolygon2 = PresenterGeometryHelper::CreatePolygon( |
| awt::Rectangle( |
| 0, |
| aViewWindowBox.Y + aViewWindowBox.Height, |
| aWindowBox.Width, |
| aWindowBox.Height - aViewWindowBox.Y - aViewWindowBox.Height), |
| mxCanvas->getDevice()); |
| } |
| } |
| |
| |
| |
| |
| void PresenterSlideShowView::ThrowIfDisposed (void) |
| throw (::com::sun::star::lang::DisposedException) |
| { |
| if (rBHelper.bDisposed || rBHelper.bInDispose) |
| { |
| throw lang::DisposedException ( |
| OUString::createFromAscii("PresenterSlideShowView object has already been disposed"), |
| static_cast<uno::XWeak*>(this)); |
| } |
| } |
| |
| |
| } } // end of namespace ::sd::presenter |