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

Generated by: LCOV version 1.10