LCOV - code coverage report
Current view: top level - sd/source/ui/slidesorter/view - SlideSorterView.cxx (source / functions) Hit Total Coverage
Test: commit c8344322a7af75b84dd3ca8f78b05543a976dfd5 Lines: 277 352 78.7 %
Date: 2015-06-13 12:38:46 Functions: 47 63 74.6 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include "view/SlideSorterView.hxx"
      21             : 
      22             : #include "ViewShellBase.hxx"
      23             : #include "SlideSorter.hxx"
      24             : #include "SlideSorterViewShell.hxx"
      25             : #include "ViewShell.hxx"
      26             : #include "SlsViewCacheContext.hxx"
      27             : #include "SlsLayeredDevice.hxx"
      28             : #include "view/SlsLayouter.hxx"
      29             : #include "view/SlsPageObjectLayouter.hxx"
      30             : #include "view/SlsPageObjectPainter.hxx"
      31             : #include "view/SlsILayerPainter.hxx"
      32             : #include "view/SlsToolTip.hxx"
      33             : #include "controller/SlideSorterController.hxx"
      34             : #include "controller/SlsProperties.hxx"
      35             : #include "controller/SlsClipboard.hxx"
      36             : #include "model/SlideSorterModel.hxx"
      37             : #include "model/SlsPageEnumerationProvider.hxx"
      38             : #include "model/SlsPageDescriptor.hxx"
      39             : #include "cache/SlsPageCache.hxx"
      40             : #include "cache/SlsPageCacheManager.hxx"
      41             : #include "cache/SlsCacheContext.hxx"
      42             : #include "taskpane/SlideSorterCacheDisplay.hxx"
      43             : #include "DrawDocShell.hxx"
      44             : #include "PaneDockingWindow.hxx"
      45             : 
      46             : #include "drawdoc.hxx"
      47             : #include "sdpage.hxx"
      48             : #include "Window.hxx"
      49             : #include "sdresid.hxx"
      50             : #include "glob.hrc"
      51             : 
      52             : #include <svl/itempool.hxx>
      53             : #include <svx/svdpagv.hxx>
      54             : #include <svx/svdopage.hxx>
      55             : #include <svx/xlndsit.hxx>
      56             : #include <svx/xlnclit.hxx>
      57             : #include <vcl/svapp.hxx>
      58             : #include <vcl/scrbar.hxx>
      59             : #include <vcl/settings.hxx>
      60             : 
      61             : #include <tools/poly.hxx>
      62             : #include <vcl/lineinfo.hxx>
      63             : #include <algorithm>
      64             : #include <svx/sdrpagewindow.hxx>
      65             : #include <basegfx/matrix/b2dhommatrix.hxx>
      66             : #include <basegfx/polygon/b2dpolygontools.hxx>
      67             : #include <basegfx/polygon/b2dpolygon.hxx>
      68             : #include <drawinglayer/geometry/viewinformation2d.hxx>
      69             : #include <canvas/elapsedtime.hxx>
      70             : 
      71             : //#define DEBUG_TIMING
      72             : #ifdef DEBUG_TIMING
      73             : #include <vector>
      74             : #endif
      75             : 
      76             : using namespace std;
      77             : using namespace ::sd::slidesorter::model;
      78             : using namespace ::drawinglayer::primitive2d;
      79             : 
      80             : namespace sd { namespace slidesorter { namespace view {
      81             : 
      82             : namespace {
      83             :     /** Wrapper around the SlideSorterView that supports the IPainter
      84             :         interface and that allows the LayeredDevice to hold the
      85             :         SlideSorterView (held as scoped_ptr by the SlideSorter) as
      86             :         shared_ptr.
      87             :     */
      88             :     class Painter : public ILayerPainter
      89             :     {
      90             :     public:
      91          64 :         Painter (SlideSorterView& rView) : mrView(rView) {}
      92         128 :         virtual ~Painter() {}
      93             : 
      94         299 :         virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) SAL_OVERRIDE
      95             :         {
      96         299 :             mrView.Paint(rDevice,rRepaintArea);
      97         299 :         }
      98             : 
      99          64 :         virtual void SetLayerInvalidator (const SharedILayerInvalidator&) SAL_OVERRIDE {}
     100             : 
     101             :     private:
     102             :         SlideSorterView& mrView;
     103             :     };
     104             : }
     105             : 
     106             : class BackgroundPainter
     107             :     : public ILayerPainter,
     108             :       public ::boost::noncopyable
     109             : {
     110             : public:
     111          64 :     BackgroundPainter (const Color& rBackgroundColor) : maBackgroundColor(rBackgroundColor) {}
     112         128 :     virtual ~BackgroundPainter() {}
     113             : 
     114         299 :     virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) SAL_OVERRIDE
     115             :     {
     116         299 :         rDevice.SetFillColor(maBackgroundColor);
     117         299 :         rDevice.SetLineColor();
     118         299 :         rDevice.DrawRect(rRepaintArea);
     119         299 :     }
     120             : 
     121          64 :     virtual void SetLayerInvalidator (const SharedILayerInvalidator&) SAL_OVERRIDE {}
     122             : 
     123           0 :     void SetColor (const Color& rColor) { maBackgroundColor = rColor; }
     124             : 
     125             : private:
     126             :     Color maBackgroundColor;
     127             : };
     128             : 
     129           0 : TYPEINIT1(SlideSorterView, ::sd::View);
     130             : 
     131          64 : SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter)
     132             :     : ::sd::View (
     133          64 :           *rSlideSorter.GetModel().GetDocument(),
     134             :           rSlideSorter.GetContentWindow(),
     135             :           rSlideSorter.GetViewShell()),
     136             :       mrSlideSorter(rSlideSorter),
     137          64 :       mrModel(rSlideSorter.GetModel()),
     138             :       mbIsDisposed(false),
     139         192 :       mpLayouter (new Layouter(rSlideSorter.GetContentWindow(), rSlideSorter.GetTheme())),
     140             :       mbPageObjectVisibilitiesValid (false),
     141             :       mpPreviewCache(),
     142          64 :       mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())),
     143             :       maVisiblePageRange(-1,-1),
     144             :       mbModelChangedWhileModifyEnabled(true),
     145             :       maPreviewSize(0,0),
     146             :       mbPreciousFlagUpdatePending(true),
     147             :       meOrientation(Layouter::GRID),
     148             :       mpProperties(rSlideSorter.GetProperties()),
     149             :       mpPageUnderMouse(),
     150             :       mnButtonUnderMouse(-1),
     151             :       mpPageObjectPainter(),
     152             :       mpSelectionPainter(),
     153             :       mpBackgroundPainter(
     154          64 :           new BackgroundPainter(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background))),
     155          64 :       mpToolTip(new ToolTip(mrSlideSorter)),
     156             :       mbIsRearrangePending(true),
     157         576 :       maVisibilityChangeListeners()
     158             : {
     159             :     // Hide the page that contains the page objects.
     160          64 :     SetPageVisible (false);
     161             : 
     162             :     // Register the background painter on level 1 to avoid the creation of a
     163             :     // background buffer.
     164          64 :     mpLayeredDevice->RegisterPainter(mpBackgroundPainter, 1);
     165             : 
     166             :     // Wrap a shared_ptr-held-wrapper around this view and register it as
     167             :     // painter at the layered device.  There is no explicit destruction: in
     168             :     // the SlideSorterView destructor the layered device is destroyed and
     169             :     // with it the only reference to the wrapper which therefore is also
     170             :     // destroyed.
     171          64 :     SharedILayerPainter pPainter (new Painter(*this));
     172             : 
     173             :     // The painter is placed on level 1 to avoid buffering.  This should be
     174             :     // a little faster during animations because the previews are painted
     175             :     // directly into the window, not via the buffer.
     176          64 :     mpLayeredDevice->RegisterPainter(pPainter, 1);
     177          64 : }
     178             : 
     179         192 : SlideSorterView::~SlideSorterView()
     180             : {
     181          64 :     if ( ! mbIsDisposed)
     182             :     {
     183             :         OSL_ASSERT(mbIsDisposed);
     184           0 :         Dispose();
     185             :     }
     186         128 : }
     187             : 
     188          64 : void SlideSorterView::Init()
     189             : {
     190          64 :     HandleModelChange();
     191          64 : }
     192             : 
     193          64 : void SlideSorterView::Dispose()
     194             : {
     195          64 :     mpSelectionPainter.reset();
     196             : 
     197          64 :     mpLayeredDevice->Dispose();
     198          64 :     mpPreviewCache.reset();
     199             : 
     200          64 :     SetPageUnderMouse(SharedPageDescriptor());
     201             : 
     202             :     // Hide the page to avoid problems in the view when deleting
     203             :     // visualized objects
     204          64 :     HideSdrPage();
     205             : 
     206             :     // Deletion of the objects and the page will be done in SdrModel
     207             :     // destructor (as long as objects and pages are added)
     208             : 
     209             :     OSL_ASSERT(mpLayeredDevice.unique());
     210          64 :     mpLayeredDevice.reset();
     211             : 
     212          64 :     mbIsDisposed = true;
     213          64 : }
     214             : 
     215          68 : sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rWindowPosition) const
     216             : {
     217          68 :     sal_Int32 nIndex (-1);
     218             : 
     219          68 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     220          68 :     if (pWindow)
     221             :     {
     222          68 :         nIndex = mpLayouter->GetIndexAtPoint(pWindow->PixelToLogic(rWindowPosition), false, false);
     223             : 
     224             :         // Clip the page index against the page count.
     225          68 :         if (nIndex >= mrModel.GetPageCount())
     226           0 :             nIndex = -1;
     227             :     }
     228             : 
     229          68 :     return nIndex;
     230             : }
     231             : 
     232         823 : Layouter& SlideSorterView::GetLayouter()
     233             : {
     234         823 :     return *mpLayouter.get();
     235             : }
     236             : 
     237         104 : void SlideSorterView::ModelHasChanged()
     238             : {
     239             :     // Ignore this call.  Rely on hints sent by the model to get informed of
     240             :     // model changes.
     241         104 : }
     242             : 
     243         152 : void SlideSorterView::PreModelChange()
     244             : {
     245             :     // Reset the slide under the mouse.  It will be re-set in PostModelChange().
     246         152 :     SetPageUnderMouse(SharedPageDescriptor());
     247         152 : }
     248             : 
     249         152 : void SlideSorterView::PostModelChange()
     250             : {
     251             :     // In PreModelChange() the page objects have been released.  Here we
     252             :     // create new ones.
     253         152 :     ::osl::MutexGuard aGuard (mrModel.GetMutex());
     254             : 
     255             :     model::PageEnumeration aPageEnumeration (
     256         304 :         model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
     257             : 
     258             :     // The new page objects have to be scaled and positioned.
     259         152 :     RequestRearrange();
     260         304 :     RequestRepaint();
     261         152 : }
     262             : 
     263             : /** At the moment for every model change all page objects are destroyed and
     264             :     re-created again.  This can be optimized by accepting hints that
     265             :     describe the type of change so that existing page objects can be
     266             :     reused.
     267             : */
     268          64 : void SlideSorterView::HandleModelChange()
     269             : {
     270          64 :     PreModelChange ();
     271          64 :     PostModelChange();
     272          64 : }
     273             : 
     274           0 : void SlideSorterView::HandleDrawModeChange()
     275             : {
     276             :     // Replace the preview cache with a new and empty one.  The
     277             :     // PreviewRenderer that is used by the cache is replaced by this as
     278             :     // well.
     279           0 :     mpPreviewCache.reset();
     280           0 :     GetPreviewCache()->InvalidateCache(true);
     281             : 
     282           0 :     RequestRepaint();
     283           0 : }
     284             : 
     285           0 : void SlideSorterView::HandleDataChangeEvent()
     286             : {
     287           0 :     GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme());
     288             : 
     289             :     // Update the color used by the background painter.
     290             :     ::boost::shared_ptr<BackgroundPainter> pPainter (
     291           0 :         ::boost::dynamic_pointer_cast<BackgroundPainter>(mpBackgroundPainter));
     292           0 :     if (pPainter)
     293           0 :         pPainter->SetColor(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background));
     294             : 
     295           0 :     RequestRepaint();
     296           0 : }
     297             : 
     298         137 : void SlideSorterView::Resize()
     299             : {
     300         137 :     UpdateOrientation();
     301             : 
     302         137 :     mpLayeredDevice->Resize();
     303         137 :     RequestRearrange();
     304         137 : }
     305             : 
     306         289 : void SlideSorterView::RequestRearrange()
     307             : {
     308         289 :     mbIsRearrangePending = true;
     309         289 :     Rearrange();
     310         289 : }
     311             : 
     312         289 : void SlideSorterView::Rearrange()
     313             : {
     314         289 :     if ( ! mbIsRearrangePending)
     315         128 :         return;
     316         289 :     if (mrModel.GetPageCount() <= 0)
     317          64 :         return;
     318             : 
     319         225 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     320         225 :     if ( ! pWindow)
     321           0 :         return;
     322         225 :     const Size aWindowSize (pWindow->GetSizePixel());
     323         225 :     if (aWindowSize.Width()<=0 || aWindowSize.Height()<=0)
     324          64 :         return;
     325             : 
     326             :     const bool bRearrangeSuccess (
     327             :         mpLayouter->Rearrange (
     328             :             meOrientation,
     329             :             aWindowSize,
     330         322 :             mrModel.GetPageDescriptor(0)->GetPage()->GetSize(),
     331         322 :             mrModel.GetPageCount()));
     332         161 :     if (bRearrangeSuccess)
     333             :     {
     334         161 :         mbIsRearrangePending = false;
     335         161 :         Layout();
     336         161 :         UpdatePageUnderMouse();
     337             :         //        RequestRepaint();
     338             :     }
     339             : }
     340             : 
     341         273 : void SlideSorterView::UpdateOrientation()
     342             : {
     343             :     // The layout of slides depends on whether the slide sorter is
     344             :     // displayed in the center or the side pane.
     345         273 :     if (mrSlideSorter.GetViewShell()->IsMainViewShell())
     346           0 :         SetOrientation(Layouter::GRID);
     347             :     else
     348             :     {
     349             :         // Get access to the docking window.
     350         273 :         vcl::Window* pWindow = mrSlideSorter.GetContentWindow();
     351         273 :         PaneDockingWindow* pDockingWindow = NULL;
     352        1365 :         while (pWindow!=NULL && pDockingWindow==NULL)
     353             :         {
     354         819 :             pDockingWindow = dynamic_cast<PaneDockingWindow*>(pWindow);
     355         819 :             pWindow = pWindow->GetParent();
     356             :         }
     357             : 
     358         273 :         if (pDockingWindow != NULL)
     359             :         {
     360             :             const long nScrollBarSize (
     361         141 :                 Application::GetSettings().GetStyleSettings().GetScrollBarSize());
     362         141 :             switch (pDockingWindow->GetOrientation())
     363             :             {
     364             :                 case PaneDockingWindow::HorizontalOrientation:
     365           0 :                     if (SetOrientation(Layouter::HORIZONTAL))
     366             :                     {
     367           0 :                         const Range aRange (mpLayouter->GetValidVerticalSizeRange());
     368             :                         pDockingWindow->SetValidSizeRange(Range(
     369           0 :                             aRange.Min() + nScrollBarSize,
     370           0 :                             aRange.Max() + nScrollBarSize));
     371             :                     }
     372           0 :                     break;
     373             : 
     374             :                 case PaneDockingWindow::VerticalOrientation:
     375         141 :                     if (SetOrientation(Layouter::VERTICAL))
     376             :                     {
     377          66 :                         const Range aRange (mpLayouter->GetValidHorizontalSizeRange());
     378             :                         pDockingWindow->SetValidSizeRange(Range(
     379          66 :                             aRange.Min() + nScrollBarSize,
     380         132 :                             aRange.Max() + nScrollBarSize));
     381             :                     }
     382         141 :                     break;
     383             : 
     384             :                 case PaneDockingWindow::UnknownOrientation:
     385           0 :                     if (SetOrientation(Layouter::GRID))
     386             :                     {
     387           0 :                         const sal_Int32 nAdditionalSize (10);
     388             :                         pDockingWindow->SetMinOutputSizePixel(Size(
     389           0 :                             mpLayouter->GetValidHorizontalSizeRange().Min()
     390           0 :                                 + nScrollBarSize
     391             :                                 + nAdditionalSize,
     392           0 :                             mpLayouter->GetValidVerticalSizeRange().Min()
     393           0 :                                 + nScrollBarSize
     394           0 :                                 + nAdditionalSize));
     395             :                     }
     396         273 :                     return;
     397             :             }
     398             :         }
     399             :         else
     400             :         {
     401             :             // We are not placed in a docking window.  One possible reason
     402             :             // is that the slide sorter is temporarily into a cache and was
     403             :             // reparented to a non-docking window.
     404         132 :             SetOrientation(Layouter::GRID);
     405             :         }
     406             :     }
     407             : }
     408             : 
     409         161 : void SlideSorterView::Layout ()
     410             : {
     411         161 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     412         161 :     if (pWindow)
     413             :     {
     414             :         // Set the model area, i.e. the smallest rectangle that includes all
     415             :         // page objects.
     416         161 :         const Rectangle aViewBox (mpLayouter->GetTotalBoundingBox());
     417         161 :         pWindow->SetViewOrigin (aViewBox.TopLeft());
     418         161 :         pWindow->SetViewSize (aViewBox.GetSize());
     419             : 
     420             :         ::boost::shared_ptr<PageObjectLayouter> pPageObjectLayouter(
     421         161 :             mpLayouter->GetPageObjectLayouter());
     422         161 :         if (pPageObjectLayouter)
     423             :         {
     424         161 :             const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetPreviewSize(PageObjectLayouter::WindowCoordinateSystem));
     425         161 :             if (maPreviewSize != aNewPreviewSize && GetPreviewCache())
     426             :             {
     427          65 :                 mpPreviewCache->ChangeSize(aNewPreviewSize, Bitmap::HasFastScale());
     428          65 :                 maPreviewSize = aNewPreviewSize;
     429             :             }
     430             :         }
     431             : 
     432             :         // Iterate over all page objects and place them relative to the
     433             :         // containing page.
     434             :         model::PageEnumeration aPageEnumeration (
     435         322 :             model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel));
     436         518 :         while (aPageEnumeration.HasMoreElements())
     437             :         {
     438         196 :             model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement());
     439         196 :             pDescriptor->SetBoundingBox(mpLayouter->GetPageObjectBox(pDescriptor->GetPageIndex()));
     440         357 :         }
     441             :     }
     442             : 
     443         161 :     InvalidatePageObjectVisibilities ();
     444         161 : }
     445             : 
     446         162 : void SlideSorterView::InvalidatePageObjectVisibilities()
     447             : {
     448         162 :     mbPageObjectVisibilitiesValid = false;
     449         162 : }
     450             : 
     451          84 : void SlideSorterView::DeterminePageObjectVisibilities()
     452             : {
     453          84 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     454          84 :     if (pWindow)
     455             :     {
     456             :         // Set this flag to true here so that an invalidate during the
     457             :         // visibility calculation can correctly invalidate it again.
     458          84 :         mbPageObjectVisibilitiesValid = true;
     459             : 
     460          84 :         Rectangle aViewArea (pWindow->PixelToLogic(Rectangle(Point(0,0),pWindow->GetSizePixel())));
     461          84 :         const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(aViewArea));
     462             :         const Range aUnion(
     463         168 :             ::std::min(maVisiblePageRange.Min(), aRange.Min()),
     464         252 :             ::std::max(maVisiblePageRange.Max(), aRange.Max()));
     465             : 
     466             :         // For page objects that just dropped off the visible area we
     467             :         // decrease the priority of pending requests for preview bitmaps.
     468          84 :         if (maVisiblePageRange != aRange)
     469          75 :             mbPreciousFlagUpdatePending |= true;
     470             : 
     471          84 :         model::SharedPageDescriptor pDescriptor;
     472         250 :         for (long nIndex=aUnion.Min(); nIndex<=aUnion.Max(); nIndex++)
     473             :         {
     474         166 :             pDescriptor = mrModel.GetPageDescriptor(nIndex);
     475         166 :             if (pDescriptor.get() != NULL)
     476             :                 SetState(
     477             :                     pDescriptor,
     478             :                     PageDescriptor::ST_Visible,
     479         101 :                     aRange.IsInside(nIndex));
     480             :         }
     481             : 
     482             :         // Broadcast a change of the set of visible page objects.
     483          84 :         if (maVisiblePageRange != aRange)
     484             :         {
     485          75 :             maVisiblePageRange = aRange;
     486             : 
     487             :             // Tell the listeners that the visibility of some objects has
     488             :             // changed.
     489          75 :             ::std::vector<Link<>>& aChangeListeners (maVisibilityChangeListeners);
     490          75 :             for (::std::vector<Link<>>::const_iterator
     491          75 :                      iLink(aChangeListeners.begin()),
     492          75 :                      iEnd(aChangeListeners.end());
     493             :                  iLink!=iEnd;
     494             :                  ++iLink)
     495             :             {
     496           0 :                 iLink->Call(NULL);
     497             :             }
     498             :         }
     499             : 
     500             :         // Restore the mouse over state.
     501          84 :         UpdatePageUnderMouse();
     502             :     }
     503          84 : }
     504             : 
     505         299 : void SlideSorterView::UpdatePreciousFlags()
     506             : {
     507         299 :     if (mbPreciousFlagUpdatePending)
     508             :     {
     509         299 :         mbPreciousFlagUpdatePending = false;
     510             : 
     511         299 :         model::SharedPageDescriptor pDescriptor;
     512         598 :         ::boost::shared_ptr<cache::PageCache> pCache = GetPreviewCache();
     513         299 :         sal_Int32 nPageCount (mrModel.GetPageCount());
     514             : 
     515         660 :         for (int nIndex=0; nIndex<=nPageCount; ++nIndex)
     516             :         {
     517         660 :             pDescriptor = mrModel.GetPageDescriptor(nIndex);
     518         660 :             if (pDescriptor.get() != NULL)
     519             :             {
     520             :                 pCache->SetPreciousFlag(
     521         361 :                     pDescriptor->GetPage(),
     522         722 :                     maVisiblePageRange.IsInside(nIndex));
     523             :                 SSCD_SET_VISIBILITY(mrModel.GetDocument(), nIndex,
     524             :                     maVisiblePageRange.IsInside(nIndex));
     525             :             }
     526             :             else
     527             :             {
     528             :                 // At least one cache entry can not be updated.  Remember to
     529             :                 // repeat the whole updating later and leave the loop now.
     530         299 :                 mbPreciousFlagUpdatePending = true;
     531         299 :                 break;
     532             :             }
     533         299 :         }
     534             :     }
     535         299 : }
     536             : 
     537         273 : bool SlideSorterView::SetOrientation (const Layouter::Orientation eOrientation)
     538             : {
     539         273 :     if (meOrientation != eOrientation)
     540             :     {
     541         132 :         meOrientation = eOrientation;
     542         132 :         return true;
     543             :     }
     544             :     else
     545         141 :         return false;
     546             : }
     547             : 
     548         394 : void SlideSorterView::RequestRepaint()
     549             : {
     550         394 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     551         394 :     if (pWindow)
     552             :     {
     553             :         mpLayeredDevice->InvalidateAllLayers(
     554             :             Rectangle(
     555         788 :                 pWindow->PixelToLogic(Point(0,0)),
     556        1182 :                 pWindow->PixelToLogic(pWindow->GetSizePixel())));
     557         394 :         pWindow->Invalidate();
     558             :     }
     559         394 : }
     560             : 
     561         406 : void SlideSorterView::RequestRepaint (const model::SharedPageDescriptor& rpDescriptor)
     562             : {
     563         406 :     if (rpDescriptor)
     564         406 :         RequestRepaint(rpDescriptor->GetBoundingBox());
     565         406 : }
     566             : 
     567         406 : void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox)
     568             : {
     569         406 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     570         406 :     if (pWindow)
     571             :     {
     572         406 :         mpLayeredDevice->InvalidateAllLayers(rRepaintBox);
     573         406 :         pWindow->Invalidate(rRepaintBox);
     574             :     }
     575         406 : }
     576             : 
     577           0 : void SlideSorterView::RequestRepaint (const vcl::Region& rRepaintRegion)
     578             : {
     579           0 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     580           0 :     if (pWindow)
     581             :     {
     582           0 :         mpLayeredDevice->InvalidateAllLayers(rRepaintRegion);
     583           0 :         pWindow->Invalidate(rRepaintRegion);
     584             :     }
     585           0 : }
     586             : 
     587         549 : Rectangle SlideSorterView::GetModelArea()
     588             : {
     589         549 :     return mpLayouter->GetTotalBoundingBox();
     590             : }
     591             : 
     592             : #ifdef DEBUG_TIMING
     593             : static ::canvas::tools::ElapsedTime gaTimer;
     594             : static const size_t gFrameTimeCount (10);
     595             : static size_t gFrameTimeIndex (0);
     596             : static ::std::vector<double> gFrameTimes (gFrameTimeCount, 0);
     597             : static double gFrameTimeSum (0);
     598             : static const Rectangle gFrameTimeBox (10,10,150,20);
     599             : static double gnLastFrameStart = 0;
     600             : #endif
     601             : 
     602         299 : void SlideSorterView::CompleteRedraw (
     603             :     OutputDevice* pDevice,
     604             :     const vcl::Region& rPaintArea,
     605             :     sdr::contact::ViewObjectContactRedirector* pRedirector)
     606             : {
     607             :     (void)pRedirector;
     608             : #ifdef DEBUG_TIMING
     609             :     const double nStartTime (gaTimer.getElapsedTime());
     610             :     OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %s",
     611             :         nStartTime,
     612             :         mnLockRedrawSmph ? "locked" : "");
     613             : #endif
     614             : 
     615         299 :     if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow())
     616         299 :         return;
     617             : 
     618             :     // The parent implementation of CompleteRedraw is called only when
     619             :     // painting is locked.  We do all the painting ourself.  When painting
     620             :     // is locked the parent implementation keeps track of the repaint
     621             :     // requests and later, when painting is unlocked, calls CompleteRedraw
     622             :     // for all missed repaints.
     623             : 
     624         299 :     if (mnLockRedrawSmph == 0)
     625             :     {
     626         299 :         mrSlideSorter.GetContentWindow()->IncrementLockCount();
     627         299 :         if (mpLayeredDevice->HandleMapModeChange())
     628          64 :             DeterminePageObjectVisibilities();
     629         299 :         mpLayeredDevice->Repaint(rPaintArea);
     630         299 :         mrSlideSorter.GetContentWindow()->DecrementLockCount();
     631             :     }
     632             :     else
     633             :     {
     634           0 :         maRedrawRegion.Union(rPaintArea);
     635             :     }
     636             : 
     637             : #ifdef DEBUG_TIMING
     638             :     const double nEndTime (gaTimer.getElapsedTime());
     639             :     OSL_TRACE("SlideSorterView::CompleteRedraw end at %f after %fms", nEndTime, (nEndTime-nStartTime)*1000);
     640             :     gFrameTimeSum -= gFrameTimes[gFrameTimeIndex];
     641             :     gFrameTimes[gFrameTimeIndex] = nStartTime - gnLastFrameStart;
     642             :     gnLastFrameStart = nStartTime;
     643             :     gFrameTimeSum += gFrameTimes[gFrameTimeIndex];
     644             :     gFrameTimeIndex = (gFrameTimeIndex+1) % gFrameTimeCount;
     645             : 
     646             :     mrSlideSorter.GetContentWindow()->SetFillColor(COL_BLUE);
     647             :     mrSlideSorter.GetContentWindow()->DrawRect(gFrameTimeBox);
     648             :     mrSlideSorter.GetContentWindow()->SetTextColor(COL_WHITE);
     649             :     mrSlideSorter.GetContentWindow()->DrawText(
     650             :         gFrameTimeBox,
     651             :         OUString::number(1 / (gFrameTimeSum / gFrameTimeCount)),
     652             :         DrawTextFlags::Right | DrawTextFlags::VCenter);
     653             :     //    mrSlideSorter.GetContentWindow()->Invalidate(gFrameTimeBox);
     654             : #endif
     655             : }
     656             : 
     657         299 : void SlideSorterView::Paint (
     658             :     OutputDevice& rDevice,
     659             :     const Rectangle& rRepaintArea)
     660             : {
     661         299 :     if ( ! mpPageObjectPainter)
     662          64 :         if ( ! GetPageObjectPainter())
     663         299 :             return;
     664             : 
     665             :     // Update the page visibilities when they have been invalidated.
     666         299 :     if ( ! mbPageObjectVisibilitiesValid)
     667          20 :         DeterminePageObjectVisibilities();
     668             : 
     669         299 :     if (mbPreciousFlagUpdatePending)
     670         299 :         UpdatePreciousFlags();
     671             : 
     672         299 :     if (mbIsRearrangePending)
     673           0 :         Rearrange();
     674             : 
     675             :     // Paint all page objects that are fully or partially inside the
     676             :     // repaint region.
     677         299 :     const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(rRepaintArea));
     678         619 :     for (long nIndex=aRange.Min(); nIndex<=aRange.Max(); ++nIndex)
     679             :     {
     680         320 :         model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
     681         320 :         if (!pDescriptor || ! pDescriptor->HasState(PageDescriptor::ST_Visible))
     682           0 :             continue;
     683             : 
     684         320 :         mpPageObjectPainter->PaintPageObject(rDevice, pDescriptor);
     685         320 :     }
     686             : }
     687             : 
     688           0 : void SlideSorterView::ConfigurationChanged (
     689             :     utl::ConfigurationBroadcaster* pBroadcaster,
     690             :     sal_uInt32 nHint)
     691             : {
     692             :     // Some changes of the configuration (some of the colors for example)
     693             :     // may affect the previews.  Throw away the old ones and create new ones.
     694           0 :     cache::PageCacheManager::Instance()->InvalidateAllCaches();
     695             : 
     696           0 :     ::sd::View::ConfigurationChanged(pBroadcaster, nHint);
     697           0 :     RequestRepaint();
     698             : 
     699           0 : }
     700             : 
     701         855 : ::boost::shared_ptr<cache::PageCache> SlideSorterView::GetPreviewCache()
     702             : {
     703         855 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     704         855 :     if (pWindow && mpPreviewCache.get() == NULL)
     705             :     {
     706             :         mpPreviewCache.reset(
     707             :             new cache::PageCache(
     708          64 :                 mpLayouter->GetPageObjectSize(),
     709          64 :                 Bitmap::HasFastScale(),
     710         128 :                 cache::SharedCacheContext(new ViewCacheContext(mrSlideSorter))));
     711             :     }
     712             : 
     713         855 :     return mpPreviewCache;
     714             : }
     715             : 
     716           0 : Pair SlideSorterView::GetVisiblePageRange()
     717             : {
     718           0 :     if ( ! mbPageObjectVisibilitiesValid)
     719           0 :         DeterminePageObjectVisibilities();
     720           0 :     return maVisiblePageRange;
     721             : }
     722             : 
     723           0 : void SlideSorterView::AddVisibilityChangeListener (const Link<>& rListener)
     724             : {
     725           0 :     if (::std::find (
     726             :         maVisibilityChangeListeners.begin(),
     727             :         maVisibilityChangeListeners.end(),
     728           0 :         rListener) == maVisibilityChangeListeners.end())
     729             :     {
     730           0 :         maVisibilityChangeListeners.push_back(rListener);
     731             :     }
     732           0 : }
     733             : 
     734           0 : void SlideSorterView::RemoveVisibilityChangeListener(const Link<>&rListener)
     735             : {
     736             :     maVisibilityChangeListeners.erase (
     737             :         ::std::find (
     738             :             maVisibilityChangeListeners.begin(),
     739             :             maVisibilityChangeListeners.end(),
     740           0 :             rListener));
     741           0 : }
     742             : 
     743           0 : ToolTip& SlideSorterView::GetToolTip() const
     744             : {
     745             :     OSL_ASSERT(mpToolTip);
     746           0 :     return *mpToolTip;
     747             : }
     748             : 
     749           0 : void SlideSorterView::DragFinished (sal_Int8 nDropAction)
     750             : {
     751           0 :     mrSlideSorter.GetController().GetClipboard().DragFinished(nDropAction);
     752             : 
     753           0 :     View::DragFinished(nDropAction);
     754           0 : }
     755             : 
     756         484 : void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint)
     757             : {
     758         484 :     ::sd::DrawDocShell* pDocShell = mrModel.GetDocument()->GetDocSh();
     759         484 :     if (pDocShell!=NULL && pDocShell->IsEnableSetModified())
     760         484 :         mbModelChangedWhileModifyEnabled = true;
     761             : 
     762         484 :     ::sd::View::Notify(rBroadcaster, rHint);
     763         484 : }
     764             : 
     765         245 : void SlideSorterView::UpdatePageUnderMouse ()
     766             : {
     767         245 :     VclPtr<ScrollBar> pVScrollBar (mrSlideSorter.GetVerticalScrollBar());
     768         422 :     VclPtr<ScrollBar> pHScrollBar (mrSlideSorter.GetHorizontalScrollBar());
     769         735 :     if ((pVScrollBar && pVScrollBar->IsVisible() && pVScrollBar->IsTracking())
     770         490 :         || (pHScrollBar && pHScrollBar->IsVisible() && pHScrollBar->IsTracking()))
     771             :     {
     772             :         // One of the scroll bars is tracking mouse movement.  Do not
     773             :         // highlight the slide under the mouse in this case.
     774           0 :         SetPageUnderMouse(SharedPageDescriptor());
     775           0 :         return;
     776             :     }
     777             : 
     778         245 :     sd::Window *pWindow (mrSlideSorter.GetContentWindow());
     779         245 :     if (pWindow && pWindow->IsVisible() && ! pWindow->IsMouseCaptured())
     780             :     {
     781         245 :         const Window::PointerState aPointerState (pWindow->GetPointerState());
     782         245 :         const Rectangle aWindowBox (pWindow->GetPosPixel(), pWindow->GetSizePixel());
     783         245 :         if (aWindowBox.IsInside(aPointerState.maPos))
     784             :         {
     785          68 :             UpdatePageUnderMouse(aPointerState.maPos);
     786          68 :             return;
     787             :         }
     788             :     }
     789             : 
     790         354 :     SetPageUnderMouse(SharedPageDescriptor());
     791             : }
     792             : 
     793          68 : void SlideSorterView::UpdatePageUnderMouse (
     794             :     const Point& rMousePosition)
     795             : {
     796          68 :     SetPageUnderMouse(mrSlideSorter.GetController().GetPageAt(rMousePosition));
     797          68 : }
     798             : 
     799         461 : void SlideSorterView::SetPageUnderMouse (
     800             :     const model::SharedPageDescriptor& rpDescriptor)
     801             : {
     802         461 :     if (mpPageUnderMouse != rpDescriptor)
     803             :     {
     804           0 :         if (mpPageUnderMouse)
     805           0 :             SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false);
     806             : 
     807           0 :         mpPageUnderMouse = rpDescriptor;
     808             : 
     809           0 :         if (mpPageUnderMouse)
     810           0 :             SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true);
     811             : 
     812             :         // Change the quick help text to display the name of the page under
     813             :         // the mouse.
     814           0 :         mpToolTip->SetPage(rpDescriptor);
     815             :     }
     816         461 : }
     817             : 
     818         664 : bool SlideSorterView::SetState (
     819             :     const model::SharedPageDescriptor& rpDescriptor,
     820             :     const PageDescriptor::State eState,
     821             :     const bool bStateValue)
     822             : {
     823         664 :     model::SharedPageDescriptor pDescriptor (rpDescriptor);
     824         664 :     if ( ! pDescriptor)
     825           0 :         return false;
     826             : 
     827         664 :     const bool bModified (pDescriptor->SetState(eState, bStateValue));
     828         664 :     if ( ! bModified)
     829         318 :         return false;
     830             : 
     831             :     // When the page object is not visible (i.e. not on the screen then
     832             :     // nothing has to be painted.
     833         346 :     if (pDescriptor->HasState(PageDescriptor::ST_Visible))
     834             :     {
     835             :         // For most states a change of that state leads to visible
     836             :         // difference and we have to request a repaint.
     837          91 :         if (eState != PageDescriptor::ST_WasSelected)
     838          91 :             RequestRepaint(pDescriptor);
     839             :     }
     840             : 
     841         346 :     return bModified;
     842             : }
     843             : 
     844          64 : ::boost::shared_ptr<PageObjectPainter> SlideSorterView::GetPageObjectPainter()
     845             : {
     846          64 :     if ( ! mpPageObjectPainter)
     847          64 :         mpPageObjectPainter.reset(new PageObjectPainter(mrSlideSorter));
     848          64 :     return mpPageObjectPainter;
     849             : }
     850             : 
     851             : //===== SlideSorterView::DrawLock =============================================
     852             : 
     853          68 : SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter)
     854          68 :     : mrView(rSlideSorter.GetView()),
     855          68 :       mpWindow(rSlideSorter.GetContentWindow())
     856             : {
     857          68 :     if (mrView.mnLockRedrawSmph == 0)
     858          68 :         mrView.maRedrawRegion.SetEmpty();
     859          68 :     ++mrView.mnLockRedrawSmph;
     860          68 : }
     861             : 
     862         136 : SlideSorterView::DrawLock::~DrawLock()
     863             : {
     864             :     OSL_ASSERT(mrView.mnLockRedrawSmph>0);
     865          68 :     --mrView.mnLockRedrawSmph;
     866          68 :     if (mrView.mnLockRedrawSmph == 0)
     867          68 :         if (mpWindow)
     868             :         {
     869          68 :             mpWindow->Invalidate(mrView.maRedrawRegion);
     870          68 :             mpWindow->Update();
     871             :         }
     872          68 : }
     873             : 
     874           0 : void SlideSorterView::DrawLock::Dispose()
     875             : {
     876           0 :     mpWindow.reset();
     877           0 : }
     878             : 
     879          66 : } } } // end of namespace ::sd::slidesorter::view
     880             : 
     881             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.11