/src/libreoffice/sd/source/ui/sidebar/CurrentMasterPagesSelector.cxx
Line | Count | Source |
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 | | #include "CurrentMasterPagesSelector.hxx" |
21 | | #include <ViewShellBase.hxx> |
22 | | #include <DrawViewShell.hxx> |
23 | | #include <drawdoc.hxx> |
24 | | #include <sdpage.hxx> |
25 | | #include "MasterPageContainer.hxx" |
26 | | #include "MasterPageContainerProviders.hxx" |
27 | | #include "MasterPageDescriptor.hxx" |
28 | | #include <EventMultiplexer.hxx> |
29 | | #include <DrawDocShell.hxx> |
30 | | #include <osl/diagnose.h> |
31 | | #include <vcl/weld/Menu.hxx> |
32 | | |
33 | | #include <helpids.h> |
34 | | |
35 | | #include <set> |
36 | | |
37 | | using namespace ::com::sun::star; |
38 | | |
39 | | namespace sd::sidebar { |
40 | | |
41 | | std::unique_ptr<PanelLayout> CurrentMasterPagesSelector::Create ( |
42 | | weld::Widget* pParent, |
43 | | ViewShellBase& rViewShellBase, |
44 | | const css::uno::Reference<css::ui::XSidebar>& rxSidebar) |
45 | 0 | { |
46 | 0 | SdDrawDocument* pDocument = rViewShellBase.GetDocument(); |
47 | 0 | if (pDocument == nullptr) |
48 | 0 | return nullptr; |
49 | | |
50 | 0 | auto pContainer = std::make_shared<MasterPageContainer>(); |
51 | |
|
52 | 0 | auto xSelector(std::make_unique<CurrentMasterPagesSelector>( |
53 | 0 | pParent, |
54 | 0 | *pDocument, |
55 | 0 | rViewShellBase, |
56 | 0 | pContainer, |
57 | 0 | rxSidebar)); |
58 | 0 | xSelector->SetHelpId( HID_SD_TASK_PANE_PREVIEW_CURRENT ); |
59 | |
|
60 | 0 | return xSelector; |
61 | 0 | } |
62 | | |
63 | | CurrentMasterPagesSelector::CurrentMasterPagesSelector( |
64 | | weld::Widget* pParent, SdDrawDocument& rDocument, ViewShellBase& rBase, |
65 | | const std::shared_ptr<MasterPageContainer>& rpContainer, |
66 | | const css::uno::Reference<css::ui::XSidebar>& rxSidebar) |
67 | 0 | : MasterPagesSelector(pParent, rDocument, rBase, rpContainer, rxSidebar, |
68 | 0 | u"modules/simpress/ui/masterpagepanel.ui"_ustr, |
69 | 0 | u"masterpagecurrent_icons"_ustr) |
70 | 0 | { |
71 | 0 | Link<sdtools::EventMultiplexerEvent&, void> aLink( |
72 | 0 | LINK(this, CurrentMasterPagesSelector, EventMultiplexerListener)); |
73 | 0 | mpEventMultiplexer = rBase.GetEventMultiplexer(); |
74 | 0 | mpEventMultiplexer->AddEventListener(aLink); |
75 | 0 | } |
76 | | |
77 | | CurrentMasterPagesSelector::~CurrentMasterPagesSelector() |
78 | 0 | { |
79 | 0 | if (mrDocument.GetDocSh() != nullptr) |
80 | 0 | { |
81 | 0 | EndListening(*mrDocument.GetDocSh()); |
82 | 0 | } |
83 | 0 | else |
84 | 0 | { |
85 | 0 | OSL_ASSERT(mrDocument.GetDocSh() != nullptr); |
86 | 0 | } |
87 | |
|
88 | 0 | Link<sdtools::EventMultiplexerEvent&,void> aLink (LINK(this,CurrentMasterPagesSelector,EventMultiplexerListener)); |
89 | 0 | mpEventMultiplexer->RemoveEventListener(aLink); |
90 | 0 | } |
91 | | |
92 | | void CurrentMasterPagesSelector::LateInit() |
93 | 0 | { |
94 | 0 | MasterPagesSelector::LateInit(); |
95 | 0 | if (mrDocument.GetDocSh() != nullptr) |
96 | 0 | { |
97 | 0 | StartListening(*mrDocument.GetDocSh()); |
98 | 0 | } |
99 | 0 | else |
100 | 0 | { |
101 | 0 | OSL_ASSERT(mrDocument.GetDocSh() != nullptr); |
102 | 0 | } |
103 | 0 | } |
104 | | |
105 | | void CurrentMasterPagesSelector::Fill (ItemList& rItemList) |
106 | 0 | { |
107 | 0 | sal_uInt16 nPageCount = mrDocument.GetMasterSdPageCount(PageKind::Standard); |
108 | | // Remember the names of the master pages that have been inserted to |
109 | | // avoid double insertion. |
110 | 0 | ::std::set<OUString> aMasterPageNames; |
111 | 0 | for (sal_uInt16 nIndex=0; nIndex<nPageCount; nIndex++) |
112 | 0 | { |
113 | 0 | SdPage* pMasterPage = mrDocument.GetMasterSdPage (nIndex, PageKind::Standard); |
114 | 0 | if (pMasterPage == nullptr) |
115 | 0 | continue; |
116 | | |
117 | | // Use the name of the master page to avoid duplicate entries. |
118 | 0 | OUString sName (pMasterPage->GetName()); |
119 | 0 | if (!aMasterPageNames.insert(sName).second) |
120 | 0 | continue; |
121 | | |
122 | | // Look up the master page in the container and, when it is not yet |
123 | | // in it, insert it. |
124 | 0 | MasterPageContainer::Token aToken = mpContainer->GetTokenForPageObject(pMasterPage); |
125 | 0 | if (aToken == MasterPageContainer::NIL_TOKEN) |
126 | 0 | { |
127 | 0 | SharedMasterPageDescriptor pDescriptor = std::make_shared<MasterPageDescriptor>( |
128 | 0 | MasterPageContainer::MASTERPAGE, |
129 | 0 | nIndex, |
130 | 0 | OUString(), |
131 | 0 | pMasterPage->GetName(), |
132 | 0 | OUString(), |
133 | 0 | pMasterPage->IsPrecious(), |
134 | 0 | std::make_shared<ExistingPageProvider>(pMasterPage), |
135 | 0 | std::make_shared<PagePreviewProvider>()); |
136 | 0 | aToken = mpContainer->PutMasterPage(pDescriptor); |
137 | 0 | } |
138 | |
|
139 | 0 | rItemList.push_back(aToken); |
140 | 0 | } |
141 | 0 | } |
142 | | |
143 | | OUString CurrentMasterPagesSelector::GetContextMenuUIFile() const |
144 | 0 | { |
145 | 0 | return u"modules/simpress/ui/currentmastermenu.ui"_ustr; |
146 | 0 | } |
147 | | |
148 | | void CurrentMasterPagesSelector::UpdateSelection() |
149 | 0 | { |
150 | | // Iterate over all pages and for the selected ones put the name of |
151 | | // their master page into a set. |
152 | 0 | sal_uInt16 nPageCount = mrDocument.GetSdPageCount(PageKind::Standard); |
153 | 0 | ::std::set<OUString> aNames; |
154 | 0 | sal_uInt16 nIndex; |
155 | 0 | bool bLoop (true); |
156 | 0 | for (nIndex=0; nIndex<nPageCount && bLoop; nIndex++) |
157 | 0 | { |
158 | 0 | SdPage* pPage = mrDocument.GetSdPage (nIndex, PageKind::Standard); |
159 | 0 | if (pPage != nullptr && pPage->IsSelected()) |
160 | 0 | { |
161 | 0 | if ( ! pPage->TRG_HasMasterPage()) |
162 | 0 | { |
163 | | // One of the pages has no master page. This is an |
164 | | // indicator for that this method is called in the middle of |
165 | | // a document change and that the model is not in a valid |
166 | | // state. Therefore we stop update the selection and wait |
167 | | // for another call to UpdateSelection when the model is |
168 | | // valid again. |
169 | 0 | bLoop = false; |
170 | 0 | } |
171 | 0 | else |
172 | 0 | { |
173 | 0 | SdrPage& rMasterPage (pPage->TRG_GetMasterPage()); |
174 | 0 | assert(dynamic_cast<SdPage*>(&rMasterPage)); |
175 | 0 | aNames.insert(static_cast<SdPage&>(rMasterPage).GetName()); |
176 | 0 | } |
177 | 0 | } |
178 | 0 | } |
179 | 0 | } |
180 | | |
181 | | void CurrentMasterPagesSelector::ExecuteCommand(const OUString &rIdent) |
182 | 0 | { |
183 | 0 | if (rIdent == "delete") |
184 | 0 | { |
185 | | // Check once again that the master page can safely be deleted, |
186 | | // i.e. is not used. |
187 | 0 | SdPage* pMasterPage = GetSelectedMasterPage(); |
188 | 0 | if (pMasterPage != nullptr |
189 | 0 | && mrDocument.GetMasterPageUserCount(pMasterPage) == 0) |
190 | 0 | { |
191 | | // Removing the precious flag so that the following call to |
192 | | // RemoveUnnecessaryMasterPages() will remove this master page. |
193 | 0 | pMasterPage->SetPrecious(false); |
194 | 0 | mrDocument.RemoveUnnecessaryMasterPages(pMasterPage); |
195 | 0 | } |
196 | 0 | } |
197 | 0 | else |
198 | 0 | MasterPagesSelector::ExecuteCommand(rIdent); |
199 | 0 | } |
200 | | |
201 | | void CurrentMasterPagesSelector::ProcessPopupMenu(weld::Menu& rMenu) |
202 | 0 | { |
203 | | // Disable the delete entry when there is only one master page. |
204 | 0 | if (mrDocument.GetMasterPageUserCount(GetSelectedMasterPage()) > 0) |
205 | 0 | rMenu.set_sensitive(u"delete"_ustr, false); |
206 | |
|
207 | 0 | std::shared_ptr<DrawViewShell> pDrawViewShell ( |
208 | 0 | std::dynamic_pointer_cast<DrawViewShell>(mrBase.GetMainViewShell())); |
209 | 0 | if (pDrawViewShell && pDrawViewShell->GetEditMode() == EditMode::MasterPage) |
210 | 0 | { |
211 | 0 | rMenu.set_sensitive(u"edit"_ustr, false); |
212 | 0 | } |
213 | |
|
214 | 0 | MasterPagesSelector::ProcessPopupMenu(rMenu); |
215 | 0 | } |
216 | | |
217 | | IMPL_LINK(CurrentMasterPagesSelector,EventMultiplexerListener, |
218 | | sdtools::EventMultiplexerEvent&, rEvent, void) |
219 | 0 | { |
220 | 0 | switch (rEvent.meEventId) |
221 | 0 | { |
222 | 0 | case EventMultiplexerEventId::CurrentPageChanged: |
223 | 0 | case EventMultiplexerEventId::EditModeNormal: |
224 | 0 | case EventMultiplexerEventId::EditModeMaster: |
225 | 0 | case EventMultiplexerEventId::SlideSortedSelection: |
226 | 0 | UpdateSelection(); |
227 | 0 | break; |
228 | | |
229 | 0 | case EventMultiplexerEventId::PageOrder: |
230 | | // This is tricky. If a master page is removed, moved, or |
231 | | // added we have to wait until both the notes master page |
232 | | // and the standard master page have been removed, moved, |
233 | | // or added. We do this by looking at the number of master |
234 | | // pages which has to be odd in the consistent state (the |
235 | | // handout master page is always present). If the number is |
236 | | // even we ignore the hint. |
237 | 0 | if (mrBase.GetDocument()->GetMasterPageCount()%2 == 1) |
238 | 0 | MasterPagesSelector::Fill(); |
239 | 0 | break; |
240 | | |
241 | 0 | case EventMultiplexerEventId::ShapeChanged: |
242 | 0 | case EventMultiplexerEventId::ShapeInserted: |
243 | 0 | case EventMultiplexerEventId::ShapeRemoved: |
244 | 0 | InvalidatePreview(static_cast<const SdPage*>(rEvent.mpUserData)); |
245 | 0 | break; |
246 | 0 | default: break; |
247 | 0 | } |
248 | 0 | } |
249 | | |
250 | | } // end of namespace sd::sidebar |
251 | | |
252 | | /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ |