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 <vcl/image.hxx>
23 
24 #include <memory>
25 
26 class SdPage;
27 
28 namespace sd::sidebar
29 {
30 class MasterPageDescriptor;
31 class MasterPageContainerChangeEvent;
32 
33 /** This container manages the master pages used by the MasterPagesSelector
34     controls.  It uses internally a singleton implementation object.
35     Therefore, all MasterPageContainer object operator on the same set of
36     master pages.  Each MasterPageContainer, however, has its own
37     PreviewSize value and thus can independently switch between large and
38     small previews.
39 
40     The container maintains its own document to store master page objects.
41 
42     For each master page container stores its URL, preview bitmap, page
43     name, and, if available, the page object.
44 
45     Entries are accessed via a Token, which is mostly a numerical index but
46     whose values do not necessarily have to be consecutive.
47 */
48 class MasterPageContainer final
49 {
50 public:
51     typedef int Token;
52     static const Token NIL_TOKEN = -1;
53 
54     MasterPageContainer();
55     ~MasterPageContainer();
56 
57     void AddChangeListener(const Link<MasterPageContainerChangeEvent&, void>& rLink);
58     void RemoveChangeListener(const Link<MasterPageContainerChangeEvent&, void>& rLink);
59 
60     enum PreviewSize
61     {
62         SMALL,
63         LARGE
64     };
65     /** There are two different preview sizes, a small one and a large one.
66         Which one is used by the called container can be changed with this
67         method.
68         When the preview size is changed then all change listeners are
69         notified of this.
70     */
71     void SetPreviewSize(PreviewSize eSize);
72 
73     /** Returns the preview size.
74     */
GetPreviewSize() const75     PreviewSize GetPreviewSize() const { return mePreviewSize; }
76 
77     /** Return the preview size in pixels.
78     */
79     Size const& GetPreviewSizePixel() const;
80 
81     enum PreviewState
82     {
83         PS_AVAILABLE,
84         PS_CREATABLE,
85         PS_PREPARING,
86         PS_NOT_AVAILABLE
87     };
88     PreviewState GetPreviewState(Token aToken);
89 
90     /** This method is typically called for entries in the container for
91         which GetPreviewState() returns OS_CREATABLE.  The creation of the
92         preview is then scheduled to be executed asynchronously at a later
93         point in time.  When the preview is available the change listeners
94         will be notified.
95     */
96     bool RequestPreview(Token aToken);
97 
98     /** Each entry of the container is either the first page of a template
99         document or is a master page of an Impress document.
100     */
101     enum Origin
102     {
103         MASTERPAGE, // Master page of a document.
104         TEMPLATE, // First page of a template file.
105         DEFAULT, // Empty master page with default style.
106         UNKNOWN
107     };
108 
109     /** Put the master page identified and described by the given parameters
110         into the container.  When there already is a master page with the
111         given URL, page name, or object pointer (when that is not NULL) then
112         the existing entry is replaced/updated by the given one.  Otherwise
113         a new entry is inserted.
114     */
115     Token PutMasterPage(const std::shared_ptr<MasterPageDescriptor>& rDescriptor);
116     void AcquireToken(Token aToken);
117     void ReleaseToken(Token aToken);
118 
119     /** This and the GetTokenForIndex() methods can be used to iterate over
120         all members of the container.
121     */
122     int GetTokenCount() const;
123 
124     /** Determine whether the container has a member for the given token.
125     */
126     bool HasToken(Token aToken) const;
127 
128     /** Return a token for an index in the range
129         0 <= index < GetTokenCount().
130     */
131     Token GetTokenForIndex(int nIndex);
132 
133     Token GetTokenForURL(const OUString& sURL);
134     Token GetTokenForStyleName(const OUString& sStyleName);
135     Token GetTokenForPageObject(const SdPage* pPage);
136 
137     OUString GetURLForToken(Token aToken);
138     OUString GetPageNameForToken(Token aToken);
139     OUString GetStyleNameForToken(Token aToken);
140     SdPage* GetPageObjectForToken(Token aToken, bool bLoad);
141     Origin GetOriginForToken(Token aToken);
142     sal_Int32 GetTemplateIndexForToken(Token aToken);
143     std::shared_ptr<MasterPageDescriptor> GetDescriptorForToken(Token aToken);
144 
145     void InvalidatePreview(Token aToken);
146 
147     /** Return a preview for the specified token.  When the preview is not
148         present then the PreviewProvider associated with the token is
149         executed only when that is not expensive.  It is the responsibility
150         of the caller to call RequestPreview() to do the same
151         (asynchronously) for expensive PreviewProviders.
152         Call GetPreviewState() to find out if that is necessary.
153         @param aToken
154             This token specifies for which master page to return the preview.
155             Tokens are returned for example by the GetTokenFor...() methods.
156         @return
157             The returned image is the requested preview or a substitution.
158     */
159     Image GetPreviewForToken(Token aToken);
160 
161 private:
162     class Implementation;
163     std::shared_ptr<Implementation> mpImpl;
164     PreviewSize mePreviewSize;
165 };
166 
167 /** For some changes to the set of master pages in a MasterPageContainer or
168     to the data stored for each master page one or more events are sent to
169     registered listeners.
170     Each event has an event type and a token that tells the listener where
171     the change took place.
172 */
173 class MasterPageContainerChangeEvent
174 {
175 public:
176     enum class EventType
177     {
178         // A master page was added to the container.
179         CHILD_ADDED,
180         // A master page was removed from the container.
181         CHILD_REMOVED,
182         // The preview of a master page has changed.
183         PREVIEW_CHANGED,
184         // The size of a preview has changed.
185         SIZE_CHANGED,
186         // Some of the data stored for a master page has changed.
187         DATA_CHANGED,
188         // The TemplateIndex of a master page has changed.
189         INDEX_CHANGED,
190     } meEventType;
191 
192     // Token of the container entry whose data changed or which was added or
193     // removed.
194     MasterPageContainer::Token maChildToken;
195 };
196 
197 } // end of namespace sd::sidebar
198 
199 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
200