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 //===== PagePreviewProvider =================================================== 44 45 PagePreviewProvider::PagePreviewProvider (void) 46 { 47 } 48 49 50 Image PagePreviewProvider::operator () ( 51 int nWidth, 52 SdPage* pPage, 53 ::sd::PreviewRenderer& rRenderer) 54 { 55 Image aPreview; 56 57 if (pPage != NULL) 58 { 59 // Use the given renderer to create a preview of the given page 60 // object. 61 aPreview = rRenderer.RenderPage( 62 pPage, 63 nWidth, 64 String::CreateFromAscii(""), 65 false); 66 } 67 68 return aPreview; 69 } 70 71 72 int PagePreviewProvider::GetCostIndex (void) 73 { 74 return 5; 75 } 76 77 78 bool PagePreviewProvider::NeedsPageObject (void) 79 { 80 return true; 81 } 82 83 84 //===== TemplatePreviewProvider =============================================== 85 86 TemplatePreviewProvider::TemplatePreviewProvider (const ::rtl::OUString& rsURL) 87 : msURL(rsURL) 88 { 89 } 90 91 92 Image TemplatePreviewProvider::operator() ( 93 int nWidth, 94 SdPage* pPage, 95 ::sd::PreviewRenderer& rRenderer) 96 { 97 // Unused parameters. 98 (void)nWidth; 99 (void)pPage; 100 (void)rRenderer; 101 102 // Load the thumbnail from a template document. 103 uno::Reference<io::XInputStream> xIStream; 104 105 uno::Reference< lang::XMultiServiceFactory > xServiceManager ( 106 ::comphelper::getProcessServiceFactory()); 107 if (xServiceManager.is()) 108 { 109 try 110 { 111 uno::Reference<lang::XSingleServiceFactory> xStorageFactory( 112 xServiceManager->createInstance( 113 ::rtl::OUString::createFromAscii( 114 "com.sun.star.embed.StorageFactory")), 115 uno::UNO_QUERY); 116 117 if (xStorageFactory.is()) 118 { 119 uno::Sequence<uno::Any> aArgs (2); 120 aArgs[0] <<= msURL; 121 aArgs[1] <<= embed::ElementModes::READ; 122 uno::Reference<embed::XStorage> xDocStorage ( 123 xStorageFactory->createInstanceWithArguments(aArgs), 124 uno::UNO_QUERY); 125 126 try 127 { 128 if (xDocStorage.is()) 129 { 130 uno::Reference<embed::XStorage> xStorage ( 131 xDocStorage->openStorageElement( 132 ::rtl::OUString::createFromAscii("Thumbnails"), 133 embed::ElementModes::READ)); 134 if (xStorage.is()) 135 { 136 uno::Reference<io::XStream> xThumbnailCopy ( 137 xStorage->cloneStreamElement( 138 ::rtl::OUString::createFromAscii( 139 "thumbnail.png"))); 140 if (xThumbnailCopy.is()) 141 xIStream = xThumbnailCopy->getInputStream(); 142 } 143 } 144 } 145 catch (uno::Exception& rException) 146 { 147 OSL_TRACE ( 148 "caught exception while trying to access Thumbnail/thumbnail.png of %s: %s", 149 ::rtl::OUStringToOString(msURL, 150 RTL_TEXTENCODING_UTF8).getStr(), 151 ::rtl::OUStringToOString(rException.Message, 152 RTL_TEXTENCODING_UTF8).getStr()); 153 } 154 155 try 156 { 157 // An (older) implementation had a bug - The storage 158 // name was "Thumbnail" instead of "Thumbnails". The 159 // old name is still used as fallback but this code can 160 // be removed soon. 161 if ( ! xIStream.is()) 162 { 163 uno::Reference<embed::XStorage> xStorage ( 164 xDocStorage->openStorageElement( 165 ::rtl::OUString::createFromAscii("Thumbnail"), 166 embed::ElementModes::READ)); 167 if (xStorage.is()) 168 { 169 uno::Reference<io::XStream> xThumbnailCopy ( 170 xStorage->cloneStreamElement( 171 ::rtl::OUString::createFromAscii( 172 "thumbnail.png"))); 173 if (xThumbnailCopy.is()) 174 xIStream = xThumbnailCopy->getInputStream(); 175 } 176 } 177 } 178 catch (uno::Exception& rException) 179 { 180 OSL_TRACE ( 181 "caught exception while trying to access Thumbnails/thumbnail.png of %s: %s", 182 ::rtl::OUStringToOString(msURL, 183 RTL_TEXTENCODING_UTF8).getStr(), 184 ::rtl::OUStringToOString(rException.Message, 185 RTL_TEXTENCODING_UTF8).getStr()); 186 } 187 } 188 } 189 catch (uno::Exception& rException) 190 { 191 OSL_TRACE ( 192 "caught exception while trying to access thumbnail 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 // Extract the image from the stream. 201 BitmapEx aThumbnail; 202 if (xIStream.is()) 203 { 204 ::std::auto_ptr<SvStream> pStream ( 205 ::utl::UcbStreamHelper::CreateStream (xIStream)); 206 ::vcl::PNGReader aReader (*pStream); 207 aThumbnail = aReader.Read (); 208 } 209 210 // Note that the preview is returned without scaling it to the desired 211 // width. This gives the caller the chance to take advantage of a 212 // possibly larger resolution then was asked for. 213 return aThumbnail; 214 } 215 216 217 int TemplatePreviewProvider::GetCostIndex (void) 218 { 219 return 10; 220 } 221 222 223 bool TemplatePreviewProvider::NeedsPageObject (void) 224 { 225 return false; 226 } 227 228 229 //===== TemplatePageObjectProvider ============================================= 230 231 TemplatePageObjectProvider::TemplatePageObjectProvider (const ::rtl::OUString& rsURL) 232 : msURL(rsURL), 233 mxDocumentShell() 234 { 235 } 236 237 238 SdPage* TemplatePageObjectProvider::operator() (SdDrawDocument* pContainerDocument) 239 { 240 // Unused parameters. 241 (void)pContainerDocument; 242 243 SdPage* pPage = NULL; 244 245 mxDocumentShell = NULL; 246 ::sd::DrawDocShell* pDocumentShell = NULL; 247 try 248 { 249 // Load the template document and return its first page. 250 pDocumentShell = LoadDocument (msURL); 251 if (pDocumentShell != NULL) 252 { 253 SdDrawDocument* pDocument = pDocumentShell->GetDoc(); 254 if (pDocument != NULL) 255 { 256 pPage = pDocument->GetMasterSdPage(0, PK_STANDARD); 257 // In order to make the newly loaded master page deletable 258 // when copied into documents it is marked as no "precious". 259 // When it is modified then it is marked as "precious". 260 if (pPage != NULL) 261 pPage->SetPrecious(false); 262 } 263 } 264 } 265 catch (uno::RuntimeException) 266 { 267 DBG_UNHANDLED_EXCEPTION(); 268 pPage = NULL; 269 } 270 271 return pPage; 272 } 273 274 275 ::sd::DrawDocShell* TemplatePageObjectProvider::LoadDocument (const ::rtl::OUString& sFileName) 276 { 277 SfxApplication* pSfxApp = SFX_APP(); 278 SfxItemSet* pSet = new SfxAllItemSet (pSfxApp->GetPool()); 279 pSet->Put (SfxBoolItem (SID_TEMPLATE, sal_True)); 280 pSet->Put (SfxBoolItem (SID_PREVIEW, sal_True)); 281 if (pSfxApp->LoadTemplate (mxDocumentShell, sFileName, sal_True, pSet)) 282 { 283 mxDocumentShell = NULL; 284 } 285 SfxObjectShell* pShell = mxDocumentShell; 286 return PTR_CAST(::sd::DrawDocShell,pShell); 287 } 288 289 290 int TemplatePageObjectProvider::GetCostIndex (void) 291 { 292 return 20; 293 } 294 295 296 bool TemplatePageObjectProvider::operator== (const PageObjectProvider& rProvider) 297 { 298 const TemplatePageObjectProvider* pTemplatePageObjectProvider 299 = dynamic_cast<const TemplatePageObjectProvider*>(&rProvider); 300 if (pTemplatePageObjectProvider != NULL) 301 return (msURL == pTemplatePageObjectProvider->msURL); 302 else 303 return false; 304 } 305 306 307 //===== DefaultPageObjectProvider ============================================== 308 309 DefaultPageObjectProvider::DefaultPageObjectProvider (void) 310 { 311 } 312 313 314 SdPage* DefaultPageObjectProvider::operator () (SdDrawDocument* pContainerDocument) 315 { 316 SdPage* pLocalMasterPage = NULL; 317 if (pContainerDocument != NULL) 318 { 319 sal_Int32 nIndex (0); 320 SdPage* pLocalSlide = pContainerDocument->GetSdPage((sal_uInt16)nIndex, PK_STANDARD); 321 if (pLocalSlide!=NULL && pLocalSlide->TRG_HasMasterPage()) 322 pLocalMasterPage = dynamic_cast<SdPage*>(&pLocalSlide->TRG_GetMasterPage()); 323 } 324 325 if (pLocalMasterPage == NULL) 326 { 327 DBG_ASSERT(false, "can not create master page for slide"); 328 } 329 330 return pLocalMasterPage; 331 } 332 333 334 int DefaultPageObjectProvider::GetCostIndex (void) 335 { 336 return 15; 337 } 338 339 340 bool DefaultPageObjectProvider::operator== (const PageObjectProvider& rProvider) 341 { 342 return (dynamic_cast<const DefaultPageObjectProvider*>(&rProvider) != NULL); 343 } 344 345 346 //===== ExistingPageProvider ================================================== 347 348 ExistingPageProvider::ExistingPageProvider (SdPage* pPage) 349 : mpPage(pPage) 350 { 351 } 352 353 354 SdPage* ExistingPageProvider::operator() (SdDrawDocument* pDocument) 355 { 356 (void)pDocument; // Unused parameter. 357 358 return mpPage; 359 } 360 361 362 int ExistingPageProvider::GetCostIndex (void) 363 { 364 return 0; 365 } 366 367 368 bool ExistingPageProvider::operator== (const PageObjectProvider& rProvider) 369 { 370 const ExistingPageProvider* pExistingPageProvider 371 = dynamic_cast<const ExistingPageProvider*>(&rProvider); 372 if (pExistingPageProvider != NULL) 373 return (mpPage == pExistingPageProvider->mpPage); 374 else 375 return false; 376 } 377 378 } } // end of namespace sd::sidebar 379 380 /* vim: set noet sw=4 ts=4: */ 381