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 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_svx.hxx" 26 27 #include <unotools/streamwrap.hxx> 28 #include <unotools/ucbstreamhelper.hxx> 29 #include <unotools/processfactory.hxx> 30 #include <ucbhelper/content.hxx> 31 #include <tools/resmgr.hxx> 32 #include <tools/urlobj.hxx> 33 #include <svl/solar.hrc> 34 #include <svl/urihelper.hxx> 35 #include <svtools/filter.hxx> 36 #include <svl/itempool.hxx> 37 #include <sfx2/docfile.hxx> 38 #include <avmedia/mediawindow.hxx> 39 #include <vcl/svapp.hxx> 40 41 #include "svtools/filter.hxx" 42 #include <svx/svdpage.hxx> 43 #include <svx/svdograf.hxx> 44 #include <svx/fmmodel.hxx> 45 #include <svx/fmview.hxx> 46 #include <svx/unomodel.hxx> 47 #include "codec.hxx" 48 #include "gallery.hrc" 49 #include "svx/gallery1.hxx" 50 #include "svx/galtheme.hxx" 51 #include "svx/galmisc.hxx" 52 #include <com/sun/star/sdbc/XResultSet.hpp> 53 #include <com/sun/star/ucb/XContentAccess.hpp> 54 #include <com/sun/star/ucb/TransferInfo.hpp> 55 #include <com/sun/star/ucb/NameClash.hpp> 56 57 // -------------- 58 // - Namespaces - 59 // -------------- 60 61 using namespace ::rtl; 62 using namespace ::com::sun::star; 63 64 // ---------- 65 // - ResMgr - 66 // ---------- 67 68 ResMgr* GetGalleryResMgr() 69 { 70 static ResMgr* pGalleryResMgr = NULL; 71 72 if( !pGalleryResMgr ) 73 { 74 ByteString aResMgrName( "gal" ); 75 pGalleryResMgr = ResMgr::CreateResMgr( 76 aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() ); 77 } 78 79 return pGalleryResMgr; 80 } 81 82 // ------------------------- 83 // - GalleryResGetBitmapEx - 84 // ------------------------- 85 86 BitmapEx GalleryResGetBitmapEx( sal_uInt32 nId ) 87 { 88 BitmapEx aBmpEx( GAL_RESID( nId ) ); 89 90 if( !aBmpEx.IsTransparent() ) 91 aBmpEx = BitmapEx( aBmpEx.GetBitmap(), COL_LIGHTMAGENTA ); 92 93 return aBmpEx; 94 } 95 96 // ---------------------- 97 // - SgaUserDataFactory - 98 // ---------------------- 99 100 IMPL_LINK( SgaUserDataFactory, MakeUserData, SdrObjFactory*, pObjFactory ) 101 { 102 if ( pObjFactory->nInventor == IV_IMAPINFO && pObjFactory->nIdentifier == ID_IMAPINFO ) 103 pObjFactory->pNewData = new SgaIMapInfo; 104 105 return 0L; 106 } 107 108 // ------------------------ 109 // - GalleryGraphicImport - 110 // ------------------------ 111 112 sal_uInt16 GalleryGraphicImport( const INetURLObject& rURL, Graphic& rGraphic, 113 String& rFilterName, sal_Bool bShowProgress ) 114 { 115 sal_uInt16 nRet = SGA_IMPORT_NONE; 116 SfxMedium aMedium( rURL.GetMainURL( INetURLObject::NO_DECODE ), STREAM_READ, sal_True ); 117 String aFilterName; 118 119 aMedium.DownLoad(); 120 121 SvStream* pIStm = aMedium.GetInStream(); 122 123 if( pIStm ) 124 { 125 GraphicFilter* pGraphicFilter = GraphicFilter::GetGraphicFilter(); 126 GalleryProgress* pProgress = bShowProgress ? new GalleryProgress( pGraphicFilter ) : NULL; 127 sal_uInt16 nFormat; 128 129 if( !pGraphicFilter->ImportGraphic( rGraphic, rURL.GetMainURL( INetURLObject::NO_DECODE ), *pIStm, GRFILTER_FORMAT_DONTKNOW, &nFormat ) ) 130 { 131 rFilterName = pGraphicFilter->GetImportFormatName( nFormat ); 132 nRet = SGA_IMPORT_FILE; 133 } 134 135 delete pProgress; 136 } 137 138 return nRet; 139 } 140 141 // ----------------------- 142 // - GallerySvDrawImport - 143 // ----------------------- 144 145 sal_Bool GallerySvDrawImport( SvStream& rIStm, SdrModel& rModel ) 146 { 147 sal_uInt32 nVersion; 148 sal_Bool bRet = sal_False; 149 150 if( GalleryCodec::IsCoded( rIStm, nVersion ) ) 151 { 152 SvMemoryStream aMemStm( 65535, 65535 ); 153 GalleryCodec aCodec( rIStm ); 154 155 aCodec.Read( aMemStm ); 156 aMemStm.Seek( 0UL ); 157 158 if( 1 == nVersion ) 159 { 160 DBG_ERROR( "staroffice binary file formats are no longer supported inside the gallery!" ); 161 bRet = false; 162 } 163 else if( 2 == nVersion ) 164 { 165 // recall to read as XML 166 bRet = GallerySvDrawImport( aMemStm, rModel ); 167 } 168 } 169 else 170 { 171 // read as XML 172 uno::Reference< io::XInputStream > xInputStream( new utl::OInputStreamWrapper( rIStm ) ); 173 174 rModel.GetItemPool().SetDefaultMetric( SFX_MAPUNIT_100TH_MM ); 175 uno::Reference< lang::XComponent > xComponent; 176 177 bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLOasisImporter" ); 178 if( !bRet || (rModel.GetPageCount() == 0) ) 179 { 180 rIStm.Seek(0); 181 bRet = SvxDrawingLayerImport( &rModel, xInputStream, xComponent, "com.sun.star.comp.Draw.XMLImporter" ); 182 } 183 184 } 185 186 return bRet; 187 } 188 189 // --------------------- 190 // - CreateIMapGraphic - 191 // --------------------- 192 193 sal_Bool CreateIMapGraphic( const FmFormModel& rModel, Graphic& rGraphic, ImageMap& rImageMap ) 194 { 195 sal_Bool bRet = sal_False; 196 197 if ( rModel.GetPageCount() ) 198 { 199 const SdrPage* pPage = rModel.GetPage( 0 ); 200 const SdrObject* pObj = pPage->GetObj( 0 ); 201 202 if ( pPage->GetObjCount() == 1 && pObj->ISA( SdrGrafObj ) ) 203 { 204 const sal_uInt16 nCount = pObj->GetUserDataCount(); 205 206 // gibt es in den User-Daten eine IMap-Information? 207 for ( sal_uInt16 i = 0; i < nCount; i++ ) 208 { 209 const SdrObjUserData* pUserData = pObj->GetUserData( i ); 210 211 if ( ( pUserData->GetInventor() == IV_IMAPINFO ) && ( pUserData->GetId() == ID_IMAPINFO ) ) 212 { 213 rGraphic = ( (SdrGrafObj*) pObj )->GetGraphic(); 214 rImageMap = ( (SgaIMapInfo*) pUserData )->GetImageMap(); 215 bRet = sal_True; 216 break; 217 } 218 } 219 } 220 } 221 222 return bRet; 223 } 224 225 // -------------------- 226 // - GetReducedString - 227 // -------------------- 228 229 String GetReducedString( const INetURLObject& rURL, sal_uIntPtr nMaxLen ) 230 { 231 String aReduced( rURL.GetMainURL( INetURLObject::DECODE_UNAMBIGUOUS ) ); 232 233 aReduced = aReduced.GetToken( aReduced.GetTokenCount( '/' ) - 1, '/' ); 234 235 if( INET_PROT_PRIV_SOFFICE != rURL.GetProtocol() ) 236 { 237 sal_Unicode aDelimiter; 238 const String aPath( rURL.getFSysPath( INetURLObject::FSYS_DETECT, &aDelimiter ) ); 239 const String aName( aReduced ); 240 241 if( aPath.Len() > nMaxLen ) 242 { 243 aReduced = aPath.Copy( 0, (sal_uInt16)( nMaxLen - aName.Len() - 4 ) ); 244 aReduced += String( RTL_CONSTASCII_USTRINGPARAM( "..." ) ); 245 aReduced += aDelimiter; 246 aReduced += aName; 247 } 248 else 249 aReduced = aPath; 250 } 251 252 return aReduced; 253 } 254 255 // ----------------------------------------------------------------------------- 256 257 String GetSvDrawStreamNameFromURL( const INetURLObject& rSvDrawObjURL ) 258 { 259 String aRet; 260 261 if( rSvDrawObjURL.GetProtocol() == INET_PROT_PRIV_SOFFICE && 262 String(rSvDrawObjURL.GetMainURL( INetURLObject::NO_DECODE )).GetTokenCount( '/' ) == 3 ) 263 { 264 aRet = String(rSvDrawObjURL.GetMainURL( INetURLObject::NO_DECODE )).GetToken( 2, '/' ); 265 } 266 267 return aRet; 268 } 269 270 // ----------------------------------------------------------------------------- 271 272 sal_Bool FileExists( const INetURLObject& rURL ) 273 { 274 sal_Bool bRet = sal_False; 275 276 if( rURL.GetProtocol() != INET_PROT_NOT_VALID ) 277 { 278 try 279 { 280 ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >() ); 281 OUString aTitle; 282 283 aCnt.getPropertyValue( OUString::createFromAscii( "Title" ) ) >>= aTitle; 284 bRet = ( aTitle.getLength() > 0 ); 285 } 286 catch( const ucb::ContentCreationException& ) 287 { 288 } 289 catch( const uno::RuntimeException& ) 290 { 291 } 292 catch( const uno::Exception& ) 293 { 294 } 295 } 296 297 return bRet; 298 } 299 300 // ----------------------------------------------------------------------------- 301 302 sal_Bool CreateDir( const INetURLObject& rURL ) 303 { 304 sal_Bool bRet = FileExists( rURL ); 305 306 if( !bRet ) 307 { 308 try 309 { 310 uno::Reference< ucb::XCommandEnvironment > aCmdEnv; 311 INetURLObject aNewFolderURL( rURL ); 312 INetURLObject aParentURL( aNewFolderURL ); aParentURL.removeSegment(); 313 ::ucbhelper::Content aParent( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); 314 uno::Sequence< OUString > aProps( 1 ); 315 uno::Sequence< uno::Any > aValues( 1 ); 316 317 aProps.getArray()[ 0 ] = OUString::createFromAscii( "Title" ); 318 aValues.getArray()[ 0 ] = uno::makeAny( OUString( aNewFolderURL.GetName() ) ); 319 320 ::ucbhelper::Content aContent( aNewFolderURL.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv ); 321 bRet = aParent.insertNewContent( OUString::createFromAscii( "application/vnd.sun.staroffice.fsys-folder" ), aProps, aValues, aContent ); 322 } 323 catch( const ucb::ContentCreationException& ) 324 { 325 } 326 catch( const uno::RuntimeException& ) 327 { 328 } 329 catch( const uno::Exception& ) 330 { 331 } 332 } 333 334 return bRet; 335 } 336 337 // ----------------------------------------------------------------------------- 338 339 sal_Bool CopyFile( const INetURLObject& rSrcURL, const INetURLObject& rDstURL ) 340 { 341 sal_Bool bRet = sal_False; 342 343 try 344 { 345 ::ucbhelper::Content aDestPath( rDstURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >() ); 346 347 aDestPath.executeCommand( OUString::createFromAscii( "transfer" ), 348 uno::makeAny( ucb::TransferInfo( sal_False, rSrcURL.GetMainURL( INetURLObject::NO_DECODE ), 349 rDstURL.GetName(), ucb::NameClash::OVERWRITE ) ) ); 350 bRet = sal_True; 351 } 352 catch( const ucb::ContentCreationException& ) 353 { 354 } 355 catch( const uno::RuntimeException& ) 356 { 357 } 358 catch( const uno::Exception& ) 359 { 360 } 361 362 return bRet; 363 } 364 365 // ----------------------------------------------------------------------------- 366 367 sal_Bool KillFile( const INetURLObject& rURL ) 368 { 369 sal_Bool bRet = FileExists( rURL ); 370 371 if( bRet ) 372 { 373 try 374 { 375 ::ucbhelper::Content aCnt( rURL.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference< ucb::XCommandEnvironment >() ); 376 aCnt.executeCommand( OUString::createFromAscii( "delete" ), uno::makeAny( sal_Bool( sal_True ) ) ); 377 } 378 catch( const ucb::ContentCreationException& ) 379 { 380 bRet = sal_False; 381 } 382 catch( const uno::RuntimeException& ) 383 { 384 bRet = sal_False; 385 } 386 catch( const uno::Exception& ) 387 { 388 bRet = sal_False; 389 } 390 } 391 392 return bRet; 393 } 394 395 // ------------------- 396 // - GalleryProgress - 397 // ------------------- 398 DBG_NAME(GalleryProgress) 399 400 GalleryProgress::GalleryProgress( GraphicFilter* pFilter ) : 401 mpFilter( pFilter ) 402 { 403 DBG_CTOR(GalleryProgress,NULL); 404 405 uno::Reference< lang::XMultiServiceFactory > xMgr( ::utl::getProcessServiceFactory() ); 406 407 if( xMgr.is() ) 408 { 409 uno::Reference< awt::XProgressMonitor > xMonitor( xMgr->createInstance( 410 ::rtl::OUString::createFromAscii( "com.sun.star.awt.XProgressMonitor" ) ), 411 uno::UNO_QUERY ); 412 413 if ( xMonitor.is() ) 414 { 415 mxProgressBar = uno::Reference< awt::XProgressBar >( xMonitor, uno::UNO_QUERY ); 416 417 if( mxProgressBar.is() ) 418 { 419 String aProgressText; 420 421 if( mpFilter ) 422 { 423 aProgressText = String( GAL_RESID( RID_SVXSTR_GALLERY_FILTER ) ); 424 // mpFilter->SetUpdatePercentHdl( LINK( this, GalleryProgress, Update ) ); // sj: progress wasn't working up from SO7 at all 425 // // so I am removing this. The gallery progress should 426 // // be changed to use the XStatusIndicator instead of XProgressMonitor 427 } 428 else 429 aProgressText = String( RTL_CONSTASCII_USTRINGPARAM( "Gallery" ) ); 430 431 xMonitor->addText( String( RTL_CONSTASCII_USTRINGPARAM( "Gallery" ) ), aProgressText, sal_False ) ; 432 mxProgressBar->setRange( 0, GALLERY_PROGRESS_RANGE ); 433 } 434 } 435 } 436 } 437 438 // ------------------------------------------------------------------------ 439 440 GalleryProgress::~GalleryProgress() 441 { 442 // if( mpFilter ) 443 // mpFilter->SetUpdatePercentHdl( Link() ); 444 445 DBG_DTOR(GalleryProgress,NULL); 446 } 447 448 // ------------------------------------------------------------------------ 449 450 void GalleryProgress::Update( sal_uIntPtr nVal, sal_uIntPtr nMaxVal ) 451 { 452 if( mxProgressBar.is() && nMaxVal ) 453 mxProgressBar->setValue( Min( (sal_uIntPtr)( (double) nVal / nMaxVal * GALLERY_PROGRESS_RANGE ), (sal_uIntPtr) GALLERY_PROGRESS_RANGE ) ); 454 } 455 456 // ----------------------- 457 // - GalleryTransferable - 458 // ----------------------- 459 DBG_NAME(GalleryTransferable) 460 461 GalleryTransferable::GalleryTransferable( GalleryTheme* pTheme, sal_uIntPtr nObjectPos, bool bLazy ) : 462 mpTheme( pTheme ), 463 meObjectKind( mpTheme->GetObjectKind( nObjectPos ) ), 464 mnObjectPos( nObjectPos ), 465 mpGraphicObject( NULL ), 466 mpImageMap( NULL ), 467 mpURL( NULL ) 468 { 469 DBG_CTOR(GalleryTransferable,NULL); 470 471 InitData( bLazy ); 472 } 473 474 // ------------------------------------------------------------------------ 475 476 GalleryTransferable::~GalleryTransferable() 477 { 478 479 DBG_DTOR(GalleryTransferable,NULL); 480 } 481 482 // ------------------------------------------------------------------------ 483 484 void GalleryTransferable::InitData( bool bLazy ) 485 { 486 switch( meObjectKind ) 487 { 488 case( SGA_OBJ_SVDRAW ): 489 { 490 if( !bLazy ) 491 { 492 if( !mpGraphicObject ) 493 { 494 Graphic aGraphic; 495 496 if( mpTheme->GetGraphic( mnObjectPos, aGraphic ) ) 497 mpGraphicObject = new GraphicObject( aGraphic ); 498 } 499 500 if( !mxModelStream.Is() ) 501 { 502 mxModelStream = new SotStorageStream( String() ); 503 mxModelStream->SetBufferSize( 16348 ); 504 505 if( !mpTheme->GetModelStream( mnObjectPos, mxModelStream ) ) 506 mxModelStream.Clear(); 507 else 508 mxModelStream->Seek( 0 ); 509 } 510 } 511 } 512 break; 513 514 case( SGA_OBJ_ANIM ): 515 case( SGA_OBJ_BMP ): 516 case( SGA_OBJ_INET ): 517 case( SGA_OBJ_SOUND ): 518 { 519 if( !mpURL ) 520 { 521 mpURL = new INetURLObject; 522 523 if( !mpTheme->GetURL( mnObjectPos, *mpURL ) ) 524 delete mpURL, mpURL = NULL; 525 } 526 527 if( ( SGA_OBJ_SOUND != meObjectKind ) && !mpGraphicObject ) 528 { 529 Graphic aGraphic; 530 531 if( mpTheme->GetGraphic( mnObjectPos, aGraphic ) ) 532 mpGraphicObject = new GraphicObject( aGraphic ); 533 } 534 } 535 break; 536 537 default: 538 DBG_ERROR( "GalleryTransferable::GalleryTransferable: invalid object type" ); 539 break; 540 } 541 } 542 543 // ------------------------------------------------------------------------ 544 545 void GalleryTransferable::AddSupportedFormats() 546 { 547 if( SGA_OBJ_SVDRAW == meObjectKind ) 548 { 549 AddFormat( SOT_FORMATSTR_ID_DRAWING ); 550 AddFormat( SOT_FORMATSTR_ID_SVXB ); 551 AddFormat( FORMAT_GDIMETAFILE ); 552 AddFormat( FORMAT_BITMAP ); 553 } 554 else 555 { 556 if( mpURL ) 557 AddFormat( FORMAT_FILE ); 558 559 if( mpGraphicObject ) 560 { 561 AddFormat( SOT_FORMATSTR_ID_SVXB ); 562 563 if( mpGraphicObject->GetType() == GRAPHIC_GDIMETAFILE ) 564 { 565 AddFormat( FORMAT_GDIMETAFILE ); 566 AddFormat( FORMAT_BITMAP ); 567 } 568 else 569 { 570 AddFormat( FORMAT_BITMAP ); 571 AddFormat( FORMAT_GDIMETAFILE ); 572 } 573 } 574 } 575 } 576 577 // ------------------------------------------------------------------------ 578 579 sal_Bool GalleryTransferable::GetData( const datatransfer::DataFlavor& rFlavor ) 580 { 581 sal_uInt32 nFormat = SotExchange::GetFormat( rFlavor ); 582 sal_Bool bRet = sal_False; 583 584 InitData( false ); 585 586 if( ( SOT_FORMATSTR_ID_DRAWING == nFormat ) && ( SGA_OBJ_SVDRAW == meObjectKind ) ) 587 { 588 bRet = ( mxModelStream.Is() && SetObject( &mxModelStream, 0, rFlavor ) ); 589 } 590 else if( ( SOT_FORMATSTR_ID_SVIM == nFormat ) && mpImageMap ) 591 { 592 // TODO/MBA: do we need a BaseURL here?! 593 bRet = SetImageMap( *mpImageMap, rFlavor ); 594 } 595 else if( ( FORMAT_FILE == nFormat ) && mpURL ) 596 { 597 bRet = SetString( mpURL->GetMainURL( INetURLObject::NO_DECODE ), rFlavor ); 598 } 599 else if( ( SOT_FORMATSTR_ID_SVXB == nFormat ) && mpGraphicObject ) 600 { 601 bRet = SetGraphic( mpGraphicObject->GetGraphic(), rFlavor ); 602 } 603 else if( ( FORMAT_GDIMETAFILE == nFormat ) && mpGraphicObject ) 604 { 605 bRet = SetGDIMetaFile( mpGraphicObject->GetGraphic().GetGDIMetaFile(), rFlavor ); 606 } 607 else if( ( FORMAT_BITMAP == nFormat ) && mpGraphicObject ) 608 { 609 bRet = SetBitmap( mpGraphicObject->GetGraphic().GetBitmap(), rFlavor ); 610 } 611 612 return bRet; 613 } 614 615 // ------------------------------------------------------------------------ 616 617 sal_Bool GalleryTransferable::WriteObject( SotStorageStreamRef& rxOStm, void* pUserObject, 618 sal_uInt32, const datatransfer::DataFlavor& ) 619 { 620 sal_Bool bRet = sal_False; 621 622 if( pUserObject ) 623 { 624 *rxOStm << *static_cast< SotStorageStream* >( pUserObject ); 625 bRet = ( rxOStm->GetError() == ERRCODE_NONE ); 626 } 627 628 return bRet; 629 } 630 631 // ------------------------------------------------------------------------ 632 633 void GalleryTransferable::DragFinished( sal_Int8 nDropAction ) 634 { 635 mpTheme->SetDragging( sal_False ); 636 mpTheme->SetDragPos( 0 ); 637 if ( nDropAction ) 638 { 639 Window *pFocusWindow = Application::GetFocusWindow(); 640 if ( pFocusWindow ) 641 pFocusWindow->GrabFocusToDocument(); 642 } 643 } 644 645 // ------------------------------------------------------------------------ 646 647 void GalleryTransferable::ObjectReleased() 648 { 649 mxModelStream.Clear(); 650 delete mpGraphicObject, mpGraphicObject = NULL; 651 delete mpImageMap, mpImageMap = NULL; 652 delete mpURL, mpURL = NULL; 653 } 654 655 // ------------------------------------------------------------------------ 656 657 void GalleryTransferable::CopyToClipboard( Window* pWindow ) 658 { 659 TransferableHelper::CopyToClipboard( pWindow ); 660 } 661 662 // ------------------------------------------------------------------------ 663 664 void GalleryTransferable::StartDrag( Window* pWindow, sal_Int8 nDragSourceActions, 665 sal_Int32 nDragPointer, sal_Int32 nDragImage ) 666 { 667 INetURLObject aURL; 668 669 if( mpTheme->GetURL( mnObjectPos, aURL ) && ( aURL.GetProtocol() != INET_PROT_NOT_VALID ) ) 670 { 671 mpTheme->SetDragging( sal_True ); 672 mpTheme->SetDragPos( mnObjectPos ); 673 TransferableHelper::StartDrag( pWindow, nDragSourceActions, nDragPointer, nDragImage ); 674 } 675 } 676