1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 #include "precompiled_sd.hxx" 23 24 #include "MasterPageContainerProviders.hxx" 25 26 #include "DrawDocShell.hxx" 27 #include "drawdoc.hxx" 28 #include "PreviewRenderer.hxx" 29 #include <comphelper/processfactory.hxx> 30 #include <sfx2/app.hxx> 31 #include <sfx2/sfxsids.hrc> 32 #include <unotools/ucbstreamhelper.hxx> 33 #include <vcl/image.hxx> 34 #include <vcl/pngread.hxx> 35 #include <com/sun/star/embed/ElementModes.hpp> 36 #include <tools/diagnose_ex.h> 37 38 using namespace ::com::sun::star; 39 using namespace ::com::sun::star::uno; 40 41 namespace sd { namespace sidebar { 42 43 44 //===== PagePreviewProvider =================================================== 45 46 PagePreviewProvider::PagePreviewProvider (void) 47 { 48 } 49 50 51 52 53 Image PagePreviewProvider::operator () ( 54 int nWidth, 55 SdPage* pPage, 56 ::sd::PreviewRenderer& rRenderer) 57 { 58 Image aPreview; 59 60 if (pPage != NULL) 61 { 62 // Use the given renderer to create a preview of the given page 63 // object. 64 aPreview = rRenderer.RenderPage( 65 pPage, 66 nWidth, 67 String::CreateFromAscii(""), 68 false); 69 } 70 71 return aPreview; 72 } 73 74 75 76 77 int PagePreviewProvider::GetCostIndex (void) 78 { 79 return 5; 80 } 81 82 83 84 85 bool PagePreviewProvider::NeedsPageObject (void) 86 { 87 return true; 88 } 89 90 91 92 93 //===== TemplatePreviewProvider =============================================== 94 95 TemplatePreviewProvider::TemplatePreviewProvider (const ::rtl::OUString& rsURL) 96 : msURL(rsURL) 97 { 98 } 99 100 101 102 103 Image TemplatePreviewProvider::operator() ( 104 int nWidth, 105 SdPage* pPage, 106 ::sd::PreviewRenderer& rRenderer) 107 { 108 // Unused parameters. 109 (void)nWidth; 110 (void)pPage; 111 (void)rRenderer; 112 113 // Load the thumbnail from a template document. 114 uno::Reference<io::XInputStream> xIStream; 115 116 uno::Reference< lang::XMultiServiceFactory > xServiceManager ( 117 ::comphelper::getProcessServiceFactory()); 118 if (xServiceManager.is()) 119 { 120 try 121 { 122 uno::Reference<lang::XSingleServiceFactory> xStorageFactory( 123 xServiceManager->createInstance( 124 ::rtl::OUString::createFromAscii( 125 "com.sun.star.embed.StorageFactory")), 126 uno::UNO_QUERY); 127 128 if (xStorageFactory.is()) 129 { 130 uno::Sequence<uno::Any> aArgs (2); 131 aArgs[0] <<= msURL; 132 aArgs[1] <<= embed::ElementModes::READ; 133 uno::Reference<embed::XStorage> xDocStorage ( 134 xStorageFactory->createInstanceWithArguments(aArgs), 135 uno::UNO_QUERY); 136 137 try 138 { 139 if (xDocStorage.is()) 140 { 141 uno::Reference<embed::XStorage> xStorage ( 142 xDocStorage->openStorageElement( 143 ::rtl::OUString::createFromAscii("Thumbnails"), 144 embed::ElementModes::READ)); 145 if (xStorage.is()) 146 { 147 uno::Reference<io::XStream> xThumbnailCopy ( 148 xStorage->cloneStreamElement( 149 ::rtl::OUString::createFromAscii( 150 "thumbnail.png"))); 151 if (xThumbnailCopy.is()) 152 xIStream = xThumbnailCopy->getInputStream(); 153 } 154 } 155 } 156 catch (uno::Exception& rException) 157 { 158 OSL_TRACE ( 159 "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s", 160 ::rtl::OUStringToOString(msURL, 161 RTL_TEXTENCODING_UTF8).getStr(), 162 ::rtl::OUStringToOString(rException.Message, 163 RTL_TEXTENCODING_UTF8).getStr()); 164 } 165 166 try 167 { 168 // An (older) implementation had a bug - The storage 169 // name was "Thumbnail" instead of "Thumbnails". The 170 // old name is still used as fallback but this code can 171 // be removed soon. 172 if ( ! xIStream.is()) 173 { 174 uno::Reference<embed::XStorage> xStorage ( 175 xDocStorage->openStorageElement( 176 ::rtl::OUString::createFromAscii("Thumbnail"), 177 embed::ElementModes::READ)); 178 if (xStorage.is()) 179 { 180 uno::Reference<io::XStream> xThumbnailCopy ( 181 xStorage->cloneStreamElement( 182 ::rtl::OUString::createFromAscii( 183 "thumbnail.png"))); 184 if (xThumbnailCopy.is()) 185 xIStream = xThumbnailCopy->getInputStream(); 186 } 187 } 188 } 189 catch (uno::Exception& rException) 190 { 191 OSL_TRACE ( 192 "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s", 193 ::rtl::OUStringToOString(msURL, 194 RTL_TEXTENCODING_UTF8).getStr(), 195 ::rtl::OUStringToOString(rException.Message, 196 RTL_TEXTENCODING_UTF8).getStr()); 197 } 198 } 199 } 200 catch (uno::Exception& rException) 201 { 202 OSL_TRACE ( 203 "caught exception while trying to access tuhmbnail of %s: %s", 204 ::rtl::OUStringToOString(msURL, 205 RTL_TEXTENCODING_UTF8).getStr(), 206 ::rtl::OUStringToOString(rException.Message, 207 RTL_TEXTENCODING_UTF8).getStr()); 208 } 209 } 210 211 // Extract the image from the stream. 212 BitmapEx aThumbnail; 213 if (xIStream.is()) 214 { 215 ::std::auto_ptr<SvStream> pStream ( 216 ::utl::UcbStreamHelper::CreateStream (xIStream)); 217 ::vcl::PNGReader aReader (*pStream); 218 aThumbnail = aReader.Read (); 219 } 220 221 // Note that the preview is returned without scaling it to the desired 222 // width. This gives the caller the chance to take advantage of a 223 // possibly larger resolution then was asked for. 224 return aThumbnail; 225 } 226 227 228 229 230 int TemplatePreviewProvider::GetCostIndex (void) 231 { 232 return 10; 233 } 234 235 236 237 238 bool TemplatePreviewProvider::NeedsPageObject (void) 239 { 240 return false; 241 } 242 243 244 245 246 //===== TemplatePageObjectProvider ============================================= 247 248 TemplatePageObjectProvider::TemplatePageObjectProvider (const ::rtl::OUString& rsURL) 249 : msURL(rsURL), 250 mxDocumentShell() 251 { 252 } 253 254 255 256 257 SdPage* TemplatePageObjectProvider::operator() (SdDrawDocument* pContainerDocument) 258 { 259 // Unused parameters. 260 (void)pContainerDocument; 261 262 SdPage* pPage = NULL; 263 264 mxDocumentShell = NULL; 265 ::sd::DrawDocShell* pDocumentShell = NULL; 266 try 267 { 268 // Load the template document and return its first page. 269 pDocumentShell = LoadDocument (msURL); 270 if (pDocumentShell != NULL) 271 { 272 SdDrawDocument* pDocument = pDocumentShell->GetDoc(); 273 if (pDocument != NULL) 274 { 275 pPage = pDocument->GetMasterSdPage(0, PK_STANDARD); 276 // In order to make the newly loaded master page deletable 277 // when copied into documents it is marked as no "precious". 278 // When it is modified then it is marked as "precious". 279 if (pPage != NULL) 280 pPage->SetPrecious(false); 281 } 282 } 283 } 284 catch (uno::RuntimeException) 285 { 286 DBG_UNHANDLED_EXCEPTION(); 287 pPage = NULL; 288 } 289 290 return pPage; 291 } 292 293 294 295 296 ::sd::DrawDocShell* TemplatePageObjectProvider::LoadDocument (const ::rtl::OUString& sFileName) 297 { 298 SfxApplication* pSfxApp = SFX_APP(); 299 SfxItemSet* pSet = new SfxAllItemSet (pSfxApp->GetPool()); 300 pSet->Put (SfxBoolItem (SID_TEMPLATE, sal_True)); 301 pSet->Put (SfxBoolItem (SID_PREVIEW, sal_True)); 302 if (pSfxApp->LoadTemplate (mxDocumentShell, sFileName, sal_True, pSet)) 303 { 304 mxDocumentShell = NULL; 305 } 306 SfxObjectShell* pShell = mxDocumentShell; 307 return PTR_CAST(::sd::DrawDocShell,pShell); 308 } 309 310 311 312 313 int TemplatePageObjectProvider::GetCostIndex (void) 314 { 315 return 20; 316 } 317 318 319 320 321 bool TemplatePageObjectProvider::operator== (const PageObjectProvider& rProvider) 322 { 323 const TemplatePageObjectProvider* pTemplatePageObjectProvider 324 = dynamic_cast<const TemplatePageObjectProvider*>(&rProvider); 325 if (pTemplatePageObjectProvider != NULL) 326 return (msURL == pTemplatePageObjectProvider->msURL); 327 else 328 return false; 329 } 330 331 332 333 334 //===== DefaultPageObjectProvider ============================================== 335 336 DefaultPageObjectProvider::DefaultPageObjectProvider (void) 337 { 338 } 339 340 341 342 343 SdPage* DefaultPageObjectProvider::operator () (SdDrawDocument* pContainerDocument) 344 { 345 SdPage* pLocalMasterPage = NULL; 346 if (pContainerDocument != NULL) 347 { 348 sal_Int32 nIndex (0); 349 SdPage* pLocalSlide = pContainerDocument->GetSdPage((sal_uInt16)nIndex, PK_STANDARD); 350 if (pLocalSlide!=NULL && pLocalSlide->TRG_HasMasterPage()) 351 pLocalMasterPage = dynamic_cast<SdPage*>(&pLocalSlide->TRG_GetMasterPage()); 352 } 353 354 if (pLocalMasterPage == NULL) 355 { 356 DBG_ASSERT(false, "can not create master page for slide"); 357 } 358 359 return pLocalMasterPage; 360 } 361 362 363 364 365 int DefaultPageObjectProvider::GetCostIndex (void) 366 { 367 return 15; 368 } 369 370 371 372 373 bool DefaultPageObjectProvider::operator== (const PageObjectProvider& rProvider) 374 { 375 return (dynamic_cast<const DefaultPageObjectProvider*>(&rProvider) != NULL); 376 } 377 378 379 380 381 //===== ExistingPageProvider ================================================== 382 383 ExistingPageProvider::ExistingPageProvider (SdPage* pPage) 384 : mpPage(pPage) 385 { 386 } 387 388 389 390 391 SdPage* ExistingPageProvider::operator() (SdDrawDocument* pDocument) 392 { 393 (void)pDocument; // Unused parameter. 394 395 return mpPage; 396 } 397 398 399 400 401 int ExistingPageProvider::GetCostIndex (void) 402 { 403 return 0; 404 } 405 406 407 408 409 bool ExistingPageProvider::operator== (const PageObjectProvider& rProvider) 410 { 411 const ExistingPageProvider* pExistingPageProvider 412 = dynamic_cast<const ExistingPageProvider*>(&rProvider); 413 if (pExistingPageProvider != NULL) 414 return (mpPage == pExistingPageProvider->mpPage); 415 else 416 return false; 417 } 418 419 420 } } // end of namespace sd::sidebar 421