1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  *   Licensed to the Apache Software Foundation (ASF) under one or more
12  *   contributor license agreements. See the NOTICE file distributed
13  *   with this work for additional information regarding copyright
14  *   ownership. The ASF licenses this file to you under the Apache
15  *   License, Version 2.0 (the "License"); you may not use this file
16  *   except in compliance with the License. You may obtain a copy of
17  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
20 #pragma once
21 
22 #include <map>
23 #include <memory>
24 #include "MasterPageContainer.hxx"
25 #include "PreviewValueSet.hxx"
26 #include <sfx2/sidebar/ILayoutableWindow.hxx>
27 #include <sfx2/sidebar/PanelLayout.hxx>
28 
29 #include <osl/mutex.hxx>
30 
31 namespace com::sun::star::ui { class XSidebar; }
32 class MouseEvent;
33 class SdDrawDocument;
34 class SdPage;
35 
36 namespace sd {
37 class ViewShellBase;
38 }
39 
40 namespace sd::sidebar {
41 
42 /** Base class of a menu that lets the user select from a list of
43     templates or designs that are loaded from files.
44 */
45 class MasterPagesSelector : public PanelLayout
46                           , public sfx2::sidebar::ILayoutableWindow
47 {
48 public:
49     MasterPagesSelector (
50         weld::Widget* pParent,
51         SdDrawDocument& rDocument,
52         ViewShellBase& rBase,
53         const std::shared_ptr<MasterPageContainer>& rpContainer,
54         const css::uno::Reference<css::ui::XSidebar>& rxSidebar);
55     virtual ~MasterPagesSelector() override;
56 
57     virtual void LateInit();
58 
59     sal_Int32 GetPreferredHeight (sal_Int32 nWidth);
60 
61     /** Make the selector empty.  This method clear the value set from any
62         entries. Override this method to add functionality, especially to
63         destroy objects set as data items at the value set.
64     */
65     void ClearPageSet();
66 
67     void SetHelpId( const OString& aId );
68 
69     /** Mark the preview that belongs to the given index as not up-to-date
70         anymore with respect to page content or preview size.
71         The implementation of this method will either sunchronously or
72         asynchronously call UpdatePreview().
73         @param nIndex
74             Index into the value set control that is used for displaying the
75             previews.
76     */
77     void InvalidatePreview (const SdPage* pPage);
78 
79     void UpdateAllPreviews();
80 
81     void ShowContextMenu(const Point* pPos);
82 
83     // ILayoutableWindow
84     virtual css::ui::LayoutSize GetHeightForWidth (const sal_Int32 nWidth) override;
85 
86 protected:
87     mutable ::osl::Mutex maMutex;
88     std::shared_ptr<MasterPageContainer> mpContainer;
89 
90     std::unique_ptr<PreviewValueSet> mxPreviewValueSet;
91     std::unique_ptr<weld::CustomWeld> mxPreviewValueSetWin;
92 
93     SdDrawDocument& mrDocument;
94     ViewShellBase& mrBase;
95 
96     SdPage* GetSelectedMasterPage();
97 
98     /** Assign the given master page to all slides of the document.
99         @param pMasterPage
100             The master page to assign to all slides.
101     */
102     void AssignMasterPageToAllSlides (SdPage* pMasterPage);
103 
104     /** Assign the given master page to all slides that are selected in a
105         slide sorter that is displayed in the lef or center pane.  When both
106         panes display a slide sorter then the one in the center pane is
107         used.
108     */
109     void AssignMasterPageToSelectedSlides (SdPage* pMasterPage);
110 
111     virtual void AssignMasterPageToPageList (
112         SdPage* pMasterPage,
113         const std::shared_ptr<std::vector<SdPage*>>& rPageList);
114 
115     virtual void NotifyContainerChangeEvent (const MasterPageContainerChangeEvent& rEvent);
116 
117     typedef ::std::pair<int, MasterPageContainer::Token> UserData;
118     UserData* GetUserData (int nIndex) const;
119     void SetUserData (int nIndex, std::unique_ptr<UserData> pData);
120 
121     sal_Int32 GetIndexForToken (MasterPageContainer::Token aToken) const;
122     typedef ::std::vector<MasterPageContainer::Token> ItemList;
123     void UpdateItemList (::std::unique_ptr<ItemList> && pList);
124     void Clear();
125     /** Invalidate the specified item so that on the next Fill() this item
126         is updated.
127     */
128     void InvalidateItem (MasterPageContainer::Token aToken);
129 
130     // For every item in the ValueSet we store its associated token.  This
131     // allows a faster access and easier change tracking.
132     ItemList maCurrentItemList;
133     typedef ::std::map<MasterPageContainer::Token,sal_Int32> TokenToValueSetIndex;
134     TokenToValueSetIndex maTokenToValueSetIndex;
135 
136     ItemList maLockedMasterPages;
137     /** Lock master pages in the given list and release locks that were
138         previously acquired.
139     */
140     void UpdateLocks (const ItemList& rItemList);
141 
142     void Fill();
143     virtual void Fill (ItemList& rItemList) = 0;
144 
145     /** Give derived classes the opportunity to provide their own context
146         menu.  If they do then they probably have to provide their own
147         Execute() and GetState() methods as well.
148     */
149     virtual OUString GetContextMenuUIFile() const;
150 
151     virtual void ProcessPopupMenu(weld::Menu& rMenu);
152     virtual void ExecuteCommand(const OString& rIdent);
153 
154 private:
155     css::uno::Reference<css::ui::XSidebar> mxSidebar;
156 
157     /** The offset between ValueSet index and MasterPageContainer::Token
158         last seen.  This value is used heuristically to speed up the lookup
159         of an index for a token.
160     */
161     DECL_LINK(ClickHandler, ValueSet*, void);
162     DECL_LINK(ContextMenuHandler, const Point*, void);
163     DECL_LINK(ContainerChangeListener, MasterPageContainerChangeEvent&, void);
164 
165     void SetItem (
166         sal_uInt16 nIndex,
167         MasterPageContainer::Token aToken);
168     void AddTokenToIndexEntry (
169         sal_uInt16 nIndex,
170         MasterPageContainer::Token aToken);
171     void RemoveTokenToIndexEntry (
172         sal_uInt16 nIndex,
173         MasterPageContainer::Token aToken);
174 };
175 
176 } // end of namespace sd::sidebar
177 
178 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
179