diff options
Diffstat (limited to 'sd/source/ui/slidesorter/view/SlideSorterView.cxx')
-rw-r--r-- | sd/source/ui/slidesorter/view/SlideSorterView.cxx | 1132 |
1 files changed, 1132 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/view/SlideSorterView.cxx b/sd/source/ui/slidesorter/view/SlideSorterView.cxx new file mode 100644 index 000000000000..728eff5ee384 --- /dev/null +++ b/sd/source/ui/slidesorter/view/SlideSorterView.cxx @@ -0,0 +1,1132 @@ +/************************************************************************* + * + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * Copyright 2000, 2010 Oracle and/or its affiliates. + * + * OpenOffice.org - a multi-platform office productivity suite + * + * This file is part of OpenOffice.org. + * + * OpenOffice.org is free software: you can redistribute it and/or modify + * it under the terms of the GNU Lesser General Public License version 3 + * only, as published by the Free Software Foundation. + * + * OpenOffice.org is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Lesser General Public License version 3 for more details + * (a copy is included in the LICENSE file that accompanied this code). + * + * You should have received a copy of the GNU Lesser General Public License + * version 3 along with OpenOffice.org. If not, see + * <http://www.openoffice.org/license.html> + * for a copy of the LGPLv3 License. + * + ************************************************************************/ + +#include "precompiled_sd.hxx" + +#include "view/SlideSorterView.hxx" + +#include "ViewShellBase.hxx" +#include "SlideSorter.hxx" +#include "SlideSorterViewShell.hxx" +#include "ViewShell.hxx" +#include "SlsViewCacheContext.hxx" +#include "SlsLayeredDevice.hxx" +#include "view/SlsLayouter.hxx" +#include "view/SlsPageObjectLayouter.hxx" +#include "view/SlsPageObjectPainter.hxx" +#include "view/SlsILayerPainter.hxx" +#include "view/SlsButtonBar.hxx" +#include "view/SlsToolTip.hxx" +#include "controller/SlideSorterController.hxx" +#include "controller/SlsProperties.hxx" +#include "model/SlideSorterModel.hxx" +#include "model/SlsPageEnumerationProvider.hxx" +#include "model/SlsPageDescriptor.hxx" +#include "cache/SlsPageCache.hxx" +#include "cache/SlsPageCacheManager.hxx" +#include "cache/SlsCacheContext.hxx" +#include "taskpane/SlideSorterCacheDisplay.hxx" +#include "DrawDocShell.hxx" +#include "PaneDockingWindow.hxx" + +#include "drawdoc.hxx" +#include "sdpage.hxx" +#include "Window.hxx" +#include "sdresid.hxx" +#include "glob.hrc" + +#include <svl/itempool.hxx> +#include <svx/svdpagv.hxx> +#include <svx/svdopage.hxx> +#include <svx/xlndsit.hxx> +#include <svx/xlnclit.hxx> +#include <vcl/svapp.hxx> +#include <vcl/scrbar.hxx> +#include <tools/poly.hxx> +#include <vcl/lineinfo.hxx> +#include <algorithm> +#include <svx/sdrpagewindow.hxx> +#include <svl/itempool.hxx> +#include <basegfx/matrix/b2dhommatrix.hxx> +#include <basegfx/polygon/b2dpolygontools.hxx> +#include <basegfx/polygon/b2dpolygon.hxx> +#include <drawinglayer/geometry/viewinformation2d.hxx> +#include <canvas/elapsedtime.hxx> + +//#define DEBUG_TIMING +#include <svl/itempool.hxx> +#ifdef DEBUG_TIMING +#include <vector> +#endif +#include <boost/foreach.hpp> + + +using namespace std; +using namespace ::sd::slidesorter::model; +using namespace ::drawinglayer::primitive2d; + + +namespace sd { namespace slidesorter { namespace view { + +namespace { + /** Wrapper around the SlideSorterView that supports the IPainter + interface and that allows the LayeredDevice to hold the + SlideSorterView (held as scoped_ptr by the SlideSorter) as + shared_ptr. + */ + class Painter : public ILayerPainter + { + public: + Painter (SlideSorterView& rView) : mrView(rView) {} + virtual ~Painter (void) {} + + virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) + { + mrView.Paint(rDevice,rRepaintArea); + } + + virtual void SetLayerInvalidator (const SharedILayerInvalidator&) {} + + private: + SlideSorterView& mrView; + }; +} + + + +class BackgroundPainter + : public ILayerPainter, + public ::boost::noncopyable +{ +public: + BackgroundPainter (const Color aBackgroundColor) : maBackgroundColor(aBackgroundColor) {} + virtual ~BackgroundPainter (void) {} + + virtual void Paint (OutputDevice& rDevice, const Rectangle& rRepaintArea) + { + rDevice.SetFillColor(maBackgroundColor); + rDevice.SetLineColor(); + rDevice.DrawRect(rRepaintArea); + } + + virtual void SetLayerInvalidator (const SharedILayerInvalidator&) {} + + void SetColor (const Color aColor) { maBackgroundColor = aColor; } + +private: + Color maBackgroundColor; +}; + + + +TYPEINIT1(SlideSorterView, ::sd::View); + +SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter) + : ::sd::View ( + rSlideSorter.GetModel().GetDocument(), + rSlideSorter.GetContentWindow().get(), + rSlideSorter.GetViewShell()), + mrSlideSorter(rSlideSorter), + mrModel(rSlideSorter.GetModel()), + mbIsDisposed(false), + mpLayouter (new Layouter(rSlideSorter.GetContentWindow(), rSlideSorter.GetTheme())), + mbPageObjectVisibilitiesValid (false), + mpPreviewCache(), + mpLayeredDevice(new LayeredDevice(rSlideSorter.GetContentWindow())), + maVisiblePageRange(-1,-1), + mbModelChangedWhileModifyEnabled(true), + maPreviewSize(0,0), + mbPreciousFlagUpdatePending(true), + meOrientation(Layouter::GRID), + mpProperties(rSlideSorter.GetProperties()), + mpPageUnderMouse(), + mnButtonUnderMouse(-1), + mpPageObjectPainter(), + mpSelectionPainter(), + mpBackgroundPainter( + new BackgroundPainter(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background))), + mpButtonBar(new ButtonBar(mrSlideSorter)), + mpToolTip(new ToolTip(mrSlideSorter)), + mbIsRearrangePending(true), + maVisibilityChangeListeners() +{ + // Hide the page that contains the page objects. + SetPageVisible (sal_False); + + + // Register the background painter on level 1 to avoid the creation of a + // background buffer. + mpLayeredDevice->RegisterPainter(mpBackgroundPainter, 1); + + // Wrap a shared_ptr-held-wrapper around this view and register it as + // painter at the layered device. There is no explicit destruction: in + // the SlideSorterView destructor the layered device is destroyed and + // with it the only reference to the wrapper which therefore is also + // destroyed. + SharedILayerPainter pPainter (new Painter(*this)); + + // The painter is placed on level 1 to avoid buffering. This should be + // a little faster during animations because the previews are painted + // directly into the window, not via the buffer. + mpLayeredDevice->RegisterPainter(pPainter, 1); +} + + + + +SlideSorterView::~SlideSorterView (void) +{ + if ( ! mbIsDisposed) + { + OSL_ASSERT(mbIsDisposed); + Dispose(); + } +} + + + + +void SlideSorterView::Init (void) +{ + HandleModelChange(); +} + + + + +void SlideSorterView::Dispose (void) +{ + mpSelectionPainter.reset(); + + mpLayeredDevice->Dispose(); + mpPreviewCache.reset(); + + SetPageUnderMouse(SharedPageDescriptor(),false); + + // Hide the page to avoid problems in the view when deleting + // visualized objects + HideSdrPage(); + + // Deletion of the objects and the page will be done in SdrModel + // destructor (as long as objects and pages are added) + + OSL_ASSERT(mpLayeredDevice.unique()); + mpLayeredDevice.reset(); + + mbIsDisposed = true; +} + + + + +sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rWindowPosition) const +{ + sal_Int32 nIndex (-1); + + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + nIndex = mpLayouter->GetIndexAtPoint(pWindow->PixelToLogic(rWindowPosition), false, false); + + // Clip the page index against the page count. + if (nIndex >= mrModel.GetPageCount()) + nIndex = -1; + } + + return nIndex; +} + + + + +Layouter& SlideSorterView::GetLayouter (void) +{ + return *mpLayouter.get(); +} + + + + +void SlideSorterView::ModelHasChanged (void) +{ + // Ignore this call. Rely on hints sent by the model to get informed of + // model changes. +} + + + + +void SlideSorterView::LocalModelHasChanged(void) +{ + mbModelChangedWhileModifyEnabled = false; + + // First call our base class. + View::ModelHasChanged (); +} + + + + +void SlideSorterView::PreModelChange (void) +{ + // Reset the slide under the mouse. It will be re-set in PostModelChange(). + SetPageUnderMouse(SharedPageDescriptor()); +} + + + + +void SlideSorterView::PostModelChange (void) +{ + // In PreModelChange() the page objects have been released. Here we + // create new ones. + ::osl::MutexGuard aGuard (mrModel.GetMutex()); + + model::PageEnumeration aPageEnumeration ( + model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); + + // The new page objects have to be scaled and positioned. + RequestRearrange(); + RequestRepaint(); +} + + + + +/** At the moment for every model change all page objects are destroyed and + re-created again. This can be optimized by accepting hints that + describe the type of change so that existing page objects can be + reused. +*/ +void SlideSorterView::HandleModelChange (void) +{ + PreModelChange (); + PostModelChange(); +} + + + + +void SlideSorterView::HandleDrawModeChange (void) +{ + // Replace the preview cache with a new and empty one. The + // PreviewRenderer that is used by the cache is replaced by this as + // well. + mpPreviewCache.reset(); + GetPreviewCache()->InvalidateCache(true); + + RequestRepaint(); +} + + + + +void SlideSorterView::HandleDataChangeEvent (void) +{ + GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme()); + + // Update the color used by the background painter. + ::boost::shared_ptr<BackgroundPainter> pPainter ( + ::boost::dynamic_pointer_cast<BackgroundPainter>(mpBackgroundPainter)); + if (pPainter) + pPainter->SetColor(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background)); + + if (mpButtonBar) + mpButtonBar->HandleDataChangeEvent(); + + RequestRepaint(); +} + + + + +void SlideSorterView::Resize (void) +{ + UpdateOrientation(); + + mpLayeredDevice->Resize(); + RequestRearrange(); +} + + + + +void SlideSorterView::RequestRearrange (void) +{ + mbIsRearrangePending = true; + Rearrange(); +} + + + + +void SlideSorterView::Rearrange (void) +{ + if ( ! mbIsRearrangePending) + return; + if (mrModel.GetPageCount() <= 0) + return; + + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if ( ! pWindow) + return; + const Size aWindowSize (pWindow->GetSizePixel()); + if (aWindowSize.Width()<=0 || aWindowSize.Height()<=0) + return; + + const bool bRearrangeSuccess ( + mpLayouter->Rearrange ( + meOrientation, + aWindowSize, + mrModel.GetPageDescriptor(0)->GetPage()->GetSize(), + mrModel.GetPageCount())); + if (bRearrangeSuccess) + { + mbIsRearrangePending = false; + Layout(); + UpdatePageUnderMouse(false); + // RequestRepaint(); + } +} + + + + +void SlideSorterView::UpdateOrientation (void) +{ + // The layout of slides depends on whether the slide sorter is + // displayed in the center or the side pane. + if (mrSlideSorter.GetViewShell()->IsMainViewShell()) + SetOrientation(Layouter::GRID); + else + { + // Get access to the docking window. + ::Window* pWindow = mrSlideSorter.GetContentWindow().get(); + PaneDockingWindow* pDockingWindow = NULL; + while (pWindow!=NULL && pDockingWindow==NULL) + { + pDockingWindow = dynamic_cast<PaneDockingWindow*>(pWindow); + pWindow = pWindow->GetParent(); + } + + if (pDockingWindow != NULL) + { + const long nScrollBarSize ( + Application::GetSettings().GetStyleSettings().GetScrollBarSize()); + switch (pDockingWindow->GetOrientation()) + { + case PaneDockingWindow::HorizontalOrientation: + if (SetOrientation(Layouter::HORIZONTAL)) + { + const Range aRange (mpLayouter->GetValidVerticalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::VerticalOrientation: + if (SetOrientation(Layouter::VERTICAL)) + { + const Range aRange (mpLayouter->GetValidHorizontalSizeRange()); + pDockingWindow->SetValidSizeRange(Range( + aRange.Min() + nScrollBarSize, + aRange.Max() + nScrollBarSize)); + } + break; + + case PaneDockingWindow::UnknownOrientation: + if (SetOrientation(Layouter::GRID)) + { + const sal_Int32 nAdditionalSize (10); + pDockingWindow->SetMinOutputSizePixel(Size( + mpLayouter->GetValidHorizontalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize, + mpLayouter->GetValidVerticalSizeRange().Min() + + nScrollBarSize + + nAdditionalSize)); + } + return; + } + } + else + { + // We are not placed in a docking window. One possible reason + // is that the slide sorter is temporarily into a cache and was + // reparented to a non-docking window. + SetOrientation(Layouter::GRID); + } + } +} + + + + +void SlideSorterView::Layout () +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + // Set the model area, i.e. the smallest rectangle that includes all + // page objects. + const Rectangle aViewBox (mpLayouter->GetTotalBoundingBox()); + pWindow->SetViewOrigin (aViewBox.TopLeft()); + pWindow->SetViewSize (aViewBox.GetSize()); + + ::boost::shared_ptr<PageObjectLayouter> pPageObjectLayouter( + mpLayouter->GetPageObjectLayouter()); + if (pPageObjectLayouter) + { + const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetSize( + PageObjectLayouter::Preview, + PageObjectLayouter::WindowCoordinateSystem)); + if (maPreviewSize != aNewPreviewSize && GetPreviewCache()) + { + mpPreviewCache->ChangeSize(aNewPreviewSize, true); + maPreviewSize = aNewPreviewSize; + } + } + + // Iterate over all page objects and place them relative to the + // containing page. + model::PageEnumeration aPageEnumeration ( + model::PageEnumerationProvider::CreateAllPagesEnumeration(mrModel)); + while (aPageEnumeration.HasMoreElements()) + { + model::SharedPageDescriptor pDescriptor (aPageEnumeration.GetNextElement()); + pDescriptor->SetBoundingBox(mpLayouter->GetPageObjectBox(pDescriptor->GetPageIndex())); + } + + GetPageObjectPainter()->NotifyResize(); + } + + InvalidatePageObjectVisibilities (); +} + + + + +void SlideSorterView::InvalidatePageObjectVisibilities (void) +{ + mbPageObjectVisibilitiesValid = false; +} + + + + +void SlideSorterView::DeterminePageObjectVisibilities (void) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + // Set this flag to true here so that an invalidate during the + // visibility calculation can correctly invalidate it again. + mbPageObjectVisibilitiesValid = true; + + Rectangle aViewArea (pWindow->PixelToLogic(Rectangle(Point(0,0),pWindow->GetSizePixel()))); + const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(aViewArea)); + const Range aUnion( + ::std::min(maVisiblePageRange.Min(), aRange.Min()), + ::std::max(maVisiblePageRange.Max(), aRange.Max())); + + // For page objects that just dropped off the visible area we + // decrease the priority of pending requests for preview bitmaps. + if (maVisiblePageRange != aRange) + mbPreciousFlagUpdatePending |= true; + + model::SharedPageDescriptor pDescriptor; + for (int nIndex=aUnion.Min(); nIndex<=aUnion.Max(); nIndex++) + { + pDescriptor = mrModel.GetPageDescriptor(nIndex); + if (pDescriptor.get() != NULL) + SetState( + pDescriptor, + PageDescriptor::ST_Visible, + aRange.IsInside(nIndex)); + } + + // Broadcast a change of the set of visible page objects. + if (maVisiblePageRange != aRange) + { + maVisiblePageRange = aRange; + + // Tell the listeners that the visibility of some objects has + // changed. + ::std::vector<Link>& aChangeListeners (maVisibilityChangeListeners); + for (::std::vector<Link>::const_iterator + iLink(aChangeListeners.begin()), + iEnd(aChangeListeners.end()); + iLink!=iEnd; + ++iLink) + { + iLink->Call(NULL); + } + } + + + // Restore the mouse over state. + UpdatePageUnderMouse(true); + } +} + + + + +void SlideSorterView::UpdatePreciousFlags (void) +{ + if (mbPreciousFlagUpdatePending) + { + mbPreciousFlagUpdatePending = false; + + model::SharedPageDescriptor pDescriptor; + ::boost::shared_ptr<cache::PageCache> pCache = GetPreviewCache(); + sal_Int32 nPageCount (mrModel.GetPageCount()); + + for (int nIndex=0; nIndex<=nPageCount; ++nIndex) + { + pDescriptor = mrModel.GetPageDescriptor(nIndex); + if (pDescriptor.get() != NULL) + { + pCache->SetPreciousFlag( + pDescriptor->GetPage(), + maVisiblePageRange.IsInside(nIndex)); + SSCD_SET_VISIBILITY(mrModel.GetDocument(), nIndex, + maVisiblePageRange.IsInside(nIndex)); + } + else + { + // At least one cache entry can not be updated. Remember to + // repeat the whole updating later and leave the loop now. + mbPreciousFlagUpdatePending = true; + break; + } + } + } +} + + + + +bool SlideSorterView::SetOrientation (const Layouter::Orientation eOrientation) +{ + if (meOrientation != eOrientation) + { + meOrientation = eOrientation; + return true; + } + else + return false; +} + + + + +Layouter::Orientation SlideSorterView::GetOrientation (void) const +{ + return meOrientation; +} + + + + +void SlideSorterView::RequestRepaint (void) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + mpLayeredDevice->InvalidateAllLayers( + Rectangle( + pWindow->PixelToLogic(Point(0,0)), + pWindow->PixelToLogic(pWindow->GetSizePixel()))); + pWindow->Invalidate(); + } +} + + + + +void SlideSorterView::RequestRepaint (const model::SharedPageDescriptor& rpDescriptor) +{ + if (rpDescriptor) + RequestRepaint(rpDescriptor->GetBoundingBox()); +} + + + + +void SlideSorterView::RequestRepaint (const Rectangle& rRepaintBox) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + mpLayeredDevice->InvalidateAllLayers(rRepaintBox); + pWindow->Invalidate(rRepaintBox); + } +} + + + +void SlideSorterView::RequestRepaint (const Region& rRepaintRegion) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow) + { + mpLayeredDevice->InvalidateAllLayers(rRepaintRegion); + pWindow->Invalidate(rRepaintRegion); + } +} + + + + +Rectangle SlideSorterView::GetModelArea (void) +{ + return mpLayouter->GetTotalBoundingBox(); +} + + +#ifdef DEBUG_TIMING +static ::canvas::tools::ElapsedTime gaTimer; +static const size_t gFrameTimeCount (10); +static size_t gFrameTimeIndex (0); +static ::std::vector<double> gFrameTimes (gFrameTimeCount, 0); +static double gFrameTimeSum (0); +static const Rectangle gFrameTimeBox (10,10,150,20); +static double gnLastFrameStart = 0; +#endif + +void SlideSorterView::CompleteRedraw ( + OutputDevice* pDevice, + const Region& rPaintArea, + sdr::contact::ViewObjectContactRedirector* pRedirector) +{ + (void)pRedirector; +#ifdef DEBUG_TIMING + const double nStartTime (gaTimer.getElapsedTime()); + OSL_TRACE("SlideSorterView::CompleteRedraw start at %f, %s", + nStartTime, + mnLockRedrawSmph ? "locked" : ""); +#endif + + if (pDevice == NULL || pDevice!=mrSlideSorter.GetContentWindow().get()) + return; + + // The parent implementation of CompleteRedraw is called only when + // painting is locked. We do all the painting ourself. When painting + // is locked the parent implementation keeps track of the repaint + // requests and later, when painting is unlocked, calls CompleteRedraw + // for all missed repaints. + + if (mnLockRedrawSmph == 0) + { + mrSlideSorter.GetContentWindow()->IncrementLockCount(); + if (mpLayeredDevice->HandleMapModeChange()) + DeterminePageObjectVisibilities(); + mpLayeredDevice->Repaint(rPaintArea); + mrSlideSorter.GetContentWindow()->DecrementLockCount(); + } + else + { + maRedrawRegion.Union(rPaintArea); + } + +#ifdef DEBUG_TIMING + const double nEndTime (gaTimer.getElapsedTime()); + OSL_TRACE("SlideSorterView::CompleteRedraw end at %f after %fms", nEndTime, (nEndTime-nStartTime)*1000); + gFrameTimeSum -= gFrameTimes[gFrameTimeIndex]; + gFrameTimes[gFrameTimeIndex] = nStartTime - gnLastFrameStart; + gnLastFrameStart = nStartTime; + gFrameTimeSum += gFrameTimes[gFrameTimeIndex]; + gFrameTimeIndex = (gFrameTimeIndex+1) % gFrameTimeCount; + + + mrSlideSorter.GetContentWindow()->SetFillColor(COL_BLUE); + mrSlideSorter.GetContentWindow()->DrawRect(gFrameTimeBox); + mrSlideSorter.GetContentWindow()->SetTextColor(COL_WHITE); + mrSlideSorter.GetContentWindow()->DrawText( + gFrameTimeBox, + ::rtl::OUString::valueOf(1 / (gFrameTimeSum / gFrameTimeCount)), + TEXT_DRAW_RIGHT | TEXT_DRAW_VCENTER); + // mrSlideSorter.GetContentWindow()->Invalidate(gFrameTimeBox); +#endif +} + + + + +void SlideSorterView::Paint ( + OutputDevice& rDevice, + const Rectangle& rRepaintArea) +{ + if ( ! mpPageObjectPainter) + if ( ! GetPageObjectPainter()) + return; + + // Update the page visibilities when they have been invalidated. + if ( ! mbPageObjectVisibilitiesValid) + DeterminePageObjectVisibilities(); + + if (mbPreciousFlagUpdatePending) + UpdatePreciousFlags(); + + if (mbIsRearrangePending) + Rearrange(); + + // Paint all page objects that are fully or partially inside the + // repaint region. + const Range aRange (mpLayouter->GetRangeOfVisiblePageObjects(rRepaintArea)); + for (sal_Int32 nIndex=aRange.Min(); nIndex<=aRange.Max(); ++nIndex) + { + model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex)); + if (!pDescriptor || ! pDescriptor->HasState(PageDescriptor::ST_Visible)) + continue; + + mpPageObjectPainter->PaintPageObject(rDevice, pDescriptor); + } +} + + + + +void SlideSorterView::ConfigurationChanged ( + utl::ConfigurationBroadcaster* pBroadcaster, + sal_uInt32 nHint) +{ + // Some changes of the configuration (some of the colors for example) + // may affect the previews. Throw away the old ones and create new ones. + cache::PageCacheManager::Instance()->InvalidateAllCaches(); + + ::sd::View::ConfigurationChanged(pBroadcaster, nHint); + RequestRepaint(); + +} + + + + +::boost::shared_ptr<cache::PageCache> SlideSorterView::GetPreviewCache (void) +{ + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow && mpPreviewCache.get() == NULL) + { + mpPreviewCache.reset( + new cache::PageCache( + mpLayouter->GetPageObjectSize(), + false, + cache::SharedCacheContext(new ViewCacheContext(mrSlideSorter)))); + } + + return mpPreviewCache; +} + + + + +Pair SlideSorterView::GetVisiblePageRange (void) +{ + if ( ! mbPageObjectVisibilitiesValid) + DeterminePageObjectVisibilities(); + return maVisiblePageRange; +} + + + + +void SlideSorterView::AddVisibilityChangeListener (const Link& rListener) +{ + if (::std::find ( + maVisibilityChangeListeners.begin(), + maVisibilityChangeListeners.end(), + rListener) == maVisibilityChangeListeners.end()) + { + maVisibilityChangeListeners.push_back(rListener); + } +} + + + + +void SlideSorterView::RemoveVisibilityChangeListener(const Link&rListener) +{ + maVisibilityChangeListeners.erase ( + ::std::find ( + maVisibilityChangeListeners.begin(), + maVisibilityChangeListeners.end(), + rListener)); +} + + + + +ButtonBar& SlideSorterView::GetButtonBar (void) const +{ + OSL_ASSERT(mpButtonBar); + return *mpButtonBar; +} + + + + +ToolTip& SlideSorterView::GetToolTip (void) const +{ + OSL_ASSERT(mpToolTip); + return *mpToolTip; +} + + + + +void SlideSorterView::Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) +{ + ::sd::DrawDocShell* pDocShell = mrModel.GetDocument()->GetDocSh(); + if (pDocShell!=NULL && pDocShell->IsEnableSetModified()) + mbModelChangedWhileModifyEnabled = true; + + ::sd::View::Notify(rBroadcaster, rHint); +} + + + + +void SlideSorterView::UpdatePageUnderMouse (bool bAnimate) +{ + ::boost::shared_ptr<ScrollBar> pVScrollBar (mrSlideSorter.GetVerticalScrollBar()); + ::boost::shared_ptr<ScrollBar> pHScrollBar (mrSlideSorter.GetHorizontalScrollBar()); + if ((pVScrollBar && pVScrollBar->IsVisible() && pVScrollBar->IsTracking()) + || (pHScrollBar && pHScrollBar->IsVisible() && pHScrollBar->IsTracking())) + { + // One of the scroll bars is tracking mouse movement. Do not + // highlight the slide under the mouse in this case. + SetPageUnderMouse(SharedPageDescriptor(),false); + return; + } + + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + if (pWindow && pWindow->IsVisible() && ! pWindow->IsMouseCaptured()) + { + const Window::PointerState aPointerState (pWindow->GetPointerState()); + const Rectangle aWindowBox (pWindow->GetPosPixel(), pWindow->GetSizePixel()); + if (aWindowBox.IsInside(aPointerState.maPos)) + { + UpdatePageUnderMouse ( + aPointerState.maPos, + (aPointerState.mnState & MOUSE_LEFT)!=0, + bAnimate); + return; + } + } + + SetPageUnderMouse(SharedPageDescriptor(),false); +} + + + + +void SlideSorterView::UpdatePageUnderMouse ( + const Point& rMousePosition, + const bool bIsMouseButtonDown, + const bool bAnimate) +{ + UpdatePageUnderMouse( + mrSlideSorter.GetController().GetPageAt(rMousePosition), + rMousePosition, + bIsMouseButtonDown, + bAnimate); +} + + + + +void SlideSorterView::UpdatePageUnderMouse ( + const model::SharedPageDescriptor& rpDescriptor, + const Point& rMousePosition, + const bool bIsMouseButtonDown, + const bool bAnimate) +{ + // Update the page under the mouse. + SetPageUnderMouse(rpDescriptor, bAnimate); + + // Tell the button bar about the new mouse position. + SharedSdWindow pWindow (mrSlideSorter.GetContentWindow()); + const Point aMouseModelPosition (pWindow->PixelToLogic(rMousePosition)); + + ::boost::shared_ptr<ViewShell> pMainViewShell (mrSlideSorter.GetViewShellBase()->GetMainViewShell()); + if (pMainViewShell + && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW) + { + const bool bIsMouseOverButtonBar (GetButtonBar().IsMouseOverBar()); + GetButtonBar().ProcessMouseMotionEvent(rpDescriptor, aMouseModelPosition, bIsMouseButtonDown); + // Set the help text of the slide when the mouse was moved from the + // button bar back over the preview. + if (rpDescriptor + && GetButtonBar().IsMouseOverBar() != bIsMouseOverButtonBar + && bIsMouseOverButtonBar) + { + mpToolTip->ShowDefaultHelpText(); + } + } +} + + + + +void SlideSorterView::SetPageUnderMouse ( + const model::SharedPageDescriptor& rpDescriptor, + const bool bAnimate) +{ + if (mpPageUnderMouse != rpDescriptor) + { + if (mpPageUnderMouse) + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false, bAnimate); + + mpPageUnderMouse = rpDescriptor; + + if (mpPageUnderMouse) + SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true, bAnimate); + + // Change the quick help text to display the name of the page under + // the mouse. + mpToolTip->SetPage(rpDescriptor); + } +} + + + + +bool SlideSorterView::SetState ( + const model::SharedPageDescriptor& rpDescriptor, + const PageDescriptor::State eState, + const bool bStateValue, + const bool bAnimate) +{ + model::SharedPageDescriptor pDescriptor (rpDescriptor); + if ( ! pDescriptor) + return false; + + const bool bModified (pDescriptor->SetState(eState, bStateValue)); + if ( ! bModified) + return false; + + // When the page object is not visible (i.e. not on the screen then + // nothing has to be painted. + if (pDescriptor->HasState(PageDescriptor::ST_Visible)) + { + // For most states a change of that state leads to visible + // difference and we have to request a repaint. + if (eState != PageDescriptor::ST_WasSelected) + RequestRepaint(pDescriptor); + } + + ::boost::shared_ptr<ViewShell> pMainViewShell(mrSlideSorter.GetViewShellBase()->GetMainViewShell()); + if (pMainViewShell + && pMainViewShell->GetShellType()!=ViewShell::ST_DRAW) + { + // Fade in or out the buttons. + if (eState == PageDescriptor::ST_MouseOver) + { + if (bStateValue) + GetButtonBar().RequestFadeIn(rpDescriptor, bAnimate); + else + GetButtonBar().RequestFadeOut(rpDescriptor, bAnimate); + } + } + + return bModified; +} + + + + +::boost::shared_ptr<PageObjectPainter> SlideSorterView::GetPageObjectPainter (void) +{ + if ( ! mpPageObjectPainter) + mpPageObjectPainter.reset(new PageObjectPainter(mrSlideSorter)); + return mpPageObjectPainter; +} + + + + +::boost::shared_ptr<LayeredDevice> SlideSorterView::GetLayeredDevice (void) const +{ + return mpLayeredDevice; +} + + + + +//===== SlideSorterView::DrawLock ============================================= + +SlideSorterView::DrawLock::DrawLock ( + view::SlideSorterView& rView, + const SharedSdWindow& rpWindow) + : mrView(rView), + mpWindow(rpWindow) +{ + if (mrView.mnLockRedrawSmph == 0) + mrView.maRedrawRegion.SetEmpty(); + ++mrView.mnLockRedrawSmph; +} + + + + +SlideSorterView::DrawLock::DrawLock (SlideSorter& rSlideSorter) + : mrView(rSlideSorter.GetView()), + mpWindow(rSlideSorter.GetContentWindow()) +{ + if (mrView.mnLockRedrawSmph == 0) + mrView.maRedrawRegion.SetEmpty(); + ++mrView.mnLockRedrawSmph; +} + + + + +SlideSorterView::DrawLock::~DrawLock (void) +{ + OSL_ASSERT(mrView.mnLockRedrawSmph>0); + --mrView.mnLockRedrawSmph; + if (mrView.mnLockRedrawSmph == 0) + if (mpWindow) + { + mpWindow->Invalidate(mrView.maRedrawRegion); + mpWindow->Update(); + } +} + + + + +void SlideSorterView::DrawLock::Dispose (void) +{ + mpWindow.reset(); +} + + +} } } // end of namespace ::sd::slidesorter::view |