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 <memory> 21 #include "MasterPageDescriptor.hxx" 22 #include "MasterPageContainerProviders.hxx" 23 24 #include "DocumentHelper.hxx" 25 #include <PreviewRenderer.hxx> 26 #include <sdpage.hxx> 27 #include <tools/urlobj.hxx> 28 #include <sal/log.hxx> 29 30 namespace sd::sidebar { 31 32 //===== MasterPageDescriptor ================================================== 33 34 MasterPageDescriptor::MasterPageDescriptor ( 35 MasterPageContainer::Origin eOrigin, 36 const sal_Int32 nTemplateIndex, 37 const OUString& rsURL, 38 const OUString& rsPageName, 39 const OUString& rsStyleName, 40 const bool bIsPrecious, 41 const std::shared_ptr<PageObjectProvider>& rpPageObjectProvider, 42 const std::shared_ptr<PreviewProvider>& rpPreviewProvider) 43 : maToken(MasterPageContainer::NIL_TOKEN), 44 meOrigin(eOrigin), 45 msURL(INetURLObject(rsURL).GetMainURL(INetURLObject::DecodeMechanism::Unambiguous)), 46 msPageName(rsPageName), 47 msStyleName(rsStyleName), 48 mbIsPrecious(bIsPrecious), 49 mpMasterPage(nullptr), 50 mpSlide(nullptr), 51 maSmallPreview(), 52 maLargePreview(), 53 mpPreviewProvider(rpPreviewProvider), 54 mpPageObjectProvider(rpPageObjectProvider), 55 mnTemplateIndex(nTemplateIndex), 56 meURLClassification(URLCLASS_UNDETERMINED), 57 mnUseCount(0) 58 { 59 } 60 61 void MasterPageDescriptor::SetToken (MasterPageContainer::Token aToken) 62 { 63 maToken = aToken; 64 } 65 66 const Image& MasterPageDescriptor::GetPreview (MasterPageContainer::PreviewSize eSize) const 67 { 68 if (eSize == MasterPageContainer::SMALL) 69 return maSmallPreview; 70 else 71 return maLargePreview; 72 } 73 74 ::std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > 75 MasterPageDescriptor::Update ( 76 const MasterPageDescriptor& rDescriptor) 77 { 78 bool bDataChanged (false); 79 bool bIndexChanged (false); 80 bool bPreviewChanged (false); 81 82 if (meOrigin==MasterPageContainer::UNKNOWN 83 && rDescriptor.meOrigin!=MasterPageContainer::UNKNOWN) 84 { 85 meOrigin = rDescriptor.meOrigin; 86 bIndexChanged = true; 87 } 88 89 if (msURL.isEmpty() && !rDescriptor.msURL.isEmpty()) 90 { 91 msURL = rDescriptor.msURL; 92 bDataChanged = true; 93 } 94 95 if (msPageName.isEmpty() && !rDescriptor.msPageName.isEmpty()) 96 { 97 msPageName = rDescriptor.msPageName; 98 bDataChanged = true; 99 } 100 101 if (msStyleName.isEmpty() && !rDescriptor.msStyleName.isEmpty()) 102 { 103 msStyleName = rDescriptor.msStyleName; 104 bDataChanged = true; 105 } 106 107 if (mpPageObjectProvider == nullptr && rDescriptor.mpPageObjectProvider != nullptr) 108 { 109 mpPageObjectProvider = rDescriptor.mpPageObjectProvider; 110 bDataChanged = true; 111 } 112 113 if (mpPreviewProvider == nullptr && rDescriptor.mpPreviewProvider != nullptr) 114 { 115 mpPreviewProvider = rDescriptor.mpPreviewProvider; 116 bPreviewChanged = true; 117 } 118 119 if (mnTemplateIndex<0 && rDescriptor.mnTemplateIndex>=0) 120 { 121 mnTemplateIndex = rDescriptor.mnTemplateIndex; 122 bIndexChanged = true; 123 } 124 125 // Prepare the list of event types that will be returned. 126 ::std::unique_ptr<std::vector<MasterPageContainerChangeEvent::EventType> > pResult; 127 if (bDataChanged || bIndexChanged || bPreviewChanged) 128 { 129 pResult.reset(new std::vector<MasterPageContainerChangeEvent::EventType>); 130 if (bDataChanged) 131 pResult->push_back(MasterPageContainerChangeEvent::EventType::DATA_CHANGED); 132 if (bIndexChanged) 133 pResult->push_back(MasterPageContainerChangeEvent::EventType::INDEX_CHANGED); 134 if (bPreviewChanged) 135 pResult->push_back(MasterPageContainerChangeEvent::EventType::PREVIEW_CHANGED); 136 } 137 138 return pResult; 139 } 140 141 int MasterPageDescriptor::UpdatePageObject ( 142 sal_Int32 nCostThreshold, 143 SdDrawDocument* pDocument) 144 { 145 int nModified = 0; 146 147 // Update the page object when that is not yet known. 148 if (mpMasterPage == nullptr && mpPageObjectProvider != nullptr 149 && (nCostThreshold < 0 || mpPageObjectProvider->GetCostIndex() <= nCostThreshold)) 150 { 151 // Note that pDocument may be NULL. 152 153 SdPage* pPage = (*mpPageObjectProvider)(pDocument); 154 if (meOrigin == MasterPageContainer::MASTERPAGE) 155 { 156 mpMasterPage = pPage; 157 if (mpMasterPage != nullptr) 158 mpMasterPage->SetPrecious(mbIsPrecious); 159 } 160 else 161 { 162 // Master pages from templates are copied into the local document. 163 if (pDocument != nullptr) 164 mpMasterPage = DocumentHelper::CopyMasterPageToLocalDocument(*pDocument,pPage); 165 mpSlide = DocumentHelper::GetSlideForMasterPage(mpMasterPage); 166 } 167 168 if (mpMasterPage != nullptr) 169 { 170 // Update page name and style name. 171 if (msPageName.isEmpty()) 172 msPageName = mpMasterPage->GetName(); 173 msStyleName = mpMasterPage->GetName(); 174 175 // Delete an existing substitution. The next request for a preview 176 // will create the real one. 177 maSmallPreview = Image(); 178 maLargePreview = Image(); 179 mpPreviewProvider = std::make_shared<PagePreviewProvider>(); 180 } 181 else 182 { 183 SAL_WARN( "sd", "UpdatePageObject: master page is NULL"); 184 return -1; 185 } 186 187 nModified = 1; 188 } 189 190 return nModified; 191 } 192 193 bool MasterPageDescriptor::UpdatePreview ( 194 sal_Int32 nCostThreshold, 195 const Size& rSmallSize, 196 const Size& rLargeSize, 197 ::sd::PreviewRenderer& rRenderer) 198 { 199 bool bModified (false); 200 201 // Update the preview when that is not yet known. 202 if (maLargePreview.GetSizePixel().Width() == 0 && mpPreviewProvider != nullptr 203 && (nCostThreshold < 0 || mpPreviewProvider->GetCostIndex() <= nCostThreshold)) 204 { 205 SdPage* pPage = mpSlide; 206 if (pPage == nullptr) 207 { 208 pPage = mpMasterPage; 209 } 210 //TODO: Notify LOOL of preview updates. 211 maLargePreview = (*mpPreviewProvider)( 212 rLargeSize.Width(), 213 pPage, 214 rRenderer); 215 if (maLargePreview.GetSizePixel().Width() > 0) 216 { 217 // Create the small preview by scaling the large one down. 218 maSmallPreview = rRenderer.ScaleBitmap( 219 maLargePreview.GetBitmapEx(), 220 rSmallSize.Width()); 221 // The large preview may not have the desired width. Scale it 222 // accordingly. 223 if (maLargePreview.GetSizePixel().Width() != rLargeSize.Width()) 224 maLargePreview = rRenderer.ScaleBitmap( 225 maLargePreview.GetBitmapEx(), 226 rLargeSize.Width()); 227 bModified = true; 228 } 229 } 230 231 return bModified; 232 } 233 234 MasterPageDescriptor::URLClassification MasterPageDescriptor::GetURLClassification() 235 { 236 if (meURLClassification == URLCLASS_UNDETERMINED) 237 { 238 if (msURL.isEmpty()) 239 meURLClassification = URLCLASS_UNKNOWN; 240 else if (msURL.indexOf("presnt")>=0) 241 { 242 meURLClassification = URLCLASS_PRESENTATION; 243 } 244 else if (msURL.indexOf("layout")>=0) 245 { 246 meURLClassification = URLCLASS_LAYOUT; 247 } 248 else if (msURL.indexOf("educate")>=0) 249 { 250 meURLClassification = URLCLASS_OTHER; 251 } 252 else 253 { 254 meURLClassification = URLCLASS_USER; 255 } 256 } 257 258 return meURLClassification; 259 } 260 261 //===== URLComparator ========================================================= 262 263 MasterPageDescriptor::URLComparator::URLComparator (const OUString& sURL) 264 : msURL(sURL) 265 { 266 } 267 268 bool MasterPageDescriptor::URLComparator::operator() ( 269 const SharedMasterPageDescriptor& rDescriptor) 270 { 271 if (!rDescriptor) 272 return false; 273 else 274 return rDescriptor->msURL == msURL; 275 } 276 277 // ===== StyleNameComparator ================================================== 278 279 MasterPageDescriptor::StyleNameComparator::StyleNameComparator (const OUString& sStyleName) 280 : msStyleName(sStyleName) 281 { 282 } 283 284 bool MasterPageDescriptor::StyleNameComparator::operator() ( 285 const SharedMasterPageDescriptor& rDescriptor) 286 { 287 if (!rDescriptor) 288 return false; 289 else 290 return rDescriptor->msStyleName == msStyleName; 291 } 292 293 //===== PageObjectComparator ================================================== 294 295 MasterPageDescriptor::PageObjectComparator::PageObjectComparator (const SdPage* pPageObject) 296 : mpMasterPage(pPageObject) 297 { 298 } 299 300 bool MasterPageDescriptor::PageObjectComparator::operator() ( 301 const SharedMasterPageDescriptor& rDescriptor) 302 { 303 if (!rDescriptor) 304 return false; 305 else 306 return rDescriptor->mpMasterPage==mpMasterPage; 307 } 308 309 //===== AllComparator ========================================================= 310 311 MasterPageDescriptor::AllComparator::AllComparator(const SharedMasterPageDescriptor& rDescriptor) 312 : mpDescriptor(rDescriptor) 313 { 314 } 315 316 bool MasterPageDescriptor::AllComparator::operator() (const SharedMasterPageDescriptor&rDescriptor) 317 { 318 if (!rDescriptor) 319 return false; 320 else 321 { 322 // Take URL, page name, style name, and page object into account 323 // when comparing two descriptors. When two descriptors are 324 // identical in any of these values then there are thought of as 325 // equivalent. Only the Origin has to be the same in both 326 // descriptors. 327 return mpDescriptor->meOrigin == rDescriptor->meOrigin 328 && ((!mpDescriptor->msURL.isEmpty() && mpDescriptor->msURL == rDescriptor->msURL) 329 || (!mpDescriptor->msPageName.isEmpty() 330 && mpDescriptor->msPageName == rDescriptor->msPageName) 331 || (!mpDescriptor->msStyleName.isEmpty() 332 && mpDescriptor->msStyleName == rDescriptor->msStyleName) 333 || (mpDescriptor->mpMasterPage != nullptr 334 && mpDescriptor->mpMasterPage == rDescriptor->mpMasterPage) 335 || (mpDescriptor->mpPageObjectProvider != nullptr 336 && rDescriptor->mpPageObjectProvider != nullptr 337 && mpDescriptor->mpPageObjectProvider == rDescriptor->mpPageObjectProvider)); 338 } 339 } 340 341 } // end of namespace sd::sidebar 342 343 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ 344
