summaryrefslogtreecommitdiffstats
path: root/sd/source/ui/slidesorter/inc
diff options
context:
space:
mode:
Diffstat (limited to 'sd/source/ui/slidesorter/inc')
-rw-r--r--sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx98
-rw-r--r--sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx141
-rw-r--r--sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx155
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx327
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx77
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx122
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx208
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx112
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx211
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx138
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx219
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx125
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx248
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx145
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx139
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx77
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx98
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsTransferableData.hxx78
-rw-r--r--sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx90
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx227
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsEnumeration.hxx44
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx144
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsPageEnumeration.hxx95
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsPageEnumerationProvider.hxx51
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsSharedPageDescriptor.hxx32
-rw-r--r--sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx47
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx225
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx53
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx59
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx101
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx237
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx144
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx119
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsTheme.hxx135
-rw-r--r--sd/source/ui/slidesorter/inc/view/SlsToolTip.hxx75
35 files changed, 4596 insertions, 0 deletions
diff --git a/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx b/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx
new file mode 100644
index 000000000..12993fdbb
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/cache/SlsCacheContext.hxx
@@ -0,0 +1,98 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <com/sun/star/uno/Reference.hxx>
+#include <memory>
+#include <vector>
+
+namespace com::sun::star::uno
+{
+class XInterface;
+}
+
+class SdrPage;
+
+namespace sd::slidesorter::cache
+{
+typedef const SdrPage* CacheKey;
+
+/** This interface allows the individualisation of different instances of
+ the PreviewCache.
+*/
+class CacheContext
+{
+public:
+ virtual ~CacheContext() {}
+
+ /** This method is called when the asynchronous creation of a preview
+ has been finished.
+ @param aKey
+ The key of the page for which the preview has been created.
+ */
+ virtual void NotifyPreviewCreation(CacheKey aKey) = 0;
+
+ /** Called to determine whether the system is idle and a preview can be
+ created without annoying the user.
+ */
+ virtual bool IsIdle() = 0;
+
+ /** This method is used to determine whether a page is currently visible
+ or not. It is called when the cache becomes too large and some
+ previews have to be released or scaled down.
+ */
+ virtual bool IsVisible(CacheKey aKey) = 0;
+
+ /** Return the page associated with the given key. Note that different
+ keys may map to a single page (this may be the case with custom
+ slide shows.)
+ */
+ virtual const SdrPage* GetPage(CacheKey aKey) = 0;
+
+ /** This method is used when the request queue is filled. It asks for
+ the list of visible entries and maybe for the list of not visible
+ entries and creates preview creation requests for them.
+ @param bVisible
+ When this is <FALSE/> then the implementation can decide whether
+ to allow rendering of previews that are not visible (ahead of
+ time). When not then return an empty pointer or an empty vector.
+ */
+ virtual std::shared_ptr<std::vector<CacheKey>> GetEntryList(bool bVisible) = 0;
+
+ /** Return the priority that defines the order in which previews are
+ created for different keys/pages. Typically the visible pages come
+ first, then top-down, left-to-right.
+ */
+ virtual sal_Int32 GetPriority(CacheKey aKey) = 0;
+
+ /** Return the model to which the pages belong for which the called
+ cache manages the previews. Different caches that belong to the
+ same model but have different preview sizes may access previews of
+ each other in order to create fast previews of the previews.
+ */
+ virtual css::uno::Reference<css::uno::XInterface> GetModel() = 0;
+};
+
+typedef std::shared_ptr<CacheContext> SharedCacheContext;
+
+} // end of namespace ::sd::slidesorter::cache
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx
new file mode 100644
index 000000000..4fb596195
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCache.hxx
@@ -0,0 +1,141 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <cache/SlsCacheContext.hxx>
+#include <vcl/bitmapex.hxx>
+#include <memory>
+
+class Size;
+
+namespace sd::slidesorter::cache
+{
+class GenericPageCache;
+
+/** The page cache is responsible for the creation and storage of preview
+ bitmaps of pages that are shown by the slide sorter.
+
+ <p>Bitmaps for previews and a cache are used to speed up the display
+ (painting) of the slide sorter. But, of course, we have to limit this
+ time-space-tradeoff by limiting the amount of space that can be use to
+ store bitmaps.</p>
+
+ <p>There are several strategies employed by this class to shorten the
+ perceived time that is used to paint the slide sorter:
+ <ul>
+ <li>Rendering pages ahead of time. Additionally to rendering the
+ visible slides we try to render part or all of the slides that are not
+ (yet) visible. This, of course, makes sense only when the computer is
+ otherwise idle while doing that.</li>
+ <li>When the size of the slides on the screen changes we mark the
+ bitmaps as needing an update but use them while the new bitmap in the
+ correct size is not available.</li>
+ <li>Give the UI the chance to handle user events between the rendering
+ of differe slides.</li>
+ <li>Limit the amount of space that may be used for storing preview
+ bitmaps and throw.</li>
+ </p>
+
+ <p>There is another somewhat similar methods for requesting new previews:
+ GetPreviewBitmap() schedules a re-rendering (when necessary) and
+ returns the preview what is currently available, either as a preview of
+ the preview or, when nothing has changed since the last call, as the
+ final thing.
+ </p>
+*/
+class PageCache
+{
+public:
+ /** The page cache is created with a reference to the slide sorter so
+ that it has access to both the view and the model and so can fill
+ itself with requests for all or just the visible pages.
+
+ It is the task of the PageCacheManager to create new objects of this
+ class.
+ */
+ PageCache(const Size& rPreviewSize, const bool bDoSuperSampling,
+ const SharedCacheContext& rpCacheContext);
+
+ ~PageCache();
+
+ void ChangeSize(const Size& rPreviewSize, const bool bDoSuperSampling);
+
+ /** Request a preview bitmap for the specified page object in the
+ specified size. The returned bitmap may be a preview of the
+ preview, i.e. either a scaled (up or down) version of a previous
+ preview (of the wrong size) or an empty bitmap. In this case a
+ request for the generation of a new preview is created and inserted
+ into the request queue. When the preview is available in the right
+ size the page shape will be told to paint itself again. When it
+ then calls this method again if receives the correctly sized preview
+ bitmap.
+ @param rRequestData
+ This data is used to determine the preview.
+ @param bResize
+ When <TRUE/> then when the available bitmap has not the
+ requested size, it is scaled before it is returned. When
+ <FALSE/> then the bitmap is returned in the wrong size and it is
+ the task of the caller to scale it.
+ @return
+ Returns a bitmap that is either empty, contains a scaled (up or
+ down) version or is the requested bitmap.
+ */
+ BitmapEx GetPreviewBitmap(const CacheKey aKey, const bool bResize);
+
+ BitmapEx GetMarkedPreviewBitmap(const CacheKey aKey);
+ void SetMarkedPreviewBitmap(const CacheKey aKey, const BitmapEx& rBitmap);
+
+ /** When the requested preview bitmap does not yet exist or is not
+ up-to-date then the rendering of one is scheduled. Otherwise this
+ method does nothing.
+ */
+ void RequestPreviewBitmap(const CacheKey aKey);
+
+ /** Tell the cache that the bitmap associated with the given request
+ data is not up-to-date anymore. This will invalidate all previews
+ in other caches that represent the same page as well.
+ A new preview is requested and will lead
+ eventually to a repaint of the associated page object.
+ */
+ void InvalidatePreviewBitmap(const CacheKey aKey);
+
+ /** Call this method when all preview bitmaps have to be generated anew.
+ This is the case when the size of the page objects on the screen has
+ changed or when the model has changed.
+ */
+ void InvalidateCache();
+
+ /** With the precious flag you can control whether a bitmap can be
+ removed or reduced in size to make room for other bitmaps or is so
+ precious that it will not touched. A typical use is to set the
+ precious flag for exactly the visible pages.
+ */
+ void SetPreciousFlag(const CacheKey aKey, const bool bIsPrecious);
+
+ void Pause();
+ void Resume();
+
+private:
+ std::unique_ptr<GenericPageCache> mpImplementation;
+};
+
+} // end of namespace ::sd::slidesorter::cache
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx b/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx
new file mode 100644
index 000000000..eaddea5b2
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/cache/SlsPageCacheManager.hxx
@@ -0,0 +1,155 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <com/sun/star/uno/XInterface.hpp>
+#include <memory>
+#include <vector>
+
+class Size;
+class SdrPage;
+
+namespace sd::slidesorter::cache {
+
+class BitmapCache;
+
+/** Provide and manage the preview bitmap caches for all slide sorter
+ instances. There is one cache per active slide sorter plus a small
+ number of caches that are no longer in use. The later are kept to speed
+ up the switching between views.
+*/
+class PageCacheManager
+{
+public:
+ typedef std::vector< std::pair<Size, std::shared_ptr<BitmapCache> > > BestFittingPageCaches;
+ typedef css::uno::Reference<css::uno::XInterface> DocumentKey;
+
+ /** Return the one instance of the PageCacheManager class.
+ */
+ static std::shared_ptr<PageCacheManager> Instance();
+
+ /** Look up the cache for the given model in which the previews have the
+ specified size. If no such cache exists, then one is created. When
+ a new BitmapCache is created its Recycle() method is called with a
+ sorted list of existing caches from which the new one initialize its
+ previews.
+ @return
+ The returned cache lives as long as somebody keeps a shared
+ pointer and the ReleaseCache() method has not been called.
+ */
+ std::shared_ptr<BitmapCache> GetCache (
+ const DocumentKey& pDocument,
+ const Size& rPreviewSize);
+
+ /** Tell the cache manager to release its own reference to the specified
+ cache. After that the cache will live as long as the caller (and
+ maybe others) holds its reference.
+ */
+ void ReleaseCache (const std::shared_ptr<BitmapCache>& rpCache);
+
+ /** This is an information to the cache manager that the size of preview
+ bitmaps in the specified cache has changed.
+
+ */
+ std::shared_ptr<BitmapCache> ChangeSize (
+ const std::shared_ptr<BitmapCache>& rpCache,
+ const Size& rOldPreviewSize,
+ const Size& rNewPreviewSize);
+
+ /** Invalidate the preview bitmap for one slide that belongs to the
+ specified document. The bitmaps for this slide in all caches are
+ marked as out-of-date and will be re-created when they are requested
+ the next time.
+ */
+ bool InvalidatePreviewBitmap (
+ const DocumentKey& pDocument,
+ const SdrPage* pPage);
+
+ /** Invalidate the preview bitmaps for all slides that belong to the
+ specified document. This is necessary after model changes that
+ affect e.g. page number fields.
+ */
+ void InvalidateAllPreviewBitmaps (const DocumentKey& pDocument);
+
+ /** Invalidate all the caches that are currently in use and destroy
+ those that are not. This is used for example when the high contrast
+ mode is turned on or off.
+ */
+ void InvalidateAllCaches();
+
+ /** Call this method when a page has been deleted and its preview
+ is not needed anymore.
+ */
+ void ReleasePreviewBitmap (const SdrPage* pPage);
+
+private:
+ /** Singleton instance of the cache manager. Note that this is a weak
+ pointer. The (implementation class of) ViewShellBase holds a
+ shared_ptr so that the cache manager has the same life time as the
+ ViewShellBase.
+ */
+ static std::weak_ptr<PageCacheManager> mpInstance;
+
+ /// List of active caches.
+ class PageCacheContainer;
+ std::unique_ptr<PageCacheContainer> mpPageCaches;
+
+ /// List of inactive, recently used caches.
+ class RecentlyUsedPageCaches;
+ std::unique_ptr<RecentlyUsedPageCaches> mpRecentlyUsedPageCaches;
+
+ /** The maximal number of recently used caches that are kept alive after
+ they have become inactive, i.e. after they are not used anymore by a
+ slide sorter.
+ */
+ static const sal_uInt32 mnMaximalRecentlyCacheCount = 2;
+
+ PageCacheManager();
+ ~PageCacheManager();
+
+ class Deleter;
+ friend class Deleter;
+
+ std::shared_ptr<BitmapCache> GetRecentlyUsedCache(
+ const DocumentKey& pDocument,
+ const Size& rSize);
+
+ /** Add the given cache to the list of recently used caches for the
+ document. There is one such list per document. Each least has at
+ most mnMaximalRecentlyCacheCount members.
+ */
+ void PutRecentlyUsedCache(
+ DocumentKey const & pDocument,
+ const Size& rPreviewSize,
+ const std::shared_ptr<BitmapCache>& rpCache);
+
+ /** This method is used internally to initialize a newly created
+ BitmapCache with already existing previews.
+ */
+ void Recycle (
+ const std::shared_ptr<BitmapCache>& rpCache,
+ const DocumentKey& pDocument,
+ const Size& rPreviewSize);
+};
+
+} // end of namespace ::sd::slidesorter::cache
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx
new file mode 100644
index 000000000..10c2aa13e
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlideSorterController.hxx
@@ -0,0 +1,327 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <pres.hxx>
+
+#include <tools/link.hxx>
+#include <tools/gen.hxx>
+#include <rtl/ref.hxx>
+#include <rtl/ustring.hxx>
+
+#include <sddllapi.h>
+
+#include <memory>
+#include <vector>
+
+namespace com::sun::star::container
+{
+class XIndexAccess;
+}
+namespace com::sun::star::uno
+{
+template <typename> class Reference;
+}
+namespace sd
+{
+class FuPoor;
+}
+namespace sd
+{
+class Window;
+}
+namespace vcl
+{
+class Window;
+}
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+namespace sd::slidesorter::view
+{
+class SlideSorterView;
+}
+namespace sd::slidesorter::model
+{
+class SlideSorterModel;
+}
+
+class CommandEvent;
+class SdPage;
+class SfxItemSet;
+class SfxRequest;
+class VclSimpleEvent;
+class VclWindowEvent;
+
+namespace sd::slidesorter::controller
+{
+class Animator;
+class Clipboard;
+class CurrentSlideManager;
+class FocusManager;
+class InsertionIndicatorHandler;
+class Listener;
+class PageSelector;
+class ScrollBarManager;
+class SelectionFunction;
+class SelectionManager;
+class SlotManager;
+class VisibleAreaManager;
+
+class SlideSorterController final
+{
+public:
+ /** Create a new controller for the slide sorter.
+ @param pParentWindow
+ The window that contains the controls of the new
+ controller.
+ */
+ SlideSorterController(SlideSorter& rSlideSorter);
+
+ /** Late initialization. Call this method once a new object has been
+ created.
+ */
+ void Init();
+
+ ~SlideSorterController();
+
+ void Dispose();
+
+ /** Place and size the scroll bars and the browser window so that the
+ given rectangle is filled.
+ */
+ void Resize(const ::tools::Rectangle& rAvailableSpace);
+
+ /** Determine which of the UI elements--the scroll bars, the scroll bar
+ filler, the actual slide sorter view--are visible and place them in
+ the area last passed to Resize().
+ @param bForce
+ When <TRUE/> is given (<FALSE/> is the default) then the content
+ window and with it the SlideSorterView is resized event when its
+ size does not change (the size does change when the visibility
+ of scroll bars changes.)
+ */
+ void Rearrange(bool bForce);
+
+ /** Return the descriptor of the page that is rendered under the
+ given position. This takes the IsOnlyPreviewTriggersMouseOver
+ property into account.
+ @return
+ Returns a pointer to a page descriptor instead of a
+ reference because when no page is found at the position
+ then NULL is returned to indicate this.
+ */
+ model::SharedPageDescriptor GetPageAt(const Point& rPixelPosition);
+
+ // Exported for unit test
+ SD_DLLPUBLIC PageSelector& GetPageSelector();
+ FocusManager& GetFocusManager();
+ // Exported for unit test
+ SD_DLLPUBLIC controller::Clipboard& GetClipboard();
+
+ /** Return the object that manages the scroll bars.
+ */
+ ScrollBarManager& GetScrollBarManager();
+
+ std::shared_ptr<CurrentSlideManager> const& GetCurrentSlideManager() const;
+ std::shared_ptr<SlotManager> const& GetSlotManager() const;
+ std::shared_ptr<SelectionManager> const& GetSelectionManager() const;
+ std::shared_ptr<InsertionIndicatorHandler> const& GetInsertionIndicatorHandler() const;
+
+ /** This method forwards the call to the SlideSorterView and executes
+ pending operations like moving selected pages into the visible area.
+ */
+ void Paint(const ::tools::Rectangle& rRect, vcl::Window* pWin);
+
+ void FuTemporary(SfxRequest& rRequest);
+ void FuPermanent(SfxRequest& rRequest);
+ void FuSupport(SfxRequest& rRequest);
+ bool Command(const CommandEvent& rEvent, ::sd::Window* pWindow);
+
+ void GetCtrlState(SfxItemSet& rSet);
+ void GetStatusBarState(SfxItemSet& rSet);
+
+ void ExecCtrl(SfxRequest& rRequest);
+ void GetAttrState(SfxItemSet& rSet);
+
+ /** Create an object of this inner class to prevent updates due to model
+ changes.
+ */
+ class ModelChangeLock
+ {
+ public:
+ ModelChangeLock(SlideSorterController& rController);
+ ~ModelChangeLock() COVERITY_NOEXCEPT_FALSE;
+ void Release();
+
+ private:
+ SlideSorterController* mpController;
+ };
+ friend class ModelChangeLock;
+
+ /** Handle a change of the model, that is, handle the removal and
+ insertion of whole pages or a change of the edit mode.
+
+ This method is a convenience function that simply calls
+ PreModelChange() and then PostModelChange().
+ */
+ void HandleModelChange();
+
+ DECL_LINK(WindowEventHandler, VclWindowEvent&, void);
+ DECL_LINK(ApplicationEventHandler, VclSimpleEvent&, void);
+
+ /** Update the display of all pages. This involves a redraw and
+ releasing previews and caches.
+ */
+ void UpdateAllPages();
+
+ /** This factory method creates a selection function.
+ */
+ rtl::Reference<FuPoor> CreateSelectionFunction(SfxRequest& rRequest);
+
+ /** When the current function of the view shell is the slide sorter
+ selection function then return a reference to it. Otherwise return
+ an empty reference.
+ */
+ ::rtl::Reference<SelectionFunction> GetCurrentSelectionFunction() const;
+
+ /** Prepare for a change of the edit mode. Depending on the current
+ edit mode we may save the selection so that it can be restored when
+ later changing back to the current edit mode.
+ */
+ void PrepareEditModeChange();
+
+ /** Set a new edit mode and return whether the edit mode really
+ has been changed. For proper saving and restoring of the selection
+ this method should be called between calls to
+ PrepareEditModeChange() and FinishEditModeChange().
+ */
+ void ChangeEditMode(EditMode eEditMode);
+
+ /** Finish the change of the edit mode. Here we may select a page or
+ restore a previously saved selection.
+ */
+ void FinishEditModeChange();
+
+ /** Call this method when the name of one of the pages has changed.
+ This is then notified to the accessibility object, when that exists.
+ @param nPageIndex
+ The index of the page whose name has been changed.
+ @param rsOldName
+ The old name of the page. The new name can be taken from the
+ page object.
+ */
+ void PageNameHasChanged(int nPageIndex, const OUString& rsOldName);
+
+ /** Provide the set of pages to be displayed in the slide sorter. The
+ GetDocumentSlides() method can be found only in the SlideSorterModel.
+ */
+ void SetDocumentSlides(const css::uno::Reference<css::container::XIndexAccess>& rxSlides);
+
+ /** Return an Animator object.
+ */
+ const std::shared_ptr<Animator>& GetAnimator() const { return mpAnimator; }
+
+ VisibleAreaManager& GetVisibleAreaManager() const;
+
+ void CheckForMasterPageAssignment();
+ void CheckForSlideTransitionAssignment();
+
+private:
+ SlideSorter& mrSlideSorter;
+ model::SlideSorterModel& mrModel;
+ view::SlideSorterView& mrView;
+ std::unique_ptr<PageSelector> mpPageSelector;
+ std::unique_ptr<FocusManager> mpFocusManager;
+ std::shared_ptr<SlotManager> mpSlotManager;
+ std::unique_ptr<ScrollBarManager> mpScrollBarManager;
+ mutable std::shared_ptr<CurrentSlideManager> mpCurrentSlideManager;
+ std::shared_ptr<SelectionManager> mpSelectionManager;
+ std::unique_ptr<controller::Clipboard> mpClipboard;
+ std::shared_ptr<InsertionIndicatorHandler> mpInsertionIndicatorHandler;
+ std::shared_ptr<Animator> mpAnimator;
+ std::unique_ptr<VisibleAreaManager> mpVisibleAreaManager;
+
+ // The listener listens to UNO events and thus is a UNO object.
+ ::rtl::Reference<controller::Listener> mpListener;
+
+ int mnModelChangeLockCount;
+ bool mbIsForcedRearrangePending;
+ bool mbContextMenuOpen;
+
+ bool mbPostModelChangePending;
+
+ /** This array stores the indices of the selected page descriptors at
+ the time when the edit mode is switched to EditMode::MasterPage. With this
+ we can restore the selection when switching back to EditMode::Page mode.
+ */
+ ::std::vector<SdPage*> maSelectionBeforeSwitch;
+ /// The current page before the edit mode is switched to EditMode::MasterPage.
+ int mnCurrentPageBeforeSwitch;
+
+ /** The master page to select after the edit mode is changed. This
+ member is used to pass the pointer from PrepareEditModeChange() to
+ FinishEditModeChange().
+ */
+ SdPage* mpEditModeChangeMasterPage;
+
+ /** This rectangle in the parent window encloses scroll bars and slide
+ sorter window. It is set when Resize() is called.
+ */
+ ::tools::Rectangle maTotalWindowArea;
+
+ /** This counter is used to avoid processing of reentrant calls to
+ Paint().
+ */
+ sal_Int32 mnPaintEntranceCount;
+
+ /** Prepare for several model changes, i.e. prevent time-consuming and
+ non-critical operations like repaints until UnlockModelChange() is
+ called. Critical operations like releasing references to pages that
+ do not exist anymore are executed.
+ */
+ void LockModelChange();
+
+ /** Further calls to HandleModelChange() will result in a full featured
+ update of model, view, and controller. When HandleModelChange() has
+ been called since the last LockModelChange() then this is done right
+ away to bring the view up-to-date.
+ */
+ void UnlockModelChange();
+
+ /** Prepare for a model change. This method does all the things that
+ need to be done _before_ the model changes, e.g. because they need
+ access to the model data before the change.
+ */
+ void PreModelChange();
+
+ /** Complete a model change. This includes the recreation of data
+ structures that depend on the model and the request for a repaint to
+ show the changes.
+ */
+ void PostModelChange();
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx
new file mode 100644
index 000000000..b4847de1a
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimationFunction.hxx
@@ -0,0 +1,77 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <basegfx/point/b2dpoint.hxx>
+
+#include <functional>
+#include <vector>
+
+
+namespace sd::slidesorter::controller {
+
+class AnimationBezierFunction
+{
+public:
+ /** Create a cubic bezier curve whose start and end points are given
+ implicitly as P0=(0,0) and P3=(1,1). The second control point is
+ implicitly given as P2=(1-nY1,1-nX1).
+ */
+ AnimationBezierFunction (
+ const double nX1,
+ const double nY1);
+
+ ::basegfx::B2DPoint operator() (const double nT);
+
+private:
+ const double mnX1;
+ const double mnY1;
+ const double mnX2;
+ const double mnY2;
+
+ static double EvaluateComponent (
+ const double nT,
+ const double nV1,
+ const double nV2);
+};
+
+/** Turn a parametric function into one whose y-Values depend on its
+ x-Values. Note a lot of interpolation takes place. The resulting
+ accuracy should be good enough for the purpose of acceleration
+ function for animations.
+*/
+class AnimationParametricFunction
+{
+public:
+ typedef ::std::function<basegfx::B2DPoint (double)> ParametricFunction;
+ AnimationParametricFunction (const ParametricFunction& rFunction);
+
+ double operator() (const double nX);
+
+private:
+ /** y-Values of the parametric function given to the constructor
+ evaluated (and interpolated) for evenly spaced x-Values.
+ */
+ ::std::vector<double> maY;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx
new file mode 100644
index 000000000..8c9ec9e81
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsAnimator.hxx
@@ -0,0 +1,122 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <view/SlideSorterView.hxx>
+#include <canvas/elapsedtime.hxx>
+#include <vcl/idle.hxx>
+#include <sal/types.h>
+#include <o3tl/deleter.hxx>
+
+#include <functional>
+#include <memory>
+#include <vector>
+
+namespace sd::slidesorter { class SlideSorter; }
+
+namespace sd::slidesorter::controller {
+
+/** Experimental class for simple eye candy animations.
+*/
+class Animator
+{
+public:
+ /** In some circumstances we have to avoid animation and jump to the
+ final animation state immediately. Use this enum instead of a bool
+ to be more expressive.
+ */
+ enum AnimationMode { AM_Animated, AM_Immediate };
+
+ explicit Animator (SlideSorter& rSlideSorter);
+ ~Animator();
+ Animator(const Animator&) = delete;
+ Animator& operator=(const Animator&) = delete;
+
+ /** When disposed the animator will stop its work immediately and not
+ process any timer events anymore.
+ */
+ void Dispose();
+
+ /** An animation object is called with values between 0 and 1 as single
+ argument to its operator() method.
+ */
+ typedef ::std::function<void (double)> AnimationFunctor;
+ typedef ::std::function<void ()> FinishFunctor;
+
+ typedef sal_Int32 AnimationId;
+ static const AnimationId NotAnAnimationId = -1;
+
+ /** Schedule a new animation for execution. The () operator of that
+ animation will be called with increasing values between 0 and 1 for
+ the specified duration.
+ @param rAnimation
+ The animation operation.
+ */
+ AnimationId AddAnimation (
+ const AnimationFunctor& rAnimation,
+ const FinishFunctor& rFinishFunctor);
+
+ /** Abort and remove an animation. In order to reduce the bookkeeping
+ on the caller side, it is OK to call this method with an animation
+ function that is not currently being animated. Such a call is
+ silently ignored.
+ */
+ void RemoveAnimation (const AnimationId nAnimationId);
+
+ /** A typical use case for this method is the temporary shutdown of the
+ slidesorter when the slide sorter bar is put into a cache due to a
+ change of the edit mode.
+ */
+ void RemoveAllAnimations();
+
+private:
+ SlideSorter& mrSlideSorter;
+ Idle maIdle;
+ bool mbIsDisposed;
+ class Animation;
+ typedef ::std::vector<std::shared_ptr<Animation> > AnimationList;
+ AnimationList maAnimations;
+ ::canvas::tools::ElapsedTime maElapsedTime;
+
+ std::unique_ptr<view::SlideSorterView::DrawLock, o3tl::default_delete<view::SlideSorterView::DrawLock>> mpDrawLock;
+
+ AnimationId mnNextAnimationId;
+
+ DECL_LINK(TimeoutHandler, Timer *, void);
+
+ /** Execute one step of every active animation.
+ @param nTime
+ Time measured in milliseconds with some arbitrary reference point.
+ @return
+ When one or more animation has finished then <TRUE/> is
+ returned. Call CleanUpAnimationList() in this case.
+ */
+ bool ProcessAnimations (const double nTime);
+
+ /** Remove animations that have expired.
+ */
+ void CleanUpAnimationList();
+
+ void RequestNextFrame();
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx
new file mode 100644
index 000000000..6ced17486
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsClipboard.hxx
@@ -0,0 +1,208 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+#include <ViewClipboard.hxx>
+#include <controller/SlsSelectionObserver.hxx>
+#include <sdxfer.hxx>
+
+#include <sal/types.h>
+#include <o3tl/deleter.hxx>
+#include <svx/svdtypes.hxx>
+
+#include <sddllapi.h>
+
+class SfxRequest;
+struct AcceptDropEvent;
+class DropTargetHelper;
+struct ExecuteDropEvent;
+struct ImplSVEvent;
+class Point;
+class SdPage;
+namespace vcl { class Window; }
+
+namespace sd {
+class Window;
+}
+
+namespace sd::slidesorter { class SlideSorter; }
+
+namespace sd::slidesorter::controller {
+
+class SlideSorterController;
+
+class SAL_DLLPUBLIC_RTTI Clipboard final
+ : public ViewClipboard
+{
+public:
+ Clipboard (SlideSorter& rSlideSorter);
+ virtual ~Clipboard() override;
+
+ /** Create a slide sorter transferable from the given sd
+ transferable. The returned transferable is set up with all
+ information necessary so that it can be dropped on a slide sorter.
+ */
+ static std::shared_ptr<SdTransferable::UserData> CreateTransferableUserData (SdTransferable* pTransferable);
+
+ void HandleSlotCall (SfxRequest& rRequest);
+
+ void DoCut ();
+ // Exported for unit test
+ SD_DLLPUBLIC void DoCopy();
+ // Exported for unit test
+ SD_DLLPUBLIC void DoPaste();
+ void DoDelete ();
+
+ void StartDrag (
+ const Point& rDragPt,
+ vcl::Window* pWindow );
+
+ void DragFinished (
+ sal_Int8 nDropAction);
+
+ sal_Int8 AcceptDrop (
+ const AcceptDropEvent& rEvt,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ sal_uInt16 nPage,
+ SdrLayerID nLayer );
+
+ sal_Int8 ExecuteDrop (
+ const ExecuteDropEvent& rEvt,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ sal_uInt16 nPage,
+ SdrLayerID nLayer );
+
+ void Abort();
+
+private:
+ virtual sal_uInt16 DetermineInsertPosition () override;
+
+ SlideSorter& mrSlideSorter;
+ SlideSorterController& mrController;
+
+ typedef ::std::vector<SdPage*> PageList;
+ /** Remember the pages that are dragged to another document or to
+ another place in the same document so that they can be removed after
+ a move operation.
+ */
+ PageList maPagesToRemove;
+
+ /** Used when a drop is executed to combine all undo actions into one.
+ Typically created in ExecuteDrop() and released in DragFinish().
+ */
+ class UndoContext;
+ std::unique_ptr<UndoContext> mxUndoContext;
+
+ std::unique_ptr<SelectionObserver::Context, o3tl::default_delete<SelectionObserver::Context>> mxSelectionObserverContext;
+ ImplSVEvent * mnDragFinishedUserEventId;
+
+ void CreateSlideTransferable (
+ vcl::Window* pWindow,
+ bool bDrag);
+
+ /** Determine the position of where to insert the pages in the current
+ transferable of the sd module.
+ @return
+ The index in the range [0,n] (both inclusive) with n the number
+ of pages is returned.
+ */
+ sal_Int32 GetInsertionPosition ();
+
+ /** Paste the pages of the transferable of the sd module at the given
+ position.
+ @param nInsertPosition
+ The position at which to insert the pages. The valid range is
+ [0,n] (both inclusive) with n the number of pages in the
+ document.
+ @return
+ The number of inserted pages is returned.
+ */
+ sal_Int32 PasteTransferable (sal_Int32 nInsertPosition);
+
+ /** Select a range of pages of the model. Typically usage is the
+ selection of newly inserted pages.
+ @param nFirstIndex
+ The index of the first page to select.
+ @param nPageCount
+ The number of pages to select.
+ */
+ void SelectPageRange (sal_Int32 nFirstIndex, sal_Int32 nPageCount);
+
+ /** Return <TRUE/> when the current transferable in the current state of
+ the slidesorter is acceptable to be pasted. For this the
+ transferable has to
+ a) exist,
+ b) contain one or more regular draw pages, no master pages.
+ When master pages are involved, either in the transferable or in the
+ slide sorter (by it displaying master pages) the drop of the
+ transferable is not accepted. The reason is the missing
+ implementation of proper handling master pages copy-and-paste.
+ */
+ enum DropType { DT_PAGE, DT_PAGE_FROM_NAVIGATOR, DT_SHAPE, DT_NONE };
+ DropType IsDropAccepted() const;
+
+ /** This method contains the code for AcceptDrop() and ExecuteDrop() shapes.
+ There are only minor differences for the two cases at this level.
+ @param eCommand
+ This parameter specifies whether to do an AcceptDrop() or
+ ExecuteDrop().
+ @param rPosition
+ Since the event is given as void pointer we can not take the
+ mouse position from it. The caller has to supply it in this
+ parameter.
+ @param pDropEvent
+ Event though the AcceptDropEvent and ExecuteDropEvent are very
+ similar they do not have a common base class. Because of that
+ we have to use a void* to pass these structs.
+ @param nPage
+ When the page number is given as 0xffff then it is replaced by
+ the number of the page at the mouse position. If the mouse is
+ not over a page then neither AcceptDrop() nor ExecuteDrop() are
+ executed.
+ */
+ enum DropCommand { DC_ACCEPT, DC_EXECUTE };
+ sal_Int8 ExecuteOrAcceptShapeDrop (
+ DropCommand eCommand,
+ const Point& rPosition,
+ const void* pDropEvent ,
+ DropTargetHelper& rTargetHelper,
+ ::sd::Window* pTargetWindow,
+ sal_uInt16 nPage,
+ SdrLayerID nLayer);
+
+ /** Return whether the insertion defined by the transferable is
+ trivial, ie would not change either source nor target document.
+ */
+ bool IsInsertionTrivial (
+ SdTransferable const * pTransferable,
+ const sal_Int8 nDndAction) const;
+
+ /** Asynchronous part of DragFinished. The argument is the sal_Int8
+ nDropAction, disguised as void*.
+ */
+ DECL_DLLPRIVATE_LINK(ProcessDragFinished, void*, void);
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx
new file mode 100644
index 000000000..0c5b3b243
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsCurrentSlideManager.hxx
@@ -0,0 +1,112 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <vcl/timer.hxx>
+#include <tools/link.hxx>
+
+class SdPage;
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::controller
+{
+/** Manage the current slide. This includes setting the according flags at
+ the PageDescriptor objects and setting the current slide at the main
+ view shell.
+
+ Switching pages is triggered only after a little delay. This allows
+ fast travelling through a larger set of slides without having to wait
+ for the edit view to update its content after every slide change.
+*/
+class CurrentSlideManager
+{
+public:
+ /** Create a new CurrentSlideManager object that manages the current
+ slide for the given SlideSorter.
+ */
+ CurrentSlideManager(SlideSorter& rSlideSorter);
+
+ ~CurrentSlideManager();
+
+ /** Call this when the current page of the main view shell has been
+ switched. Use SwitchCurrentSlide() to initiate such a switch.
+ */
+ void NotifyCurrentSlideChange(const sal_Int32 nSlideIndex);
+ void NotifyCurrentSlideChange(const SdPage* pPage);
+
+ /** Call this method to switch the current page of the main view shell
+ to the given slide. Use CurrentSlideHasChanged() when the current
+ slide change has been initiated by someone else.
+ @param nSlideIndex
+ Zero based index in the range [0,number-of-slides).
+ The page selection is cleared and only the new
+ current slide is selected.
+ */
+ void SwitchCurrentSlide(const sal_Int32 nSlideIndex);
+ void SwitchCurrentSlide(const model::SharedPageDescriptor& rpSlide,
+ const bool bUpdateSelection = false);
+
+ /** Return the page descriptor for the current slide. Note, that when
+ there is no current slide then the returned pointer is empty.
+ */
+ const model::SharedPageDescriptor& GetCurrentSlide() const { return mpCurrentSlide; }
+
+ /** Release all references to model data.
+ */
+ void PrepareModelChange();
+
+ /** Modify inner state in reaction to a change of the SlideSorterModel.
+ */
+ void HandleModelChange();
+
+private:
+ SlideSorter& mrSlideSorter;
+ sal_Int32 mnCurrentSlideIndex;
+ model::SharedPageDescriptor mpCurrentSlide;
+ /** Timer to control the delay after which to ask
+ XController/ViewShellBase to switch to another slide.
+ */
+ Timer maSwitchPageDelayTimer;
+
+ void SetCurrentSlideAtViewShellBase(const model::SharedPageDescriptor& rpSlide);
+ void SetCurrentSlideAtTabControl(const model::SharedPageDescriptor& rpSlide);
+ void SetCurrentSlideAtXController(const model::SharedPageDescriptor& rpSlide);
+
+ /** When switching from one slide to a new current slide then this
+ method releases all ties to the old slide.
+ */
+ void ReleaseCurrentSlide();
+
+ /** When switching from one slide to a new current slide then this
+ method connects to the new current slide.
+ */
+ void AcquireCurrentSlide(const sal_Int32 nSlideIndex);
+
+ DECL_LINK(SwitchPageCallback, Timer*, void);
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx
new file mode 100644
index 000000000..180b7143f
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsFocusManager.hxx
@@ -0,0 +1,211 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+
+#include <sal/types.h>
+#include <tools/link.hxx>
+#include <vector>
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::controller
+{
+/** This class manages the focus of the slide sorter. There is the focus
+ page which is or is not focused. Initialized to point to the first page
+ it can be set to other pages by using the MoveFocus() method. The
+ focused state of the focus page can be toggled with the ToggleFocus()
+ method.
+*/
+class FocusManager
+{
+public:
+ /** Create a new focus manager that operates on the pages of the model
+ associated with the given controller. The focus page is set to the
+ first page. Focused state is off.
+ */
+ FocusManager(SlideSorter& rSlideSorter);
+
+ ~FocusManager();
+
+ enum class FocusMoveDirection
+ {
+ Left,
+ Right,
+ Up,
+ Down
+ };
+
+ /** Move the focus from the currently focused page to one that is
+ displayed adjacent to it, either vertically or horizontally.
+ @param eDirection
+ Direction in which to move the focus. Wrap around is done
+ differently when moving vertically or horizontally. Vertical
+ wrap around takes place in the same column, i.e. when you are
+ in the top row and move up you come out in the bottom row in the
+ same column. Horizontal wrap around moves to the next
+ (FocusMoveDirection::Right) or previous (FocusMoveDirection::Left) page. Moving to the right
+ from the last page goes to the first page and vice versa.
+ The current page index is set to the nearest valid
+ page index.
+ */
+ void MoveFocus(FocusMoveDirection eDirection);
+
+ /** Show the focus indicator of the current slide.
+ @param bScrollToFocus
+ When <TRUE/> (the default) then the view is scrolled so that the
+ focus rectangle lies inside its visible area.
+ */
+ void ShowFocus(const bool bScrollToFocus = true);
+
+ /** Hide the focus indicator.
+ */
+ void HideFocus();
+
+ /** Toggle the focused state of the current slide.
+ @return
+ Returns the focused state of the focus page after the call.
+ */
+ bool ToggleFocus();
+
+ /** Return whether the window managed by the called focus manager has
+ the input focus of the application.
+ */
+ bool HasFocus() const;
+
+ /** Return the descriptor of the page that currently has the focus.
+ @return
+ When there is no page that currently has the focus then NULL is
+ returned.
+ */
+ model::SharedPageDescriptor GetFocusedPageDescriptor() const;
+
+ /** Return the index of the page that currently has the focus as it is
+ accepted by the slide sorter model.
+ @return
+ When there is no page that currently has the focus then -1 is
+ returned.
+ */
+ sal_Int32 GetFocusedPageIndex() const { return mnPageIndex; }
+
+ /** Set the focused page to the one described by the given page
+ descriptor. The visibility of the focus indicator is not modified.
+ @param rDescriptor
+ One of the page descriptors that are currently managed by the
+ SlideSorterModel.
+ */
+ bool SetFocusedPage(const model::SharedPageDescriptor& rDescriptor);
+
+ /** Set the focused page to the one described by the given page
+ index. The visibility of the focus indicator is not modified.
+ @param nPageIndex
+ A valid page index that is understood by the SlideSorterModel.
+ */
+ void SetFocusedPage(sal_Int32 nPageIndex);
+
+ bool SetFocusedPageToCurrentPage();
+
+ /** Return <TRUE/> when the focus indicator is currently shown. A
+ prerequisite is that the window managed by this focus manager has
+ the input focus as indicated by a <TRUE/> return value of
+ HasFocus(). It is not necessary that the focus indicator is
+ visible. It may have been scrolled outside the visible area.
+ */
+ bool IsFocusShowing() const;
+
+ /** Add a listener that is called when the focus is shown or hidden or
+ set to another page object.
+ @param rListener
+ When this method is called multiple times for the same listener
+ the second and all following calls are ignored. Each listener
+ is added only once.
+ */
+ void AddFocusChangeListener(const Link<LinkParamNone*, void>& rListener);
+
+ /** Remove a focus change listener.
+ @param rListener
+ It is safe to pass a listener that was not added are has been
+ removed previously. Such calls are ignored.
+ */
+ void RemoveFocusChangeListener(const Link<LinkParamNone*, void>& rListener);
+
+ /** Create an instance of this class to temporarily hide the focus
+ indicator. It is restored to its former visibility state when the
+ FocusHider is destroyed.
+ */
+ class FocusHider
+ {
+ public:
+ FocusHider(FocusManager&);
+ ~FocusHider() COVERITY_NOEXCEPT_FALSE;
+
+ private:
+ bool mbFocusVisible;
+ FocusManager& mrManager;
+ };
+
+private:
+ SlideSorter& mrSlideSorter;
+
+ /** Index of the page that may be focused. It is -1 when the model
+ contains no page.
+ */
+ sal_Int32 mnPageIndex;
+
+ /** This flag indicates whether the page pointed to by mpFocusDescriptor
+ has the focus.
+ */
+ bool mbPageIsFocused;
+
+ ::std::vector<Link<LinkParamNone*, void>> maFocusChangeListeners;
+
+ /** Reset the focus state of the given descriptor and request a repaint
+ so that the focus indicator is hidden.
+ @param pDescriptor
+ When NULL is given then the call is ignored.
+ */
+ void HideFocusIndicator(const model::SharedPageDescriptor& rpDescriptor);
+
+ /** Set the focus state of the given descriptor, scroll it into the
+ visible area and request a repaint so that the focus indicator is
+ made visible.
+ @param pDescriptor
+ When NULL is given then the call is ignored.
+ @param bScrollToFocus
+ When <TRUE/> (the default) then the view is scrolled so that the
+ focus rectangle lies inside its visible area.
+ */
+ void ShowFocusIndicator(const model::SharedPageDescriptor& rpDescriptor,
+ const bool bScrollToFocus);
+
+ /** Call all currently registered listeners that a focus change has
+ happened. The focus may be hidden or shown or moved from one page
+ object to another.
+ */
+ void NotifyFocusChangeListeners() const;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx
new file mode 100644
index 000000000..43f2d2f6a
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsInsertionIndicatorHandler.hxx
@@ -0,0 +1,138 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <controller/SlsAnimator.hxx>
+
+#include <view/SlsLayouter.hxx>
+
+namespace sd::slidesorter { class SlideSorter; }
+namespace sd::slidesorter::view {
+class InsertAnimator;
+class InsertionIndicatorOverlay;
+}
+
+class SdTransferable;
+
+namespace sd::slidesorter::controller {
+
+/** Manage the visibility and location of the insertion indicator. Its
+ actual display is controlled by the InsertionIndicatorOverlay.
+*/
+class InsertionIndicatorHandler
+{
+public:
+ InsertionIndicatorHandler (SlideSorter& rSlideSorter);
+ ~InsertionIndicatorHandler() COVERITY_NOEXCEPT_FALSE;
+
+ enum Mode { CopyMode, MoveMode, UnknownMode };
+ static Mode GetModeFromDndAction (const sal_Int8 nDndAction);
+
+ /** Activate the insertion marker at the given coordinates.
+ */
+ void Start (const bool bIsOverSourceView);
+
+ /** Deactivate the insertion marker.
+ */
+ void End (const controller::Animator::AnimationMode eMode);
+
+ /** This context make sure that the insertion indicator is shown
+ (provided that the clipboard is not empty) while the context is
+ alive. Typically used while a context menu is displayed.
+ */
+ class ForceShowContext
+ {
+ public:
+ ForceShowContext (const std::shared_ptr<InsertionIndicatorHandler>& rpHandler);
+ ~ForceShowContext() COVERITY_NOEXCEPT_FALSE;
+ private:
+ const std::shared_ptr<InsertionIndicatorHandler> mpHandler;
+ };
+
+ /** Update the indicator icon from the current transferable (from the
+ clipboard or an active drag and drop operation.)
+ */
+ void UpdateIndicatorIcon (const SdTransferable* pTransferable);
+
+ /** Set the position of the insertion marker to the given coordinates.
+ */
+ void UpdatePosition (
+ const Point& rMouseModelPosition,
+ const Mode eMode);
+ void UpdatePosition (
+ const Point& rMouseModelPosition,
+ const sal_Int8 nDndAction);
+
+ /** Return whether the insertion marker is active.
+ */
+ bool IsActive() const { return mbIsActive;}
+
+ /** Return the insertion index that corresponds with the current
+ graphical location of the insertion indicator.
+ */
+ sal_Int32 GetInsertionPageIndex() const;
+
+ /** Determine whether moving the current selection to the current
+ position of the insertion marker would alter the document. This
+ would be the case when the selection is not consecutive or would be
+ moved to a position outside and not adjacent to the selection.
+ */
+ bool IsInsertionTrivial (
+ const sal_Int32 nInsertionIndex,
+ const Mode eMode) const;
+ /** This method is like the other variant. It operates implicitly
+ on the current insertion index as would be returned by
+ GetInsertionPageIndex().
+ */
+ bool IsInsertionTrivial (const sal_Int8 nDndAction);
+
+private:
+ SlideSorter& mrSlideSorter;
+ std::shared_ptr<view::InsertAnimator> mpInsertAnimator;
+ std::shared_ptr<view::InsertionIndicatorOverlay> mpInsertionIndicatorOverlay;
+ view::InsertPosition maInsertPosition;
+ Mode meMode;
+ bool mbIsInsertionTrivial;
+ bool mbIsActive;
+ bool mbIsReadOnly;
+ bool mbIsOverSourceView;
+ Size maIconSize;
+ bool mbIsForcedShow;
+
+ void SetPosition (
+ const Point& rPoint,
+ const Mode eMode);
+ std::shared_ptr<view::InsertAnimator> const & GetInsertAnimator();
+
+ /** Make the insertion indicator visible (that is the show part) and
+ keep it visible, even when the mouse leaves the window (that is the
+ force part). We need this when a context menu is displayed (mouse
+ over the popup menu triggers a mouse leave event) while the
+ insertion indicator remains visible in the background.
+
+ In effect all calls to End() are ignored until ForceEnd() is called.
+ */
+ void ForceShow();
+ void ForceEnd();
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx
new file mode 100644
index 000000000..6a4b75004
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsPageSelector.hxx
@@ -0,0 +1,219 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+
+#include <vector>
+#include <memory>
+
+#include <sddllapi.h>
+
+class SdPage;
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+namespace sd::slidesorter::model
+{
+class SlideSorterModel;
+}
+
+namespace sd::slidesorter::controller
+{
+class SlideSorterController;
+
+/** A sub-controller that handles page selection of the slide browser.
+ Selecting a page does not make it the current page (of the main view)
+ automatically as this would not be desired in a multi selection. This
+ has to be done explicitly by calling the
+ CurrentSlideManager::SetCurrentSlide() method.
+
+ Indices of pages relate always to the number of all pages in the model
+ (as returned by GetPageCount()) not just the selected pages.
+*/
+class PageSelector
+{
+public:
+ explicit PageSelector(SlideSorter& rSlideSorter);
+ PageSelector(const PageSelector&) = delete;
+ PageSelector& operator=(const PageSelector&) = delete;
+
+ // Exported for unit test
+ SD_DLLPUBLIC void SelectAllPages();
+ SD_DLLPUBLIC void DeselectAllPages();
+
+ /** Update the selection state of all page descriptors to be the same as
+ that of the corresponding pages of the SdPage objects and issue
+ redraw requests where necessary.
+ */
+ void GetCoreSelection();
+
+ /** Update the selection state of the SdPage objects to be the same as
+ that of the corresponding page descriptors.
+ */
+ void SetCoreSelection();
+
+ /** Select the specified descriptor. The selection state of the other
+ descriptors is not affected.
+ */
+ void SelectPage(int nPageIndex);
+ /** Select the descriptor that is associated with the given page. The
+ selection state of the other descriptors is not affected.
+ */
+ void SelectPage(const SdPage* pPage);
+ /** Select the specified descriptor. The selection state of the other
+ descriptors is not affected.
+ */
+ void SelectPage(const model::SharedPageDescriptor& rpDescriptor);
+
+ /** Return whether the specified page is selected. This convenience
+ method is a substitute for
+ SlideSorterModel::GetPageDescriptor(i)->HasState(ST_Selected) is
+ included here to make this class more self contained.
+ */
+ SD_DLLPUBLIC bool IsPageSelected(int nPageIndex);
+
+ /** Return whether the specified page is visible. This convenience
+ method is a substitute for
+ SlideSorterModel::GetPageDescriptor(i)->HasState(ST_Visible) is
+ included here to make this class more self contained.
+ */
+ bool IsPageVisible(int nPageIndex);
+
+ /** Deselect the descriptor that is associated with the given page.
+ The current page is updated to the first slide
+ of the remaining selection.
+ */
+ void DeselectPage(int nPageIndex);
+ void DeselectPage(const model::SharedPageDescriptor& rpDescriptor,
+ const bool bUpdateCurrentPage = true);
+
+ /** This convenience method returns the same number of pages that
+ SlideSorterModel.GetPageCount() returns. It is included here so
+ that it is self contained for iterating over all pages to select or
+ deselect them.
+ */
+ int GetPageCount() const;
+ int GetSelectedPageCount() const { return mnSelectedPageCount; }
+
+ /** Return the anchor for a range selection. This usually is the first
+ selected page after all pages have been deselected.
+ @return
+ The returned anchor may be NULL.
+ */
+ const model::SharedPageDescriptor& GetSelectionAnchor() const { return mpSelectionAnchor; }
+
+ typedef ::std::vector<SdPage*> PageSelection;
+
+ /** Return an object that describes the current selection. The caller
+ can use that object to later restore the selection.
+ @return
+ The object returned describes the selection via indices. So
+ even if pages are exchanged a later call to SetPageSelection()
+ is valid.
+ */
+ std::shared_ptr<PageSelection> GetPageSelection() const;
+
+ /** Restore a page selection according to the given selection object.
+ @param rSelection
+ Typically obtained by calling GetPageSelection() this object
+ is used to restore the selection. If pages were exchanged since
+ the last call to GetPageSelection() it is still valid to call
+ this method with the selection. When pages have been inserted
+ or removed the result may be unexpected.
+ @param bUpdateCurrentPage
+ When <TRUE/> (the default value) then after setting the
+ selection update the current page to the first page of the
+ selection.
+ When called from within UpdateCurrentPage() then this flag is
+ used to prevent a recursion loop.
+ */
+ void SetPageSelection(const std::shared_ptr<PageSelection>& rSelection,
+ const bool bUpdateCurrentPage);
+
+ /** Call this method after the model has changed to set the number
+ of selected pages.
+ */
+ void CountSelectedPages();
+
+ /** Use the UpdateLock whenever you do a complex selection, i.e. call
+ more than one method in a row. An active lock prevents intermediate
+ changes of the current slide.
+ */
+ class UpdateLock
+ {
+ public:
+ UpdateLock(SlideSorter const& rSlideSorter);
+ UpdateLock(PageSelector& rPageSelector);
+ ~UpdateLock();
+ void Release();
+
+ private:
+ PageSelector* mpSelector;
+ };
+
+ class BroadcastLock
+ {
+ public:
+ BroadcastLock(SlideSorter const& rSlideSorter);
+ BroadcastLock(PageSelector& rPageSelector);
+ ~BroadcastLock();
+
+ private:
+ PageSelector& mrSelector;
+ };
+
+private:
+ model::SlideSorterModel& mrModel;
+ SlideSorter& mrSlideSorter;
+ SlideSorterController& mrController;
+ int mnSelectedPageCount;
+ int mnBroadcastDisableLevel;
+ bool mbSelectionChangeBroadcastPending;
+ model::SharedPageDescriptor mpMostRecentlySelectedPage;
+ /// Anchor for a range selection.
+ model::SharedPageDescriptor mpSelectionAnchor;
+ sal_Int32 mnUpdateLockCount;
+ bool mbIsUpdateCurrentPagePending;
+
+ /** Enable the broadcasting of selection change events. This calls the
+ SlideSorterController::SelectionHasChanged() method to do the actual
+ work. When EnableBroadcasting has been called as many times as
+ DisableBroadcasting() was called before and the selection has been
+ changed in the meantime, this change will be broadcasted.
+ */
+ void EnableBroadcasting();
+
+ /** Disable the broadcasting of selection change events. Subsequent
+ changes of the selection will set a flag that triggers the sending
+ of events when EnableBroadcasting() is called.
+ */
+ void DisableBroadcasting();
+
+ void UpdateCurrentPage(const bool bUpdateOnlyWhenPending = false);
+
+ void CheckConsistency() const;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx
new file mode 100644
index 000000000..344ac67f3
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsProperties.hxx
@@ -0,0 +1,125 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <tools/color.hxx>
+
+namespace sd::slidesorter::controller
+{
+/** An extensible set of properties used throughout the slide sorter.
+*/
+class Properties
+{
+public:
+ Properties();
+
+ /** Call this method after receiving a VclEventId::ApplicationDataChanged
+ event.
+ */
+ void HandleDataChangeEvent();
+
+ /** When this method returns <TRUE/> then the current slide is
+ highlighted in the view. The default value is <FALSE/>.
+ */
+ bool IsHighlightCurrentSlide() const { return mbIsHighlightCurrentSlide; }
+ void SetHighlightCurrentSlide(const bool bIsHighlightCurrentSlide);
+
+ /** When this method returns <TRUE/> then the selection is indicated in
+ the view (typically by drawing rectangles around the selected
+ slides.) The default value is <TRUE/>.
+ */
+ bool IsShowSelection() const { return mbIsShowSelection; }
+ void SetShowSelection(const bool bIsShowSelection);
+
+ /** When this method returns <TRUE/> then the focusdselection is indicated in
+ the view (typically by drawing dotted rectangles around the selected
+ slides.) The default value is <TRUE/>.
+ */
+ bool IsShowFocus() const { return mbIsShowFocus; }
+ void SetShowFocus(const bool bIsShowFocus);
+
+ /** When this method returns <TRUE/> then on a selection change the
+ visible area is adapted so that the selected slides are shown
+ centered in the view. This can be used to center the current slide
+ by selecting only the current slide. The default value is <FALSE/>.
+ */
+ bool IsCenterSelection() const { return mbIsCenterSelection; }
+ void SetCenterSelection(const bool bIsCenterSelection);
+
+ /** When this method returns <TRUE/> then the view may try to change the
+ visible area by scrolling it smoothly on the screen. Experimental.
+ Default value is <FALSE/>.
+ */
+ bool IsSmoothSelectionScrolling() const { return mbIsSmoothSelectionScrolling; }
+ void SetSmoothSelectionScrolling(const bool bIsSmoothSelectionScrolling);
+
+ /** When this method returns <TRUE/> then during a full screen
+ presentation the previews in a slide sorter are not updated.
+ Default value is <TRUE/>.
+ */
+ bool IsSuspendPreviewUpdatesDuringFullScreenPresentation() const
+ {
+ return mbIsSuspendPreviewUpdatesDuringFullScreenPresentation;
+ }
+ void SetSuspendPreviewUpdatesDuringFullScreenPresentation(const bool bFlag);
+
+ /** Return the background color.
+ */
+ const Color& GetBackgroundColor() const { return maBackgroundColor; }
+ void SetBackgroundColor(const Color& rColor);
+
+ /** Return the text color.
+ */
+ const Color& GetTextColor() const { return maTextColor; }
+ void SetTextColor(const Color& rColor);
+
+ /** Return the color in which selections are to be painted.
+ */
+ const Color& GetSelectionColor() const { return maSelectionColor; }
+ void SetSelectionColor(const Color& rColor);
+
+ /** Return the color used for highlighting e.g. the current slide.
+ */
+ const Color& GetHighlightColor() const { return maHighlightColor; }
+ void SetHighlightColor(const Color& rColor);
+
+ /** The UI can be set to be read only independently from the model status.
+ Used for instance in the presenter view.
+ */
+ bool IsUIReadOnly() const { return mbIsUIReadOnly; }
+ void SetUIReadOnly(const bool bIsUIReadOnly);
+
+private:
+ bool mbIsHighlightCurrentSlide;
+ bool mbIsShowSelection;
+ bool mbIsShowFocus;
+ bool mbIsCenterSelection;
+ bool mbIsSmoothSelectionScrolling;
+ bool mbIsSuspendPreviewUpdatesDuringFullScreenPresentation;
+ Color maBackgroundColor;
+ Color maTextColor;
+ Color maSelectionColor;
+ Color maHighlightColor;
+ bool mbIsUIReadOnly;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx
new file mode 100644
index 000000000..853d98f4a
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsScrollBarManager.hxx
@@ -0,0 +1,248 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <tools/link.hxx>
+#include <tools/gen.hxx>
+#include <vcl/timer.hxx>
+#include <vcl/scrbar.hxx>
+#include <vcl/vclptr.hxx>
+
+#include <functional>
+
+namespace sd { class Window; }
+
+namespace sd::slidesorter { class SlideSorter; }
+
+namespace sd::slidesorter::controller {
+
+/** Manage the horizontal and vertical scroll bars. Listen for events, set
+ their sizes, place them in the window, determine their visibilities.
+
+ <p>Handle auto scrolling, i.e. the scrolling of the window when the
+ mouse comes near the window border while dragging a selection.</p>
+
+ <p>In order to make the slide sorter be used in the task pane with its
+ own vertical scrollbars the vertical scrollbar of the use of the slide
+ sorter is optional. When using it the available area in a window is
+ used and the vertical scrollbar is displayed when that area is not large
+ enough. When the vertical scrollbar is not used then the available area
+ is assumed to be modifiable. In that case the PlaceScrollBars() method
+ may return an area larger than the one given.<p>
+*/
+class ScrollBarManager
+{
+public:
+ /** Create a new scroll bar manager that manages three controls: the
+ horizontal scroll bar, the vertical scroll bar, and the little
+ window that fills the gap at the bottom right corner that is left
+ between the two scroll bars. Call LateInitialization() after
+ constructing a new object.
+ */
+ ScrollBarManager (SlideSorter& rSlideSorter);
+
+ ~ScrollBarManager();
+
+ /** Register listeners at the scroll bars. This method is called after
+ startup of a new slide sorter object or after a reactivation of a
+ slide sorter that for example is taken from a cache.
+ */
+ void Connect();
+
+ /** Remove listeners from the scroll bars. This method is called when
+ the slide sorter is destroyed or when it is suspended, e.g. put
+ into a cache for later reuse.
+ */
+ void Disconnect();
+
+ /** Set up the scroll bar, i.e. thumb size and position. Call this
+ method when the content of the browser window changed, i.e. pages
+ were inserted or deleted, the layout or the zoom factor has
+ changed.
+ @param bScrollToCurrentPosition
+ When <TRUE/> then scroll the window to the new offset that is
+ defined by the scroll bars. Otherwise the new offset is simply
+ set and the whole window is repainted.
+ */
+ void UpdateScrollBars (
+ bool bScrollToCurrentPosition);
+
+ /** Place the scroll bars inside the given area. When the available
+ area is not large enough for the content to display the horizontal
+ and/or vertical scroll bar is enabled.
+ @param rAvailableArea
+ The scroll bars will be placed inside this rectangle. It is
+ expected to be given in pixel relative to its parent.
+ @param bIsHorizontalScrollBarAllowed
+ Only when this flag is <TRUE/> the horizontal scroll may be
+ displayed.
+ @param bIsVerticalScrollBarAllowed
+ Only when this flag is <TRUE/> the horizontal scroll may be
+ displayed.
+ @return
+ Returns the space that remains after the scroll bars are
+ placed.
+ */
+ ::tools::Rectangle PlaceScrollBars (
+ const ::tools::Rectangle& rAvailableArea,
+ const bool bIsHorizontalScrollBarAllowed,
+ const bool bIsVerticalScrollBarAllowed);
+
+ /** Update the vertical and horizontal scroll bars so that the visible
+ area has the given top and left values.
+ */
+ void SetTopLeft (const Point& rNewTopLeft);
+
+ /** Return the width of the vertical scroll bar, which--when
+ shown--should be fixed in contrast to its height.
+ @return
+ Returns 0 when the vertical scroll bar is not shown or does not
+ exist, otherwise its width in pixel is returned.
+ */
+ int GetVerticalScrollBarWidth() const;
+
+ /** Return the height of the horizontal scroll bar, which--when
+ shown--should be fixed in contrast to its width.
+ @return
+ Returns 0 when the vertical scroll bar is not shown or does not
+ exist, otherwise its height in pixel is returned.
+ */
+ int GetHorizontalScrollBarHeight() const;
+
+ /** Call this method to scroll a window while the mouse is in dragging a
+ selection. If the mouse is near the window border or is outside the
+ window then scroll the window accordingly.
+ @param rMouseWindowPosition
+ The mouse position for which the scroll amount is calculated.
+ @param rAutoScrollFunctor
+ Every time when the window is scrolled then this functor is executed.
+ @return
+ When the window is scrolled then this method returns <TRUE/>.
+ When the window is not changed then <FALSE/> is returned.
+ */
+ bool AutoScroll (
+ const Point& rMouseWindowPosition,
+ const ::std::function<void ()>& rAutoScrollFunctor);
+
+ void StopAutoScroll();
+
+ void clearAutoScrollFunctor();
+
+ enum Orientation { Orientation_Horizontal, Orientation_Vertical };
+ /** Scroll the slide sorter by setting the thumbs of the scroll bars and
+ by moving the content of the content window.
+ @param eOrientation
+ Defines whether to scroll horizontally or vertically.
+ @param nDistance
+ distance in slides.
+ */
+ void Scroll(
+ const Orientation eOrientation,
+ const sal_Int32 nDistance);
+
+private:
+ SlideSorter& mrSlideSorter;
+
+ /** The horizontal scroll bar. Note that is used but not owned by
+ objects of this class. It is given to the constructor.
+ */
+ VclPtr<ScrollBar> mpHorizontalScrollBar;
+
+ /** The vertical scroll bar. Note that is used but not owned by
+ objects of this class. It is given to the constructor.
+ */
+ VclPtr<ScrollBar> mpVerticalScrollBar;
+
+ /// Relative horizontal position of the visible area in the view.
+ double mnHorizontalPosition;
+ /// Relative vertical position of the visible area in the view.
+ double mnVerticalPosition;
+ /** The width and height of the border at the inside of the window which
+ when entered while in drag mode leads to a scrolling of the window.
+ */
+ Size maScrollBorder;
+ /** The only task of this little window is to paint the little square at
+ the bottom right corner left by the two scroll bars (when both are
+ visible).
+ */
+ VclPtr<ScrollBarBox> mpScrollBarFiller;
+
+ /** The auto scroll timer is used for keep scrolling the window when the
+ mouse reaches its border while dragging a selection. When the mouse
+ is not moved the timer issues events to keep scrolling.
+ */
+ Timer maAutoScrollTimer;
+ Size maAutoScrollOffset;
+ bool mbIsAutoScrollActive;
+
+ /** The content window is the one whose view port is controlled by the
+ scroll bars.
+ */
+ VclPtr<sd::Window> mpContentWindow;
+
+ ::std::function<void ()> maAutoScrollFunctor;
+
+ void SetWindowOrigin (
+ double nHorizontalPosition,
+ double nVerticalPosition);
+
+ /** Determine the visibility of the scroll bars so that the window
+ content is not clipped in any dimension without showing a scroll
+ bar.
+ @param rAvailableArea
+ The area in which the scroll bars, the scroll bar filler, and
+ the SlideSorterView will be placed.
+ @return
+ The area that is enclosed by the scroll bars is returned. It
+ will be filled with the SlideSorterView.
+ */
+ ::tools::Rectangle DetermineScrollBarVisibilities(
+ const ::tools::Rectangle& rAvailableArea,
+ const bool bIsHorizontalScrollBarAllowed,
+ const bool bIsVerticalScrollBarAllowed);
+
+ /** Typically called by DetermineScrollBarVisibilities() this method
+ tests a specific configuration of the two scroll bars being visible
+ or hidden.
+ @return
+ When the window content can be shown with only being clipped in
+ an orientation where the scroll bar would be shown then <TRUE/>
+ is returned.
+ */
+ bool TestScrollBarVisibilities (
+ bool bHorizontalScrollBarVisible,
+ bool bVerticalScrollBarVisible,
+ const ::tools::Rectangle& rAvailableArea);
+
+ void CalcAutoScrollOffset (const Point& rMouseWindowPosition);
+ bool RepeatAutoScroll();
+
+ DECL_LINK(HorizontalScrollBarHandler, ScrollBar*, void);
+ DECL_LINK(VerticalScrollBarHandler, ScrollBar*, void);
+ DECL_LINK(AutoScrollTimeoutHandler, Timer *, void);
+
+ void PlaceHorizontalScrollBar (const ::tools::Rectangle& aArea);
+ void PlaceVerticalScrollBar (const ::tools::Rectangle& aArea);
+ void PlaceFiller (const ::tools::Rectangle& aArea);
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx
new file mode 100644
index 000000000..7d80fbd26
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionFunction.hxx
@@ -0,0 +1,145 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <controller/SlsFocusManager.hxx>
+#include <fupoor.hxx>
+#include <memory>
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+struct AcceptDropEvent;
+
+namespace sd::slidesorter::controller
+{
+class SlideSorterController;
+
+class SelectionFunction final : public FuPoor
+{
+public:
+ SelectionFunction(const SelectionFunction&) = delete;
+ SelectionFunction& operator=(const SelectionFunction&) = delete;
+
+ static rtl::Reference<FuPoor> Create(SlideSorter& rSlideSorter, SfxRequest& rRequest);
+
+ // Mouse- & Key-Events
+ virtual bool KeyInput(const KeyEvent& rKEvt) override;
+ virtual bool MouseMove(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonUp(const MouseEvent& rMEvt) override;
+ virtual bool MouseButtonDown(const MouseEvent& rMEvt) override;
+
+ /// Forward to the clipboard manager.
+ virtual void DoCut() override;
+
+ /// Forward to the clipboard manager.
+ virtual void DoCopy() override;
+
+ /// Forward to the clipboard manager.
+ virtual void DoPaste() override;
+
+ /** is called when the current function should be aborted. <p>
+ This is used when a function gets a KEY_ESCAPE but can also
+ be called directly.
+
+ @returns
+ true if an active function was aborted
+ */
+ virtual bool cancel() override;
+
+ void MouseDragged(const AcceptDropEvent& rEvent, const sal_Int8 nDragAction);
+
+ /** Turn of substitution display and insertion indicator.
+ */
+ void NotifyDragFinished();
+
+ class EventDescriptor;
+ class ModeHandler;
+ friend class ModeHandler;
+ enum Mode
+ {
+ NormalMode,
+ MultiSelectionMode,
+ DragAndDropMode
+ };
+ void SwitchToNormalMode();
+ void SwitchToDragAndDropMode(const Point& rMousePosition);
+ void SwitchToMultiSelectionMode(const Point& rMousePosition, const sal_uInt32 nEventCode);
+
+ void ResetShiftKeySelectionAnchor();
+ /** Special case handling for when the context menu is hidden. This
+ method will reinitialize the current mouse position to prevent the
+ mouse motion during the time the context menu is displayed from
+ being interpreted as drag-and-drop start.
+ */
+ void ResetMouseAnchor();
+
+private:
+ SlideSorter& mrSlideSorter;
+ SlideSorterController& mrController;
+
+ SelectionFunction(SlideSorter& rSlideSorter, SfxRequest& rRequest);
+
+ virtual ~SelectionFunction() override;
+
+ /** Remember the slide where the shift key was pressed and started a
+ multiselection via keyboard.
+ */
+ sal_Int32 mnShiftKeySelectionAnchor;
+
+ /** The selection function can be in one of several mutually
+ exclusive modes.
+ */
+ std::shared_ptr<ModeHandler> mpModeHandler;
+
+ /** Make the slide nOffset slides away of the current one the new
+ current slide. When the new index is outside the range of valid
+ page numbers it is clipped to that range.
+ @param nOffset
+ When nOffset is negative then go back. When nOffset if positive go
+ forward. When it is zero then ignore the call.
+ */
+ void GotoNextPage(int nOffset);
+
+ /** Make the slide with the given index the new current slide.
+ @param nIndex
+ Index of the new current slide. When the new index is outside
+ the range of valid page numbers it is clipped to that range.
+ */
+ void GotoPage(int nIndex);
+
+ void ProcessMouseEvent(sal_uInt32 nEventType, const MouseEvent& rEvent);
+
+ // What follows are a couple of helper methods that are used by
+ // ProcessMouseEvent().
+
+ void ProcessEvent(EventDescriptor& rEvent);
+
+ void MoveFocus(const FocusManager::FocusMoveDirection eDirection, const bool bIsShiftDown,
+ const bool bIsControlDown);
+
+ void SwitchMode(const std::shared_ptr<ModeHandler>& rpHandler);
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx
new file mode 100644
index 000000000..4f52d49e6
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionManager.hxx
@@ -0,0 +1,139 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <tools/link.hxx>
+#include <vector>
+#include <memory>
+
+class SdPage;
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::controller
+{
+class SlideSorterController;
+class SelectionObserver;
+
+/** This class is a part of the controller and handles the selection of
+ slides.
+ <p>It has methods to modify the selected slides (delete them or
+ move them to other places in the document), change the visible area so
+ to make the selected slides visible, tell listeners when the selection
+ changes.</p>
+*/
+class SelectionManager
+{
+public:
+ /** Create a new SelectionManager for the given slide sorter.
+ */
+ SelectionManager(SlideSorter& rSlideSorter);
+
+ ~SelectionManager();
+
+ /** Delete the currently selected slides. When this method returns the
+ selection is empty.
+ @param bSelectFollowingPage
+ When <TRUE/> then after deleting the selected pages make the
+ slide after the last selected page the new current page.
+ When <FALSE/> then make the first slide before the selected
+ pages the new current slide.
+ */
+ void DeleteSelectedPages(const bool bSelectFollowingPage = true);
+
+ /** Call this method after the selection has changed (possible several
+ calls to the PageSelector) to invalidate the relevant slots and send
+ appropriate events.
+ */
+ void SelectionHasChanged();
+
+ /** Add a listener that is called when the selection of the slide sorter
+ changes.
+ @param rListener
+ When this method is called multiple times for the same listener
+ the second and all following calls are ignored. Each listener
+ is added only once.
+ */
+ void AddSelectionChangeListener(const Link<LinkParamNone*, void>& rListener);
+
+ /** Remove a listener that was called when the selection of the slide
+ sorter changes.
+ @param rListener
+ It is safe to pass a listener that was not added are has been
+ removed previously. Such calls are ignored.
+ */
+ void RemoveSelectionChangeListener(const Link<LinkParamNone*, void>& rListener);
+
+ /** Return the position where to insert pasted slides based on the
+ current selection. When there is a selection then the insert
+ position is behind the last slide. When the selection is empty then
+ most of the time the insert position is at the end of the document.
+ There is an exception right after the display of a popup-menu. The
+ position of the associated insertion marker is stored here and reset
+ the next time the selection changes.
+ */
+ sal_Int32 GetInsertionPosition() const;
+
+ /** Store an insertion position temporarily. It is reset when the
+ selection changes the next time.
+ */
+ void SetInsertionPosition(const sal_Int32 nInsertionPosition);
+
+ const std::shared_ptr<SelectionObserver>& GetSelectionObserver() const
+ {
+ return mpSelectionObserver;
+ }
+
+private:
+ SlideSorter& mrSlideSorter;
+ SlideSorterController& mrController;
+
+ ::std::vector<Link<LinkParamNone*, void>> maSelectionChangeListeners;
+
+ /** The insertion position is only temporarily valid. Negative values
+ indicate that the explicit insertion position is not valid. In this
+ case GetInsertionPosition() calculates it from the current selection.
+ */
+ sal_Int32 mnInsertionPosition;
+
+ std::shared_ptr<SelectionObserver> mpSelectionObserver;
+
+ /** Delete the given list of normal pages. This method is a helper
+ function for DeleteSelectedPages().
+ @param rSelectedNormalPages
+ A list of normal pages. Supplying master pages is an error.
+ */
+ void DeleteSelectedNormalPages(const ::std::vector<SdPage*>& rSelectedNormalPages);
+
+ /** Delete the given list of master pages. This method is a helper
+ function for DeleteSelectedPages().
+ @param rSelectedMasterPages
+ A list of master pages. Supplying normal pages is an error.
+ */
+ void DeleteSelectedMasterPages(const ::std::vector<SdPage*>& rSelectedMasterPages);
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx
new file mode 100644
index 000000000..11742b890
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsSelectionObserver.hxx
@@ -0,0 +1,77 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <memory>
+#include <vector>
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+class SdrPage;
+class SdPage;
+
+namespace sd::slidesorter::controller
+{
+/** Observe insertions and deletions of pages between calls to
+ StartObservation() and EndObservation(). When the later is called
+ the selection is set to just the newly inserted pages.
+*/
+class SelectionObserver final
+{
+public:
+ SelectionObserver(SlideSorter& rSlideSorter);
+ ~SelectionObserver();
+
+ void NotifyPageEvent(const SdrPage* pPage);
+ void StartObservation();
+ void AbortObservation();
+ void EndObservation();
+
+ /** Use this little class instead of calling StartObservation and
+ EndObservation directly so that EndObservation is not forgotten or
+ omitted due to an exception or some break or return in the middle of
+ code.
+ */
+ class Context
+ {
+ public:
+ Context(SlideSorter const& rSlideSorter);
+ ~Context() COVERITY_NOEXCEPT_FALSE;
+ void Abort();
+
+ private:
+ std::shared_ptr<SelectionObserver> mpSelectionObserver;
+ };
+
+private:
+ SlideSorter& mrSlideSorter;
+ bool mbIsObservationActive;
+ bool mbPageEventOccurred;
+
+ ::std::vector<const SdPage*> maInsertedPages;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx
new file mode 100644
index 000000000..57de8422a
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsSlotManager.hxx
@@ -0,0 +1,98 @@
+/* -*- 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 .
+ */
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <tools/link.hxx>
+#include <rtl/ustring.hxx>
+
+class AbstractSvxNameDialog;
+class SfxItemSet;
+class SfxRequest;
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::controller
+{
+/** This manager takes over the work of handling slot calls from the
+ controller of the slide sorter.
+*/
+class SlotManager
+{
+public:
+ /** Create a new slot manager that handles slot calls for the controller
+ of a slide sorter.
+ @param rController
+ The controller for which to handle the slot calls.
+ */
+ SlotManager(SlideSorter& rSlideSorter);
+
+ void FuTemporary(SfxRequest& rRequest);
+ void FuPermanent(SfxRequest& rRequest);
+ void FuSupport(SfxRequest& rRequest);
+ void GetMenuState(SfxItemSet& rSet);
+ void GetClipboardState(SfxItemSet& rSet);
+ void GetStatusBarState(SfxItemSet& rSet);
+ void ExecCtrl(SfxRequest& rRequest);
+ void GetAttrState(SfxItemSet& rSet);
+
+ /** Exclude or include one slide or all selected slides.
+ @param rpDescriptor
+ When the pointer is empty then apply the new state to all
+ selected pages. Otherwise apply the new state to just the
+ specified state.
+ */
+ void ChangeSlideExclusionState(const model::SharedPageDescriptor& rpDescriptor,
+ const bool bExcludeSlide);
+
+ /** Call this after a change from normal mode to master mode or back.
+ The affected slots are invalidated.
+ */
+ void NotifyEditModeChange();
+
+private:
+ /// The controller for which we manage the slot calls.
+ SlideSorter& mrSlideSorter;
+
+ /** The implementation is a copy of the code for SID_RENAMEPAGE in
+ drviews2.cxx.
+ */
+ void RenameSlide(const SfxRequest& rRequest);
+ DECL_LINK(RenameSlideHdl, AbstractSvxNameDialog&, bool);
+ DECL_STATIC_LINK(SlotManager, RenameSlideTooltipHdl, AbstractSvxNameDialog&, OUString);
+ bool RenameSlideFromDrawViewShell(sal_uInt16 nPageId, const OUString& rName);
+
+ /** Handle SID_INSERTPAGE slot calls.
+ */
+ void InsertSlide(SfxRequest& rRequest);
+
+ void DuplicateSelectedSlides(SfxRequest& rRequest);
+
+ /** Use one of several ways to determine where to insert a new page.
+ This can be the current selection or the insertion indicator.
+ */
+ sal_Int32 GetInsertionPosition() const;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsTransferableData.hxx b/sd/source/ui/slidesorter/inc/controller/SlsTransferableData.hxx
new file mode 100644
index 000000000..863c2fe73
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsTransferableData.hxx
@@ -0,0 +1,78 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sdxfer.hxx>
+
+#include <vcl/bitmapex.hxx>
+
+#include <vector>
+
+class SdDrawDocument;
+namespace sd::slidesorter { class SlideSorterViewShell; }
+
+namespace sd::slidesorter::controller {
+
+/** Represent previews and other information so that they can be
+ attached to an existing transferable.
+*/
+class TransferableData final
+ : public SdTransferable::UserData,
+ public SfxListener
+{
+public:
+ class Representative
+ {
+ public:
+ Representative (const BitmapEx& rBitmap, const bool bIsExcluded)
+ : maBitmap(rBitmap), mbIsExcluded(bIsExcluded) {}
+
+ BitmapEx maBitmap;
+ bool mbIsExcluded;
+ };
+
+ static rtl::Reference<SdTransferable> CreateTransferable (
+ SdDrawDocument* pSrcDoc,
+ SlideSorterViewShell* pViewShell,
+ ::std::vector<TransferableData::Representative>&& rRepresentatives);
+
+ static std::shared_ptr<TransferableData> GetFromTransferable (const SdTransferable* pTransferable);
+
+ TransferableData (
+ SlideSorterViewShell* pViewShell,
+ ::std::vector<TransferableData::Representative>&& rRepresentatives);
+ virtual ~TransferableData() override;
+
+ const ::std::vector<Representative>& GetRepresentatives() const { return maRepresentatives;}
+
+ /** Return the view shell for which the transferable was created.
+ */
+ SlideSorterViewShell* GetSourceViewShell() const { return mpViewShell;}
+
+private:
+ SlideSorterViewShell* mpViewShell;
+ const ::std::vector<Representative> maRepresentatives;
+
+ virtual void Notify (SfxBroadcaster& rBroadcaster, const SfxHint& rHint) override;
+};
+
+} // end of namespace ::sd::slidesorter::controller
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx
new file mode 100644
index 000000000..d9f5845af
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/controller/SlsVisibleAreaManager.hxx
@@ -0,0 +1,90 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <optional>
+#include <tools/gen.hxx>
+#include <vector>
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::controller
+{
+/** Manage requests for scrolling page objects into view.
+*/
+class VisibleAreaManager
+{
+public:
+ explicit VisibleAreaManager(SlideSorter& rSlideSorter);
+ ~VisibleAreaManager();
+ VisibleAreaManager(const VisibleAreaManager&) = delete;
+ VisibleAreaManager& operator=(const VisibleAreaManager&) = delete;
+
+ void ActivateCurrentSlideTracking();
+ void DeactivateCurrentSlideTracking();
+ bool IsCurrentSlideTrackingActive() const { return mbIsCurrentSlideTrackingActive; }
+
+ /** Request the current slide to be moved into the visible area.
+ This request is only obeyed when the current slide tracking is
+ active.
+ @see ActivateCurrentSlideTracking() and DeactivateCurrentSlideTracking()
+ */
+ void RequestCurrentSlideVisible();
+
+ /** Request to make the specified page object visible.
+ */
+ void RequestVisible(const model::SharedPageDescriptor& rpDescriptor, const bool bForce = false);
+
+ /** Temporarily disable the update of the visible area.
+ */
+ class TemporaryDisabler
+ {
+ public:
+ explicit TemporaryDisabler(SlideSorter const& rSlideSorter);
+ ~TemporaryDisabler();
+
+ private:
+ VisibleAreaManager& mrVisibleAreaManager;
+ };
+
+private:
+ SlideSorter& mrSlideSorter;
+
+ /** List of rectangle that someone wants to be moved into the visible
+ area.
+ Cleared on every call to ForgetVisibleRequests() and MakeVisible().
+ */
+ ::std::vector<::tools::Rectangle> maVisibleRequests;
+
+ Point maRequestedVisibleTopLeft;
+ bool mbIsCurrentSlideTrackingActive;
+ int mnDisableCount;
+
+ void MakeVisible();
+ ::std::optional<Point> GetRequestedTopLeft() const;
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx
new file mode 100644
index 000000000..90223a1bc
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlideSorterModel.hxx
@@ -0,0 +1,227 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <pres.hxx>
+#include <osl/mutex.hxx>
+#include <vcl/region.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+#include <vector>
+
+class SdDrawDocument;
+class SdrPage;
+class SdPage;
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+namespace com::sun::star::container
+{
+class XIndexAccess;
+}
+namespace com::sun::star::drawing
+{
+class XDrawPage;
+}
+
+namespace sd::slidesorter::model
+{
+inline sal_Int32 FromCoreIndex(const sal_uInt16 nCoreIndex) { return (nCoreIndex - 1) / 2; }
+
+/** The model of the slide sorter gives access to the slides that are to be
+ displayed in the slide sorter view. Via the SetDocumentSlides() method
+ this set of slides can be modified (but do not call it directly, use
+ SlideSorterController::SetDocumentSlides() instead.)
+*/
+class SlideSorterModel final
+{
+public:
+ SlideSorterModel(SlideSorter& rSlideSorter);
+
+ ~SlideSorterModel();
+ void Dispose();
+
+ /** This method is present to let the view create a ShowView for
+ displaying slides.
+ */
+ SdDrawDocument* GetDocument();
+
+ /** Set a new edit mode and return whether the edit mode really
+ has been changed. When the edit mode is changed then the
+ previous page descriptor list is replaced by a new one which
+ has to be repainted.
+ @return
+ A return value of <TRUE/> indicates that the edit mode has
+ changed and thus the page descriptor list has been set up
+ to reflect that change. A repaint is necessary.
+ */
+ bool SetEditMode(EditMode eEditMode);
+
+ EditMode GetEditMode() const { return meEditMode; }
+
+ /** Return the number of slides in the document regardless of whether
+ they are visible or not or whether they are hidden or not.
+ The number of slides depends on the set of slides available through
+ the XIndexAccess given to SetDocumentSlides().
+ */
+ sal_Int32 GetPageCount() const;
+
+ /** Return a page descriptor for the page with the specified index.
+ Page descriptors are created on demand. The page descriptor is
+ found (or not found) in constant time.
+ @param nPageIndex
+ The index of the requested slide. The valid values
+ are 0 to GetPageCount()-1.
+ @param bCreate
+ When <TRUE/> and the requested page descriptor is missing then
+ it is created. When <FALSE/> then an empty reference is
+ returned for missing descriptors.
+ @return
+ When the given index is not valid, i.e. lower than zero or
+ larger than or equal to the number of pages then an empty
+ reference is returned. Note that the page count may change
+ between calls to GetPageCount() and GetPageDescriptor().
+ */
+ SharedPageDescriptor GetPageDescriptor(const sal_Int32 nPageIndex,
+ const bool bCreate = true) const;
+
+ /** Return a page descriptor for the given XDrawPage. Page descriptors
+ are created on demand. The page descriptor is found (or not found)
+ in (at most) linear time. Note that all page descriptors in front of
+ the one associated with the given XDrawPage are created when not yet
+ present. When the XDrawPage is not found then all descriptors are
+ created.
+ @return
+ Returns the index to the requested page descriptor or -1 when
+ there is no such page descriptor.
+ */
+ sal_Int32 GetIndex(const css::uno::Reference<css::drawing::XDrawPage>& rxSlide) const;
+
+ /** Return a page descriptor for the given SdrPage. Page descriptors
+ are created on demand. The page descriptor is found (or not found)
+ in (at most) linear time. Note that all page descriptors in front of
+ the one associated with the given XDrawPage are created when not yet
+ present. When the SdrPage is not found then all descriptors are
+ created.
+ @return
+ Returns the index to the requested page descriptor or -1 when
+ there is no such page descriptor.
+ */
+ sal_Int32 GetIndex(const SdrPage* pPage) const;
+
+ /** Return an index for accessing an SdrModel that corresponds to the
+ given SlideSorterModel index. In many cases we just have to apply
+ the n*2+1 magic. Only when a special model is set, like a custom
+ slide show, then the returned value is different.
+ */
+ sal_uInt16 GetCoreIndex(const sal_Int32 nIndex) const;
+
+ /** Call this method after the document has changed its structure. This
+ will get the model in sync with the SdDrawDocument. This method
+ tries not to throw away too much information already gathered. This
+ is especially important for previews of complex pages that take some
+ time to create.
+ */
+ void Resync();
+
+ /** Delete all descriptors that currently are in the container. The size
+ of the container, however, is not altered. Use the AdaptSize
+ method for that.
+ */
+ void ClearDescriptorList();
+
+ /** Set the selection of the document to exactly that of the called model.
+ */
+ void SynchronizeDocumentSelection();
+
+ /** Set the selection of the called model to exactly that of the document.
+ */
+ void SynchronizeModelSelection();
+
+ /** Return the mutex so that the caller can lock it and then safely
+ access the model.
+ */
+ ::osl::Mutex& GetMutex() { return maMutex; }
+
+ /** Set the XIndexAccess from which the called SlideSorterModel takes
+ its pages.
+ @param rxSlides
+ The set of slides accessible through this XIndexAccess are not
+ necessarily the same as the ones of the XModel of the
+ XController (although it typically is a subset).
+ */
+ void SetDocumentSlides(const css::uno::Reference<css::container::XIndexAccess>& rxSlides);
+
+ /** Return the set of pages that is currently displayed by the slide sorter.
+ */
+ css::uno::Reference<css::container::XIndexAccess> GetDocumentSlides() const;
+
+ /** This method is called when the edit mode has changed. It calls
+ SetDocumentSlides() with the set of slides or master pages obtained
+ from the model of the XController.
+ */
+ void UpdatePageList();
+
+ bool IsReadOnly() const;
+
+ /** The current selection is saved by copying the ST_Selected state into
+ ST_WasSelected for slides.
+ */
+ void SaveCurrentSelection();
+
+ /** The current selection is restored from the ST_WasSelected state from
+ the slides.
+ @returns
+ The returned region has to be repainted to reflect the updated
+ selection states.
+ */
+ vcl::Region RestoreSelection();
+
+ /** Typically called from controller::Listener this method handles the
+ insertion and deletion of single pages.
+ @return
+ Returns <TRUE/> when the given page is relevant for the current
+ page kind and edit mode.
+ */
+ bool NotifyPageEvent(const SdrPage* pPage);
+
+private:
+ mutable ::osl::Mutex maMutex;
+ SlideSorter& mrSlideSorter;
+ css::uno::Reference<css::container::XIndexAccess> mxSlides;
+ EditMode meEditMode;
+ mutable ::std::vector<SharedPageDescriptor> maPageDescriptors;
+
+ /** Resize the descriptor container according to current values of
+ page kind and edit mode.
+ */
+ void AdaptSize();
+
+ SdPage* GetPage(const sal_Int32 nCoreIndex) const;
+ void InsertSlide(SdPage* pPage, bool bMarkSelected);
+ // return if this page was marked as selected before being removed
+ bool DeleteSlide(const SdPage* pPage);
+ void UpdateIndices(const sal_Int32 nFirstIndex);
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsEnumeration.hxx b/sd/source/ui/slidesorter/inc/model/SlsEnumeration.hxx
new file mode 100644
index 000000000..289f85911
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsEnumeration.hxx
@@ -0,0 +1,44 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace sd::slidesorter::model
+{
+/** Interface to generic enumerations. Designed to operate on shared
+ pointers. Therefore GetNextElement() returns T and not T&.
+*/
+template <class T> class Enumeration
+{
+public:
+ virtual ~Enumeration() {}
+
+ virtual bool HasMoreElements() const = 0;
+ /** Returns T instead of T& so that it can handle shared pointers.
+ */
+ virtual T GetNextElement() = 0;
+ virtual void Rewind() = 0;
+ virtual ::std::unique_ptr<Enumeration<T>> Clone() = 0;
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx
new file mode 100644
index 000000000..4f3be3b42
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsPageDescriptor.hxx
@@ -0,0 +1,144 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsVisualState.hxx>
+#include <tools/gen.hxx>
+#include <com/sun/star/uno/Reference.hxx>
+
+#include <memory>
+
+namespace com::sun::star::drawing { class XDrawPage; }
+
+class SdPage;
+class SdrPage;
+
+namespace sd::slidesorter::model {
+
+/** Each PageDescriptor object represents the preview of one draw page,
+ slide, or master page of a Draw or Impress document as they are displayed
+ in the slide sorter. This class gives access to some associated
+ information like prerendered preview or position on the screen.
+
+ <p>Bounding boxes of page objects come in four varieties:
+ Model and screen/pixel coordinates and the bounding boxes of the actual
+ page objects and the larger bounding boxes that include page names and
+ fade symbol.</p>
+*/
+class PageDescriptor
+ : public ::std::enable_shared_from_this<PageDescriptor>
+{
+public:
+ /** Create a PageDescriptor for the given SdPage object.
+ @param rxPage
+ The page that is represented by the new PageDescriptor object.
+ @param pPage
+ The page pointer can in some situations not be detected from
+ rxPage, e.g. after undo of page deletion. Therefore supply it
+ separately.
+ @param nIndex
+ This index is displayed in the view as page number. It is not
+ necessarily the page index (not even when you add or subtract 1
+ or use (x-1)/2 magic).
+ */
+ PageDescriptor (
+ const css::uno::Reference<css::drawing::XDrawPage>& rxPage,
+ SdPage* pPage,
+ const sal_Int32 nIndex);
+
+ ~PageDescriptor();
+
+ /** Return the page that is represented by the descriptor as SdPage pointer .
+ */
+ SdPage* GetPage() const { return mpPage;}
+
+ /** Return the page that is represented by the descriptor as XDrawPage reference.
+ */
+ const css::uno::Reference<css::drawing::XDrawPage>& GetXDrawPage() const { return mxPage;}
+
+ /** Returns the index of the page as it is displayed in the view as page
+ number. The value may differ from the index returned by the
+ XDrawPage when there are hidden slides and the XIndexAccess used to
+ access the model filters them out.
+ */
+ sal_Int32 GetPageIndex() const { return mnIndex;}
+ void SetPageIndex (const sal_Int32 nIndex);
+
+ bool UpdateMasterPage();
+ bool UpdateTransitionFlag();
+
+ enum State { ST_Visible, ST_Selected, ST_WasSelected,
+ ST_Focused, ST_MouseOver, ST_Current, ST_Excluded };
+
+ bool HasState (const State eState) const;
+
+ bool SetState (const State eState, const bool bStateValue);
+
+ /** Set the internal mbIsSelected flag to the selection state of the
+ page. Use this method to synchronize a page descriptor with the
+ page it describes and determine whether a redraw to update the
+ selection indicator is necessary.
+ @return
+ When the two selection states were different <TRUE/> is
+ returned. When they were the same this method returns
+ <FALSE/>.
+ */
+ bool GetCoreSelection();
+
+ /** Set the selection flags of the SdPage objects to the corresponding
+ selection states of the page descriptors.
+ */
+ void SetCoreSelection();
+
+ VisualState& GetVisualState() { return maVisualState;}
+
+ ::tools::Rectangle GetBoundingBox() const;
+ Point GetLocation (const bool bIgnoreLocation) const;
+ void SetBoundingBox (const ::tools::Rectangle& rBoundingBox);
+
+private:
+ SdPage* mpPage;
+ css::uno::Reference<css::drawing::XDrawPage> mxPage;
+ SdrPage const* mpMasterPage;
+
+ /** This index is displayed as page number in the view. It may or may
+ not be the actual page index.
+ */
+ sal_Int32 mnIndex;
+
+ ::tools::Rectangle maBoundingBox;
+ VisualState maVisualState;
+
+ bool mbIsSelected : 1;
+ bool mbWasSelected : 1;
+ bool mbIsVisible : 1;
+ bool mbIsFocused : 1;
+ bool mbIsCurrent : 1;
+ bool mbIsMouseOver : 1;
+ bool mbHasTransition : 1;
+
+ PageDescriptor (const PageDescriptor& rDescriptor) = delete;
+
+ PageDescriptor& operator= (const PageDescriptor& rDescriptor) = delete;
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageEnumeration.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageEnumeration.hxx
new file mode 100644
index 000000000..6901a9ff1
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsPageEnumeration.hxx
@@ -0,0 +1,95 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsEnumeration.hxx>
+#include <model/SlsSharedPageDescriptor.hxx>
+
+#include <functional>
+#include <memory>
+
+namespace sd::slidesorter::model
+{
+class SlideSorterModel;
+
+/** Public class of page enumerations that delegates its calls to an
+ implementation object that can filter pages by using a given predicate.
+
+ @see PageEnumerationProvider
+ The PageEnumerationProvider has methods for creating different types
+ of page enumerations.
+*/
+class PageEnumeration final : public Enumeration<SharedPageDescriptor>
+{
+public:
+ /** Create a new page enumeration that enumerates a subset of the pages
+ of the given model.
+ @param rModel
+ The new page enumeration enumerates the pages of this model.
+ @param rPredicate
+ This predicate determines which pages to include in the
+ enumeration. Pages for which rPredicate returns <FALSE/> are
+ exclude.
+ */
+ typedef ::std::function<bool(const SharedPageDescriptor&)> PagePredicate;
+ static PageEnumeration Create(const SlideSorterModel& rModel, const PagePredicate& rPredicate);
+
+ /** This copy constructor creates a copy of the given enumeration.
+ */
+ PageEnumeration(const PageEnumeration& rEnumeration);
+
+ virtual ~PageEnumeration() override;
+
+ /** Create and return an exact copy of the called object.
+ */
+ virtual ::std::unique_ptr<Enumeration<SharedPageDescriptor>> Clone() override;
+
+ PageEnumeration& operator=(const PageEnumeration& rEnumeration);
+
+ /** Return <TRUE/> when the enumeration has more elements, i.e. it is
+ save to call GetNextElement() at least one more time.
+ */
+ virtual bool HasMoreElements() const override;
+
+ /** Return the next element of the enumeration. Call the
+ HasMoreElements() before to make sure that there exists at least one
+ more element. Calling this method with HasMoreElements() returning
+ <FALSE/> is an error.
+ */
+ virtual SharedPageDescriptor GetNextElement() override;
+
+ /** Rewind the enumeration so that the next call to GetNextElement()
+ will return its first element.
+ */
+ virtual void Rewind() override;
+
+private:
+ /// Implementation object.
+ ::std::unique_ptr<Enumeration<SharedPageDescriptor>> mpImpl;
+
+ /** This constructor expects an implementation object that holds
+ the predicate that filters the pages.
+ */
+ PageEnumeration(::std::unique_ptr<Enumeration<SharedPageDescriptor>>&& pImpl);
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsPageEnumerationProvider.hxx b/sd/source/ui/slidesorter/inc/model/SlsPageEnumerationProvider.hxx
new file mode 100644
index 000000000..b6de98d13
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsPageEnumerationProvider.hxx
@@ -0,0 +1,51 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsPageEnumeration.hxx>
+
+namespace sd::slidesorter::model
+{
+class SlideSorterModel;
+
+/** Collection of methods that create enumeration of slides.
+*/
+class PageEnumerationProvider
+{
+public:
+ /** The returned enumeration of slides iterates over all slides of the
+ given model.
+ */
+ static PageEnumeration CreateAllPagesEnumeration(const SlideSorterModel& rModel);
+
+ /** The returned enumeration of slides iterates over the currently
+ selected slides of the given model.
+ */
+ static PageEnumeration CreateSelectedPagesEnumeration(const SlideSorterModel& rModel);
+
+ /** The returned enumeration of slides iterates over the slides
+ (partially) inside the visible area.
+ */
+ static PageEnumeration CreateVisiblePagesEnumeration(const SlideSorterModel& rModel);
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsSharedPageDescriptor.hxx b/sd/source/ui/slidesorter/inc/model/SlsSharedPageDescriptor.hxx
new file mode 100644
index 000000000..6ee1e2b22
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsSharedPageDescriptor.hxx
@@ -0,0 +1,32 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+
+namespace sd::slidesorter::model
+{
+class PageDescriptor;
+
+typedef std::shared_ptr<PageDescriptor> SharedPageDescriptor;
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx
new file mode 100644
index 000000000..89eae16ca
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/model/SlsVisualState.hxx
@@ -0,0 +1,47 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <sal/types.h>
+#include <tools/gen.hxx>
+
+namespace sd::slidesorter::model
+{
+/** This class gives access to values related to the visualization of page
+ objects. This includes animation state when blending from one state to
+ another.
+*/
+class VisualState
+{
+public:
+ VisualState(const sal_Int32 nPageId);
+
+ const Point& GetLocationOffset() const { return maLocationOffset; }
+ void SetLocationOffset(const Point& rPoint);
+
+ sal_Int32 mnPageId; // For debugging
+
+private:
+ Point maLocationOffset;
+};
+
+} // end of namespace ::sd::slidesorter::model
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx
new file mode 100644
index 000000000..0f3493ab3
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlideSorterView.hxx
@@ -0,0 +1,225 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsPageDescriptor.hxx>
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <view/SlsLayouter.hxx>
+#include <view/SlsILayerPainter.hxx>
+#include <o3tl/deleter.hxx>
+
+#include <View.hxx>
+#include <tools/gen.hxx>
+#include <vcl/region.hxx>
+#include <memory>
+
+namespace sd::slidesorter::cache { class PageCache; }
+namespace sd::slidesorter::model { class SlideSorterModel; }
+namespace sd { class Window; }
+namespace sd::slidesorter { class SlideSorter; }
+namespace sd::slidesorter::view {
+
+class LayeredDevice;
+class PageObjectPainter;
+class ToolTip;
+
+class SlideSorterView final
+ : public sd::View
+{
+public:
+
+ /** Create a new view for the slide sorter.
+ @param rViewShell
+ This reference is simply passed to the base class and not used
+ by this class.
+
+ */
+ explicit SlideSorterView (SlideSorter& rSlideSorter);
+ void Init();
+
+ virtual ~SlideSorterView() override;
+ void Dispose();
+
+ SlideSorterView(const SlideSorterView&) = delete;
+ SlideSorterView& operator=(const SlideSorterView&) = delete;
+
+ /** Set the general way of layouting the page objects. Note that this
+ method does not trigger any repaints or layouts.
+ */
+ bool SetOrientation (const Layouter::Orientation eOrientation);
+ Layouter::Orientation GetOrientation() const { return meOrientation;}
+
+ void RequestRepaint();
+ void RequestRepaint (const model::SharedPageDescriptor& rDescriptor);
+ void RequestRepaint (const ::tools::Rectangle& rRepaintBox);
+ void RequestRepaint (const vcl::Region& rRepaintRegion);
+
+ ::tools::Rectangle GetModelArea() const;
+
+ /** Return the index of the page that is rendered at the given position.
+ @param rPosition
+ The position is expected to be in pixel coordinates.
+ @return
+ The returned index is -1 when there is no page object at the
+ given position.
+ */
+ sal_Int32 GetPageIndexAtPoint (const Point& rPosition) const;
+
+ view::Layouter& GetLayouter();
+
+ virtual void ModelHasChanged() override;
+
+ /** This method is typically called before a model change takes place.
+ All references to model data are released. PostModelChange() has to
+ be called to complete the handling of the model change. When the
+ calls to Pre- and PostModelChange() are very close to each other you
+ may call HandleModelChange() instead.
+ */
+ void PreModelChange();
+
+ /** This method is typically called after a model change took place.
+ References to model data are re-allocated. Call this method only
+ after PreModelChange() has been called.
+ */
+ void PostModelChange();
+
+ /** This method is a convenience function that simply calls
+ PreModelChange() and then PostModelChange().
+ */
+ void HandleModelChange();
+
+ void HandleDrawModeChange();
+
+ void Resize();
+ virtual void CompleteRedraw (
+ OutputDevice* pDevice,
+ const vcl::Region& rPaintArea,
+ sdr::contact::ViewObjectContactRedirector* pRedirector = nullptr) override;
+ void Paint (OutputDevice& rDevice, const ::tools::Rectangle& rRepaintArea);
+
+ virtual void ConfigurationChanged (
+ utl::ConfigurationBroadcaster* pBroadcaster,
+ ConfigurationHints nHint) override;
+
+ void HandleDataChangeEvent();
+
+ void Layout();
+ /** This tells the view that it has to re-determine the visibility of
+ the page objects before painting them the next time.
+ */
+ void InvalidatePageObjectVisibilities();
+
+ std::shared_ptr<cache::PageCache> const & GetPreviewCache();
+
+ /** Return the range of currently visible page objects including the
+ first and last one in that range.
+ @return
+ The returned pair of page object indices is empty when the
+ second index is lower than the first.
+ */
+ Range const & GetVisiblePageRange();
+
+ /** Add a shape to the page. Typically used from inside
+ PostModelChange().
+ */
+ // void AddSdrObject (SdrObject& rObject);
+
+ /** Add a listener that is called when the set of visible slides.
+ @param rListener
+ When this method is called multiple times for the same listener
+ the second and all following calls are ignored. Each listener
+ is added only once.
+ */
+ void AddVisibilityChangeListener (const Link<LinkParamNone*,void>& rListener);
+
+ /** Remove a listener that is called when the set of visible slides changes.
+ @param rListener
+ It is safe to pass a listener that was not added or has been
+ removed previously. Such calls are ignored.
+ */
+ void RemoveVisibilityChangeListener (const Link<LinkParamNone*,void>& rListener);
+
+ /** The page under the mouse is not highlighted in some contexts. Call
+ this method on context changes.
+ */
+ void UpdatePageUnderMouse ();
+ void UpdatePageUnderMouse (const Point& rMousePosition);
+ void SetPageUnderMouse (const model::SharedPageDescriptor& rpDescriptor);
+
+ bool SetState (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const model::PageDescriptor::State eState,
+ const bool bStateValue);
+
+ void UpdateOrientation();
+
+ std::shared_ptr<PageObjectPainter> const & GetPageObjectPainter();
+ const std::shared_ptr<LayeredDevice>& GetLayeredDevice() const { return mpLayeredDevice;}
+
+ class DrawLock
+ {
+ public:
+ DrawLock (SlideSorter const & rSlideSorter);
+ ~DrawLock();
+ /** When the DrawLock is disposed then it will not request a repaint
+ on destruction.
+ */
+ void Dispose();
+ private:
+ view::SlideSorterView& mrView;
+ VclPtr<sd::Window> mpWindow;
+ };
+
+ ToolTip& GetToolTip() const;
+
+ virtual void DragFinished (sal_Int8 nDropAction) override;
+
+private:
+ SlideSorter& mrSlideSorter;
+ model::SlideSorterModel& mrModel;
+ bool mbIsDisposed;
+ ::std::unique_ptr<Layouter> mpLayouter;
+ bool mbPageObjectVisibilitiesValid;
+ std::shared_ptr<cache::PageCache> mpPreviewCache;
+ std::shared_ptr<LayeredDevice> mpLayeredDevice;
+ Range maVisiblePageRange;
+ Size maPreviewSize;
+ bool mbPreciousFlagUpdatePending;
+ Layouter::Orientation meOrientation;
+ model::SharedPageDescriptor mpPageUnderMouse;
+ std::shared_ptr<PageObjectPainter> mpPageObjectPainter;
+ vcl::Region maRedrawRegion;
+ SharedILayerPainter mpBackgroundPainter;
+ std::unique_ptr<ToolTip, o3tl::default_delete<ToolTip>> mpToolTip;
+ bool mbIsRearrangePending;
+ ::std::vector<Link<LinkParamNone*,void>> maVisibilityChangeListeners;
+
+ /** Determine the visibility of all page objects.
+ */
+ void DeterminePageObjectVisibilities();
+
+ void UpdatePreciousFlags();
+ void RequestRearrange();
+ void Rearrange();
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx
new file mode 100644
index 000000000..57b90af0a
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsILayerPainter.hxx
@@ -0,0 +1,53 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <memory>
+
+class OutputDevice;
+namespace tools { class Rectangle; }
+
+namespace sd::slidesorter::view {
+
+class ILayerInvalidator
+{
+public:
+ virtual ~ILayerInvalidator() {}
+
+ virtual void Invalidate (const ::tools::Rectangle& rInvalidationBox) = 0;
+};
+typedef std::shared_ptr<ILayerInvalidator> SharedILayerInvalidator;
+
+class ILayerPainter
+{
+public:
+ virtual ~ILayerPainter() {}
+
+ virtual void SetLayerInvalidator (
+ const SharedILayerInvalidator& rpInvalidator) = 0;
+ virtual void Paint (
+ OutputDevice& rDevice,
+ const ::tools::Rectangle& rRepaintArea) = 0;
+};
+typedef std::shared_ptr<ILayerPainter> SharedILayerPainter;
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx
new file mode 100644
index 000000000..c74d06cb9
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsInsertAnimator.hxx
@@ -0,0 +1,59 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <controller/SlsAnimator.hxx>
+#include <memory>
+
+namespace sd::slidesorter::view
+{
+class InsertPosition;
+
+/** Animate the positions of page objects to make room at the insert
+ position while a move or copy operation takes place.
+*/
+class InsertAnimator
+{
+public:
+ explicit InsertAnimator(SlideSorter& rSlideSorter);
+ InsertAnimator(const InsertAnimator&) = delete;
+ InsertAnimator& operator=(const InsertAnimator&) = delete;
+
+ /** Set the position at which we have to make room for the display of an
+ icon.
+ */
+ void SetInsertPosition(const InsertPosition& rInsertPosition);
+
+ /** Restore the normal position of all page objects.
+ @param eMode
+ This flag controls whether to start an animation that ends in the
+ normal positions of all slides (AM_Animated) or to restore the
+ normal positions immediately (AM_Immediate).
+ */
+ void Reset(const controller::Animator::AnimationMode eMode);
+
+private:
+ class Implementation;
+ std::shared_ptr<Implementation> mpImplementation;
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx b/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx
new file mode 100644
index 000000000..3f4cc2218
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsInsertionIndicatorOverlay.hxx
@@ -0,0 +1,101 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <view/SlsILayerPainter.hxx>
+#include <controller/SlsTransferableData.hxx>
+
+#include <tools/gen.hxx>
+#include <vcl/bitmapex.hxx>
+#include <memory>
+#include <vector>
+
+class OutputDevice;
+class SdTransferable;
+
+namespace sd::slidesorter { class SlideSorter; }
+
+namespace sd::slidesorter::view {
+
+class FramePainter;
+
+/** The insertion indicator is painted as a vertical or horizontal bar
+ in the space between slides.
+*/
+class InsertionIndicatorOverlay final
+ : public ILayerPainter,
+ public std::enable_shared_from_this<InsertionIndicatorOverlay>
+{
+public:
+ InsertionIndicatorOverlay (SlideSorter& rSlideSorter);
+ virtual ~InsertionIndicatorOverlay() override;
+
+ virtual void SetLayerInvalidator (const SharedILayerInvalidator& rpInvalidator) override;
+
+ void Create (const SdTransferable* pTransferable);
+
+ /** Given a position in model coordinates this method calculates the
+ insertion marker both as an index in the document and as a location
+ used for drawing the insertion indicator.
+ */
+ void SetLocation (const Point& rPosition);
+
+ Size GetSize() const;
+
+ virtual void Paint (
+ OutputDevice& rDevice,
+ const ::tools::Rectangle& rRepaintArea) override;
+
+ bool IsVisible() const { return mbIsVisible;}
+ void Hide();
+ void Show();
+
+ ::tools::Rectangle GetBoundingBox() const;
+
+private:
+ SlideSorter& mrSlideSorter;
+ bool mbIsVisible;
+ SharedILayerInvalidator mpLayerInvalidator;
+ // Center of the insertion indicator.
+ Point maLocation;
+ BitmapEx maIcon;
+ std::unique_ptr<FramePainter> mpShadowPainter;
+
+ Point PaintRepresentatives (
+ OutputDevice& rContent,
+ const Size& rPreviewSize,
+ const sal_Int32 nOffset,
+ const ::std::vector<controller::TransferableData::Representative>& rPages) const;
+ void PaintPageCount (
+ OutputDevice& rDevice,
+ const sal_Int32 nSelectionCount,
+ const Size& rPreviewSize,
+ const Point& rFirstPageOffset) const;
+ /** Setup the insertion indicator by creating the icon. It consists of
+ scaled down previews of some of the selected pages.
+ */
+ void Create (
+ const ::std::vector<controller::TransferableData::Representative>& rPages,
+ const sal_Int32 nSelectionCount);
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx
new file mode 100644
index 000000000..b91ae83c5
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsLayouter.hxx
@@ -0,0 +1,237 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/vclptr.hxx>
+#include <tools/gen.hxx>
+#include <sal/types.h>
+#include <memory>
+
+namespace sd { class Window; }
+namespace sd::slidesorter::model { class SlideSorterModel; }
+namespace sd::slidesorter::view { class PageObjectLayouter; }
+namespace sd::slidesorter::view { class Theme; }
+
+namespace sd::slidesorter::view {
+
+class InsertPosition;
+
+/** Calculate the size and position of page objects displayed by a slide
+ sorter. The layouter takes into account various input values:
+ 1.) Size of the window in which the slide sorter is displayed.
+ 2.) Desired and minimal and maximal widths of page objects.
+ 3.) Minimal and maximal number of columns.
+ 4.) Vertical and horizontal gaps between objects in adjacent columns.
+ 5.) Borders around every page object.
+ 6.) Vertical and horizontal borders between enclosing page and outer
+ page objects.
+ From these, it calculates various output values:
+ 1.) The width of page objects.
+ 2.) The number of columns.
+ 3.) The size of the enclosing page.
+
+ <p>Sizes and lengths are all in pixel except where explicitly stated
+ otherwise.</p>
+
+ <p>The GetIndex... methods may return indices that are larger than or
+ equal to (zero based) the number of pages. This is so because the
+ number of pages is not known to the class instances. Indices are
+ calculated with reference to the general grid layout of page
+ objects.</p>
+*/
+class Layouter
+{
+public:
+ enum Orientation { HORIZONTAL, VERTICAL, GRID };
+
+ Layouter (
+ sd::Window *rpWindow,
+ const std::shared_ptr<Theme>& rpTheme);
+ ~Layouter();
+
+ std::shared_ptr<PageObjectLayouter> const & GetPageObjectLayouter() const;
+ /** Set the interval of valid column counts. When nMinimalColumnCount
+ <= nMaximalColumnCount is not fulfilled then the call is ignored.
+ @param nMinimalColumnCount
+ The default value is 1. The question whether higher values make
+ any sense is left to the caller.
+ @param nMaximalColumnCount
+ The default value is 5.
+ */
+ void SetColumnCount (sal_Int32 nMinimalColumnCount,
+ sal_Int32 nMaximalColumnCount);
+
+ /** Central method of this class. It takes the input values and
+ calculates the output values. Both given sizes must not be 0 in any
+ dimension or the call is ignored.
+ @param eOrientation
+ This defines the generally layout and specifies whether there may
+ be more than one row or more than one column.
+ @param rWindowSize
+ The size of the window in pixels that the slide sorter is
+ displayed in. This can differ from the size of mpWindow during
+ detection of whether or not the scroll bars should be visible.
+ @param rPreviewModelSize
+ Size of each page in model coordinates.
+ @param rpWindow
+ The map mode of this window is adapted to the new layout of the
+ page objects.
+ @return
+ The return value indicates whether the Get... methods can be
+ used to obtain valid values (<TRUE/>).
+ */
+ bool Rearrange (
+ const Orientation eOrientation,
+ const Size& rWindowSize,
+ const Size& rPreviewModelSize,
+ const sal_uInt32 nPageCount);
+
+ /** Return the number of columns.
+ */
+ sal_Int32 GetColumnCount() const;
+
+ sal_Int32 GetIndex (const sal_Int32 nRow, const sal_Int32 nColumn) const;
+
+ Size const & GetPageObjectSize() const;
+
+ /** Return the bounding box in window coordinates of the nIndex-th page
+ object.
+ */
+ ::tools::Rectangle GetPageObjectBox (
+ const sal_Int32 nIndex,
+ const bool bIncludeBorderAndGap) const;
+
+ /** Return the bounding box in model coordinates of the page that
+ contains the given amount of page objects.
+ */
+ ::tools::Rectangle GetTotalBoundingBox() const;
+
+ /** Return the index of the first fully or partially visible page
+ object. This takes into account only the vertical dimension.
+ @return
+ The second index may be larger than the number of existing
+ page objects.
+ */
+ Range GetRangeOfVisiblePageObjects (const ::tools::Rectangle& rVisibleArea) const;
+
+ /** Return the index of the page object that is rendered at the given
+ point.
+ @param rPosition
+ The position is expected to be in model coordinates relative to
+ the page origin.
+ @param bIncludePageBorders
+ When <TRUE/> then include the page borders into the calculation,
+ i.e. when a point lies in the border of a page object but not on
+ the actual page area the index of that page is returned;
+ otherwise -1 would be returned to indicate that no page object
+ has been hit.
+ @param bClampToValidRange
+ When <TRUE/> then values outside the valid range [0,mnPageCount)
+ are mapped to 0 (when smaller than 0) or mnPageCount-1 when
+ equal to or larger than mnPageCount.
+ When <FALSE/> then -1 is returned for values outside the valid range.
+ @return
+ The returned index may be larger than the number of existing
+ page objects.
+ */
+ sal_Int32 GetIndexAtPoint (
+ const Point& rModelPosition,
+ const bool bIncludePageBorders,
+ const bool bClampToValidRange = true) const;
+
+ /** Return an object that describes the logical and visual properties of
+ where to do an insert operation when the user would release the
+ mouse button at the given position after a drag operation and of
+ where and how to display an insertion indicator.
+ @param rModelPosition
+ The position in the model coordinate system for which to
+ determine the insertion page index. The position does not have
+ to be over a page object to return a valid value.
+ @param rIndicatorSize
+ The size of the insertion indicator. This size is used to adapt
+ the location when at the left or right of a row or at the top or
+ bottom of a column.
+ @param rModel
+ The model is used to get access to the selection states of the
+ pages. This in turn is used to determine the visual bounding
+ boxes.
+ */
+ InsertPosition GetInsertPosition (
+ const Point& rModelPosition,
+ const Size& rIndicatorSize,
+ model::SlideSorterModel const & rModel) const;
+
+ Range GetValidHorizontalSizeRange() const;
+ Range GetValidVerticalSizeRange() const;
+
+ class Implementation;
+
+private:
+ std::unique_ptr<Implementation> mpImplementation;
+ VclPtr<sd::Window> mpWindow;
+};
+
+/** Collect all values concerning the logical and visual properties of the
+ insertion position that is used for drag-and-drop and copy-and-paste.
+*/
+class InsertPosition
+{
+public:
+ InsertPosition();
+ bool operator== (const InsertPosition& rInsertPosition) const;
+ bool operator!= (const InsertPosition& rInsertPosition) const;
+
+ void SetLogicalPosition (
+ const sal_Int32 nRow,
+ const sal_Int32 nColumn,
+ const sal_Int32 nIndex,
+ const bool bIsAtRunStart,
+ const bool bIsAtRunEnd,
+ const bool bIsExtraSpaceNeeded);
+ void SetGeometricalPosition(
+ const Point& rLocation,
+ const Point& rLeadingOffset,
+ const Point& rTrailingOffset);
+
+ sal_Int32 GetRow() const { return mnRow; }
+ sal_Int32 GetColumn() const { return mnColumn; }
+ sal_Int32 GetIndex() const { return mnIndex; }
+ const Point& GetLocation() const { return maLocation; }
+ const Point& GetLeadingOffset() const { return maLeadingOffset; }
+ const Point& GetTrailingOffset() const { return maTrailingOffset; }
+ bool IsAtRunStart() const { return mbIsAtRunStart; }
+ bool IsAtRunEnd() const { return mbIsAtRunEnd; }
+ bool IsExtraSpaceNeeded() const { return mbIsExtraSpaceNeeded; }
+
+private:
+ sal_Int32 mnRow;
+ sal_Int32 mnColumn;
+ sal_Int32 mnIndex;
+ bool mbIsAtRunStart : 1;
+ bool mbIsAtRunEnd : 1;
+ bool mbIsExtraSpaceNeeded : 1;
+ Point maLocation;
+ Point maLeadingOffset;
+ Point maTrailingOffset;
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx
new file mode 100644
index 000000000..8bb77a988
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectLayouter.hxx
@@ -0,0 +1,144 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <tools/gen.hxx>
+#include <vcl/image.hxx>
+
+namespace vcl { class Font; }
+namespace sd { class Window; }
+
+namespace sd::slidesorter::view {
+
+/** In contrast to the Layouter that places page objects in the view, the
+ PageObjectLayouter places the parts of individual page objects like page
+ number area, borders, preview.
+*/
+class PageObjectLayouter
+{
+public:
+ /** Create a new PageObjectLayouter object.
+ @param rPageObjectSize
+ In general either the width or the height will be 0 in order to
+ signal that this size component has to be calculated from the other.
+ This calculation will make the preview as large as possible.
+ @param nPageCount
+ The page count is used to determine how wide the page number
+ area has to be, how many digits to except for the largest page number.
+ */
+ PageObjectLayouter(
+ const Size& rPageObjectWindowSize,
+ const Size& rPreviewModelSize,
+ sd::Window *pWindow,
+ const sal_Int32 nPageCount);
+ ~PageObjectLayouter();
+
+ enum class Part {
+ // The focus indicator is painted outside the actual page object.
+ FocusIndicator,
+ // This is the outer bounding box that includes the preview, page
+ // number, title.
+ PageObject,
+ // Bounding box of the actual preview.
+ Preview,
+ // Bounding box of the page number.
+ PageNumber,
+ // Indicator whether or not there is a slide transition associated
+ // with this slide.
+ TransitionEffectIndicator,
+ // Indicator whether or not there is a custom animation associated
+ // with this slide.
+ CustomAnimationEffectIndicator
+ };
+ /** Two coordinate systems are supported. They differ only in
+ translation not in scale. Both relate to pixel values in the window.
+ A position in the model coordinate system does not change when the window content is
+ scrolled up or down. In the window coordinate system (relative
+ to the top left point of the window)scrolling leads to different values.
+ */
+ enum CoordinateSystem {
+ WindowCoordinateSystem,
+ ModelCoordinateSystem
+ };
+
+ /** Return the bounding box of the page object or one of its graphical
+ parts.
+ @param rWindow
+ This device is used to translate between model and window
+ coordinates.
+ @param rpPageDescriptor
+ The page for which to calculate the bounding box. This may be
+ NULL. When it is NULL then a generic bounding box is calculated
+ for the location (0,0).
+ @param ePart
+ The part of the page object for which to return the bounding
+ box.
+ @param eCoordinateSystem
+ The bounding box can be returned in model and in pixel
+ (window) coordinates.
+ @param bIgnoreLocation
+ Return a position ignoring the slides' location, ie. as if
+ we were the first slide.
+ */
+ ::tools::Rectangle GetBoundingBox (
+ const model::SharedPageDescriptor& rpPageDescriptor,
+ const Part ePart,
+ const CoordinateSystem eCoordinateSystem,
+ bool bIgnoreLocation = false);
+
+ /// the size of the embedded preview: position independent, in window coordinate system
+ Size GetPreviewSize();
+
+ /// the maximum size of each tile, also position independent, in window coordinate system
+ Size GetGridMaxSize();
+
+ const Image& GetTransitionEffectIcon() const { return maTransitionEffectIcon;}
+ const Image& GetCustomAnimationEffectIcon() const { return maCustomAnimationEffectIcon;}
+
+private:
+ ::tools::Rectangle GetBoundingBox (
+ const Point& rPageObjectLocation,
+ const Part ePart,
+ const CoordinateSystem eCoordinateSystem);
+
+private:
+ VclPtr<sd::Window> mpWindow;
+ ::tools::Rectangle maFocusIndicatorBoundingBox;
+ ::tools::Rectangle maPageObjectBoundingBox;
+ ::tools::Rectangle maPageNumberAreaBoundingBox;
+ ::tools::Rectangle maPreviewBoundingBox;
+ ::tools::Rectangle maTransitionEffectBoundingBox;
+ ::tools::Rectangle maCustomAnimationEffectBoundingBox;
+ const Image maTransitionEffectIcon;
+ const Image maCustomAnimationEffectIcon;
+ const std::shared_ptr<vcl::Font> mpPageNumberFont;
+
+ Size GetPageNumberAreaSize (const int nPageCount);
+ ::tools::Rectangle CalculatePreviewBoundingBox (
+ Size& rPageObjectSize,
+ const Size& rPreviewModelSize,
+ const sal_Int32 nPageNumberAreaWidth,
+ const sal_Int32 nFocusIndicatorWidth);
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx
new file mode 100644
index 000000000..747c09500
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsPageObjectPainter.hxx
@@ -0,0 +1,119 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <view/SlsTheme.hxx>
+#include <memory>
+
+namespace sd::slidesorter::cache { class PageCache; }
+namespace sd::slidesorter { class SlideSorter; }
+
+namespace sd::slidesorter::view {
+
+class Layouter;
+class PageObjectLayouter;
+class FramePainter;
+
+class PageObjectPainter
+{
+public:
+ PageObjectPainter (const SlideSorter& rSlideSorter);
+ ~PageObjectPainter();
+
+ void PaintPageObject (
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor);
+
+ /** Called when the theme changes, either because it is replaced with
+ another or because the system colors have changed. So, even when
+ the given theme is the same object as the one already in use by this
+ painter everything that depends on the theme is updated.
+ */
+ void SetTheme (const std::shared_ptr<view::Theme>& rpTheme);
+
+ /** Return a preview bitmap for the given page descriptor. When the
+ page is excluded from the show then the preview is marked
+ accordingly.
+ @rpDescriptor
+ Defines the page for which to return the preview.
+ @pReferenceDevice
+ When not <NULL/> then this reference device is used to created a
+ compatible bitmap.
+ @return
+ The returned bitmap may have a different size then the preview area.
+ */
+ BitmapEx GetPreviewBitmap (
+ const model::SharedPageDescriptor& rpDescriptor,
+ const OutputDevice* pReferenceDevice) const;
+
+private:
+ const Layouter& mrLayouter;
+ std::shared_ptr<cache::PageCache> mpCache;
+ std::shared_ptr<view::Theme> mpTheme;
+ std::shared_ptr<vcl::Font> mpPageNumberFont;
+ std::unique_ptr<FramePainter> mpShadowPainter;
+ std::unique_ptr<FramePainter> mpFocusBorderPainter;
+
+ void PaintBackground (
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor) const;
+ void PaintPreview (
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor) const;
+ void PaintPageNumber (
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor) const;
+ static void PaintTransitionEffect (
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor);
+ static void PaintCustomAnimationEffect (
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor);
+ void PaintBorder (
+ OutputDevice& rDevice,
+ const Theme::GradientColorType eColorType,
+ const ::tools::Rectangle& rBox) const;
+ void PaintBackgroundDetail(
+ PageObjectLayouter *pPageObjectLayouter,
+ OutputDevice& rDevice,
+ const model::SharedPageDescriptor& rpDescriptor) const;
+
+ static BitmapEx CreateMarkedPreview(
+ const Size& rSize,
+ const BitmapEx& rPreview,
+ const BitmapEx& rOverlay,
+ const OutputDevice* pReferenceDevice);
+
+ /** Update the local pointer to the page object layouter to the
+ one owned by the general layouter.
+ Return <TRUE/> when after the call we have a valid page object layouter.
+ */
+ bool UpdatePageObjectLayouter();
+};
+
+} // end of namespace sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx
new file mode 100644
index 000000000..efb7b2a3e
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsTheme.hxx
@@ -0,0 +1,135 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <vcl/bitmapex.hxx>
+#include <tools/color.hxx>
+
+#include <memory>
+
+namespace vcl { class Font; }
+
+namespace sd::slidesorter::controller { class Properties; }
+
+namespace sd::slidesorter::view {
+
+const int Theme_FocusIndicatorWidth = 3;
+
+/** Collection of colors and styles that are used to paint the slide sorter
+ view.
+*/
+class Theme
+{
+public:
+ Theme (const std::shared_ptr<controller::Properties>& rpProperties);
+
+ /** Call this method to update some colors as response to a change of
+ a system color change.
+ */
+ void Update (
+ const std::shared_ptr<controller::Properties>& rpProperties);
+
+ // BitmapEx GetInsertIndicatorIcon() const;
+
+ enum FontType {
+ Font_PageNumber,
+ Font_PageCount
+ };
+ static std::shared_ptr<vcl::Font> GetFont (
+ const FontType eType,
+ const OutputDevice& rDevice);
+
+ enum ColorType {
+ Color_Background,
+ Color_PageNumberDefault,
+ Color_PageNumberHover,
+ Color_PageNumberHighContrast,
+ Color_PageNumberBrightBackground,
+ Color_PageNumberDarkBackground,
+ Color_Selection,
+ Color_PreviewBorder,
+ Color_PageCountFontColor,
+ ColorType_Size_
+ };
+ Color GetColor (const ColorType eType);
+
+ enum GradientColorType {
+ Gradient_NormalPage,
+ Gradient_SelectedPage,
+ Gradient_SelectedAndFocusedPage,
+ Gradient_MouseOverPage,
+ Gradient_MouseOverSelected,
+ Gradient_MouseOverSelectedAndFocusedPage,
+ Gradient_FocusedPage,
+ GradientColorType_Size_
+ };
+ enum class GradientColorClass {
+ Border1,
+ Border2,
+ Fill1,
+ Fill2
+ };
+ Color GetGradientColor (
+ const GradientColorType eType,
+ const GradientColorClass eClass);
+ void SetGradient (
+ const GradientColorType eType,
+ const Color aBaseColor,
+ const sal_Int32 nSaturationOverride,
+ const sal_Int32 nBrightnessOverride,
+ const sal_Int32 nFillStartOffset,
+ const sal_Int32 nFillEndOffset,
+ const sal_Int32 nBorderStartOffset,
+ const sal_Int32 nBorderEndOffset);
+
+ enum IconType
+ {
+ Icon_RawShadow,
+ Icon_RawInsertShadow,
+ Icon_HideSlideOverlay,
+ Icon_FocusBorder,
+ IconType_Size_
+ };
+ const BitmapEx& GetIcon (const IconType eType);
+
+private:
+ class GradientDescriptor
+ {
+ public:
+ Color maFillColor1;
+ Color maFillColor2;
+ Color maBorderColor1;
+ Color maBorderColor2;
+ };
+ Color maBackgroundColor;
+ ::std::vector<GradientDescriptor> maGradients;
+ ::std::vector<BitmapEx> maIcons;
+ ::std::vector<Color> maColor;
+
+ GradientDescriptor& GetGradient (const GradientColorType eType);
+ /** Guarded initialization of the specified icon in the maIcons
+ container.
+ */
+ void InitializeIcon(const IconType eType, const OUString& rResourceId);
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
diff --git a/sd/source/ui/slidesorter/inc/view/SlsToolTip.hxx b/sd/source/ui/slidesorter/inc/view/SlsToolTip.hxx
new file mode 100644
index 000000000..6c3557e64
--- /dev/null
+++ b/sd/source/ui/slidesorter/inc/view/SlsToolTip.hxx
@@ -0,0 +1,75 @@
+/* -*- 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 .
+ */
+
+#pragma once
+
+#include <model/SlsSharedPageDescriptor.hxx>
+#include <rtl/ustring.hxx>
+#include <vcl/timer.hxx>
+
+namespace sd::slidesorter
+{
+class SlideSorter;
+}
+
+namespace sd::slidesorter::view
+{
+/** Manage the display of tool tips. The tool tip text changes when the
+ mouse is moved from slide to slide or from button to button.
+ After the mouse enters a slide the first display of the tool tip is
+ delayed for a short time in order to not draw attention from the slide
+ or its button bar.
+*/
+class ToolTip
+{
+public:
+ ToolTip(SlideSorter& rSlideSorter);
+ ~ToolTip();
+
+ /** Set a new page. This modifies the default help text. After a page
+ change a timer is started to delay the display of the tool tip for
+ the new page.
+ @param rpPage
+ When this is empty then the tool tip is hidden.
+ */
+ void SetPage(const model::SharedPageDescriptor& rpPage);
+
+ /** Hide the tool tip.
+ @return
+ Returns whether the tool tip was visible at the time this method
+ was called.
+ */
+ bool Hide();
+
+private:
+ SlideSorter& mrSlideSorter;
+ model::SharedPageDescriptor mpDescriptor;
+ OUString msCurrentHelpText;
+ void* mnHelpWindowHandle;
+ Timer maShowTimer;
+ Timer maHiddenTimer;
+
+ void DoShow();
+
+ DECL_LINK(DelayTrigger, Timer*, void);
+};
+
+} // end of namespace ::sd::slidesorter::view
+
+/* vim:set shiftwidth=4 softtabstop=4 expandtab: */