Quellcodebibliothek Statistik Leitseite products/sources/formale Sprachen/C/LibreOffice/sd/source/ui/slidesorter/view/   (Office von Apache Version 25.8.3.2©)  Datei vom 5.10.2025 mit Größe 26 kB image not shown  

Quelle  SlideSorterView.cxx   Sprache: C

 
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/*
 * This file is part of the LibreOffice project.
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
 *
 * This file incorporates work covered by the following license notice:
 *
 *   Licensed to the Apache Software Foundation (ASF) under one or more
 *   contributor license agreements. See the NOTICE file distributed
 *   with this work for additional information regarding copyright
 *   ownership. The ASF licenses this file to you under the Apache
 *   License, Version 2.0 (the "License"); you may not use this file
 *   except in compliance with the License. You may obtain a copy of
 *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
 */


#include <view/SlideSorterView.hxx>

#include <SlideSorter.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/SlsToolTip.hxx>
#include <controller/SlideSorterController.hxx>
#include <controller/SlsClipboard.hxx>
#include <model/SlideSorterModel.hxx>
#include <model/SlsPageEnumerationProvider.hxx>
#include <model/SlsPageDescriptor.hxx>
#include <cache/SlsPageCache.hxx>
#include <cache/SlsPageCacheManager.hxx>
#include <titledockwin.hxx>

#include <sdpage.hxx>
#include <Window.hxx>

#include <comphelper/lok.hxx>
#include <osl/diagnose.h>
#include <vcl/svapp.hxx>
#include <vcl/settings.hxx>
#include <vcl/graphicfilter.hxx>

#include <algorithm>

//#define DEBUG_TIMING
#ifdef DEBUG_TIMING
#include <memory>
#include <vector>
#endif

using namespace ::sd::slidesorter::model;

namespace sd::slidesorter::view {

namespace {
    /** Wrapper around the SlideSorterView that supports the IPainter
        interface and that allows the LayeredDevice to hold the
        SlideSorterView (held as unique_ptr by the SlideSorter) as
        shared_ptr.
    */

    class Painter : public ILayerPainter
    {
    public:
        explicit Painter (SlideSorterView& rView) : mrView(rView) {}

        virtual void Paint (OutputDevice& rDevice, const ::tools::Rectangle& rRepaintArea) override
        {
            mrView.Paint(rDevice,rRepaintArea);
        }

        virtual void SetLayerInvalidator (const SharedILayerInvalidator&) override {}

    private:
        SlideSorterView& mrView;
    };
}

namespace {

class BackgroundPainter
    : public ILayerPainter
{
public:
    explicit BackgroundPainter (const Color& rBackgroundColor) : maBackgroundColor(rBackgroundColor) {}
    BackgroundPainter(const BackgroundPainter&) = delete;
    BackgroundPainter& operator=(const BackgroundPainter&) = delete;

    virtual void Paint (OutputDevice& rDevice, const ::tools::Rectangle& rRepaintArea) override
    {
        rDevice.SetFillColor(maBackgroundColor);
        rDevice.SetLineColor();
        rDevice.DrawRect(rRepaintArea);
    }

    virtual void SetLayerInvalidator (const SharedILayerInvalidator&) override {}

    void SetColor (const Color& rColor) { maBackgroundColor = rColor; }

private:
    Color maBackgroundColor;
};

}

SlideSorterView::SlideSorterView (SlideSorter& rSlideSorter)
    : ::sd::View (
          *rSlideSorter.GetModel().GetDocument(),
          rSlideSorter.GetContentWindow()->GetOutDev(),
          &rSlideSorter.GetViewShell()),
      mrSlideSorter(rSlideSorter),
      mrModel(rSlideSorter.GetModel()),
      mbIsDisposed(false),
      mpLayouter (new Layouter(rSlideSorter.GetContentWindow(), rSlideSorter.GetTheme())),
      mbPageObjectVisibilitiesValid (false),
      mpLayeredDevice(std::make_shared<LayeredDevice>(rSlideSorter.GetContentWindow())),
      maVisiblePageRange(-1,-1),
      maPreviewSize(0,0),
      mbPreciousFlagUpdatePending(true),
      meOrientation(Layouter::GRID),
      mpBackgroundPainter(
          std::make_shared<BackgroundPainter>(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background))),
      mpToolTip(new ToolTip(mrSlideSorter)),
      mbIsRearrangePending(true)
{
    // Hide the page that contains the page objects.
    SetPageVisible (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 = std::make_shared<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()
{
    if ( ! mbIsDisposed)
    {
        OSL_ASSERT(mbIsDisposed);
        Dispose();
    }
}

void SlideSorterView::Init()
{
    HandleModelChange();
}

void SlideSorterView::Dispose()
{
    mpLayeredDevice->Dispose();
    mpPreviewCache.reset();

    SetPageUnderMouse(SharedPageDescriptor());

    // 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.use_count() == 1);
    mpLayeredDevice.reset();

    mbIsDisposed = true;
}

sal_Int32 SlideSorterView::GetPageIndexAtPoint (const Point& rWindowPosition) const
{
    sal_Int32 nIndex (-1);

    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow)
    {
        nIndex = mpLayouter->GetIndexAtPoint(pWindow->PixelToLogic(rWindowPosition));

        // Clip the page index against the page count.
        if (nIndex >= mrModel.GetPageCount())
            nIndex = -1;
    }

    return nIndex;
}

Layouter& SlideSorterView::GetLayouter() { return *mpLayouter; }

void SlideSorterView::ModelHasChanged()
{
    // Ignore this call.  Rely on hints sent by the model to get informed of
    // model changes.
}

void SlideSorterView::PreModelChange()
{
    // Reset the slide under the mouse.  It will be re-set in PostModelChange().
    SetPageUnderMouse(SharedPageDescriptor());
}

void SlideSorterView::PostModelChange()
{
    // In PreModelChange() the page objects have been released.  Here we
    // create new ones.
    ::osl::MutexGuard aGuard (mrModel.GetMutex());

    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()
{
    PreModelChange ();
    PostModelChange();
}

void SlideSorterView::HandleDrawModeChange()
{
    // 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();

    RequestRepaint();
}

void SlideSorterView::HandleDataChangeEvent()
{
    GetPageObjectPainter()->SetTheme(mrSlideSorter.GetTheme());

    // Update the color used by the background painter.
    std::shared_ptr<BackgroundPainter> pPainter (
        std::dynamic_pointer_cast<BackgroundPainter>(mpBackgroundPainter));
    if (pPainter)
        pPainter->SetColor(mrSlideSorter.GetTheme()->GetColor(Theme::Color_Background));

    RequestRepaint();
}

void SlideSorterView::Resize()
{
    UpdateOrientation();

    mpLayeredDevice->Resize();
    RequestRearrange();
}

void SlideSorterView::RequestRearrange()
{
    mbIsRearrangePending = true;
    Rearrange();
}

void SlideSorterView::Rearrange()
{
    if ( ! mbIsRearrangePending)
        return;
    if (mrModel.GetPageCount() <= 0)
        return;

    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if ( ! pWindow)
        return;
    const Size aWindowSize (pWindow->GetSizePixel());
    if (aWindowSize.IsEmpty())
        return;

    const bool bRearrangeSuccess (
        mpLayouter->Rearrange (
            meOrientation,
            aWindowSize,
            mrModel.GetPageDescriptor(0)->GetPage()->GetSize(),
            mrModel.GetPageCount()));
    if (bRearrangeSuccess)
    {
        mbIsRearrangePending = false;
        Layout();
        UpdatePageUnderMouse();
        //        RequestRepaint();
    }
}

void SlideSorterView::UpdateOrientation()
{
    // 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.
        vcl::Window* pWindow = mrSlideSorter.GetContentWindow();
        TitledDockingWindow* pDockingWindow = nullptr;
        while (pWindow!=nullptr && pDockingWindow==nullptr)
        {
            pDockingWindow = dynamic_cast<TitledDockingWindow*>(pWindow);
            pWindow = pWindow->GetParent();
        }

        if (pDockingWindow != nullptr)
        {
            const ::tools::Long nScrollBarSize (
                Application::GetSettings().GetStyleSettings().GetScrollBarSize());
            switch (pDockingWindow->GetOrientation())
            {
                case TitledDockingWindow::HorizontalOrientation:
                    if (SetOrientation(Layouter::HORIZONTAL))
                    {
                        const Range aRange (mpLayouter->GetValidVerticalSizeRange());
                        pDockingWindow->SetValidSizeRange(Range(
                            aRange.Min() + nScrollBarSize,
                            aRange.Max() + nScrollBarSize));
                    }
                    break;

                case TitledDockingWindow::VerticalOrientation:
                    if (SetOrientation(Layouter::VERTICAL))
                    {
                        const Range aRange (mpLayouter->GetValidHorizontalSizeRange());
                        pDockingWindow->SetValidSizeRange(Range(
                            aRange.Min() + nScrollBarSize,
                            aRange.Max() + nScrollBarSize));
                    }
                    break;

                case TitledDockingWindow::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 ()
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow)
    {
        // Set the model area, i.e. the smallest rectangle that includes all
        // page objects.
        const ::tools::Rectangle aViewBox (mpLayouter->GetTotalBoundingBox());
        pWindow->SetViewOrigin (aViewBox.TopLeft());
        pWindow->SetViewSize (aViewBox.GetSize());

        std::shared_ptr<PageObjectLayouter> pPageObjectLayouter(
            mpLayouter->GetPageObjectLayouter());
        if (pPageObjectLayouter)
        {
            const Size aNewPreviewSize (mpLayouter->GetPageObjectLayouter()->GetPreviewSize());
            if (maPreviewSize != aNewPreviewSize && GetPreviewCache())
            {
                mpPreviewCache->ChangeSize(aNewPreviewSize, Bitmap::HasFastScale());
                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(), false));
        }
    }

    InvalidatePageObjectVisibilities ();
}

void SlideSorterView::InvalidatePageObjectVisibilities()
{
    mbPageObjectVisibilitiesValid = false;
}

void SlideSorterView::DeterminePageObjectVisibilities()
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (!pWindow)
        return;

    // Set this flag to true here so that an invalidate during the
    // visibility calculation can correctly invalidate it again.
    mbPageObjectVisibilitiesValid = true;

    ::tools::Rectangle aViewArea (pWindow->PixelToLogic(::tools::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 (::tools::Long nIndex=aUnion.Min(); nIndex<=aUnion.Max(); nIndex++)
    {
        pDescriptor = mrModel.GetPageDescriptor(nIndex);
        if (pDescriptor)
            SetState(
                pDescriptor,
                PageDescriptor::ST_Visible,
                aRange.Contains(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<LinkParamNone*,void>>& aChangeListeners (maVisibilityChangeListeners);
        for (const auto& rLink : aChangeListeners)
        {
            rLink.Call(nullptr);
        }
    }

    // Restore the mouse over state.
    UpdatePageUnderMouse();
}

void SlideSorterView::UpdatePreciousFlags()
{
    if (!mbPreciousFlagUpdatePending)
        return;

    mbPreciousFlagUpdatePending = false;

    model::SharedPageDescriptor pDescriptor;
    std::shared_ptr<cache::PageCache> pCache = GetPreviewCache();
    sal_Int32 nPageCount (mrModel.GetPageCount());

    for (int nIndex=0; nIndex<=nPageCount; ++nIndex)
    {
        pDescriptor = mrModel.GetPageDescriptor(nIndex);
        if (pDescriptor)
        {
            pCache->SetPreciousFlag(
                pDescriptor->GetPage(),
                maVisiblePageRange.Contains(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;
}

void SlideSorterView::RequestRepaint()
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow)
    {
        mpLayeredDevice->InvalidateAllLayers(
            ::tools::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 ::tools::Rectangle& rRepaintBox)
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow)
    {
        mpLayeredDevice->InvalidateAllLayers(rRepaintBox);
        pWindow->Invalidate(rRepaintBox);
    }
}

void SlideSorterView::RequestRepaint (const vcl::Region& rRepaintRegion)
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow)
    {
        mpLayeredDevice->InvalidateAllLayers(rRepaintRegion);
        pWindow->Invalidate(rRepaintRegion);
    }
}

::tools::Rectangle SlideSorterView::GetModelArea() const
{
    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 ::tools::Rectangle gFrameTimeBox (10,10,150,20);
static double gnLastFrameStart = 0;
#endif

void SlideSorterView::CompleteRedraw (
    OutputDevice* pDevice,
    const vcl::Region& rPaintArea,
    sdr::contact::ViewObjectContactRedirector* pRedirector)
{
    (void)pRedirector;

    if (comphelper::LibreOfficeKit::isActive())
        return;

    if (pDevice == nullptr || pDevice!=mrSlideSorter.GetContentWindow()->GetOutDev())
        return;

#ifdef DEBUG_TIMING
    const double nStartTime (gaTimer.getElapsedTime());
    SAL_INFO("sd.timing""SlideSorterView::CompleteRedraw start" << (mnLockRedrawSmph ? " locked" : ""));
#endif

    // 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)
    {
        if (mpLayeredDevice->HandleMapModeChange())
            DeterminePageObjectVisibilities();
        mpLayeredDevice->Repaint(rPaintArea);
    }
    else
    {
        maRedrawRegion.Union(rPaintArea);
    }

#ifdef DEBUG_TIMING
    const double nEndTime (gaTimer.getElapsedTime());
    SAL_INFO("sd.timing""SlideSorterView::CompleteRedraw end after " << (nEndTime-nStartTime)*1000 << " ms");
    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,
        OUString::number(1 / (gFrameTimeSum / gFrameTimeCount)),
        DrawTextFlags::Right | DrawTextFlags::VCenter);
    //    mrSlideSorter.GetContentWindow()->Invalidate(gFrameTimeBox);
#endif
}

void SlideSorterView::Paint (
    OutputDevice& rDevice,
    const ::tools::Rectangle& rRepaintArea)
{
    if (rRepaintArea.IsEmpty())
        return;

    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));
    // Try to prefetch all graphics from the pages to paint. This will be done
    // in threads to be more efficient than loading them on-demand one by one.
    std::vector<Graphic*> graphics;
    for (::tools::Long nIndex=aRange.Min(); nIndex<=aRange.Max(); ++nIndex)
    {
        model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
        if (!pDescriptor || ! pDescriptor->HasState(PageDescriptor::ST_Visible))
            continue;
        pDescriptor->GetPage()->getGraphicsForPrefetch(graphics);
    }
    // Handle also one page before and after to have those in advance on scrolling.
    for (::tools::Long nIndex : { aRange.Min() - 1, aRange.Max() + 1 })
    {
        model::SharedPageDescriptor pDescriptor (mrModel.GetPageDescriptor(nIndex));
        if (!pDescriptor)
            continue;
        pDescriptor->GetPage()->getGraphicsForPrefetch(graphics);
    }
    if(graphics.size() > 1) // threading does not help with loading just one
        GraphicFilter::GetGraphicFilter().MakeGraphicsAvailableThreaded(graphics);

    for (::tools::Long 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,
    ConfigurationHints 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();

}

std::shared_ptr<cache::PageCache> const & SlideSorterView::GetPreviewCache()
{
    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow && mpPreviewCache == nullptr)
    {
        mpPreviewCache =
            std::make_shared<cache::PageCache>(
                mpLayouter->GetPageObjectSize(),
                Bitmap::HasFastScale(),
                std::make_shared<ViewCacheContext>(mrSlideSorter));
    }

    return mpPreviewCache;
}

Range const & SlideSorterView::GetVisiblePageRange()
{
    if ( ! mbPageObjectVisibilitiesValid)
        DeterminePageObjectVisibilities();
    return maVisiblePageRange;
}

void SlideSorterView::AddVisibilityChangeListener (const Link<LinkParamNone*,void>&&nbsp;rListener)
{
    if (::std::find (
        maVisibilityChangeListeners.begin(),
        maVisibilityChangeListeners.end(),
        rListener) == maVisibilityChangeListeners.end())
    {
        maVisibilityChangeListeners.push_back(rListener);
    }
}

void SlideSorterView::RemoveVisibilityChangeListener(const Link<LinkParamNone*,void>&rListener)
{
    maVisibilityChangeListeners.erase (
        ::std::find (
            maVisibilityChangeListeners.begin(),
            maVisibilityChangeListeners.end(),
            rListener));
}

ToolTip& SlideSorterView::GetToolTip() const
{
    OSL_ASSERT(mpToolTip);
    return *mpToolTip;
}

void SlideSorterView::DragFinished (sal_Int8 nDropAction)
{
    mrSlideSorter.GetController().GetClipboard().DragFinished(nDropAction);

    View::DragFinished(nDropAction);
}

void SlideSorterView::UpdatePageUnderMouse ()
{
    // Tracking TODO check
    VclPtr<ScrollAdaptor> pVScrollBar (mrSlideSorter.GetVerticalScrollBar());
    VclPtr<ScrollAdaptor> pHScrollBar (mrSlideSorter.GetHorizontalScrollBar());
    if ((pVScrollBar && pVScrollBar->IsVisible() && pVScrollBar->HasGrab())
        || (pHScrollBar && pHScrollBar->IsVisible() && pHScrollBar->HasGrab()))
    {
        // One of the scroll bars is tracking mouse movement.  Do not
        // highlight the slide under the mouse in this case.
        SetPageUnderMouse(SharedPageDescriptor());
        return;
    }

    sd::Window *pWindow (mrSlideSorter.GetContentWindow().get());
    if (pWindow && pWindow->IsVisible() && ! pWindow->IsMouseCaptured())
    {
        const Window::PointerState aPointerState (pWindow->GetPointerState());
        const ::tools::Rectangle aWindowBox (pWindow->GetPosPixel(), pWindow->GetSizePixel());
        if (aWindowBox.Contains(aPointerState.maPos))
        {
            UpdatePageUnderMouse(aPointerState.maPos);
            return;
        }
    }

    SetPageUnderMouse(SharedPageDescriptor());
}

void SlideSorterView::UpdatePageUnderMouse (
    const Point& rMousePosition)
{
    SetPageUnderMouse(mrSlideSorter.GetController().GetPageAt(rMousePosition));
}

void SlideSorterView::SetPageUnderMouse (
    const model::SharedPageDescriptor& rpDescriptor)
{
    if (mpPageUnderMouse == rpDescriptor)
        return;

    if (mpPageUnderMouse)
        SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, false);

    mpPageUnderMouse = rpDescriptor;

    if (mpPageUnderMouse)
        SetState(mpPageUnderMouse, PageDescriptor::ST_MouseOver, true);

    // 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)
{
    if ( ! rpDescriptor)
        return false;

    const bool bModified (rpDescriptor->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 (rpDescriptor->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(rpDescriptor);
    }

    return bModified;
}

std::shared_ptr<PageObjectPainter> const & SlideSorterView::GetPageObjectPainter()
{
    if ( ! mpPageObjectPainter)
        mpPageObjectPainter = std::make_shared<PageObjectPainter>(mrSlideSorter);
    return mpPageObjectPainter;
}

//===== SlideSorterView::DrawLock =============================================

SlideSorterView::DrawLock::DrawLock (SlideSorter const & rSlideSorter)
    : mrView(rSlideSorter.GetView()),
      mpWindow(rSlideSorter.GetContentWindow())
{
    if (mrView.mnLockRedrawSmph == 0)
        mrView.maRedrawRegion.SetEmpty();
    ++mrView.mnLockRedrawSmph;
}

SlideSorterView::DrawLock::~DrawLock()
{
    OSL_ASSERT(mrView.mnLockRedrawSmph>0);
    --mrView.mnLockRedrawSmph;
    if (mrView.mnLockRedrawSmph == 0)
        if (mpWindow)
        {
            mpWindow->Invalidate(mrView.maRedrawRegion);
        }
}

void SlideSorterView::DrawLock::Dispose()
{
    mpWindow.reset();
}

// end of namespace ::sd::slidesorter::view

/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Messung V0.5
C=94 H=96 G=94

¤ Dauer der Verarbeitung: 0.14 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.