LCOV - code coverage report
Current view: top level - sdext/source/presenter - PresenterSlideSorter.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 1 782 0.1 %
Date: 2015-06-13 12:38:46 Functions: 2 77 2.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "vcl/svapp.hxx"
      21             : #include "vcl/settings.hxx"
      22             : 
      23             : #include "PresenterSlideSorter.hxx"
      24             : #include "PresenterButton.hxx"
      25             : #include "PresenterCanvasHelper.hxx"
      26             : #include "PresenterGeometryHelper.hxx"
      27             : #include "PresenterHelper.hxx"
      28             : #include "PresenterPaintManager.hxx"
      29             : #include "PresenterPaneBase.hxx"
      30             : #include "PresenterScrollBar.hxx"
      31             : #include "PresenterUIPainter.hxx"
      32             : #include "PresenterWindowManager.hxx"
      33             : #include <com/sun/star/awt/PosSize.hpp>
      34             : #include <com/sun/star/awt/XWindowPeer.hpp>
      35             : #include <com/sun/star/container/XNameAccess.hpp>
      36             : #include <com/sun/star/container/XNamed.hpp>
      37             : #include <com/sun/star/drawing/XSlideSorterBase.hpp>
      38             : #include <com/sun/star/drawing/framework/XConfigurationController.hpp>
      39             : #include <com/sun/star/drawing/framework/XControllerManager.hpp>
      40             : #include <com/sun/star/rendering/XBitmapCanvas.hpp>
      41             : #include <com/sun/star/rendering/CompositeOperation.hpp>
      42             : #include <com/sun/star/rendering/TextDirection.hpp>
      43             : #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
      44             : #include <com/sun/star/util/Color.hpp>
      45             : #include <algorithm>
      46             : #include <math.h>
      47             : #include <boost/bind.hpp>
      48             : 
      49             : using namespace ::com::sun::star;
      50             : using namespace ::com::sun::star::uno;
      51             : using namespace ::com::sun::star::drawing::framework;
      52             : 
      53             : namespace {
      54             :     const static sal_Int32 gnVerticalGap (10);
      55             :     const static sal_Int32 gnVerticalBorder (10);
      56             :     const static sal_Int32 gnHorizontalGap (10);
      57             :     const static sal_Int32 gnHorizontalBorder (10);
      58             : 
      59             :     const static double gnMinimalPreviewWidth (200);
      60             :     const static double gnPreferredPreviewWidth (300);
      61             :     const static double gnMaximalPreviewWidth (400);
      62             :     const static sal_Int32 gnPreferredColumnCount (6);
      63             :     const static double gnMinimalHorizontalPreviewGap(15);
      64             :     const static double gnPreferredHorizontalPreviewGap(25);
      65             :     const static double gnMaximalHorizontalPreviewGap(50);
      66             :     const static double gnPreferredVerticalPreviewGap(25);
      67             : 
      68             :     const static sal_Int32 gnHorizontalLabelBorder (3);
      69             :     const static sal_Int32 gnHorizontalLabelPadding (5);
      70             : 
      71             :     const static sal_Int32 gnVerticalButtonPadding (gnVerticalGap);
      72             : }
      73             : 
      74             : namespace sdext { namespace presenter {
      75             : 
      76             : namespace {
      77           0 :     sal_Int32 round (const double nValue) { return sal::static_int_cast<sal_Int32>(0.5 + nValue); }
      78           0 :     sal_Int32 floor (const double nValue) { return sal::static_int_cast<sal_Int32>(nValue); }
      79             : }
      80             : 
      81             : //===== PresenterSlideSorter::Layout ==========================================
      82             : 
      83           0 : class PresenterSlideSorter::Layout
      84             : {
      85             : public:
      86             :     Layout (const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar);
      87             : 
      88             :     void Update (const geometry::RealRectangle2D& rBoundingBox, const double nSlideAspectRatio);
      89             :     void SetupVisibleArea();
      90             :     void UpdateScrollBars();
      91             :     bool IsScrollBarNeeded (const sal_Int32 nSlideCount);
      92             :     geometry::RealPoint2D GetLocalPosition (const geometry::RealPoint2D& rWindowPoint) const;
      93             :     geometry::RealPoint2D GetWindowPosition(const geometry::RealPoint2D& rLocalPoint) const;
      94             :     sal_Int32 GetColumn (const geometry::RealPoint2D& rLocalPoint,
      95             :         const bool bReturnInvalidValue = false) const;
      96             :     sal_Int32 GetRow (const geometry::RealPoint2D& rLocalPoint,
      97             :         const bool bReturnInvalidValue = false) const;
      98             :     sal_Int32 GetSlideIndexForPosition (const css::geometry::RealPoint2D& rPoint) const;
      99             :     css::geometry::RealPoint2D GetPoint (
     100             :         const sal_Int32 nSlideIndex,
     101             :         const sal_Int32 nRelativeHorizontalPosition,
     102             :         const sal_Int32 nRelativeVerticalPosition) const;
     103             :     css::awt::Rectangle GetBoundingBox (const sal_Int32 nSlideIndex) const;
     104             :     void ForAllVisibleSlides (const ::boost::function<void(sal_Int32)>& rAction);
     105             :     sal_Int32 GetFirstVisibleSlideIndex() const;
     106             :     sal_Int32 GetLastVisibleSlideIndex() const;
     107             :     bool SetHorizontalOffset (const double nOffset);
     108             :     bool SetVerticalOffset (const double nOffset);
     109             : 
     110             :     css::geometry::RealRectangle2D maBoundingBox;
     111             :     css::geometry::IntegerSize2D maPreviewSize;
     112             :     sal_Int32 mnHorizontalOffset;
     113             :     sal_Int32 mnVerticalOffset;
     114             :     sal_Int32 mnHorizontalGap;
     115             :     sal_Int32 mnVerticalGap;
     116             :     sal_Int32 mnHorizontalBorder;
     117             :     sal_Int32 mnVerticalBorder;
     118             :     sal_Int32 mnRowCount;
     119             :     sal_Int32 mnColumnCount;
     120             :     sal_Int32 mnSlideCount;
     121             :     sal_Int32 mnSlideIndexAtMouse;
     122             :     sal_Int32 mnFirstVisibleColumn;
     123             :     sal_Int32 mnLastVisibleColumn;
     124             :     sal_Int32 mnFirstVisibleRow;
     125             :     sal_Int32 mnLastVisibleRow;
     126             : 
     127             : private:
     128             :     ::rtl::Reference<PresenterScrollBar> mpVerticalScrollBar;
     129             : 
     130             :     sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const;
     131             :     sal_Int32 GetRow (const sal_Int32 nSlideIndex) const;
     132             :     sal_Int32 GetColumn (const sal_Int32 nSlideIndex) const;
     133             : };
     134             : 
     135             : //==== PresenterSlideSorter::MouseOverManager =================================
     136             : 
     137             : class PresenterSlideSorter::MouseOverManager
     138             :     : ::boost::noncopyable
     139             : {
     140             : public:
     141             :     MouseOverManager (
     142             :         const Reference<container::XIndexAccess>& rxSlides,
     143             :         const ::boost::shared_ptr<PresenterTheme>& rpTheme,
     144             :         const Reference<awt::XWindow>& rxInvalidateTarget,
     145             :         const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager);
     146             :     ~MouseOverManager();
     147             : 
     148             :     void Paint (
     149             :         const sal_Int32 nSlideIndex,
     150             :         const Reference<rendering::XCanvas>& rxCanvas,
     151             :         const Reference<rendering::XPolyPolygon2D>& rxClip);
     152             : 
     153             :     void SetSlide (
     154             :         const sal_Int32 nSlideIndex,
     155             :         const awt::Rectangle& rBox);
     156             : 
     157             : private:
     158             :     Reference<rendering::XCanvas> mxCanvas;
     159             :     const Reference<container::XIndexAccess> mxSlides;
     160             :     SharedBitmapDescriptor mpLeftLabelBitmap;
     161             :     SharedBitmapDescriptor mpCenterLabelBitmap;
     162             :     SharedBitmapDescriptor mpRightLabelBitmap;
     163             :     PresenterTheme::SharedFontDescriptor mpFont;
     164             :     sal_Int32 mnSlideIndex;
     165             :     awt::Rectangle maSlideBoundingBox;
     166             :     OUString msText;
     167             :     Reference<rendering::XBitmap> mxBitmap;
     168             :     Reference<awt::XWindow> mxInvalidateTarget;
     169             :     ::boost::shared_ptr<PresenterPaintManager> mpPaintManager;
     170             : 
     171             :     void SetCanvas (
     172             :         const Reference<rendering::XCanvas>& rxCanvas);
     173             :     /** Create a bitmap that shows the given text and is not wider than the
     174             :         given maximal width.
     175             :     */
     176             :     Reference<rendering::XBitmap> CreateBitmap (
     177             :         const OUString& rsText,
     178             :         const sal_Int32 nMaximalWidth) const;
     179             :     void Invalidate();
     180             :     geometry::IntegerSize2D CalculateLabelSize (
     181             :         const OUString& rsText) const;
     182             :     OUString GetFittingText (const OUString& rsText, const double nMaximalWidth) const;
     183             :     void PaintButtonBackground (
     184             :         const Reference<rendering::XCanvas>& rxCanvas,
     185             :         const geometry::IntegerSize2D& rSize) const;
     186             : };
     187             : 
     188             : //==== PresenterSlideSorter::CurrentSlideFrameRenderer ========================
     189             : 
     190             : class PresenterSlideSorter::CurrentSlideFrameRenderer
     191             : {
     192             : public:
     193             :     CurrentSlideFrameRenderer (
     194             :         const css::uno::Reference<css::uno::XComponentContext>& rxContext,
     195             :         const css::uno::Reference<css::rendering::XCanvas>& rxCanvas);
     196             :     ~CurrentSlideFrameRenderer();
     197             : 
     198             :     void PaintCurrentSlideFrame (
     199             :         const awt::Rectangle& rSlideBoundingBox,
     200             :         const Reference<rendering::XCanvas>& rxCanvas,
     201             :         const geometry::RealRectangle2D& rClipBox);
     202             : 
     203             :     /** Enlarge the given rectangle to include the current slide indicator.
     204             :     */
     205             :     awt::Rectangle GetBoundingBox (
     206             :         const awt::Rectangle& rSlideBoundingBox);
     207             : 
     208             : private:
     209             :     SharedBitmapDescriptor mpTopLeft;
     210             :     SharedBitmapDescriptor mpTop;
     211             :     SharedBitmapDescriptor mpTopRight;
     212             :     SharedBitmapDescriptor mpLeft;
     213             :     SharedBitmapDescriptor mpRight;
     214             :     SharedBitmapDescriptor mpBottomLeft;
     215             :     SharedBitmapDescriptor mpBottom;
     216             :     SharedBitmapDescriptor mpBottomRight;
     217             :     sal_Int32 mnTopFrameSize;
     218             :     sal_Int32 mnLeftFrameSize;
     219             :     sal_Int32 mnRightFrameSize;
     220             :     sal_Int32 mnBottomFrameSize;
     221             : 
     222             :     static void PaintBitmapOnce(
     223             :         const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
     224             :         const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
     225             :         const Reference<rendering::XPolyPolygon2D>& rxClip,
     226             :         const double nX,
     227             :         const double nY);
     228             :     static void PaintBitmapTiled(
     229             :         const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
     230             :         const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
     231             :         const geometry::RealRectangle2D& rClipBox,
     232             :         const double nX,
     233             :         const double nY,
     234             :         const double nWidth,
     235             :         const double nHeight);
     236             : };
     237             : 
     238             : //===== PresenterSlideSorter ==================================================
     239             : 
     240           0 : PresenterSlideSorter::PresenterSlideSorter (
     241             :     const Reference<uno::XComponentContext>& rxContext,
     242             :     const Reference<XResourceId>& rxViewId,
     243             :     const Reference<frame::XController>& rxController,
     244             :     const ::rtl::Reference<PresenterController>& rpPresenterController)
     245             :     : PresenterSlideSorterInterfaceBase(m_aMutex),
     246             :       mxComponentContext(rxContext),
     247             :       mxViewId(rxViewId),
     248             :       mxPane(),
     249             :       mxCanvas(),
     250             :       mxWindow(),
     251             :       mpPresenterController(rpPresenterController),
     252             :       mxSlideShowController(mpPresenterController->GetSlideShowController()),
     253             :       mxPreviewCache(),
     254             :       mbIsPaintPending(true),
     255             :       mbIsLayoutPending(true),
     256             :       mpLayout(),
     257             :       mpVerticalScrollBar(),
     258             :       mpCloseButton(),
     259             :       mpMouseOverManager(),
     260             :       mnSlideIndexMousePressed(-1),
     261             :       mnCurrentSlideIndex(-1),
     262             :       mnSeparatorY(0),
     263             :       maSeparatorColor(0x00ffffff),
     264             :       maCloseButtonCenter(),
     265             :       maCurrentSlideFrameBoundingBox(),
     266             :       mpCurrentSlideFrameRenderer(),
     267           0 :       mxPreviewFrame()
     268             : {
     269           0 :     if ( ! rxContext.is()
     270           0 :         || ! rxViewId.is()
     271           0 :         || ! rxController.is()
     272           0 :         || rpPresenterController.get()==NULL)
     273             :     {
     274           0 :         throw lang::IllegalArgumentException();
     275             :     }
     276             : 
     277           0 :     if ( ! mxSlideShowController.is())
     278           0 :         throw RuntimeException();
     279             : 
     280             :     try
     281             :     {
     282             :         // Get pane and window.
     283           0 :         Reference<XControllerManager> xCM (rxController, UNO_QUERY_THROW);
     284             :         Reference<XConfigurationController> xCC (
     285           0 :             xCM->getConfigurationController(), UNO_QUERY_THROW);
     286             :         Reference<lang::XMultiComponentFactory> xFactory (
     287           0 :             mxComponentContext->getServiceManager(), UNO_QUERY_THROW);
     288             : 
     289           0 :         mxPane = Reference<XPane>(xCC->getResource(rxViewId->getAnchor()), UNO_QUERY_THROW);
     290           0 :         mxWindow = mxPane->getWindow();
     291             : 
     292             :         // Add window listener.
     293           0 :         mxWindow->addWindowListener(this);
     294           0 :         mxWindow->addPaintListener(this);
     295           0 :         mxWindow->addMouseListener(this);
     296           0 :         mxWindow->addMouseMotionListener(this);
     297           0 :         mxWindow->setVisible(sal_True);
     298             : 
     299             :         // Remember the current slide.
     300           0 :         mnCurrentSlideIndex = mxSlideShowController->getCurrentSlideIndex();
     301             : 
     302             :         // Create the scroll bar.
     303           0 :         mpVerticalScrollBar = ::rtl::Reference<PresenterScrollBar>(
     304             :             new PresenterVerticalScrollBar(
     305             :                 rxContext,
     306             :                 mxWindow,
     307             :                 mpPresenterController->GetPaintManager(),
     308           0 :                 ::boost::bind(&PresenterSlideSorter::SetVerticalOffset,this,_1)));
     309             : 
     310           0 :         mpCloseButton = PresenterButton::Create(
     311             :             rxContext,
     312             :             mpPresenterController,
     313             :             mpPresenterController->GetTheme(),
     314             :             mxWindow,
     315             :             mxCanvas,
     316           0 :             "SlideSorterCloser");
     317             : 
     318           0 :         if (mpPresenterController->GetTheme().get() != NULL)
     319             :         {
     320             :             PresenterTheme::SharedFontDescriptor pFont (
     321           0 :                 mpPresenterController->GetTheme()->GetFont("ButtonFont"));
     322           0 :             if (pFont.get() != NULL)
     323           0 :                 maSeparatorColor = pFont->mnColor;
     324             :         }
     325             : 
     326             :         // Create the layout.
     327           0 :         mpLayout.reset(new Layout(mpVerticalScrollBar));
     328             : 
     329             :         // Create the preview cache.
     330           0 :         mxPreviewCache = Reference<drawing::XSlidePreviewCache>(
     331           0 :             xFactory->createInstanceWithContext(
     332             :                 OUString("com.sun.star.drawing.PresenterPreviewCache"),
     333           0 :                 mxComponentContext),
     334           0 :             UNO_QUERY_THROW);
     335           0 :         Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY);
     336           0 :         mxPreviewCache->setDocumentSlides(xSlides, rxController->getModel());
     337           0 :         mxPreviewCache->addPreviewCreationNotifyListener(this);
     338           0 :         if (xSlides.is())
     339             :         {
     340           0 :             mpLayout->mnSlideCount = xSlides->getCount();
     341             :         }
     342             : 
     343             :         // Create the mouse over manager.
     344             :         mpMouseOverManager.reset(new MouseOverManager(
     345             :             Reference<container::XIndexAccess>(mxSlideShowController, UNO_QUERY),
     346             :             mpPresenterController->GetTheme(),
     347             :             mxWindow,
     348           0 :             mpPresenterController->GetPaintManager()));
     349             : 
     350             :         // Listen for changes of the current slide.
     351           0 :         Reference<beans::XPropertySet> xControllerProperties (rxController, UNO_QUERY_THROW);
     352           0 :         xControllerProperties->addPropertyChangeListener(
     353             :             OUString("CurrentPage"),
     354           0 :             this);
     355             : 
     356             :         // Move the current slide in the center of the window.
     357           0 :         const awt::Rectangle aCurrentSlideBBox (mpLayout->GetBoundingBox(mnCurrentSlideIndex));
     358           0 :         const awt::Rectangle aWindowBox (mxWindow->getPosSize());
     359           0 :         SetHorizontalOffset(aCurrentSlideBBox.X - aWindowBox.Width/2.0);
     360             :     }
     361           0 :     catch (RuntimeException&)
     362             :     {
     363           0 :         disposing();
     364           0 :         throw;
     365             :     }
     366           0 : }
     367             : 
     368           0 : PresenterSlideSorter::~PresenterSlideSorter()
     369             : {
     370           0 : }
     371             : 
     372           0 : void SAL_CALL PresenterSlideSorter::disposing()
     373             : {
     374           0 :     mxComponentContext = NULL;
     375           0 :     mxViewId = NULL;
     376           0 :     mxPane = NULL;
     377             : 
     378           0 :     if (mpVerticalScrollBar.is())
     379             :     {
     380             :         Reference<lang::XComponent> xComponent (
     381           0 :             static_cast<XWeak*>(mpVerticalScrollBar.get()), UNO_QUERY);
     382           0 :         mpVerticalScrollBar = NULL;
     383           0 :         if (xComponent.is())
     384           0 :             xComponent->dispose();
     385             :     }
     386           0 :     if (mpCloseButton.is())
     387             :     {
     388             :         Reference<lang::XComponent> xComponent (
     389           0 :             static_cast<XWeak*>(mpCloseButton.get()), UNO_QUERY);
     390           0 :         mpCloseButton = NULL;
     391           0 :         if (xComponent.is())
     392           0 :             xComponent->dispose();
     393             :     }
     394             : 
     395           0 :     if (mxCanvas.is())
     396             :     {
     397           0 :         Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
     398           0 :         if (xComponent.is())
     399           0 :             xComponent->removeEventListener(static_cast<awt::XWindowListener*>(this));
     400           0 :         mxCanvas = NULL;
     401             :     }
     402           0 :     mpPresenterController = NULL;
     403           0 :     mxSlideShowController = NULL;
     404           0 :     mpLayout.reset();
     405           0 :     mpMouseOverManager.reset();
     406             : 
     407           0 :     if (mxPreviewCache.is())
     408             :     {
     409           0 :         mxPreviewCache->removePreviewCreationNotifyListener(this);
     410             : 
     411           0 :         Reference<XComponent> xComponent (mxPreviewCache, UNO_QUERY);
     412           0 :         mxPreviewCache = NULL;
     413           0 :         if (xComponent.is())
     414           0 :             xComponent->dispose();
     415             :     }
     416             : 
     417           0 :     if (mxWindow.is())
     418             :     {
     419           0 :         mxWindow->removeWindowListener(this);
     420           0 :         mxWindow->removePaintListener(this);
     421           0 :         mxWindow->removeMouseListener(this);
     422           0 :         mxWindow->removeMouseMotionListener(this);
     423             :     }
     424           0 : }
     425             : 
     426           0 : void PresenterSlideSorter::SetActiveState (const bool bIsActive)
     427             : {
     428             :     (void)bIsActive;
     429           0 : }
     430             : 
     431             : //----- lang::XEventListener --------------------------------------------------
     432             : 
     433           0 : void SAL_CALL PresenterSlideSorter::disposing (const lang::EventObject& rEventObject)
     434             :     throw (RuntimeException, std::exception)
     435             : {
     436           0 :     if (rEventObject.Source == mxWindow)
     437             :     {
     438           0 :         mxWindow = NULL;
     439           0 :         dispose();
     440             :     }
     441           0 :     else if (rEventObject.Source == mxPreviewCache)
     442             :     {
     443           0 :         mxPreviewCache = NULL;
     444           0 :         dispose();
     445             :     }
     446           0 :     else if (rEventObject.Source == mxCanvas)
     447             :     {
     448           0 :         mxCanvas = NULL;
     449           0 :         mbIsLayoutPending = true;
     450           0 :         mbIsPaintPending = true;
     451             : 
     452           0 :         mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
     453             :     }
     454           0 : }
     455             : 
     456             : //----- XWindowListener -------------------------------------------------------
     457             : 
     458           0 : void SAL_CALL PresenterSlideSorter::windowResized (const awt::WindowEvent& rEvent)
     459             :     throw (uno::RuntimeException, std::exception)
     460             : {
     461             :     (void)rEvent;
     462           0 :     ThrowIfDisposed();
     463           0 :     mbIsLayoutPending = true;
     464           0 :     mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
     465           0 : }
     466             : 
     467           0 : void SAL_CALL PresenterSlideSorter::windowMoved (const awt::WindowEvent& rEvent)
     468             :     throw (uno::RuntimeException, std::exception)
     469             : {
     470             :     (void)rEvent;
     471           0 :     ThrowIfDisposed();
     472           0 : }
     473             : 
     474           0 : void SAL_CALL PresenterSlideSorter::windowShown (const lang::EventObject& rEvent)
     475             :     throw (uno::RuntimeException, std::exception)
     476             : {
     477             :     (void)rEvent;
     478           0 :     ThrowIfDisposed();
     479           0 :     mbIsLayoutPending = true;
     480           0 :     mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
     481           0 : }
     482             : 
     483           0 : void SAL_CALL PresenterSlideSorter::windowHidden (const lang::EventObject& rEvent)
     484             :     throw (uno::RuntimeException, std::exception)
     485             : {
     486             :     (void)rEvent;
     487           0 :     ThrowIfDisposed();
     488           0 : }
     489             : 
     490             : //----- XPaintListener --------------------------------------------------------
     491             : 
     492           0 : void SAL_CALL PresenterSlideSorter::windowPaint (const css::awt::PaintEvent& rEvent)
     493             :     throw (RuntimeException, std::exception)
     494             : {
     495             :     (void)rEvent;
     496             : 
     497             :     // Deactivated views must not be painted.
     498           0 :     if ( ! mbIsPresenterViewActive)
     499           0 :         return;
     500             : 
     501           0 :     Paint(rEvent.UpdateRect);
     502             : 
     503           0 :     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
     504           0 :     if (xSpriteCanvas.is())
     505           0 :         xSpriteCanvas->updateScreen(sal_False);
     506             : }
     507             : 
     508             : //----- XMouseListener --------------------------------------------------------
     509             : 
     510           0 : void SAL_CALL PresenterSlideSorter::mousePressed (const css::awt::MouseEvent& rEvent)
     511             :     throw(css::uno::RuntimeException, std::exception)
     512             : {
     513           0 :     css::awt::MouseEvent rTemp =rEvent;
     514             :     /// check whether RTL interface or not
     515           0 :     if(AllSettings::GetLayoutRTL()){
     516           0 :         awt::Rectangle aBox = mxWindow->getPosSize();
     517           0 :         rTemp.X=aBox.Width-rEvent.X;
     518             :     }
     519           0 :     const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y);
     520           0 :     mnSlideIndexMousePressed = mpLayout->GetSlideIndexForPosition(aPosition);
     521           0 : }
     522             : 
     523           0 : void SAL_CALL PresenterSlideSorter::mouseReleased (const css::awt::MouseEvent& rEvent)
     524             :     throw(css::uno::RuntimeException, std::exception)
     525             : {
     526           0 :     css::awt::MouseEvent rTemp =rEvent;
     527             :     /// check whether RTL interface or not
     528           0 :     if(AllSettings::GetLayoutRTL()){
     529           0 :         awt::Rectangle aBox = mxWindow->getPosSize();
     530           0 :         rTemp.X=aBox.Width-rEvent.X;
     531             :     }
     532           0 :     const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y);
     533           0 :     const sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition));
     534             : 
     535           0 :     if (nSlideIndex == mnSlideIndexMousePressed && mnSlideIndexMousePressed >= 0)
     536             :     {
     537           0 :         switch (rEvent.ClickCount)
     538             :         {
     539             :             case 1:
     540             :             default:
     541           0 :                 GotoSlide(nSlideIndex);
     542           0 :                 break;
     543             : 
     544             :             case 2:
     545             :                 OSL_ASSERT(mpPresenterController.get()!=NULL);
     546             :                 OSL_ASSERT(mpPresenterController->GetWindowManager().get()!=NULL);
     547           0 :                 mpPresenterController->GetWindowManager()->SetSlideSorterState(false);
     548           0 :                 GotoSlide(nSlideIndex);
     549           0 :                 break;
     550             :         }
     551           0 :     }
     552           0 : }
     553             : 
     554           0 : void SAL_CALL PresenterSlideSorter::mouseEntered (const css::awt::MouseEvent& rEvent)
     555             :     throw(css::uno::RuntimeException, std::exception)
     556             : {
     557             :     (void)rEvent;
     558           0 : }
     559             : 
     560           0 : void SAL_CALL PresenterSlideSorter::mouseExited (const css::awt::MouseEvent& rEvent)
     561             :     throw(css::uno::RuntimeException, std::exception)
     562             : {
     563             :     (void)rEvent;
     564           0 :     mnSlideIndexMousePressed = -1;
     565           0 :     if (mpMouseOverManager.get() != NULL)
     566           0 :         mpMouseOverManager->SetSlide(mnSlideIndexMousePressed, awt::Rectangle(0,0,0,0));
     567           0 : }
     568             : 
     569             : //----- XMouseMotionListener --------------------------------------------------
     570             : 
     571           0 : void SAL_CALL PresenterSlideSorter::mouseMoved (const css::awt::MouseEvent& rEvent)
     572             :     throw (css::uno::RuntimeException, std::exception)
     573             : {
     574           0 :     if (mpMouseOverManager.get() != NULL)
     575             :     {
     576           0 :         css::awt::MouseEvent rTemp =rEvent;
     577             :         /// check whether RTL interface or not
     578           0 :         if(AllSettings::GetLayoutRTL()){
     579           0 :             awt::Rectangle aBox = mxWindow->getPosSize();
     580           0 :             rTemp.X=aBox.Width-rEvent.X;
     581             :         }
     582           0 :         const geometry::RealPoint2D aPosition(rTemp.X, rEvent.Y);
     583           0 :         sal_Int32 nSlideIndex (mpLayout->GetSlideIndexForPosition(aPosition));
     584             : 
     585           0 :         if (nSlideIndex < 0)
     586           0 :             mnSlideIndexMousePressed = -1;
     587             : 
     588           0 :         if (nSlideIndex < 0)
     589             :         {
     590           0 :             mpMouseOverManager->SetSlide(nSlideIndex, awt::Rectangle(0,0,0,0));
     591             :         }
     592             :         else
     593             :         {
     594             :             mpMouseOverManager->SetSlide(
     595             :                 nSlideIndex,
     596           0 :                 mpLayout->GetBoundingBox(nSlideIndex));
     597           0 :         }
     598             :     }
     599           0 : }
     600             : 
     601           0 : void SAL_CALL PresenterSlideSorter::mouseDragged (const css::awt::MouseEvent& rEvent)
     602             :     throw (css::uno::RuntimeException, std::exception)
     603             : {
     604             :     (void)rEvent;
     605           0 : }
     606             : 
     607             : //----- XResourceId -----------------------------------------------------------
     608             : 
     609           0 : Reference<XResourceId> SAL_CALL PresenterSlideSorter::getResourceId()
     610             :     throw (RuntimeException, std::exception)
     611             : {
     612           0 :     ThrowIfDisposed();
     613           0 :     return mxViewId;
     614             : }
     615             : 
     616           0 : sal_Bool SAL_CALL PresenterSlideSorter::isAnchorOnly()
     617             :     throw (RuntimeException, std::exception)
     618             : {
     619           0 :     return false;
     620             : }
     621             : 
     622             : //----- XPropertyChangeListener -----------------------------------------------
     623             : 
     624           0 : void SAL_CALL PresenterSlideSorter::propertyChange (
     625             :     const css::beans::PropertyChangeEvent& rEvent)
     626             :     throw(css::uno::RuntimeException, std::exception)
     627             : {
     628             :     (void)rEvent;
     629           0 : }
     630             : 
     631             : //----- XSlidePreviewCacheListener --------------------------------------------
     632             : 
     633           0 : void SAL_CALL PresenterSlideSorter::notifyPreviewCreation (
     634             :     sal_Int32 nSlideIndex)
     635             :     throw(css::uno::RuntimeException, std::exception)
     636             : {
     637             :     OSL_ASSERT(mpLayout.get()!=NULL);
     638             : 
     639           0 :     awt::Rectangle aBBox (mpLayout->GetBoundingBox(nSlideIndex));
     640           0 :     mpPresenterController->GetPaintManager()->Invalidate(mxWindow, aBBox, true);
     641           0 : }
     642             : 
     643             : //----- XDrawView -------------------------------------------------------------
     644             : 
     645           0 : void SAL_CALL PresenterSlideSorter::setCurrentPage (const Reference<drawing::XDrawPage>& rxSlide)
     646             :     throw (RuntimeException, std::exception)
     647             : {
     648             :     (void)rxSlide;
     649             : 
     650           0 :     ThrowIfDisposed();
     651           0 :     ::osl::MutexGuard aGuard (::osl::Mutex::getGlobalMutex());
     652             : 
     653           0 :     if (mxSlideShowController.is())
     654             :     {
     655           0 :         const sal_Int32 nNewCurrentSlideIndex (mxSlideShowController->getCurrentSlideIndex());
     656           0 :         if (nNewCurrentSlideIndex != mnCurrentSlideIndex)
     657             :         {
     658           0 :             mnCurrentSlideIndex = nNewCurrentSlideIndex;
     659             : 
     660             :             // Request a repaint of the previous current slide to hide its
     661             :             // current slide indicator.
     662             :             mpPresenterController->GetPaintManager()->Invalidate(
     663             :                 mxWindow,
     664           0 :                 maCurrentSlideFrameBoundingBox);
     665             : 
     666             :             // Request a repaint of the new current slide to show its
     667             :             // current slide indicator.
     668             :             maCurrentSlideFrameBoundingBox = mpCurrentSlideFrameRenderer->GetBoundingBox(
     669           0 :                 mpLayout->GetBoundingBox(mnCurrentSlideIndex));
     670             :             mpPresenterController->GetPaintManager()->Invalidate(
     671             :                 mxWindow,
     672           0 :                 maCurrentSlideFrameBoundingBox);
     673             :         }
     674           0 :     }
     675           0 : }
     676             : 
     677           0 : Reference<drawing::XDrawPage> SAL_CALL PresenterSlideSorter::getCurrentPage()
     678             :     throw (RuntimeException, std::exception)
     679             : {
     680           0 :     ThrowIfDisposed();
     681           0 :     return NULL;
     682             : }
     683             : 
     684             : 
     685             : 
     686           0 : void PresenterSlideSorter::UpdateLayout()
     687             : {
     688           0 :     if ( ! mxWindow.is())
     689           0 :         return;
     690             : 
     691           0 :     mbIsLayoutPending = false;
     692           0 :     mbIsPaintPending = true;
     693             : 
     694           0 :     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
     695           0 :     awt::Rectangle aCenterBox (aWindowBox);
     696           0 :     sal_Int32 nLeftBorderWidth (aWindowBox.X);
     697             : 
     698             :     // Get border width.
     699             :     PresenterPaneContainer::SharedPaneDescriptor pPane (
     700             :         mpPresenterController->GetPaneContainer()->FindViewURL(
     701           0 :             mxViewId->getResourceURL()));
     702             :     do
     703             :     {
     704           0 :         if (pPane.get() == NULL)
     705           0 :             break;
     706           0 :         if ( ! pPane->mxPane.is())
     707           0 :             break;
     708             : 
     709             :         Reference<drawing::framework::XPaneBorderPainter> xBorderPainter (
     710           0 :             pPane->mxPane->GetPaneBorderPainter());
     711           0 :         if ( ! xBorderPainter.is())
     712           0 :             break;
     713           0 :         aCenterBox = xBorderPainter->addBorder (
     714           0 :             mxViewId->getAnchor()->getResourceURL(),
     715             :             awt::Rectangle(0, 0, aWindowBox.Width, aWindowBox.Height),
     716           0 :             drawing::framework::BorderType_INNER_BORDER);
     717             :     }
     718             :     while(false);
     719             : 
     720             :     // Place vertical separator.
     721           0 :     mnSeparatorY = aWindowBox.Height - mpCloseButton->GetSize().Height - gnVerticalButtonPadding;
     722             : 
     723           0 :     PlaceCloseButton(pPane, aWindowBox, nLeftBorderWidth);
     724             : 
     725             :     geometry::RealRectangle2D aUpperBox(
     726             :         gnHorizontalBorder,
     727             :         gnVerticalBorder,
     728           0 :         aWindowBox.Width - 2*gnHorizontalBorder,
     729           0 :         mnSeparatorY - gnVerticalGap);
     730             : 
     731             :     // Determine whether the scroll bar has to be displayed.
     732           0 :     aUpperBox = PlaceScrollBars(aUpperBox);
     733             : 
     734           0 :     mpLayout->Update(aUpperBox, GetSlideAspectRatio());
     735           0 :     mpLayout->SetupVisibleArea();
     736           0 :     mpLayout->UpdateScrollBars();
     737             : 
     738             :     // Tell the preview cache about some of the values.
     739           0 :     mxPreviewCache->setPreviewSize(mpLayout->maPreviewSize);
     740           0 :     mxPreviewCache->setVisibleRange(
     741             :         mpLayout->GetFirstVisibleSlideIndex(),
     742           0 :         mpLayout->GetLastVisibleSlideIndex());
     743             : 
     744             :     // Clear the frame polygon so that it is re-created on the next paint.
     745           0 :     mxPreviewFrame = NULL;
     746             : }
     747             : 
     748           0 : geometry::RealRectangle2D PresenterSlideSorter::PlaceScrollBars (
     749             :     const geometry::RealRectangle2D& rUpperBox)
     750             : {
     751           0 :     mpLayout->Update(rUpperBox, GetSlideAspectRatio());
     752           0 :     bool bIsScrollBarNeeded (false);
     753           0 :     Reference<container::XIndexAccess> xSlides (mxSlideShowController, UNO_QUERY_THROW);
     754           0 :     if (xSlides.is())
     755           0 :         bIsScrollBarNeeded = mpLayout->IsScrollBarNeeded(xSlides->getCount());
     756           0 :     if (mpVerticalScrollBar.get() != NULL)
     757             :         {
     758           0 :             if (bIsScrollBarNeeded)
     759             :                 {
     760           0 :                     if(AllSettings::GetLayoutRTL())
     761             :                         {
     762             :                             mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D(
     763             :                                                                                       rUpperBox.X1,
     764             :                                                                                       rUpperBox.Y1,
     765           0 :                                                                                       rUpperBox.X1 +  mpVerticalScrollBar->GetSize(),
     766           0 :                                                                                       rUpperBox.Y2));
     767           0 :                             mpVerticalScrollBar->SetVisible(true);
     768             :                             // Reduce area covered by the scroll bar from the available
     769             :                             // space.
     770             :                             return geometry::RealRectangle2D(
     771           0 :                                                              rUpperBox.X1 + gnHorizontalGap + mpVerticalScrollBar->GetSize(),
     772             :                                                              rUpperBox.Y1,
     773             :                                                              rUpperBox.X2,
     774           0 :                                                              rUpperBox.Y2);
     775             :                         }
     776             :                     else
     777             :                         {
     778             :                             // if its not RTL place vertical scroll bar at right border.
     779             :                             mpVerticalScrollBar->SetPosSize(geometry::RealRectangle2D(
     780           0 :                                                                                       rUpperBox.X2 - mpVerticalScrollBar->GetSize(),
     781             :                                                                                       rUpperBox.Y1,
     782             :                                                                                       rUpperBox.X2,
     783           0 :                                                                                       rUpperBox.Y2));
     784           0 :                             mpVerticalScrollBar->SetVisible(true);
     785             :                             // Reduce area covered by the scroll bar from the available
     786             :                             // space.
     787             :                             return geometry::RealRectangle2D(
     788             :                                                              rUpperBox.X1,
     789             :                                                              rUpperBox.Y1,
     790           0 :                                                              rUpperBox.X2 - mpVerticalScrollBar->GetSize() - gnHorizontalGap,
     791           0 :                                                              rUpperBox.Y2);
     792             :                         }
     793             :                 }
     794             :             else
     795           0 :                 mpVerticalScrollBar->SetVisible(false);
     796             :         }
     797           0 :     return rUpperBox;
     798             : }
     799             : 
     800           0 : void PresenterSlideSorter::PlaceCloseButton (
     801             :     const PresenterPaneContainer::SharedPaneDescriptor& rpPane,
     802             :     const awt::Rectangle& rCenterBox,
     803             :     const sal_Int32 nLeftBorderWidth)
     804             : {
     805             :     // Place button.  When the callout is near the center then the button is
     806             :     // centered over the callout.  Otherwise it is centered with respect to
     807             :     // the whole window.
     808           0 :     sal_Int32 nCloseButtonCenter (rCenterBox.Width/2);
     809           0 :     if (rpPane.get() != NULL && rpPane->mxPane.is())
     810             :     {
     811           0 :         const sal_Int32 nCalloutCenter (rpPane->mxPane->GetCalloutAnchor().X - nLeftBorderWidth);
     812           0 :         const sal_Int32 nDistanceFromWindowCenter (abs(nCalloutCenter - rCenterBox.Width/2));
     813           0 :         const sal_Int32 nButtonWidth (mpCloseButton->GetSize().Width);
     814           0 :         const static sal_Int32 nMaxDistanceForCalloutCentering (nButtonWidth * 2);
     815           0 :         if (nDistanceFromWindowCenter < nMaxDistanceForCalloutCentering)
     816             :         {
     817           0 :             if (nCalloutCenter < nButtonWidth/2)
     818           0 :                 nCloseButtonCenter = nButtonWidth/2;
     819           0 :             else if (nCalloutCenter > rCenterBox.Width-nButtonWidth/2)
     820           0 :                 nCloseButtonCenter = rCenterBox.Width-nButtonWidth/2;
     821             :             else
     822           0 :                 nCloseButtonCenter = nCalloutCenter;
     823             :         }
     824             :     }
     825             :     mpCloseButton->SetCenter(geometry::RealPoint2D(
     826             :         nCloseButtonCenter,
     827           0 :         rCenterBox.Height - mpCloseButton->GetSize().Height/ 2));
     828           0 : }
     829             : 
     830           0 : void PresenterSlideSorter::ClearBackground (
     831             :     const Reference<rendering::XCanvas>& rxCanvas,
     832             :     const awt::Rectangle& rUpdateBox)
     833             : {
     834             :     OSL_ASSERT(rxCanvas.is());
     835             : 
     836           0 :     const awt::Rectangle aWindowBox (mxWindow->getPosSize());
     837             :     mpPresenterController->GetCanvasHelper()->Paint(
     838           0 :         mpPresenterController->GetViewBackground(mxViewId->getResourceURL()),
     839             :         rxCanvas,
     840             :         rUpdateBox,
     841             :         awt::Rectangle(0,0,aWindowBox.Width,aWindowBox.Height),
     842           0 :         awt::Rectangle());
     843           0 : }
     844             : 
     845           0 : double PresenterSlideSorter::GetSlideAspectRatio() const
     846             : {
     847           0 :     double nSlideAspectRatio (28.0/21.0);
     848             : 
     849             :     try
     850             :     {
     851           0 :         Reference<container::XIndexAccess> xSlides(mxSlideShowController, UNO_QUERY_THROW);
     852           0 :         if (mxSlideShowController.is() && xSlides->getCount()>0)
     853             :         {
     854           0 :             Reference<beans::XPropertySet> xProperties(xSlides->getByIndex(0),UNO_QUERY_THROW);
     855           0 :             sal_Int32 nWidth (28000);
     856           0 :             sal_Int32 nHeight (21000);
     857           0 :             if ((xProperties->getPropertyValue("Width") >>= nWidth)
     858           0 :                 && (xProperties->getPropertyValue("Height") >>= nHeight)
     859           0 :                 && nHeight > 0)
     860             :             {
     861           0 :                 nSlideAspectRatio = double(nWidth) / double(nHeight);
     862           0 :             }
     863           0 :         }
     864             :     }
     865           0 :     catch (RuntimeException&)
     866             :     {
     867             :         OSL_ASSERT(false);
     868             :     }
     869             : 
     870           0 :     return nSlideAspectRatio;
     871             : }
     872             : 
     873           0 : Reference<rendering::XBitmap> PresenterSlideSorter::GetPreview (const sal_Int32 nSlideIndex)
     874             : {
     875           0 :     if (nSlideIndex < 0 || nSlideIndex>=mpLayout->mnSlideCount)
     876           0 :         return NULL;
     877           0 :     else if (mxPane.is())
     878           0 :         return mxPreviewCache->getSlidePreview(nSlideIndex, mxPane->getCanvas());
     879             :     else
     880           0 :         return NULL;
     881             : }
     882             : 
     883           0 : void PresenterSlideSorter::PaintPreview (
     884             :     const Reference<rendering::XCanvas>& rxCanvas,
     885             :     const css::awt::Rectangle& rUpdateBox,
     886             :     const sal_Int32 nSlideIndex)
     887             : {
     888             :     OSL_ASSERT(rxCanvas.is());
     889             : 
     890           0 :     geometry::IntegerSize2D aSize (mpLayout->maPreviewSize);
     891             : 
     892           0 :     if (PresenterGeometryHelper::AreRectanglesDisjoint(
     893             :         rUpdateBox,
     894           0 :         mpLayout->GetBoundingBox(nSlideIndex)))
     895             :     {
     896           0 :         return;
     897             :     }
     898             : 
     899           0 :     Reference<rendering::XBitmap> xPreview (GetPreview(nSlideIndex));
     900           0 :     bool isRTL = AllSettings::GetLayoutRTL();
     901             : 
     902             :     const geometry::RealPoint2D aTopLeft (
     903             :                                           mpLayout->GetWindowPosition(
     904           0 :                                                                       mpLayout->GetPoint(nSlideIndex, isRTL?1:-1, -1)));
     905             : 
     906             :     PresenterBitmapContainer aContainer (
     907             :         "PresenterScreenSettings/ScrollBar/Bitmaps",
     908             :         ::boost::shared_ptr<PresenterBitmapContainer>(),
     909             :         mxComponentContext,
     910           0 :         rxCanvas);
     911           0 :     Reference<container::XIndexAccess> xIndexAccess(mxSlideShowController, UNO_QUERY);
     912             :     Reference<drawing::XDrawPage> xPage = Reference<drawing::XDrawPage>(
     913           0 :         xIndexAccess->getByIndex(nSlideIndex), UNO_QUERY);
     914           0 :     bool bTransition = PresenterController::HasTransition(xPage);
     915           0 :     bool bCustomAnimation = PresenterController::HasCustomAnimation(xPage);
     916             : 
     917             :     // Create clip rectangle as intersection of the current update area and
     918             :     // the bounding box of all previews.
     919           0 :     geometry::RealRectangle2D aBoundingBox (mpLayout->maBoundingBox);
     920           0 :     aBoundingBox.Y2 += 1;
     921             :     const geometry::RealRectangle2D aClipBox (
     922             :         PresenterGeometryHelper::Intersection(
     923             :             PresenterGeometryHelper::ConvertRectangle(rUpdateBox),
     924           0 :             aBoundingBox));
     925             :     Reference<rendering::XPolyPolygon2D> xClip (
     926           0 :         PresenterGeometryHelper::CreatePolygon(aClipBox, rxCanvas->getDevice()));
     927             : 
     928           0 :     const rendering::ViewState aViewState (geometry::AffineMatrix2D(1,0,0, 0,1,0), xClip);
     929             : 
     930             :     rendering::RenderState aRenderState (
     931             :         geometry::AffineMatrix2D(
     932             :             1, 0, aTopLeft.X,
     933             :             0, 1, aTopLeft.Y),
     934             :         NULL,
     935             :         Sequence<double>(4),
     936           0 :         rendering::CompositeOperation::SOURCE);
     937             : 
     938             :     // Emphasize the current slide.
     939           0 :     if (nSlideIndex == mnCurrentSlideIndex)
     940             :     {
     941           0 :         if (mpCurrentSlideFrameRenderer.get() != NULL)
     942             :         {
     943             :             const awt::Rectangle aSlideBoundingBox(
     944           0 :                 sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.X),
     945           0 :                 sal::static_int_cast<sal_Int32>(0.5 + aTopLeft.Y),
     946             :                 aSize.Width,
     947           0 :                 aSize.Height);
     948             :             maCurrentSlideFrameBoundingBox
     949           0 :                 = mpCurrentSlideFrameRenderer->GetBoundingBox(aSlideBoundingBox);
     950             :             mpCurrentSlideFrameRenderer->PaintCurrentSlideFrame (
     951             :                 aSlideBoundingBox,
     952             :                 mxCanvas,
     953           0 :                 aClipBox);
     954             :         }
     955             :     }
     956             : 
     957             :     // Paint the preview.
     958           0 :     if (xPreview.is())
     959             :     {
     960           0 :         aSize = xPreview->getSize();
     961           0 :         if (aSize.Width > 0 && aSize.Height > 0)
     962             :         {
     963           0 :             rxCanvas->drawBitmap(xPreview, aViewState, aRenderState);
     964           0 :             if( bCustomAnimation )
     965             :             {
     966           0 :                 const awt::Rectangle aAnimationPreviewBox(aTopLeft.X+3, aTopLeft.Y+aSize.Height-40, 0, 0);
     967           0 :                 SharedBitmapDescriptor aAnimationDescriptor = aContainer.GetBitmap("Animation");
     968           0 :                 Reference<rendering::XBitmap> xAnimationIcon (aAnimationDescriptor->GetNormalBitmap());
     969             :                 rendering::RenderState aAnimationRenderState (
     970             :                     geometry::AffineMatrix2D(
     971             :                     1, 0, aAnimationPreviewBox.X,
     972             :                     0, 1, aAnimationPreviewBox.Y),
     973             :                     NULL,
     974             :                     Sequence<double>(4),
     975           0 :                     rendering::CompositeOperation::SOURCE);
     976           0 :                     rxCanvas->drawBitmap(xAnimationIcon, aViewState, aAnimationRenderState);
     977             :             }
     978           0 :             if( bTransition )
     979             :             {
     980           0 :                 const awt::Rectangle aTransitionPreviewBox(aTopLeft.X+3, aTopLeft.Y+aSize.Height-20, 0, 0);
     981           0 :                 SharedBitmapDescriptor aTransitionDescriptor = aContainer.GetBitmap("Transition");
     982           0 :                 Reference<rendering::XBitmap> xTransitionIcon (aTransitionDescriptor->GetNormalBitmap());
     983             :                 rendering::RenderState aTransitionRenderState (
     984             :                     geometry::AffineMatrix2D(
     985             :                     1, 0, aTransitionPreviewBox.X,
     986             :                     0, 1, aTransitionPreviewBox.Y),
     987             :                     NULL,
     988             :                     Sequence<double>(4),
     989           0 :                     rendering::CompositeOperation::SOURCE);
     990           0 :                     rxCanvas->drawBitmap(xTransitionIcon, aViewState, aTransitionRenderState);
     991             :             }
     992             :         }
     993             :     }
     994             : 
     995             :     // Create a polygon that is used to paint a frame around previews.  Its
     996             :     // coordinates are chosen in the local coordinate system of a preview.
     997           0 :     if ( ! mxPreviewFrame.is())
     998           0 :         mxPreviewFrame = PresenterGeometryHelper::CreatePolygon(
     999           0 :             awt::Rectangle(-1, -1, aSize.Width+2, aSize.Height+2),
    1000           0 :             rxCanvas->getDevice());
    1001             : 
    1002             :     // Paint a border around the preview.
    1003           0 :     if (mxPreviewFrame.is())
    1004             :     {
    1005           0 :         const geometry::RealRectangle2D aBox (0, 0, aSize.Width, aSize.Height);
    1006           0 :         const util::Color aFrameColor (0x00000000);
    1007           0 :         PresenterCanvasHelper::SetDeviceColor(aRenderState, aFrameColor);
    1008           0 :         rxCanvas->drawPolyPolygon(mxPreviewFrame, aViewState, aRenderState);
    1009             :     }
    1010             : 
    1011             :     // Paint mouse over effect.
    1012           0 :     mpMouseOverManager->Paint(nSlideIndex, mxCanvas, xClip);
    1013             : }
    1014             : 
    1015           0 : void PresenterSlideSorter::Paint (const awt::Rectangle& rUpdateBox)
    1016             : {
    1017           0 :     const bool bCanvasChanged ( ! mxCanvas.is());
    1018           0 :     if ( ! ProvideCanvas())
    1019           0 :         return;
    1020             : 
    1021           0 :     if (mpLayout->mnRowCount<=0 || mpLayout->mnColumnCount<=0)
    1022             :     {
    1023             :         OSL_ASSERT(mpLayout->mnRowCount>0 || mpLayout->mnColumnCount>0);
    1024           0 :         return;
    1025             :     }
    1026             : 
    1027           0 :     mbIsPaintPending = false;
    1028             : 
    1029           0 :     ClearBackground(mxCanvas, rUpdateBox);
    1030             : 
    1031             :     // Give the canvas to the controls.
    1032           0 :     if (bCanvasChanged)
    1033             :     {
    1034           0 :         if (mpVerticalScrollBar.is())
    1035           0 :             mpVerticalScrollBar->SetCanvas(mxCanvas);
    1036           0 :         if (mpCloseButton.is())
    1037           0 :             mpCloseButton->SetCanvas(mxCanvas, mxWindow);
    1038             :     }
    1039             : 
    1040             :     // Now that the controls have a canvas we can do the layouting.
    1041           0 :     if (mbIsLayoutPending)
    1042           0 :         UpdateLayout();
    1043             : 
    1044             :     // Paint the horizontal separator.
    1045             :     rendering::RenderState aRenderState (geometry::AffineMatrix2D(1,0,0, 0,1,0),
    1046           0 :             NULL, Sequence<double>(4), rendering::CompositeOperation::SOURCE);
    1047           0 :     PresenterCanvasHelper::SetDeviceColor(aRenderState, maSeparatorColor);
    1048           0 :     mxCanvas->drawLine(
    1049             :         geometry::RealPoint2D(0, mnSeparatorY),
    1050           0 :         geometry::RealPoint2D(mxWindow->getPosSize().Width, mnSeparatorY),
    1051             :         rendering::ViewState(geometry::AffineMatrix2D(1,0,0, 0,1,0), NULL),
    1052           0 :         aRenderState);
    1053             : 
    1054             :     // Paint the slides.
    1055           0 :     if ( ! PresenterGeometryHelper::AreRectanglesDisjoint(
    1056             :         rUpdateBox,
    1057           0 :         PresenterGeometryHelper::ConvertRectangle(mpLayout->maBoundingBox)))
    1058             :     {
    1059             :         mpLayout->ForAllVisibleSlides(
    1060           0 :             ::boost::bind(&PresenterSlideSorter::PaintPreview, this, mxCanvas, rUpdateBox, _1));
    1061             :     }
    1062             : 
    1063           0 :     Reference<rendering::XSpriteCanvas> xSpriteCanvas (mxCanvas, UNO_QUERY);
    1064           0 :     if (xSpriteCanvas.is())
    1065           0 :         xSpriteCanvas->updateScreen(sal_False);
    1066             : }
    1067             : 
    1068           0 : void PresenterSlideSorter::SetHorizontalOffset (const double nXOffset)
    1069             : {
    1070           0 :     if (mpLayout->SetHorizontalOffset(nXOffset))
    1071             :     {
    1072           0 :         mxPreviewCache->setVisibleRange(
    1073             :             mpLayout->GetFirstVisibleSlideIndex(),
    1074           0 :             mpLayout->GetLastVisibleSlideIndex());
    1075             : 
    1076           0 :         mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
    1077             :     }
    1078           0 : }
    1079             : 
    1080           0 : void PresenterSlideSorter::SetVerticalOffset (const double nYOffset)
    1081             : {
    1082           0 :     if (mpLayout->SetVerticalOffset(nYOffset))
    1083             :     {
    1084           0 :         mxPreviewCache->setVisibleRange(
    1085             :             mpLayout->GetFirstVisibleSlideIndex(),
    1086           0 :             mpLayout->GetLastVisibleSlideIndex());
    1087             : 
    1088           0 :         mpPresenterController->GetPaintManager()->Invalidate(mxWindow);
    1089             :     }
    1090           0 : }
    1091             : 
    1092           0 : void PresenterSlideSorter::GotoSlide (const sal_Int32 nSlideIndex)
    1093             : {
    1094           0 :     mxSlideShowController->gotoSlideIndex(nSlideIndex);
    1095           0 : }
    1096             : 
    1097           0 : bool PresenterSlideSorter::ProvideCanvas()
    1098             : {
    1099           0 :     if ( ! mxCanvas.is())
    1100             :     {
    1101           0 :         if (mxPane.is())
    1102           0 :             mxCanvas = mxPane->getCanvas();
    1103             : 
    1104             :         // Register as event listener so that we are informed when the
    1105             :         // canvas is disposed (and we have to fetch another one).
    1106           0 :         Reference<lang::XComponent> xComponent (mxCanvas, UNO_QUERY);
    1107           0 :         if (xComponent.is())
    1108           0 :             xComponent->addEventListener(static_cast<awt::XWindowListener*>(this));
    1109             : 
    1110             :         mpCurrentSlideFrameRenderer.reset(
    1111           0 :             new CurrentSlideFrameRenderer(mxComponentContext, mxCanvas));
    1112             :     }
    1113           0 :     return mxCanvas.is();
    1114             : }
    1115             : 
    1116           0 : void PresenterSlideSorter::ThrowIfDisposed()
    1117             :     throw (lang::DisposedException)
    1118             : {
    1119           0 :     if (rBHelper.bDisposed || rBHelper.bInDispose)
    1120             :     {
    1121             :         throw lang::DisposedException (
    1122             :             OUString(
    1123             :                 "PresenterSlideSorter has been already disposed"),
    1124           0 :             const_cast<uno::XWeak*>(static_cast<const uno::XWeak*>(this)));
    1125             :     }
    1126           0 : }
    1127             : 
    1128             : //===== PresenterSlideSorter::Layout ==========================================
    1129             : 
    1130           0 : PresenterSlideSorter::Layout::Layout (
    1131             :     const ::rtl::Reference<PresenterScrollBar>& rpVerticalScrollBar)
    1132             :     : maBoundingBox(),
    1133             :       maPreviewSize(),
    1134             :       mnHorizontalOffset(0),
    1135             :       mnVerticalOffset(0),
    1136             :       mnHorizontalGap(0),
    1137             :       mnVerticalGap(0),
    1138             :       mnHorizontalBorder(0),
    1139             :       mnVerticalBorder(0),
    1140             :       mnRowCount(1),
    1141             :       mnColumnCount(1),
    1142             :       mnSlideCount(0),
    1143             :       mnSlideIndexAtMouse(-1),
    1144             :       mnFirstVisibleColumn(-1),
    1145             :       mnLastVisibleColumn(-1),
    1146             :       mnFirstVisibleRow(-1),
    1147             :       mnLastVisibleRow(-1),
    1148           0 :       mpVerticalScrollBar(rpVerticalScrollBar)
    1149             : {
    1150           0 : }
    1151             : 
    1152           0 : void PresenterSlideSorter::Layout::Update (
    1153             :     const geometry::RealRectangle2D& rBoundingBox,
    1154             :     const double nSlideAspectRatio)
    1155             : {
    1156           0 :     maBoundingBox = rBoundingBox;
    1157             : 
    1158           0 :     mnHorizontalBorder = gnHorizontalBorder;
    1159           0 :     mnVerticalBorder = gnVerticalBorder;
    1160             : 
    1161           0 :     const double nWidth (rBoundingBox.X2 - rBoundingBox.X1 - 2*mnHorizontalBorder);
    1162           0 :     const double nHeight (rBoundingBox.Y2 - rBoundingBox.Y1 - 2*mnVerticalBorder);
    1163           0 :     if (nWidth<=0 || nHeight<=0)
    1164           0 :         return;
    1165             : 
    1166             :     double nPreviewWidth;
    1167             : 
    1168             :     // Determine column count, preview width, and horizontal gap (borders
    1169             :     // are half the gap).  Try to use the preferred values.  Try more to
    1170             :     // stay in the valid intervalls.  This last constraint may be not
    1171             :     // fulfilled in some cases.
    1172           0 :     const double nElementWidth = nWidth / gnPreferredColumnCount;
    1173           0 :     if (nElementWidth < gnMinimalPreviewWidth + gnMinimalHorizontalPreviewGap)
    1174             :     {
    1175             :         // The preferred column count is too large.
    1176             :         // Can we use the preferred preview width?
    1177           0 :         if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
    1178             :         {
    1179             :             // Yes.
    1180           0 :             nPreviewWidth = gnPreferredPreviewWidth;
    1181           0 :             mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
    1182           0 :                 / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
    1183           0 :             mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
    1184             :         }
    1185             :         else
    1186             :         {
    1187             :             // No.  Set the column count to 1 and adapt preview width and
    1188             :             // gap.
    1189           0 :             mnColumnCount = 1;
    1190           0 :             mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
    1191           0 :             if (nWidth - gnMinimalHorizontalPreviewGap >= gnPreferredPreviewWidth)
    1192           0 :                 nPreviewWidth = nWidth - gnMinimalHorizontalPreviewGap;
    1193             :             else
    1194           0 :                 nPreviewWidth = ::std::max(gnMinimalPreviewWidth, nWidth-mnHorizontalGap);
    1195             :         }
    1196             :     }
    1197           0 :     else if (nElementWidth > gnMaximalPreviewWidth + gnMaximalHorizontalPreviewGap)
    1198             :     {
    1199             :         // The preferred column count is too small.
    1200           0 :         nPreviewWidth = gnPreferredPreviewWidth;
    1201           0 :         mnColumnCount = floor((nWidth+gnPreferredHorizontalPreviewGap)
    1202           0 :             / (nPreviewWidth+gnPreferredHorizontalPreviewGap));
    1203           0 :         mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
    1204             :     }
    1205             :     else
    1206             :     {
    1207             :         // The preferred column count is possible.  Determine gap and
    1208             :         // preview width.
    1209           0 :         mnColumnCount = gnPreferredColumnCount;
    1210           0 :         if (nElementWidth - gnPreferredPreviewWidth < gnMinimalHorizontalPreviewGap)
    1211             :         {
    1212             :             // Use the minimal gap and adapt the preview width.
    1213           0 :             mnHorizontalGap = floor(gnMinimalHorizontalPreviewGap);
    1214           0 :             nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
    1215             :         }
    1216           0 :         else if (nElementWidth - gnPreferredPreviewWidth <= gnMaximalHorizontalPreviewGap)
    1217             :         {
    1218             :             // Use the maximal gap and adapt the preview width.
    1219           0 :             mnHorizontalGap = round(gnMaximalHorizontalPreviewGap);
    1220           0 :             nPreviewWidth = (nWidth - mnColumnCount*mnHorizontalGap) / mnColumnCount;
    1221             :         }
    1222             :         else
    1223             :         {
    1224             :             // Use the preferred preview width and adapt the gap.
    1225           0 :             nPreviewWidth = gnPreferredPreviewWidth;
    1226           0 :             mnHorizontalGap = round((nWidth - mnColumnCount*nPreviewWidth) / mnColumnCount);
    1227             :         }
    1228             :     }
    1229             : 
    1230             :     // Now determine the row count, preview height, and vertical gap.
    1231           0 :     const double nPreviewHeight = nPreviewWidth / nSlideAspectRatio;
    1232             :     mnRowCount = ::std::max(
    1233             :         sal_Int32(1),
    1234           0 :         sal_Int32(ceil((nHeight+gnPreferredVerticalPreviewGap)
    1235           0 :                 / (nPreviewHeight + gnPreferredVerticalPreviewGap))));
    1236           0 :     mnVerticalGap = round(gnPreferredVerticalPreviewGap);
    1237             : 
    1238           0 :     maPreviewSize = geometry::IntegerSize2D(floor(nPreviewWidth), floor(nPreviewHeight));
    1239             : 
    1240             :     // Reset the offset.
    1241           0 :     mnVerticalOffset = 0;
    1242             :     mnHorizontalOffset = round(-(nWidth
    1243           0 :         - mnColumnCount*maPreviewSize.Width
    1244           0 :         - (mnColumnCount-1)*mnHorizontalGap)
    1245           0 :         / 2);
    1246             : }
    1247             : 
    1248           0 : void PresenterSlideSorter::Layout::SetupVisibleArea()
    1249             : {
    1250             :     geometry::RealPoint2D aPoint (GetLocalPosition(
    1251           0 :         geometry::RealPoint2D(maBoundingBox.X1, maBoundingBox.Y1)));
    1252           0 :     mnFirstVisibleColumn = 0;
    1253           0 :     mnFirstVisibleRow = ::std::max(sal_Int32(0), GetRow(aPoint));
    1254             : 
    1255           0 :     aPoint = GetLocalPosition(geometry::RealPoint2D( maBoundingBox.X2, maBoundingBox.Y2));
    1256           0 :     mnLastVisibleColumn = mnColumnCount - 1;
    1257           0 :     mnLastVisibleRow = GetRow(aPoint, true);
    1258           0 : }
    1259             : 
    1260           0 : bool PresenterSlideSorter::Layout::IsScrollBarNeeded (const sal_Int32 nSlideCount)
    1261             : {
    1262           0 :     geometry::RealPoint2D aBottomRight;
    1263             :     aBottomRight = GetPoint(
    1264           0 :         mnColumnCount * (GetRow(nSlideCount)+1) - 1, +1, +1);
    1265           0 :     return aBottomRight.X > maBoundingBox.X2-maBoundingBox.X1
    1266           0 :         || aBottomRight.Y > maBoundingBox.Y2-maBoundingBox.Y1;
    1267             : }
    1268             : 
    1269           0 : geometry::RealPoint2D PresenterSlideSorter::Layout::GetLocalPosition(
    1270             :     const geometry::RealPoint2D& rWindowPoint) const
    1271             : {
    1272           0 :     if(AllSettings::GetLayoutRTL())
    1273             :         {
    1274             :             return css::geometry::RealPoint2D(
    1275           0 :                                               -rWindowPoint.X  + maBoundingBox.X2 + mnHorizontalOffset,
    1276           0 :                                               rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset);
    1277             :         }
    1278             :     else
    1279             :         {
    1280             :             return css::geometry::RealPoint2D(
    1281           0 :                                               rWindowPoint.X - maBoundingBox.X1 + mnHorizontalOffset,
    1282           0 :                                               rWindowPoint.Y - maBoundingBox.Y1 + mnVerticalOffset);
    1283             :         }
    1284             : }
    1285             : 
    1286           0 : geometry::RealPoint2D PresenterSlideSorter::Layout::GetWindowPosition(
    1287             :     const geometry::RealPoint2D& rLocalPoint) const
    1288             : {
    1289           0 :     if(AllSettings::GetLayoutRTL())
    1290             :         {
    1291             :             return css::geometry::RealPoint2D(
    1292           0 :                                               -rLocalPoint.X + mnHorizontalOffset + maBoundingBox.X2,
    1293           0 :                                               rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1);
    1294             :         }
    1295             :     else
    1296             :         {
    1297             :             return css::geometry::RealPoint2D(
    1298           0 :                                               rLocalPoint.X - mnHorizontalOffset + maBoundingBox.X1,
    1299           0 :                                               rLocalPoint.Y - mnVerticalOffset + maBoundingBox.Y1);
    1300             :         }
    1301             : }
    1302             : 
    1303           0 : sal_Int32 PresenterSlideSorter::Layout::GetColumn (
    1304             :     const css::geometry::RealPoint2D& rLocalPoint,
    1305             :     const bool bReturnInvalidValue) const
    1306             : {
    1307             :     const sal_Int32 nColumn(floor(
    1308           0 :         (rLocalPoint.X + mnHorizontalGap/2.0) / (maPreviewSize.Width+mnHorizontalGap)));
    1309           0 :     if (bReturnInvalidValue
    1310           0 :         || (nColumn>=mnFirstVisibleColumn && nColumn<=mnLastVisibleColumn))
    1311             :     {
    1312           0 :         return nColumn;
    1313             :     }
    1314             :     else
    1315           0 :         return -1;
    1316             : }
    1317             : 
    1318           0 : sal_Int32 PresenterSlideSorter::Layout::GetRow (
    1319             :     const css::geometry::RealPoint2D& rLocalPoint,
    1320             :     const bool bReturnInvalidValue) const
    1321             : {
    1322             :     const sal_Int32 nRow (floor(
    1323           0 :         (rLocalPoint.Y + mnVerticalGap/2.0) / (maPreviewSize.Height+mnVerticalGap)));
    1324           0 :     if (bReturnInvalidValue
    1325           0 :         || (nRow>=mnFirstVisibleRow && nRow<=mnLastVisibleRow))
    1326             :     {
    1327           0 :         return nRow;
    1328             :     }
    1329             :     else
    1330           0 :         return -1;
    1331             : }
    1332             : 
    1333           0 : sal_Int32 PresenterSlideSorter::Layout::GetSlideIndexForPosition (
    1334             :     const css::geometry::RealPoint2D& rWindowPoint) const
    1335             : {
    1336           0 :     if ( ! PresenterGeometryHelper::IsInside(maBoundingBox, rWindowPoint))
    1337           0 :         return -1;
    1338             : 
    1339           0 :     const css::geometry::RealPoint2D aLocalPosition (GetLocalPosition(rWindowPoint));
    1340           0 :     const sal_Int32 nColumn (GetColumn(aLocalPosition));
    1341           0 :     const sal_Int32 nRow (GetRow(aLocalPosition));
    1342             : 
    1343           0 :     if (nColumn < 0 || nRow < 0)
    1344           0 :         return -1;
    1345             :     else
    1346             :     {
    1347           0 :         sal_Int32 nIndex (GetIndex(nRow, nColumn));
    1348           0 :         if (nIndex >= mnSlideCount)
    1349           0 :             return -1;
    1350             :         else
    1351           0 :             return nIndex;
    1352             :     }
    1353             : }
    1354             : 
    1355           0 : geometry::RealPoint2D PresenterSlideSorter::Layout::GetPoint (
    1356             :     const sal_Int32 nSlideIndex,
    1357             :     const sal_Int32 nRelativeHorizontalPosition,
    1358             :     const sal_Int32 nRelativeVerticalPosition) const
    1359             : {
    1360           0 :     sal_Int32 nColumn (GetColumn(nSlideIndex));
    1361           0 :     sal_Int32 nRow (GetRow(nSlideIndex));
    1362             : 
    1363             :     geometry::RealPoint2D aPosition (
    1364           0 :         mnHorizontalBorder + nColumn*(maPreviewSize.Width+mnHorizontalGap),
    1365           0 :         mnVerticalBorder + nRow*(maPreviewSize.Height+mnVerticalGap));
    1366             : 
    1367           0 :     if (nRelativeHorizontalPosition >= 0)
    1368             :     {
    1369           0 :         if (nRelativeHorizontalPosition > 0)
    1370           0 :             aPosition.X += maPreviewSize.Width;
    1371             :         else
    1372           0 :             aPosition.X += maPreviewSize.Width / 2.0;
    1373             :     }
    1374           0 :     if (nRelativeVerticalPosition >= 0)
    1375             :     {
    1376           0 :         if (nRelativeVerticalPosition > 0)
    1377           0 :             aPosition.Y += maPreviewSize.Height;
    1378             :         else
    1379           0 :             aPosition.Y += maPreviewSize.Height / 2.0;
    1380             :     }
    1381             : 
    1382           0 :     return aPosition;
    1383             : }
    1384             : 
    1385           0 : awt::Rectangle PresenterSlideSorter::Layout::GetBoundingBox (const sal_Int32 nSlideIndex) const
    1386             : {
    1387           0 :     bool isRTL = AllSettings::GetLayoutRTL();
    1388           0 :     const geometry::RealPoint2D aWindowPosition(GetWindowPosition(GetPoint(nSlideIndex, isRTL?1:-1, -1)));
    1389             :     return PresenterGeometryHelper::ConvertRectangle(
    1390             :                                                      geometry::RealRectangle2D(
    1391             :                                                                                aWindowPosition.X,
    1392             :                                                                                aWindowPosition.Y,
    1393           0 :                                                                                aWindowPosition.X + maPreviewSize.Width,
    1394           0 :                                                                                aWindowPosition.Y + maPreviewSize.Height));
    1395             : }
    1396             : 
    1397           0 : void PresenterSlideSorter::Layout::ForAllVisibleSlides (const ::boost::function<void(sal_Int32)>& rAction)
    1398             : {
    1399           0 :     for (sal_Int32 nRow=mnFirstVisibleRow; nRow<=mnLastVisibleRow; ++nRow)
    1400             :     {
    1401           0 :         for (sal_Int32 nColumn=mnFirstVisibleColumn; nColumn<=mnLastVisibleColumn; ++nColumn)
    1402             :         {
    1403           0 :             const sal_Int32 nSlideIndex (GetIndex(nRow, nColumn));
    1404           0 :             if (nSlideIndex >= mnSlideCount)
    1405           0 :                 return;
    1406           0 :             rAction(nSlideIndex);
    1407             :         }
    1408             :     }
    1409             : }
    1410             : 
    1411           0 : sal_Int32 PresenterSlideSorter::Layout::GetFirstVisibleSlideIndex() const
    1412             : {
    1413           0 :     return GetIndex(mnFirstVisibleRow, mnFirstVisibleColumn);
    1414             : }
    1415             : 
    1416           0 : sal_Int32 PresenterSlideSorter::Layout::GetLastVisibleSlideIndex() const
    1417             : {
    1418             :     return ::std::min(
    1419           0 :         GetIndex(mnLastVisibleRow, mnLastVisibleColumn),
    1420           0 :         mnSlideCount);
    1421             : }
    1422             : 
    1423           0 : bool PresenterSlideSorter::Layout::SetHorizontalOffset (const double nOffset)
    1424             : {
    1425           0 :     if (mnHorizontalOffset != nOffset)
    1426             :     {
    1427           0 :         mnHorizontalOffset = round(nOffset);
    1428           0 :         SetupVisibleArea();
    1429           0 :         UpdateScrollBars();
    1430           0 :         return true;
    1431             :     }
    1432             :     else
    1433           0 :         return false;
    1434             : }
    1435             : 
    1436           0 : bool PresenterSlideSorter::Layout::SetVerticalOffset (const double nOffset)
    1437             : {
    1438           0 :     if (mnVerticalOffset != nOffset)
    1439             :     {
    1440           0 :         mnVerticalOffset = round(nOffset);
    1441           0 :         SetupVisibleArea();
    1442           0 :         UpdateScrollBars();
    1443           0 :         return true;
    1444             :     }
    1445             :     else
    1446           0 :         return false;
    1447             : }
    1448             : 
    1449           0 : void PresenterSlideSorter::Layout::UpdateScrollBars()
    1450             : {
    1451           0 :     sal_Int32 nTotalRowCount (0);
    1452           0 :     nTotalRowCount = sal_Int32(ceil(double(mnSlideCount) / double(mnColumnCount)));
    1453             : 
    1454           0 :     if (mpVerticalScrollBar.get() != NULL)
    1455             :     {
    1456             :         mpVerticalScrollBar->SetTotalSize(
    1457           0 :             nTotalRowCount * maPreviewSize.Height
    1458           0 :                 + (nTotalRowCount-1) * mnVerticalGap
    1459           0 :             + 2*mnVerticalGap);
    1460           0 :         mpVerticalScrollBar->SetThumbPosition(mnVerticalOffset, false);
    1461           0 :         mpVerticalScrollBar->SetThumbSize(maBoundingBox.Y2 - maBoundingBox.Y1 + 1);
    1462           0 :         mpVerticalScrollBar->SetLineHeight(maPreviewSize.Height);
    1463             :     }
    1464             : 
    1465             :     // No place yet for the vertical scroll bar.
    1466           0 : }
    1467             : 
    1468           0 : sal_Int32 PresenterSlideSorter::Layout::GetIndex (
    1469             :     const sal_Int32 nRow,
    1470             :     const sal_Int32 nColumn) const
    1471             : {
    1472           0 :     return nRow * mnColumnCount + nColumn;
    1473             : }
    1474             : 
    1475           0 : sal_Int32 PresenterSlideSorter::Layout::GetRow (const sal_Int32 nSlideIndex) const
    1476             : {
    1477           0 :     return nSlideIndex / mnColumnCount;
    1478             : }
    1479             : 
    1480           0 : sal_Int32 PresenterSlideSorter::Layout::GetColumn (const sal_Int32 nSlideIndex) const
    1481             : {
    1482           0 :     return nSlideIndex % mnColumnCount;
    1483             : }
    1484             : 
    1485             : //===== PresenterSlideSorter::MouseOverManager ================================
    1486             : 
    1487           0 : PresenterSlideSorter::MouseOverManager::MouseOverManager (
    1488             :     const Reference<container::XIndexAccess>& rxSlides,
    1489             :     const ::boost::shared_ptr<PresenterTheme>& rpTheme,
    1490             :     const Reference<awt::XWindow>& rxInvalidateTarget,
    1491             :     const ::boost::shared_ptr<PresenterPaintManager>& rpPaintManager)
    1492             :     : mxCanvas(),
    1493             :       mxSlides(rxSlides),
    1494             :       mpLeftLabelBitmap(),
    1495             :       mpCenterLabelBitmap(),
    1496             :       mpRightLabelBitmap(),
    1497             :       mpFont(),
    1498             :       mnSlideIndex(-1),
    1499             :       maSlideBoundingBox(),
    1500             :       mxInvalidateTarget(rxInvalidateTarget),
    1501           0 :       mpPaintManager(rpPaintManager)
    1502             : {
    1503           0 :     if (rpTheme.get()!=NULL)
    1504             :     {
    1505           0 :         ::boost::shared_ptr<PresenterBitmapContainer> pBitmaps (rpTheme->GetBitmapContainer());
    1506           0 :         if (pBitmaps.get() != NULL)
    1507             :         {
    1508           0 :             mpLeftLabelBitmap = pBitmaps->GetBitmap("LabelLeft");
    1509           0 :             mpCenterLabelBitmap = pBitmaps->GetBitmap("LabelCenter");
    1510           0 :             mpRightLabelBitmap = pBitmaps->GetBitmap("LabelRight");
    1511             :         }
    1512             : 
    1513           0 :         mpFont = rpTheme->GetFont("SlideSorterLabelFont");
    1514             :     }
    1515           0 : }
    1516             : 
    1517           0 : PresenterSlideSorter::MouseOverManager::~MouseOverManager()
    1518             : {
    1519           0 : }
    1520             : 
    1521           0 : void PresenterSlideSorter::MouseOverManager::Paint (
    1522             :     const sal_Int32 nSlideIndex,
    1523             :     const Reference<rendering::XCanvas>& rxCanvas,
    1524             :     const Reference<rendering::XPolyPolygon2D>& rxClip)
    1525             : {
    1526           0 :     if (nSlideIndex != mnSlideIndex)
    1527           0 :         return;
    1528             : 
    1529           0 :     if (mxCanvas != rxCanvas)
    1530           0 :         SetCanvas(rxCanvas);
    1531           0 :     if (rxCanvas != NULL)
    1532             :     {
    1533           0 :         if ( ! mxBitmap.is())
    1534           0 :             mxBitmap = CreateBitmap(msText, maSlideBoundingBox.Width);
    1535           0 :         if (mxBitmap.is())
    1536             :         {
    1537           0 :             geometry::IntegerSize2D aSize (mxBitmap->getSize());
    1538             :             const double nXOffset (maSlideBoundingBox.X
    1539           0 :                 + (maSlideBoundingBox.Width - aSize.Width) / 2.0);
    1540             :             const double nYOffset (maSlideBoundingBox.Y
    1541           0 :                 + (maSlideBoundingBox.Height - aSize.Height) / 2.0);
    1542           0 :             rxCanvas->drawBitmap(
    1543             :                 mxBitmap,
    1544             :                 rendering::ViewState(
    1545             :                     geometry::AffineMatrix2D(1,0,0, 0,1,0),
    1546             :                     rxClip),
    1547             :                 rendering::RenderState(
    1548             :                     geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
    1549             :                     NULL,
    1550             :                     Sequence<double>(4),
    1551           0 :                     rendering::CompositeOperation::SOURCE));
    1552             :         }
    1553             :     }
    1554             : }
    1555             : 
    1556           0 : void PresenterSlideSorter::MouseOverManager::SetCanvas (
    1557             :     const Reference<rendering::XCanvas>& rxCanvas)
    1558             : {
    1559           0 :     mxCanvas = rxCanvas;
    1560           0 :     if (mpFont.get() != NULL)
    1561           0 :         mpFont->PrepareFont(Reference<rendering::XCanvas>(mxCanvas, UNO_QUERY));
    1562           0 : }
    1563             : 
    1564           0 : void PresenterSlideSorter::MouseOverManager::SetSlide (
    1565             :     const sal_Int32 nSlideIndex,
    1566             :     const awt::Rectangle& rBox)
    1567             : {
    1568           0 :     if (mnSlideIndex == nSlideIndex)
    1569           0 :         return;
    1570             : 
    1571           0 :     mnSlideIndex = -1;
    1572           0 :     Invalidate();
    1573             : 
    1574           0 :     maSlideBoundingBox = rBox;
    1575           0 :     mnSlideIndex = nSlideIndex;
    1576             : 
    1577           0 :     if (nSlideIndex >= 0)
    1578             :     {
    1579           0 :         if (mxSlides.get() != NULL)
    1580             :         {
    1581           0 :             msText.clear();
    1582             : 
    1583           0 :             Reference<beans::XPropertySet> xSlideProperties(mxSlides->getByIndex(nSlideIndex), UNO_QUERY);
    1584           0 :             if (xSlideProperties.is())
    1585           0 :                 xSlideProperties->getPropertyValue("LinkDisplayName") >>= msText;
    1586             : 
    1587           0 :             if (msText.isEmpty())
    1588           0 :                 msText = "Slide " + OUString::number(nSlideIndex + 1);
    1589             :         }
    1590             :     }
    1591             :     else
    1592             :     {
    1593           0 :         msText.clear();
    1594             :     }
    1595           0 :     mxBitmap = NULL;
    1596             : 
    1597           0 :     Invalidate();
    1598             : }
    1599             : 
    1600           0 : Reference<rendering::XBitmap> PresenterSlideSorter::MouseOverManager::CreateBitmap (
    1601             :     const OUString& rsText,
    1602             :     const sal_Int32 nMaximalWidth) const
    1603             : {
    1604           0 :     if ( ! mxCanvas.is())
    1605           0 :         return NULL;
    1606             : 
    1607           0 :     if (mpFont.get()==NULL || !mpFont->mxFont.is())
    1608           0 :         return NULL;
    1609             : 
    1610             :     // Long text has to be shortened.
    1611             :     const OUString sText (GetFittingText(rsText, nMaximalWidth
    1612             :             - 2*gnHorizontalLabelBorder
    1613           0 :             - 2*gnHorizontalLabelPadding));
    1614             : 
    1615             :     // Determine the size of the label.  Its height is defined by the
    1616             :     // bitmaps that are used to paints its background.  The width is defined
    1617             :     // by the text.
    1618           0 :     geometry::IntegerSize2D aLabelSize (CalculateLabelSize(sText));
    1619             : 
    1620             :     // Create a new bitmap that will contain the complete label.
    1621             :     Reference<rendering::XBitmap> xBitmap (
    1622           0 :         mxCanvas->getDevice()->createCompatibleAlphaBitmap(aLabelSize));
    1623             : 
    1624           0 :     if ( ! xBitmap.is())
    1625           0 :         return NULL;
    1626             : 
    1627           0 :     Reference<rendering::XBitmapCanvas> xBitmapCanvas (xBitmap, UNO_QUERY);
    1628           0 :     if ( ! xBitmapCanvas.is())
    1629           0 :         return NULL;
    1630             : 
    1631             :     // Paint the background.
    1632           0 :     PaintButtonBackground(xBitmapCanvas, aLabelSize);
    1633             : 
    1634             :     // Paint the text.
    1635           0 :     if (!sText.isEmpty())
    1636             :     {
    1637             : 
    1638           0 :         const rendering::StringContext aContext (sText, 0, sText.getLength());
    1639           0 :         const Reference<rendering::XTextLayout> xLayout (mpFont->mxFont->createTextLayout(
    1640           0 :             aContext, rendering::TextDirection::WEAK_LEFT_TO_RIGHT,0));
    1641           0 :         const geometry::RealRectangle2D aTextBBox (xLayout->queryTextBounds());
    1642             : 
    1643           0 :         const double nXOffset = (aLabelSize.Width - aTextBBox.X2 + aTextBBox.X1) / 2;
    1644             :         const double nYOffset = aLabelSize.Height
    1645           0 :             - (aLabelSize.Height - aTextBBox.Y2 + aTextBBox.Y1)/2 - aTextBBox.Y2;
    1646             : 
    1647             :         const rendering::ViewState aViewState(
    1648             :             geometry::AffineMatrix2D(1,0,0, 0,1,0),
    1649           0 :             NULL);
    1650             : 
    1651             :         rendering::RenderState aRenderState (
    1652             :             geometry::AffineMatrix2D(1,0,nXOffset, 0,1,nYOffset),
    1653             :             NULL,
    1654             :             Sequence<double>(4),
    1655           0 :             rendering::CompositeOperation::SOURCE);
    1656           0 :         PresenterCanvasHelper::SetDeviceColor(aRenderState, mpFont->mnColor);
    1657             : 
    1658           0 :         xBitmapCanvas->drawTextLayout (
    1659             :             xLayout,
    1660             :             aViewState,
    1661           0 :             aRenderState);
    1662             :     }
    1663             : 
    1664           0 :     return xBitmap;
    1665             : }
    1666             : 
    1667           0 : OUString PresenterSlideSorter::MouseOverManager::GetFittingText (
    1668             :     const OUString& rsText,
    1669             :     const double nMaximalWidth) const
    1670             : {
    1671             :     const double nTextWidth (
    1672           0 :         PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText).Width);
    1673           0 :     if (nTextWidth > nMaximalWidth)
    1674             :     {
    1675             :         // Text is too wide.  Shorten it by removing characters from the end
    1676             :         // and replacing them by ellipses.
    1677             : 
    1678             :         // Guess a start value of the final string length.
    1679           0 :         double nBestWidth (0);
    1680           0 :         OUString sBestCandidate;
    1681           0 :         sal_Int32 nLength (round(rsText.getLength() * nMaximalWidth / nTextWidth));
    1682           0 :         const OUString sEllipses ("...");
    1683             :         while (true)
    1684             :         {
    1685           0 :             const OUString sCandidate (rsText.copy(0,nLength) + sEllipses);
    1686             :             const double nWidth (
    1687           0 :                 PresenterCanvasHelper::GetTextSize(mpFont->mxFont, sCandidate).Width);
    1688           0 :             if (nWidth > nMaximalWidth)
    1689             :             {
    1690             :                 // Candidate still too wide, shorten it.
    1691           0 :                 nLength -= 1;
    1692           0 :                 if (nLength <= 0)
    1693           0 :                     break;
    1694             :             }
    1695           0 :             else if (nWidth < nMaximalWidth)
    1696             :             {
    1697             :                 // Candidate short enough.
    1698           0 :                 if (nWidth > nBestWidth)
    1699             :                 {
    1700             :                     // Best length so far.
    1701           0 :                     sBestCandidate = sCandidate;
    1702           0 :                     nBestWidth = nWidth;
    1703           0 :                     nLength += 1;
    1704           0 :                     if (nLength >= rsText.getLength())
    1705           0 :                         break;
    1706             :                 }
    1707             :                 else
    1708           0 :                     break;
    1709             :             }
    1710             :             else
    1711             :             {
    1712             :                 // Candidate is exactly as long as it may be.  Use it
    1713             :                 // without looking any further.
    1714           0 :                 sBestCandidate = sCandidate;
    1715           0 :                 break;
    1716             :             }
    1717           0 :         }
    1718           0 :         return sBestCandidate;
    1719             :     }
    1720             :     else
    1721           0 :         return rsText;
    1722             : }
    1723             : 
    1724           0 : geometry::IntegerSize2D PresenterSlideSorter::MouseOverManager::CalculateLabelSize (
    1725             :     const OUString& rsText) const
    1726             : {
    1727             :     // Height is specified by the label bitmaps.
    1728           0 :     sal_Int32 nHeight (32);
    1729           0 :     if (mpCenterLabelBitmap.get() != NULL)
    1730             :     {
    1731           0 :         Reference<rendering::XBitmap> xBitmap (mpCenterLabelBitmap->GetNormalBitmap());
    1732           0 :         if (xBitmap.is())
    1733           0 :             nHeight = xBitmap->getSize().Height;
    1734             :     }
    1735             : 
    1736             :     // Width is specified by text width and maximal width.
    1737             :     const geometry::RealSize2D aTextSize (
    1738           0 :         PresenterCanvasHelper::GetTextSize(mpFont->mxFont, rsText));
    1739             : 
    1740           0 :     const sal_Int32 nWidth (round(aTextSize.Width + 2*gnHorizontalLabelPadding));
    1741             : 
    1742           0 :     return geometry::IntegerSize2D(nWidth, nHeight);
    1743             : }
    1744             : 
    1745           0 : void PresenterSlideSorter::MouseOverManager::PaintButtonBackground (
    1746             :     const Reference<rendering::XCanvas>& rxCanvas,
    1747             :     const geometry::IntegerSize2D& rSize) const
    1748             : {
    1749             :     // Get the bitmaps for painting the label background.
    1750           0 :     Reference<rendering::XBitmap> xLeftLabelBitmap;
    1751           0 :     if (mpLeftLabelBitmap.get() != NULL)
    1752           0 :         xLeftLabelBitmap = mpLeftLabelBitmap->GetNormalBitmap();
    1753             : 
    1754           0 :     Reference<rendering::XBitmap> xCenterLabelBitmap;
    1755           0 :     if (mpCenterLabelBitmap.get() != NULL)
    1756           0 :         xCenterLabelBitmap = mpCenterLabelBitmap->GetNormalBitmap();
    1757             : 
    1758           0 :     Reference<rendering::XBitmap> xRightLabelBitmap;
    1759           0 :     if (mpRightLabelBitmap.get() != NULL)
    1760           0 :         xRightLabelBitmap = mpRightLabelBitmap->GetNormalBitmap();
    1761             : 
    1762             :     PresenterUIPainter::PaintHorizontalBitmapComposite (
    1763             :         Reference<rendering::XCanvas>(rxCanvas, UNO_QUERY),
    1764             :         awt::Rectangle(0,0, rSize.Width,rSize.Height),
    1765             :         awt::Rectangle(0,0, rSize.Width,rSize.Height),
    1766             :         xLeftLabelBitmap,
    1767             :         xCenterLabelBitmap,
    1768           0 :         xRightLabelBitmap);
    1769           0 : }
    1770             : 
    1771           0 : void PresenterSlideSorter::MouseOverManager::Invalidate()
    1772             : {
    1773           0 :     if (mpPaintManager.get() != NULL)
    1774           0 :         mpPaintManager->Invalidate(mxInvalidateTarget, maSlideBoundingBox, true);
    1775           0 : }
    1776             : 
    1777             : //===== PresenterSlideSorter::CurrentSlideFrameRenderer =======================
    1778             : 
    1779           0 : PresenterSlideSorter::CurrentSlideFrameRenderer::CurrentSlideFrameRenderer (
    1780             :     const css::uno::Reference<css::uno::XComponentContext>& rxContext,
    1781             :     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas)
    1782             :     : mpTopLeft(),
    1783             :       mpTop(),
    1784             :       mpTopRight(),
    1785             :       mpLeft(),
    1786             :       mpRight(),
    1787             :       mpBottomLeft(),
    1788             :       mpBottom(),
    1789             :       mpBottomRight(),
    1790             :       mnTopFrameSize(0),
    1791             :       mnLeftFrameSize(0),
    1792             :       mnRightFrameSize(0),
    1793           0 :       mnBottomFrameSize(0)
    1794             : {
    1795             :     PresenterConfigurationAccess aConfiguration (
    1796             :         rxContext,
    1797             :         OUString("/org.openoffice.Office.PresenterScreen/"),
    1798           0 :         PresenterConfigurationAccess::READ_ONLY);
    1799             :     Reference<container::XHierarchicalNameAccess> xBitmaps (
    1800             :         aConfiguration.GetConfigurationNode(
    1801             :             "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps"),
    1802           0 :         UNO_QUERY);
    1803           0 :     if ( ! xBitmaps.is())
    1804           0 :         return;
    1805             : 
    1806             :     PresenterBitmapContainer aContainer (
    1807             :         "PresenterScreenSettings/SlideSorter/CurrentSlideBorderBitmaps",
    1808             :         ::boost::shared_ptr<PresenterBitmapContainer>(),
    1809             :         rxContext,
    1810           0 :         rxCanvas);
    1811             : 
    1812           0 :     mpTopLeft = aContainer.GetBitmap("TopLeft");
    1813           0 :     mpTop = aContainer.GetBitmap("Top");
    1814           0 :     mpTopRight = aContainer.GetBitmap("TopRight");
    1815           0 :     mpLeft = aContainer.GetBitmap("Left");
    1816           0 :     mpRight = aContainer.GetBitmap("Right");
    1817           0 :     mpBottomLeft = aContainer.GetBitmap("BottomLeft");
    1818           0 :     mpBottom = aContainer.GetBitmap("Bottom");
    1819           0 :     mpBottomRight = aContainer.GetBitmap("BottomRight");
    1820             : 
    1821             :     // Determine size of frame.
    1822           0 :     if (mpTop.get() != NULL)
    1823           0 :         mnTopFrameSize = mpTop->mnHeight;
    1824           0 :     if (mpLeft.get() != NULL)
    1825           0 :         mnLeftFrameSize = mpLeft->mnWidth;
    1826           0 :     if (mpRight.get() != NULL)
    1827           0 :         mnRightFrameSize = mpRight->mnWidth;
    1828           0 :     if (mpBottom.get() != NULL)
    1829           0 :         mnBottomFrameSize = mpBottom->mnHeight;
    1830             : 
    1831           0 :     if (mpTopLeft.get() != NULL)
    1832             :     {
    1833           0 :         mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopLeft->mnHeight);
    1834           0 :         mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpTopLeft->mnWidth);
    1835             :     }
    1836           0 :     if (mpTopRight.get() != NULL)
    1837             :     {
    1838           0 :         mnTopFrameSize = ::std::max(mnTopFrameSize, mpTopRight->mnHeight);
    1839           0 :         mnRightFrameSize = ::std::max(mnRightFrameSize, mpTopRight->mnWidth);
    1840             :     }
    1841           0 :     if (mpBottomLeft.get() != NULL)
    1842             :     {
    1843           0 :         mnLeftFrameSize = ::std::max(mnLeftFrameSize, mpBottomLeft->mnWidth);
    1844           0 :         mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomLeft->mnHeight);
    1845             :     }
    1846           0 :     if (mpBottomRight.get() != NULL)
    1847             :     {
    1848           0 :         mnRightFrameSize = ::std::max(mnRightFrameSize, mpBottomRight->mnWidth);
    1849           0 :         mnBottomFrameSize = ::std::max(mnBottomFrameSize, mpBottomRight->mnHeight);
    1850           0 :     }
    1851             : }
    1852             : 
    1853           0 : PresenterSlideSorter::CurrentSlideFrameRenderer::~CurrentSlideFrameRenderer()
    1854             : {
    1855           0 : }
    1856             : 
    1857           0 : void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintCurrentSlideFrame (
    1858             :     const awt::Rectangle& rSlideBoundingBox,
    1859             :     const Reference<rendering::XCanvas>& rxCanvas,
    1860             :     const geometry::RealRectangle2D& rClipBox)
    1861             : {
    1862           0 :     if ( ! rxCanvas.is())
    1863           0 :         return;
    1864             : 
    1865             :     const Reference<rendering::XPolyPolygon2D> xClip (
    1866           0 :         PresenterGeometryHelper::CreatePolygon(rClipBox, rxCanvas->getDevice()));
    1867             : 
    1868           0 :     if (mpTop.get() != NULL)
    1869             :     {
    1870             :         PaintBitmapTiled(
    1871             :             mpTop->GetNormalBitmap(),
    1872             :             rxCanvas,
    1873             :             rClipBox,
    1874             :             rSlideBoundingBox.X,
    1875           0 :             rSlideBoundingBox.Y - mpTop->mnHeight,
    1876             :             rSlideBoundingBox.Width,
    1877           0 :             mpTop->mnHeight);
    1878             :     }
    1879           0 :     if (mpLeft.get() != NULL)
    1880             :     {
    1881             :         PaintBitmapTiled(
    1882             :             mpLeft->GetNormalBitmap(),
    1883             :             rxCanvas,
    1884             :             rClipBox,
    1885           0 :             rSlideBoundingBox.X - mpLeft->mnWidth,
    1886             :             rSlideBoundingBox.Y,
    1887           0 :             mpLeft->mnWidth,
    1888           0 :             rSlideBoundingBox.Height);
    1889             :     }
    1890           0 :     if (mpRight.get() != NULL)
    1891             :     {
    1892             :         PaintBitmapTiled(
    1893             :             mpRight->GetNormalBitmap(),
    1894             :             rxCanvas,
    1895             :             rClipBox,
    1896           0 :             rSlideBoundingBox.X + rSlideBoundingBox.Width,
    1897             :             rSlideBoundingBox.Y,
    1898           0 :             mpRight->mnWidth,
    1899           0 :             rSlideBoundingBox.Height);
    1900             :     }
    1901           0 :     if (mpBottom.get() != NULL)
    1902             :     {
    1903             :         PaintBitmapTiled(
    1904             :             mpBottom->GetNormalBitmap(),
    1905             :             rxCanvas,
    1906             :             rClipBox,
    1907             :             rSlideBoundingBox.X,
    1908           0 :             rSlideBoundingBox.Y + rSlideBoundingBox.Height,
    1909             :             rSlideBoundingBox.Width,
    1910           0 :             mpBottom->mnHeight);
    1911             :     }
    1912           0 :     if (mpTopLeft.get() != NULL)
    1913             :     {
    1914             :         PaintBitmapOnce(
    1915             :             mpTopLeft->GetNormalBitmap(),
    1916             :             rxCanvas,
    1917             :             xClip,
    1918           0 :             rSlideBoundingBox.X - mpTopLeft->mnWidth,
    1919           0 :             rSlideBoundingBox.Y - mpTopLeft->mnHeight);
    1920             :     }
    1921           0 :     if (mpTopRight.get() != NULL)
    1922             :     {
    1923             :         PaintBitmapOnce(
    1924             :             mpTopRight->GetNormalBitmap(),
    1925             :             rxCanvas,
    1926             :             xClip,
    1927           0 :             rSlideBoundingBox.X + rSlideBoundingBox.Width,
    1928           0 :             rSlideBoundingBox.Y - mpTopLeft->mnHeight);
    1929             :     }
    1930           0 :     if (mpBottomLeft.get() != NULL)
    1931             :     {
    1932             :         PaintBitmapOnce(
    1933             :             mpBottomLeft->GetNormalBitmap(),
    1934             :             rxCanvas,
    1935             :             xClip,
    1936           0 :             rSlideBoundingBox.X - mpBottomLeft->mnWidth,
    1937           0 :             rSlideBoundingBox.Y + rSlideBoundingBox.Height);
    1938             :     }
    1939           0 :     if (mpBottomRight.get() != NULL)
    1940             :     {
    1941             :         PaintBitmapOnce(
    1942             :             mpBottomRight->GetNormalBitmap(),
    1943             :             rxCanvas,
    1944             :             xClip,
    1945           0 :             rSlideBoundingBox.X + rSlideBoundingBox.Width,
    1946           0 :             rSlideBoundingBox.Y + rSlideBoundingBox.Height);
    1947           0 :     }
    1948             : }
    1949             : 
    1950           0 : awt::Rectangle PresenterSlideSorter::CurrentSlideFrameRenderer::GetBoundingBox (
    1951             :     const awt::Rectangle& rSlideBoundingBox)
    1952             : {
    1953             :     return awt::Rectangle(
    1954           0 :         rSlideBoundingBox.X - mnLeftFrameSize,
    1955           0 :         rSlideBoundingBox.Y - mnTopFrameSize,
    1956           0 :         rSlideBoundingBox.Width + mnLeftFrameSize + mnRightFrameSize,
    1957           0 :         rSlideBoundingBox.Height + mnTopFrameSize + mnBottomFrameSize);
    1958             : }
    1959             : 
    1960           0 : void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapOnce(
    1961             :     const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
    1962             :     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
    1963             :     const Reference<rendering::XPolyPolygon2D>& rxClip,
    1964             :     const double nX,
    1965             :     const double nY)
    1966             : {
    1967             :     OSL_ASSERT(rxCanvas.is());
    1968           0 :     if ( ! rxBitmap.is())
    1969           0 :         return;
    1970             : 
    1971             :     const rendering::ViewState aViewState(
    1972             :         geometry::AffineMatrix2D(1,0,0, 0,1,0),
    1973           0 :         rxClip);
    1974             : 
    1975             :     const rendering::RenderState aRenderState (
    1976             :         geometry::AffineMatrix2D(
    1977             :             1, 0, nX,
    1978             :             0, 1, nY),
    1979             :         NULL,
    1980             :         Sequence<double>(4),
    1981           0 :         rendering::CompositeOperation::SOURCE);
    1982             : 
    1983           0 :     rxCanvas->drawBitmap(
    1984             :         rxBitmap,
    1985             :         aViewState,
    1986           0 :         aRenderState);
    1987             : }
    1988             : 
    1989           0 : void PresenterSlideSorter::CurrentSlideFrameRenderer::PaintBitmapTiled(
    1990             :     const css::uno::Reference<css::rendering::XBitmap>& rxBitmap,
    1991             :     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
    1992             :     const geometry::RealRectangle2D& rClipBox,
    1993             :     const double nX0,
    1994             :     const double nY0,
    1995             :     const double nWidth,
    1996             :     const double nHeight)
    1997             : {
    1998             :     OSL_ASSERT(rxCanvas.is());
    1999           0 :     if ( ! rxBitmap.is())
    2000           0 :         return;
    2001             : 
    2002           0 :     geometry::IntegerSize2D aSize (rxBitmap->getSize());
    2003             : 
    2004             :     const rendering::ViewState aViewState(
    2005             :         geometry::AffineMatrix2D(1,0,0, 0,1,0),
    2006             :         PresenterGeometryHelper::CreatePolygon(
    2007             :             PresenterGeometryHelper::Intersection(
    2008             :                 rClipBox,
    2009           0 :                 geometry::RealRectangle2D(nX0,nY0,nX0+nWidth,nY0+nHeight)),
    2010           0 :             rxCanvas->getDevice()));
    2011             : 
    2012             :     rendering::RenderState aRenderState (
    2013             :         geometry::AffineMatrix2D(
    2014             :             1, 0, nX0,
    2015             :             0, 1, nY0),
    2016             :         NULL,
    2017             :         Sequence<double>(4),
    2018           0 :         rendering::CompositeOperation::SOURCE);
    2019             : 
    2020           0 :     const double nX1 = nX0 + nWidth;
    2021           0 :     const double nY1 = nY0 + nHeight;
    2022           0 :     for (double nY=nY0; nY<nY1; nY+=aSize.Height)
    2023           0 :         for (double nX=nX0; nX<nX1; nX+=aSize.Width)
    2024             :         {
    2025           0 :             aRenderState.AffineTransform.m02 = nX;
    2026           0 :             aRenderState.AffineTransform.m12 = nY;
    2027           0 :             rxCanvas->drawBitmap(
    2028             :                 rxBitmap,
    2029             :                 aViewState,
    2030           0 :                 aRenderState);
    2031           0 :         }
    2032             : }
    2033             : 
    2034          18 : } } // end of namespace ::sdext::presenter
    2035             : 
    2036             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11