1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sfx2.hxx" 30 31 #include <limits.h> 32 #include <com/sun/star/uno/Any.h> 33 #include <vos/mutex.hxx> 34 #include <vos/thread.hxx> 35 36 #ifndef _SV_RESARY_HXX 37 #include <tools/resary.hxx> 38 #endif 39 #include <vcl/svapp.hxx> 40 #include <vcl/settings.hxx> 41 #include <unotools/localedatawrapper.hxx> 42 #include <unotools/pathoptions.hxx> 43 #include <tools/string.hxx> 44 #include <tools/urlobj.hxx> 45 #include <svtools/ehdl.hxx> 46 #include <svtools/sfxecode.hxx> 47 #include <comphelper/processfactory.hxx> 48 #include <ucbhelper/content.hxx> 49 #include <com/sun/star/beans/PropertyAttribute.hpp> 50 #include <com/sun/star/beans/PropertyValue.hpp> 51 #include <com/sun/star/beans/XPropertyContainer.hpp> 52 #include <com/sun/star/beans/XPropertySet.hpp> 53 #include <com/sun/star/beans/XPropertySetInfo.hpp> 54 #include <com/sun/star/document/XTypeDetection.hpp> 55 #include <com/sun/star/document/XDocumentPropertiesSupplier.hpp> 56 #include <com/sun/star/frame/XComponentLoader.hpp> 57 #include <com/sun/star/frame/XDocumentTemplates.hpp> 58 #include <com/sun/star/io/XInputStream.hpp> 59 #include <com/sun/star/io/XPersist.hpp> 60 #include <com/sun/star/lang/XLocalizable.hpp> 61 #include <com/sun/star/sdbc/XResultSet.hpp> 62 #include <com/sun/star/sdbc/XRow.hpp> 63 #include <com/sun/star/ucb/ContentInfo.hpp> 64 #include <com/sun/star/ucb/InsertCommandArgument.hpp> 65 #include <com/sun/star/ucb/NameClash.hpp> 66 #include <com/sun/star/ucb/TransferInfo.hpp> 67 #include <com/sun/star/ucb/XCommandProcessor.hpp> 68 #include <com/sun/star/ucb/XContent.hpp> 69 #include <com/sun/star/ucb/XContentAccess.hpp> 70 #include <com/sun/star/ucb/XAnyCompareFactory.hpp> 71 #include <com/sun/star/ucb/XAnyCompare.hpp> 72 #include <com/sun/star/ucb/NumberedSortingInfo.hpp> 73 #include <com/sun/star/embed/ElementModes.hpp> 74 #include <com/sun/star/embed/XTransactedObject.hpp> 75 76 #include "sfxurlrelocator.hxx" 77 78 using namespace ::com::sun::star; 79 using namespace ::com::sun::star::beans; 80 using namespace ::com::sun::star::frame; 81 using namespace ::com::sun::star::io; 82 using namespace ::com::sun::star::lang; 83 using namespace ::com::sun::star::sdbc; 84 using namespace ::com::sun::star::uno; 85 using namespace ::com::sun::star::ucb; 86 using namespace ::com::sun::star::document; 87 using namespace ::rtl; 88 using namespace ::ucbhelper; 89 90 91 #include <sfx2/doctempl.hxx> 92 #include <sfx2/docfac.hxx> 93 #include <sfx2/docfile.hxx> 94 #include <sfx2/objsh.hxx> 95 #include "sfxtypes.hxx" 96 #include <sfx2/app.hxx> 97 #include "sfx2/sfxresid.hxx" 98 #include "doc.hrc" 99 #include <sfx2/fcontnr.hxx> 100 #include <svtools/templatefoldercache.hxx> 101 102 #include <comphelper/storagehelper.hxx> 103 #include <unotools/ucbhelper.hxx> 104 105 //======================================================================== 106 107 // #define DONT_USE_HIERARCHY 108 109 #define TITLE "Title" 110 #define IS_FOLDER "IsFolder" 111 #define PROPERTY_TYPE "TypeDescription" 112 #define TARGET_URL "TargetURL" 113 #define TYPE_FOLDER "application/vnd.sun.star.hier-folder" 114 #define TYPE_LINK "application/vnd.sun.star.hier-link" 115 #define TYPE_FSYS_FOLDER "application/vnd.sun.staroffice.fsys-folder" 116 117 #define TARGET_DIR_URL "TargetDirURL" 118 #define COMMAND_DELETE "delete" 119 #define COMMAND_TRANSFER "transfer" 120 121 #define STANDARD_FOLDER "standard" 122 123 #define SERVICENAME_TYPEDETECTION "com.sun.star.document.TypeDetection" 124 #define TYPEDETECTION_PARAMETER "FileName" 125 //#define SERVICENAME_OLD_TYPEDETECTION "com.sun.star.frame.FrameLoaderFactory" 126 //#define PARAMETER_OLD_TYPEDETECTION "DeepDetection" 127 #define SERVICENAME_DOCINFO "com.sun.star.document.DocumentProperties" 128 #define SERVICENAME_DOCTEMPLATES "com.sun.star.frame.DocumentTemplates" 129 #define SERVICENAME_DESKTOP "com.sun.star.frame.Desktop" 130 131 //======================================================================== 132 133 class RegionData_Impl; 134 135 namespace DocTempl { 136 137 class DocTempl_EntryData_Impl 138 { 139 RegionData_Impl* mpParent; 140 141 // the following member must be SfxObjectShellLock since it controlls that SfxObjectShell lifetime by design 142 // and users of this class expect it to be so. 143 SfxObjectShellLock mxObjShell; 144 145 OUString maTitle; 146 OUString maOwnURL; 147 OUString maTargetURL; 148 sal_Bool mbIsOwner : 1; 149 sal_Bool mbDidConvert: 1; 150 151 private: 152 RegionData_Impl* GetParent() const { return mpParent; } 153 154 public: 155 DocTempl_EntryData_Impl( RegionData_Impl* pParent, 156 const OUString& rTitle ); 157 158 const OUString& GetTitle() const { return maTitle; } 159 const OUString& GetTargetURL(); 160 const OUString& GetHierarchyURL(); 161 162 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; } 163 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; } 164 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; } 165 166 int Compare( const OUString& rTitle ) const; 167 168 SfxObjectShellRef CreateObjectShell(); 169 sal_Bool DeleteObjectShell(); 170 }; 171 172 } 173 174 using namespace ::DocTempl; 175 176 // ------------------------------------------------------------------------ 177 178 class RegionData_Impl 179 { 180 DECLARE_LIST( EntryList_Impl, DocTempl_EntryData_Impl* ) 181 const SfxDocTemplate_Impl* mpParent; 182 EntryList_Impl maEntries; 183 OUString maTitle; 184 OUString maOwnURL; 185 OUString maTargetURL; 186 187 private: 188 long GetEntryPos( const OUString& rTitle, 189 sal_Bool& rFound ) const; 190 const SfxDocTemplate_Impl* GetParent() const { return mpParent; } 191 192 public: 193 RegionData_Impl( const SfxDocTemplate_Impl* pParent, 194 const OUString& rTitle ); 195 ~RegionData_Impl(); 196 197 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; } 198 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; } 199 200 DocTempl_EntryData_Impl* GetEntry( sal_uIntPtr nIndex ) const; 201 DocTempl_EntryData_Impl* GetEntry( const OUString& rName ) const; 202 DocTempl_EntryData_Impl* GetByTargetURL( const OUString& rName ) const; 203 204 const OUString& GetTitle() const { return maTitle; } 205 const OUString& GetTargetURL(); 206 const OUString& GetHierarchyURL(); 207 208 sal_uIntPtr GetCount() const; 209 210 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; } 211 212 void AddEntry( const OUString& rTitle, 213 const OUString& rTargetURL, 214 sal_uInt16 *pPos = NULL ); 215 void DeleteEntry( sal_uIntPtr nIndex ); 216 217 int Compare( const OUString& rTitle ) const 218 { return maTitle.compareTo( rTitle ); } 219 int Compare( RegionData_Impl* pCompareWith ) const; 220 }; 221 222 DECLARE_LIST( RegionList_Impl, RegionData_Impl* ) 223 224 // ------------------------------------------------------------------------ 225 226 class SfxDocTemplate_Impl : public SvRefBase 227 { 228 uno::Reference< XPersist > mxInfo; 229 uno::Reference< XDocumentTemplates > mxTemplates; 230 231 ::osl::Mutex maMutex; 232 OUString maRootURL; 233 OUString maStandardGroup; 234 RegionList_Impl maRegions; 235 sal_Bool mbConstructed; 236 237 uno::Reference< XAnyCompareFactory > m_rCompareFactory; 238 239 // the following member is intended to prevent clearing of the global data when it is in use 240 // TODO/LATER: it still does not make the implementation complete thread-safe 241 sal_Int32 mnLockCounter; 242 243 private: 244 void Clear(); 245 246 public: 247 SfxDocTemplate_Impl(); 248 ~SfxDocTemplate_Impl(); 249 250 void IncrementLock(); 251 void DecrementLock(); 252 253 sal_Bool Construct( ); 254 void CreateFromHierarchy( Content &rTemplRoot ); 255 void ReInitFromComponent(); 256 void AddRegion( const OUString& rTitle, 257 Content& rContent ); 258 259 void Rescan(); 260 261 void DeleteRegion( sal_uIntPtr nIndex ); 262 263 sal_uIntPtr GetRegionCount() const 264 { return maRegions.Count(); } 265 RegionData_Impl* GetRegion( const OUString& rName ) const; 266 RegionData_Impl* GetRegion( sal_uIntPtr nIndex ) const; 267 void GetTemplates( Content& rTargetFolder, 268 Content& rParentFolder, 269 RegionData_Impl* pRegion ); 270 271 long GetRegionPos( const OUString& rTitle, 272 sal_Bool& rFound ) const; 273 274 sal_Bool GetTitleFromURL( const OUString& rURL, OUString& aTitle ); 275 sal_Bool InsertRegion( RegionData_Impl *pData, sal_uIntPtr nPos = LIST_APPEND ); 276 OUString GetRootURL() const { return maRootURL; } 277 278 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; } 279 }; 280 281 // ------------------------------------------------------------------------ 282 283 class DocTemplLocker_Impl 284 { 285 SfxDocTemplate_Impl& m_aDocTempl; 286 public: 287 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl ) 288 : m_aDocTempl( aDocTempl ) 289 { 290 m_aDocTempl.IncrementLock(); 291 } 292 293 ~DocTemplLocker_Impl() 294 { 295 m_aDocTempl.DecrementLock(); 296 } 297 }; 298 299 // ------------------------------------------------------------------------ 300 301 #ifndef SFX_DECL_DOCTEMPLATES_DEFINED 302 #define SFX_DECL_DOCTEMPLATES_DEFINED 303 SV_DECL_REF(SfxDocTemplate_Impl) 304 #endif 305 306 SV_IMPL_REF(SfxDocTemplate_Impl) 307 308 // ------------------------------------------------------------------------ 309 310 SfxDocTemplate_Impl *gpTemplateData = 0; 311 312 // ----------------------------------------------------------------------- 313 314 static sal_Bool getTextProperty_Impl( Content& rContent, 315 const OUString& rPropName, 316 OUString& rPropValue ); 317 318 //======================================================================== 319 //======================================================================== 320 //======================================================================== 321 322 String SfxDocumentTemplates::GetFullRegionName 323 ( 324 sal_uInt16 nIdx // Index des Bereiches 325 ) const 326 327 /* [Beschreibung] 328 329 Liefert den logischen Namen eines Bereiches Plus seinem Pfad 330 331 332 [R"uckgabewert] Referenz auf diesen Namen 333 334 */ 335 336 { 337 // First: find the RegionData for the index 338 String aName; 339 340 DocTemplLocker_Impl aLocker( *pImp ); 341 342 if ( pImp->Construct() ) 343 { 344 RegionData_Impl *pData1 = pImp->GetRegion( nIdx ); 345 346 if ( pData1 ) 347 aName = pData1->GetTitle(); 348 349 // --**-- here was some code which appended the path to the 350 // group if there was more than one with the same name. 351 // this should not happen anymore 352 } 353 354 return aName; 355 } 356 357 //------------------------------------------------------------------------ 358 359 const String& SfxDocumentTemplates::GetRegionName 360 ( 361 sal_uInt16 nIdx // Index des Bereiches 362 ) const 363 364 /* [Beschreibung] 365 366 Liefert den logischen Namen eines Bereiches 367 368 369 [R"uckgabewert] 370 371 const String& Referenz auf diesen Namen 372 373 */ 374 { 375 static String maTmpString; 376 377 DocTemplLocker_Impl aLocker( *pImp ); 378 379 if ( pImp->Construct() ) 380 { 381 RegionData_Impl *pData = pImp->GetRegion( nIdx ); 382 383 if ( pData ) 384 maTmpString = pData->GetTitle(); 385 else 386 maTmpString.Erase(); 387 } 388 else 389 maTmpString.Erase(); 390 391 return maTmpString; 392 } 393 394 395 //------------------------------------------------------------------------ 396 397 sal_uInt16 SfxDocumentTemplates::GetRegionNo 398 ( 399 const String &rRegion // Name der Region 400 ) const 401 402 /* [Beschreibung] 403 404 Liefert den Index f"ur einen logischen Namen eines Bereiches. 405 406 407 [R"uckgabewert] 408 409 sal_uInt16 Index von 'rRegion' oder USHRT_MAX falls unbekannt 410 411 */ 412 { 413 DocTemplLocker_Impl aLocker( *pImp ); 414 415 if ( !pImp->Construct() ) 416 return USHRT_MAX; 417 418 sal_Bool bFound; 419 sal_uIntPtr nIndex = pImp->GetRegionPos( rRegion, bFound ); 420 421 if ( bFound ) 422 return (sal_uInt16) nIndex; 423 else 424 return USHRT_MAX; 425 } 426 427 428 //------------------------------------------------------------------------ 429 430 sal_uInt16 SfxDocumentTemplates::GetRegionCount() const 431 432 /* [Beschreibung] 433 434 Liefert die Anzahl der Bereiche 435 436 437 [R"uckgabewert] 438 439 sal_uInt16 Anzahl der Bereiche 440 441 */ 442 { 443 DocTemplLocker_Impl aLocker( *pImp ); 444 445 if ( !pImp->Construct() ) 446 return 0; 447 448 sal_uIntPtr nCount = pImp->GetRegionCount(); 449 450 return (sal_uInt16) nCount; 451 } 452 453 //------------------------------------------------------------------------ 454 455 sal_Bool SfxDocumentTemplates::IsRegionLoaded( sal_uInt16 nIdx ) const 456 { 457 DocTemplLocker_Impl aLocker( *pImp ); 458 459 if ( !pImp->Construct() ) 460 return sal_False; 461 462 RegionData_Impl *pData = pImp->GetRegion( nIdx ); 463 464 if ( pData ) 465 return sal_True; 466 else 467 return sal_False; 468 } 469 470 //------------------------------------------------------------------------ 471 472 sal_uInt16 SfxDocumentTemplates::GetCount 473 ( 474 const String& rName /* Name des Bereiches, dessen Eintrags- 475 anzahl ermittelt werden soll */ 476 477 ) const 478 479 /* [Beschreibung] 480 481 Liefert die Anzahl der Eintr"age eines Bereiches 482 483 484 [R"uckgabewert] 485 486 USHORT Anzahl der Eintr"age 487 488 */ 489 490 { 491 DocTemplLocker_Impl aLocker( *pImp ); 492 493 if ( !pImp->Construct() ) 494 return 0; 495 496 RegionData_Impl *pData = pImp->GetRegion( rName ); 497 sal_uIntPtr nCount = 0; 498 499 if ( pData ) 500 nCount = pData->GetCount(); 501 502 return (sal_uInt16) nCount; 503 } 504 505 //------------------------------------------------------------------------ 506 507 sal_uInt16 SfxDocumentTemplates::GetCount 508 ( 509 sal_uInt16 nRegion /* Index des Bereiches, dessen Eintrags- 510 anzahl ermittelt werden soll */ 511 512 ) const 513 514 /* [Beschreibung] 515 516 Liefert die Anzahl der Eintr"age eines Bereiches 517 518 519 [R"uckgabewert] Anzahl der Eintr"age 520 521 */ 522 523 { 524 DocTemplLocker_Impl aLocker( *pImp ); 525 526 if ( !pImp->Construct() ) 527 return 0; 528 529 RegionData_Impl *pData = pImp->GetRegion( nRegion ); 530 sal_uIntPtr nCount = 0; 531 532 if ( pData ) 533 nCount = pData->GetCount(); 534 535 return (sal_uInt16) nCount; 536 } 537 538 //------------------------------------------------------------------------ 539 540 const String& SfxDocumentTemplates::GetName 541 ( 542 sal_uInt16 nRegion, // Index des Bereiches, in dem der Eintrag liegt 543 sal_uInt16 nIdx // Index des Eintrags 544 ) const 545 546 /* [Beschreibung] 547 548 Liefert den logischen Namen eines Eintrags eines Bereiches 549 550 551 [R"uckgabewert] 552 553 const String& Name des Eintrags 554 555 */ 556 557 { 558 DocTemplLocker_Impl aLocker( *pImp ); 559 560 static String maTmpString; 561 562 if ( pImp->Construct() ) 563 { 564 DocTempl_EntryData_Impl *pEntry = NULL; 565 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 566 567 if ( pRegion ) 568 pEntry = pRegion->GetEntry( nIdx ); 569 570 if ( pEntry ) 571 maTmpString = pEntry->GetTitle(); 572 else 573 maTmpString.Erase(); 574 } 575 else 576 maTmpString.Erase(); 577 578 return maTmpString; 579 } 580 581 //------------------------------------------------------------------------ 582 583 String SfxDocumentTemplates::GetFileName 584 ( 585 sal_uInt16 nRegion, // Index des Bereiches, in dem der Eintrag liegt 586 sal_uInt16 nIdx // Index des Eintrags 587 ) const 588 589 /* [Beschreibung] 590 591 Liefert den Dateinamen eines Eintrags eines Bereiches 592 593 [R"uckgabewert] Dateiname des Eintrags 594 595 */ 596 { 597 DocTemplLocker_Impl aLocker( *pImp ); 598 599 if ( !pImp->Construct() ) 600 return String(); 601 602 DocTempl_EntryData_Impl *pEntry = NULL; 603 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 604 605 if ( pRegion ) 606 pEntry = pRegion->GetEntry( nIdx ); 607 608 if ( pEntry ) 609 { 610 INetURLObject aURLObj( pEntry->GetTargetURL() ); 611 return aURLObj.getName( INetURLObject::LAST_SEGMENT, true, 612 INetURLObject::DECODE_WITH_CHARSET ); 613 } 614 else 615 return String(); 616 } 617 618 //------------------------------------------------------------------------ 619 620 String SfxDocumentTemplates::GetPath 621 ( 622 sal_uInt16 nRegion, // Index des Bereiches, in dem der Eintrag liegt 623 sal_uInt16 nIdx // Index des Eintrags 624 ) const 625 626 /* [Beschreibung] 627 628 Liefert den Dateinamen mit vollst"andigem Pfad zu der einem 629 Eintrag zugeordneten Datei 630 631 632 [R"uckgabewert] 633 634 String Dateiname mit vollst"andigem Pfad 635 636 */ 637 { 638 DocTemplLocker_Impl aLocker( *pImp ); 639 640 if ( !pImp->Construct() ) 641 return String(); 642 643 DocTempl_EntryData_Impl *pEntry = NULL; 644 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 645 646 if ( pRegion ) 647 pEntry = pRegion->GetEntry( nIdx ); 648 649 if ( pEntry ) 650 return pEntry->GetTargetURL(); 651 else 652 return String(); 653 } 654 655 //------------------------------------------------------------------------ 656 657 String SfxDocumentTemplates::GetTemplatePath 658 ( 659 sal_uInt16 nRegion, // Index des Bereiches, in dem der Eintrag liegt 660 const String& rLongName // logischer Name des Eintrags 661 ) const 662 663 /* [Beschreibung] 664 665 Liefert den Dateinamen mit vollst"andigem Pfad zu der einem 666 Eintrag zugeordneten Datei 667 668 669 [R"uckgabewert] 670 671 String Dateiname mit vollst"andigem Pfad 672 673 */ 674 { 675 DocTemplLocker_Impl aLocker( *pImp ); 676 677 if ( !pImp->Construct() ) 678 return String(); 679 680 DocTempl_EntryData_Impl *pEntry = NULL; 681 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 682 683 if ( pRegion ) 684 pEntry = pRegion->GetEntry( rLongName ); 685 686 if ( pEntry ) 687 return pEntry->GetTargetURL(); 688 else if ( pRegion ) 689 { 690 // a new template is going to be inserted, generate a new URL 691 // TODO/LATER: if the title is localized, use minimized URL in future 692 693 // --**-- extension handling will become more complicated, because 694 // every new document type will have it's own extension 695 // e.g.: .stw or .stc instead of .vor 696 INetURLObject aURLObj( pRegion->GetTargetURL() ); 697 aURLObj.insertName( rLongName, false, 698 INetURLObject::LAST_SEGMENT, true, 699 INetURLObject::ENCODE_ALL ); 700 701 OUString aExtension = aURLObj.getExtension(); 702 703 if ( ! aExtension.getLength() ) 704 aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) ); 705 706 return aURLObj.GetMainURL( INetURLObject::NO_DECODE ); 707 } 708 else 709 return String(); 710 } 711 712 //------------------------------------------------------------------------ 713 714 String SfxDocumentTemplates::GetDefaultTemplatePath 715 ( 716 const String& rLongName 717 ) 718 719 /* [Beschreibung] 720 721 Liefert den Standardpfad zu Dokumentvorlagen 722 723 724 [R"uckgabewert] 725 726 String Standardpfad zu Dokumentvorlagen 727 728 */ 729 { 730 DocTemplLocker_Impl aLocker( *pImp ); 731 732 if ( ! pImp->Construct() ) 733 return String(); 734 735 // the first region in the list should always be the standard 736 // group 737 // --**-- perhaps we have to create it ??? 738 RegionData_Impl *pRegion = pImp->GetRegion( 0L ); 739 DocTempl_EntryData_Impl *pEntry = NULL; 740 741 if ( pRegion ) 742 pEntry = pRegion->GetEntry( rLongName ); 743 744 if ( pEntry ) 745 return pEntry->GetTargetURL(); 746 else if ( pRegion ) 747 { 748 // a new template is going to be inserted, generate a new URL 749 // TODO/LATER: if the title is localized, use minimized URL in future 750 751 INetURLObject aURLObj( pRegion->GetTargetURL() ); 752 aURLObj.insertName( rLongName, false, 753 INetURLObject::LAST_SEGMENT, true, 754 INetURLObject::ENCODE_ALL ); 755 756 OUString aExtension = aURLObj.getExtension(); 757 758 if ( ! aExtension.getLength() ) 759 aURLObj.setExtension( OUString( RTL_CONSTASCII_USTRINGPARAM( "vor" ) ) ); 760 761 return aURLObj.GetMainURL( INetURLObject::NO_DECODE ); 762 } 763 else 764 return String(); 765 766 /* dv! missing: create the directory, if it doesn't exists 767 768 769 DBG_ASSERT(aDirs.GetTokenCount(cDelim), "Keine Bereiche"); 770 DirEntry aPath(aDirs.GetToken(0, cDelim)); 771 772 // Verzeichnis anlegen 773 if(!aPath.MakeDir()) 774 return String(); 775 776 MakeFileName_Impl(aPath, rLongName, sal_True); 777 SfxTemplateDir *pEntry = new SfxTemplateDir; 778 SfxTemplateDirEntryPtr pDirEntry = 779 new SfxTemplateDirEntry( String( '.' ), aPath.GetPath() ); 780 pDirEntry->SetContent(new SfxTemplateDir(aPath.GetPath())); 781 pEntry->Insert(pDirEntry, pEntry->Count()); 782 pDirs->Insert(pEntry, pDirs->Count()); 783 return aPath.GetFull(); 784 */ 785 } 786 787 //------------------------------------------------------------------------ 788 789 ::rtl::OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( const ::rtl::OUString& aGroupName, 790 const ::rtl::OUString& aTitle ) 791 { 792 DocTemplLocker_Impl aLocker( *pImp ); 793 794 INetURLObject aTemplateObj( pImp->GetRootURL() ); 795 796 aTemplateObj.insertName( aGroupName, false, 797 INetURLObject::LAST_SEGMENT, true, 798 INetURLObject::ENCODE_ALL ); 799 800 aTemplateObj.insertName( aTitle, false, 801 INetURLObject::LAST_SEGMENT, true, 802 INetURLObject::ENCODE_ALL ); 803 804 805 ::rtl::OUString aResult; 806 Content aTemplate; 807 uno::Reference< XCommandEnvironment > aCmdEnv; 808 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ), aCmdEnv, aTemplate ) ) 809 { 810 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) ); 811 getTextProperty_Impl( aTemplate, aPropName, aResult ); 812 aResult = SvtPathOptions().SubstituteVariable( aResult ); 813 } 814 815 return aResult; 816 } 817 818 //------------------------------------------------------------------------ 819 820 sal_Bool SfxDocumentTemplates::SaveDir 821 ( 822 // SfxTemplateDir& rDir // das zu speichernde Directory 823 ) 824 825 /* [Beschreibung] 826 827 Speichert das Directory rDir 828 829 830 [R"uckgabewert] 831 832 sal_Bool sal_False, 833 Schreibfehler 834 835 sal_True 836 gespeichert 837 838 */ 839 840 { 841 return sal_True; 842 } 843 844 //------------------------------------------------------------------------ 845 846 void SfxDocumentTemplates::NewTemplate 847 ( 848 sal_uInt16 nRegion, /* Index des Bereiches, in dem die Vorlage 849 angelegt werden soll */ 850 851 const String& rLongName, // logischer Name der neuen Vorlage 852 const String& rFileName // Dateiname der neuen Vorlage 853 ) 854 855 /* [Beschreibung] 856 857 Eintragen einer neuen Dokumentvorlage in die Verwaltungsstrukturen 858 Das "Uberschreiben einer Vorlage gleichen Namens wird 859 verhindert (!! Fehlermeldung) 860 861 */ 862 863 { 864 DocTemplLocker_Impl aLocker( *pImp ); 865 866 if ( ! pImp->Construct() ) 867 return; 868 869 DocTempl_EntryData_Impl *pEntry; 870 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 871 872 // do nothing if there is no region with that index 873 if ( !pRegion ) 874 return; 875 876 pEntry = pRegion->GetEntry( rLongName ); 877 878 // do nothing if there is already an entry with that name 879 if ( pEntry ) 880 return; 881 882 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 883 884 if ( xTemplates->addTemplate( pRegion->GetTitle(), rLongName, rFileName ) ) 885 pRegion->AddEntry( rLongName, rFileName ); 886 } 887 888 //------------------------------------------------------------------------ 889 890 sal_Bool SfxDocumentTemplates::CopyOrMove 891 ( 892 sal_uInt16 nTargetRegion, // Index des Zielbereiches 893 sal_uInt16 nTargetIdx, // Index Zielposition 894 sal_uInt16 nSourceRegion, // Index des Quellbereiches 895 sal_uInt16 nSourceIdx, /* Index der zu kopierenden / zu verschiebenden 896 Dokumentvorlage */ 897 sal_Bool bMove // kopieren / verschieben 898 ) 899 900 /* [Beschreibung] 901 902 Kopieren oder Verschieben einer Dokumentvorlage 903 904 [R"uckgabewert] 905 906 sal_Bool sal_True 907 Aktion konnte ausgef"uhrt werden 908 909 sal_False 910 Aktion konnte nicht ausgef2uhrt werden 911 [Querverweise] 912 913 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)> 914 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)> 915 */ 916 917 { 918 /* to perform a copy or move, we need to send a transfer command to 919 the destination folder with the URL of the source as parameter. 920 ( If the destination content doesn't support the transfer command, 921 we could try a copy ( and delete ) instead. ) 922 We need two transfers ( one for the real template and one for its 923 representation in the hierarchy ) 924 ... 925 */ 926 927 DocTemplLocker_Impl aLocker( *pImp ); 928 929 if ( !pImp->Construct() ) 930 return sal_False; 931 932 // Don't copy or move any folders 933 if( nSourceIdx == USHRT_MAX ) 934 return sal_False ; 935 936 if ( nSourceRegion == nTargetRegion ) 937 { 938 DBG_ERRORFILE( "Don't know, what to do!" ); 939 return sal_False; 940 #if 0 941 // Verschieben einer Vorlage innerhalb eines Bereiches 942 // --> nur Verwaltungsdaten aktualisieren 943 if ( bMove && nTargetRegion == nSourceRegion ) 944 { 945 if(nTargetIdx == USHRT_MAX) 946 nTargetIdx = 0; 947 const SfxTemplateDirEntryPtr pEntry = rTargetDir[nSourceIdx]; 948 rTargetDir.Insert(pEntry, nTargetIdx); 949 if(nTargetIdx < nSourceIdx) 950 ++nSourceIdx; 951 rTargetDir.Remove(nSourceIdx); 952 return SaveDir(rTargetDir); 953 } 954 #endif 955 } 956 957 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion ); 958 if ( !pSourceRgn ) 959 return sal_False; 960 961 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx ); 962 if ( !pSource ) 963 return sal_False; 964 965 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion ); 966 if ( !pTargetRgn ) 967 return sal_False; 968 969 OUString aTitle = pSource->GetTitle(); 970 971 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 972 973 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(), 974 aTitle, 975 pSource->GetTargetURL() ) ) 976 { 977 978 INetURLObject aSourceObj( pSource->GetTargetURL() ); 979 980 ::rtl::OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle ); 981 if ( !aNewTargetURL.getLength() ) 982 return sal_False; 983 984 if ( bMove ) 985 { 986 // --**-- delete the original file 987 sal_Bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(), 988 pSource->GetTitle() ); 989 if ( bDeleted ) 990 pSourceRgn->DeleteEntry( nSourceIdx ); 991 else 992 { 993 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) ) 994 return sal_False; // will trigger tetry with copy instead of move 995 996 // if it is not possible to remove just created template ( must be possible! ) 997 // it is better to report success here, since at least the copy has succeeded 998 // TODO/LATER: solve it more gracefully in future 999 } 1000 } 1001 1002 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &nTargetIdx ); 1003 1004 return sal_True; 1005 } 1006 1007 // --**-- wenn aktuell das File geoeffnet ist, 1008 // muss es hinterher wieder geoeffnet werden 1009 1010 return sal_False; 1011 } 1012 1013 //------------------------------------------------------------------------ 1014 1015 sal_Bool SfxDocumentTemplates::Move 1016 ( 1017 sal_uInt16 nTargetRegion, // Index des Zielbereiches 1018 sal_uInt16 nTargetIdx, // Index Zielposition 1019 sal_uInt16 nSourceRegion, // Index des Quellbereiches 1020 sal_uInt16 nSourceIdx /* Index der zu kopierenden / zu verschiebenden 1021 Dokumentvorlage */ 1022 ) 1023 1024 /* [Beschreibung] 1025 1026 Verschieben einer Dokumentvorlage 1027 1028 1029 [R"uckgabewert] 1030 1031 sal_Bool sal_True 1032 Aktion konnte ausgef"uhrt werden 1033 1034 sal_False 1035 Aktion konnte nicht ausgef2uhrt werden 1036 1037 [Querverweise] 1038 1039 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)> 1040 */ 1041 { 1042 DocTemplLocker_Impl aLocker( *pImp ); 1043 1044 return CopyOrMove( nTargetRegion, nTargetIdx, 1045 nSourceRegion, nSourceIdx, sal_True ); 1046 } 1047 1048 //------------------------------------------------------------------------ 1049 1050 sal_Bool SfxDocumentTemplates::Copy 1051 ( 1052 sal_uInt16 nTargetRegion, // Index des Zielbereiches 1053 sal_uInt16 nTargetIdx, // Index Zielposition 1054 sal_uInt16 nSourceRegion, // Index des Quellbereiches 1055 sal_uInt16 nSourceIdx /* Index der zu kopierenden / zu verschiebenden 1056 Dokumentvorlage */ 1057 ) 1058 1059 /* [Beschreibung] 1060 1061 Kopieren einer Dokumentvorlage 1062 1063 1064 [R"uckgabewert] 1065 1066 sal_Bool sal_True 1067 Aktion konnte ausgef"uhrt werden 1068 1069 sal_False 1070 Aktion konnte nicht ausgef"uhrt werden 1071 1072 [Querverweise] 1073 1074 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)> 1075 */ 1076 1077 { 1078 DocTemplLocker_Impl aLocker( *pImp ); 1079 1080 return CopyOrMove( nTargetRegion, nTargetIdx, 1081 nSourceRegion, nSourceIdx, sal_False ); 1082 } 1083 1084 //------------------------------------------------------------------------ 1085 1086 sal_Bool SfxDocumentTemplates::CopyTo 1087 ( 1088 sal_uInt16 nRegion, /* Bereich der Vorlage, die exportiert werden 1089 soll */ 1090 sal_uInt16 nIdx, /* Index der Vorlage, die exportiert werden 1091 soll */ 1092 const String& rName /* Dateiname, unter dem die Vorlage angelegt 1093 werden soll */ 1094 ) const 1095 1096 /* [Beschreibung] 1097 1098 Exportieren einer Dokumentvorlage in das Dateisystem 1099 1100 1101 [R"uckgabewert] 1102 1103 sal_Bool sal_True 1104 Aktion konnte ausgef"uhrt werden 1105 1106 sal_False 1107 Aktion konnte nicht ausgef"uhrt werden 1108 1109 1110 [Querverweise] 1111 1112 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)> 1113 */ 1114 1115 { 1116 DocTemplLocker_Impl aLocker( *pImp ); 1117 1118 if ( ! pImp->Construct() ) 1119 return sal_False; 1120 1121 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion ); 1122 if ( !pSourceRgn ) 1123 return sal_False; 1124 1125 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx ); 1126 if ( !pSource ) 1127 return sal_False; 1128 1129 INetURLObject aTargetURL( rName ); 1130 1131 OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true, 1132 INetURLObject::DECODE_WITH_CHARSET ) ); 1133 aTargetURL.removeSegment(); 1134 1135 OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::NO_DECODE ); 1136 1137 uno::Reference< XCommandEnvironment > aCmdEnv; 1138 Content aTarget; 1139 1140 try 1141 { 1142 aTarget = Content( aParentURL, aCmdEnv ); 1143 1144 TransferInfo aTransferInfo; 1145 aTransferInfo.MoveData = sal_False; 1146 aTransferInfo.SourceURL = pSource->GetTargetURL(); 1147 aTransferInfo.NewTitle = aTitle; 1148 aTransferInfo.NameClash = NameClash::OVERWRITE; 1149 1150 Any aArg = makeAny( aTransferInfo ); 1151 OUString aCmd( RTL_CONSTASCII_USTRINGPARAM( COMMAND_TRANSFER ) ); 1152 1153 aTarget.executeCommand( aCmd, aArg ); 1154 } 1155 catch ( ContentCreationException& ) 1156 { return sal_False; } 1157 catch ( Exception& ) 1158 { return sal_False; } 1159 1160 return sal_True; 1161 } 1162 1163 //------------------------------------------------------------------------ 1164 1165 sal_Bool SfxDocumentTemplates::CopyFrom 1166 ( 1167 sal_uInt16 nRegion, /* Bereich, in den die Vorlage importiert 1168 werden soll */ 1169 sal_uInt16 nIdx, // Index der neuen Vorlage in diesem Bereich 1170 String& rName /* Dateiname der Vorlage, die importiert 1171 werden soll, als out-Parameter der (auto- 1172 matisch aus dem Dateinamen generierte) 1173 logische Name der Vorlage */ 1174 ) 1175 1176 /* [Beschreibung] 1177 1178 Importieren einer Dokumentvorlage aus dem Dateisystem 1179 1180 1181 [R"uckgabewert] Erfolg (sal_True) oder Mi"serfpTargetDirectory->GetContent()); 1182 1183 sal_Bool sal_True 1184 Aktion konnte ausgef"uhrt werden 1185 1186 sal_False 1187 Aktion konnte nicht ausgef"uhrt werden 1188 1189 [Querverweise] 1190 1191 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)> 1192 */ 1193 1194 { 1195 DocTemplLocker_Impl aLocker( *pImp ); 1196 1197 if ( ! pImp->Construct() ) 1198 return sal_False; 1199 1200 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion ); 1201 1202 if ( !pTargetRgn ) 1203 return sal_False; 1204 1205 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 1206 if ( !xTemplates.is() ) 1207 return sal_False; 1208 1209 OUString aTitle; 1210 sal_Bool bTemplateAdded = sal_False; 1211 1212 if( pImp->GetTitleFromURL( rName, aTitle ) ) 1213 { 1214 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName ); 1215 } 1216 else 1217 { 1218 OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DESKTOP ) ); 1219 uno::Reference< XComponentLoader > xDesktop( ::comphelper::getProcessServiceFactory()->createInstance( aService ), 1220 UNO_QUERY ); 1221 1222 Sequence< PropertyValue > aArgs( 1 ); 1223 aArgs[0].Name = ::rtl::OUString::createFromAscii("Hidden"); 1224 aArgs[0].Value <<= sal_True; 1225 1226 INetURLObject aTemplURL( rName ); 1227 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier; 1228 uno::Reference< XStorable > xStorable; 1229 try 1230 { 1231 xStorable = uno::Reference< XStorable >( 1232 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::NO_DECODE), 1233 OUString::createFromAscii( "_blank" ), 1234 0, 1235 aArgs ), 1236 UNO_QUERY ); 1237 1238 xDocPropsSupplier = uno::Reference< XDocumentPropertiesSupplier >( 1239 xStorable, UNO_QUERY ); 1240 } 1241 catch( Exception& ) 1242 { 1243 } 1244 1245 if( xStorable.is() ) 1246 { 1247 // get Title from XDocumentPropertiesSupplier 1248 if( xDocPropsSupplier.is() ) 1249 { 1250 uno::Reference< XDocumentProperties > xDocProps 1251 = xDocPropsSupplier->getDocumentProperties(); 1252 if (xDocProps.is() ) { 1253 aTitle = xDocProps->getTitle(); 1254 } 1255 } 1256 1257 if( ! aTitle.getLength() ) 1258 { 1259 INetURLObject aURL( aTemplURL ); 1260 aURL.CutExtension(); 1261 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, 1262 INetURLObject::DECODE_WITH_CHARSET ); 1263 } 1264 1265 // write a template using XStorable interface 1266 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable ); 1267 } 1268 } 1269 1270 1271 if( bTemplateAdded ) 1272 { 1273 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() ); 1274 aTemplObj.insertName( aTitle, false, 1275 INetURLObject::LAST_SEGMENT, true, 1276 INetURLObject::ENCODE_ALL ); 1277 OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::NO_DECODE ); 1278 1279 uno::Reference< XCommandEnvironment > aCmdEnv; 1280 Content aTemplCont; 1281 1282 if( Content::create( aTemplURL, aCmdEnv, aTemplCont ) ) 1283 { 1284 OUString aTemplName; 1285 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) ); 1286 1287 if( getTextProperty_Impl( aTemplCont, aPropName, aTemplName ) ) 1288 { 1289 if ( nIdx == USHRT_MAX ) 1290 nIdx = 0; 1291 else 1292 nIdx += 1; 1293 1294 pTargetRgn->AddEntry( aTitle, aTemplName, &nIdx ); 1295 rName = aTitle; 1296 return sal_True; 1297 } 1298 else 1299 { 1300 DBG_ASSERT( sal_False, "CopyFrom(): The content should contain target URL!" ); 1301 } 1302 } 1303 else 1304 { 1305 DBG_ASSERT( sal_False, "CopyFrom(): The content just was created!" ); 1306 } 1307 } 1308 1309 return sal_False; 1310 } 1311 1312 //------------------------------------------------------------------------ 1313 1314 sal_Bool SfxDocumentTemplates::Delete 1315 ( 1316 sal_uInt16 nRegion, // Index des Bereiches 1317 sal_uInt16 nIdx /* Index des Eintrags oder USHRT_MAX, 1318 wenn ein Verzeichnis gemeint ist. */ 1319 ) 1320 1321 /* [Beschreibung] 1322 1323 "oschen eines Eintrags oder eines Verzeichnisses 1324 1325 1326 [R"uckgabewert] 1327 1328 sal_Bool sal_True 1329 Aktion konnte ausgef"uhrt werden 1330 1331 sal_False 1332 Aktion konnte nicht ausgef"uhrt werden 1333 1334 1335 [Querverweise] 1336 1337 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)> 1338 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)> 1339 <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)> 1340 */ 1341 1342 { 1343 DocTemplLocker_Impl aLocker( *pImp ); 1344 1345 /* delete the template or folder in the hierarchy and in the 1346 template folder by sending a delete command to the content. 1347 Then remove the data from the lists 1348 */ 1349 if ( ! pImp->Construct() ) 1350 return sal_False; 1351 1352 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 1353 1354 if ( !pRegion ) 1355 return sal_False; 1356 1357 sal_Bool bRet; 1358 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 1359 1360 if ( nIdx == USHRT_MAX ) 1361 { 1362 bRet = xTemplates->removeGroup( pRegion->GetTitle() ); 1363 if ( bRet ) 1364 pImp->DeleteRegion( nRegion ); 1365 } 1366 else 1367 { 1368 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx ); 1369 1370 if ( !pEntry ) 1371 return sal_False; 1372 1373 bRet = xTemplates->removeTemplate( pRegion->GetTitle(), 1374 pEntry->GetTitle() ); 1375 if( bRet ) 1376 pRegion->DeleteEntry( nIdx ); 1377 } 1378 1379 return bRet; 1380 } 1381 1382 //------------------------------------------------------------------------ 1383 1384 sal_Bool SfxDocumentTemplates::InsertDir 1385 ( 1386 const String& rText, // der logische Name des neuen Bereiches 1387 sal_uInt16 nRegion // Index des Bereiches 1388 ) 1389 1390 /* [Beschreibung] 1391 1392 Einf"ugen eines Verzeichnisses 1393 1394 1395 [R"uckgabewert] 1396 1397 sal_Bool sal_True 1398 Aktion konnte ausgef"uhrt werden 1399 1400 sal_False 1401 Aktion konnte nicht ausgef"uhrt werden 1402 1403 [Querverweise] 1404 1405 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)> 1406 <SfxDocumentTemplates::SaveDir(SfxTemplateDir&)> 1407 */ 1408 { 1409 DocTemplLocker_Impl aLocker( *pImp ); 1410 1411 if ( ! pImp->Construct() ) 1412 return sal_False; 1413 1414 RegionData_Impl *pRegion = pImp->GetRegion( rText ); 1415 1416 if ( pRegion ) 1417 return sal_False; 1418 1419 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 1420 1421 if ( xTemplates->addGroup( rText ) ) 1422 { 1423 RegionData_Impl* pNewRegion = new RegionData_Impl( pImp, rText ); 1424 1425 if ( ! pImp->InsertRegion( pNewRegion, nRegion ) ) 1426 { 1427 delete pNewRegion; 1428 return sal_False; 1429 } 1430 return sal_True; 1431 } 1432 1433 return sal_False; 1434 } 1435 1436 //------------------------------------------------------------------------ 1437 1438 sal_Bool SfxDocumentTemplates::SetName 1439 ( 1440 const String& rName, // Der zu setzende Name 1441 sal_uInt16 nRegion, // Index des Bereiches 1442 sal_uInt16 nIdx /* Index des Eintrags oder USHRT_MAX, 1443 wenn ein Verzeichnis gemeint ist. */ 1444 ) 1445 1446 /* [Beschreibung] 1447 1448 "Andern des Namens eines Eintrags oder eines Verzeichnisses 1449 1450 1451 [R"uckgabewert] 1452 1453 sal_Bool sal_True 1454 Aktion konnte ausgef"uhrt werden 1455 1456 sal_False 1457 Aktion konnte nicht ausgef"uhrt werden 1458 1459 */ 1460 1461 { 1462 DocTemplLocker_Impl aLocker( *pImp ); 1463 1464 if ( ! pImp->Construct() ) 1465 return sal_False; 1466 1467 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 1468 DocTempl_EntryData_Impl *pEntry = NULL; 1469 1470 if ( !pRegion ) 1471 return sal_False; 1472 1473 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates(); 1474 OUString aEmpty; 1475 1476 if ( nIdx == USHRT_MAX ) 1477 { 1478 if ( pRegion->GetTitle() == OUString( rName ) ) 1479 return sal_True; 1480 1481 // we have to rename a region 1482 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) ) 1483 { 1484 pRegion->SetTitle( rName ); 1485 pRegion->SetTargetURL( aEmpty ); 1486 pRegion->SetHierarchyURL( aEmpty ); 1487 return sal_True; 1488 } 1489 } 1490 else 1491 { 1492 pEntry = pRegion->GetEntry( nIdx ); 1493 1494 if ( !pEntry ) 1495 return sal_False; 1496 1497 if ( pEntry->GetTitle() == OUString( rName ) ) 1498 return sal_True; 1499 1500 if ( xTemplates->renameTemplate( pRegion->GetTitle(), 1501 pEntry->GetTitle(), 1502 rName ) ) 1503 { 1504 pEntry->SetTitle( rName ); 1505 pEntry->SetTargetURL( aEmpty ); 1506 pEntry->SetHierarchyURL( aEmpty ); 1507 return sal_True; 1508 } 1509 } 1510 1511 return sal_False; 1512 } 1513 1514 //------------------------------------------------------------------------ 1515 1516 sal_Bool SfxDocumentTemplates::Rescan() 1517 1518 /* [Beschreibung] 1519 1520 Abgleich des Verwaltungsdaten mit dem aktuellen Zustand auf der Platte. 1521 Die logischen Namen, zu denen keine Datei mit existiert, werden aus 1522 der Verwaltungsstruktur entfernt; Dateien, zu denen kein Eintrag 1523 existiert, werden aufgenommen. 1524 1525 1526 [R"uckgabewert] 1527 1528 sal_Bool sal_True 1529 Aktion konnte ausgef"uhrt werden 1530 1531 sal_False 1532 Aktion konnte nicht ausgef"uhrt werden 1533 1534 1535 [Querverweise] 1536 1537 <SfxTemplateDir::Scan(sal_Bool bDirectory, sal_Bool bSave)> 1538 <SfxTemplateDir::Freshen(const SfxTemplateDir &rNew)> 1539 */ 1540 { 1541 if ( !pImp->Construct() ) 1542 return sal_False; 1543 1544 pImp->Rescan(); 1545 1546 return sal_True; 1547 } 1548 1549 //------------------------------------------------------------------------ 1550 1551 SfxObjectShellRef SfxDocumentTemplates::CreateObjectShell 1552 ( 1553 sal_uInt16 nRegion, // Index des Bereiches 1554 sal_uInt16 nIdx // Index des Eintrags 1555 ) 1556 1557 /* [Beschreibung] 1558 1559 Zugriff auf die DokumentShell eines Eintrags 1560 1561 1562 [R"uckgabewert] 1563 1564 SfxObjectShellRef Referenz auf die ObjectShell 1565 1566 1567 [Querverweise] 1568 1569 <SfxTemplateDirEntry::CreateObjectShell()> 1570 <SfxDocumentTemplates::DeleteObjectShell(sal_uInt16, sal_uInt16)> 1571 */ 1572 1573 { 1574 DocTemplLocker_Impl aLocker( *pImp ); 1575 1576 if ( !pImp->Construct() ) 1577 return NULL; 1578 1579 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 1580 DocTempl_EntryData_Impl *pEntry = NULL; 1581 1582 if ( pRegion ) 1583 pEntry = pRegion->GetEntry( nIdx ); 1584 1585 if ( pEntry ) 1586 return pEntry->CreateObjectShell(); 1587 else 1588 return NULL; 1589 } 1590 1591 //------------------------------------------------------------------------ 1592 1593 sal_Bool SfxDocumentTemplates::DeleteObjectShell 1594 ( 1595 sal_uInt16 nRegion, // Index des Bereiches 1596 sal_uInt16 nIdx // Index des Eintrags 1597 ) 1598 1599 /* [Beschreibung] 1600 1601 Freigeben der ObjectShell eines Eintrags 1602 1603 1604 [R"uckgabewert] 1605 1606 sal_Bool sal_True 1607 Aktion konnte ausgef"uhrt werden 1608 1609 sal_False 1610 Aktion konnte nicht ausgef"uhrt werden 1611 1612 [Querverweise] 1613 1614 <SfxTemplateDirEntry::DeleteObjectShell()> 1615 <SfxDocumentTemplates::CreateObjectShell(sal_uInt16, sal_uInt16)> 1616 */ 1617 1618 { 1619 DocTemplLocker_Impl aLocker( *pImp ); 1620 1621 if ( ! pImp->Construct() ) 1622 return sal_True; 1623 1624 RegionData_Impl *pRegion = pImp->GetRegion( nRegion ); 1625 DocTempl_EntryData_Impl *pEntry = NULL; 1626 1627 if ( pRegion ) 1628 pEntry = pRegion->GetEntry( nIdx ); 1629 1630 if ( pEntry ) 1631 return pEntry->DeleteObjectShell(); 1632 else 1633 return sal_True; 1634 } 1635 1636 //------------------------------------------------------------------------ 1637 1638 sal_Bool SfxDocumentTemplates::GetFull 1639 ( 1640 const String &rRegion, // Der Name des Bereiches 1641 const String &rName, // Der Name der Vorlage 1642 String &rPath // Out: Pfad + Dateiname 1643 ) 1644 1645 /* [Beschreibung] 1646 1647 Liefert Pfad + Dateiname zu der durch rRegion und rName bezeichneten 1648 Vorlage 1649 1650 1651 [R"uckgabewert] 1652 1653 sal_Bool sal_True 1654 Aktion konnte ausgef"uhrt werden 1655 1656 sal_False 1657 Aktion konnte nicht ausgef"uhrt werden 1658 1659 1660 [Querverweise] 1661 1662 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)> 1663 */ 1664 1665 { 1666 DocTemplLocker_Impl aLocker( *pImp ); 1667 1668 // We don't search for empty names! 1669 if ( ! rName.Len() ) 1670 return sal_False; 1671 1672 if ( ! pImp->Construct() ) 1673 return sal_False; 1674 1675 DocTempl_EntryData_Impl* pEntry = NULL; 1676 const sal_uInt16 nCount = GetRegionCount(); 1677 1678 for ( sal_uInt16 i = 0; i < nCount; ++i ) 1679 { 1680 RegionData_Impl *pRegion = pImp->GetRegion( i ); 1681 1682 if( pRegion && 1683 ( !rRegion.Len() || ( rRegion == String( pRegion->GetTitle() ) ) ) ) 1684 { 1685 pEntry = pRegion->GetEntry( rName ); 1686 1687 if ( pEntry ) 1688 { 1689 rPath = pEntry->GetTargetURL(); 1690 break; 1691 } 1692 } 1693 } 1694 1695 return ( pEntry != NULL ); 1696 } 1697 1698 //------------------------------------------------------------------------ 1699 1700 sal_Bool SfxDocumentTemplates::GetLogicNames 1701 ( 1702 const String &rPath, // vollst"andiger Pfad zu der Vorlage 1703 String &rRegion, // Out: der Bereichsname 1704 String &rName // Out: der Vorlagenname 1705 ) const 1706 1707 /* [Beschreibung] 1708 1709 Liefert Pfad und logischen Namen zu der durch rPath bezeichneten 1710 Vorlage 1711 1712 [R"uckgabewert] 1713 1714 sal_Bool sal_True 1715 Aktion konnte ausgef"uhrt werden 1716 1717 sal_False 1718 Aktion konnte nicht ausgef"uhrt werden 1719 1720 1721 [Querverweise] 1722 1723 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)> 1724 */ 1725 1726 { 1727 DocTemplLocker_Impl aLocker( *pImp ); 1728 1729 if ( ! pImp->Construct() ) 1730 return sal_False; 1731 1732 INetURLObject aFullPath; 1733 1734 aFullPath.SetSmartProtocol( INET_PROT_FILE ); 1735 aFullPath.SetURL( rPath ); 1736 OUString aPath( aFullPath.GetMainURL( INetURLObject::NO_DECODE ) ); 1737 1738 RegionData_Impl *pData = NULL; 1739 DocTempl_EntryData_Impl *pEntry = NULL; 1740 sal_Bool bFound = sal_False; 1741 1742 sal_uIntPtr nCount = GetRegionCount(); 1743 1744 for ( sal_uIntPtr i=0; !bFound && (i<nCount); i++ ) 1745 { 1746 pData = pImp->GetRegion( i ); 1747 if ( pData ) 1748 { 1749 sal_uIntPtr nChildCount = pData->GetCount(); 1750 1751 for ( sal_uIntPtr j=0; !bFound && (j<nChildCount); j++ ) 1752 { 1753 pEntry = pData->GetEntry( j ); 1754 if ( pEntry->GetTargetURL() == aPath ) 1755 { 1756 bFound = sal_True; 1757 } 1758 } 1759 } 1760 } 1761 1762 if ( bFound ) 1763 { 1764 rRegion = pData->GetTitle(); 1765 rName = pEntry->GetTitle(); 1766 } 1767 1768 return bFound; 1769 } 1770 1771 //------------------------------------------------------------------------ 1772 1773 SfxDocumentTemplates::SfxDocumentTemplates() 1774 1775 /* [Beschreibung] 1776 1777 Konstruktor 1778 */ 1779 { 1780 if ( !gpTemplateData ) 1781 gpTemplateData = new SfxDocTemplate_Impl; 1782 1783 pImp = gpTemplateData; 1784 } 1785 1786 //------------------------------------------------------------------------- 1787 1788 void SfxDocumentTemplates::Construct() 1789 1790 // verz"ogerter Aufbau der Verwaltungsdaten 1791 1792 { 1793 // pImp->Construct(); 1794 } 1795 1796 //------------------------------------------------------------------------ 1797 1798 SfxDocumentTemplates::~SfxDocumentTemplates() 1799 1800 /* [Beschreibung] 1801 1802 Destruktor 1803 Freigeben der Verwaltungsdaten 1804 */ 1805 1806 { 1807 pImp = NULL; 1808 } 1809 1810 void SfxDocumentTemplates::Update( sal_Bool _bSmart ) 1811 { 1812 if ( !_bSmart // don't be smart 1813 || ::svt::TemplateFolderCache( sal_True ).needsUpdate() // update is really necessary 1814 ) 1815 { 1816 if ( pImp->Construct() ) 1817 pImp->Rescan(); 1818 } 1819 } 1820 1821 void SfxDocumentTemplates::ReInitFromComponent() 1822 { 1823 pImp->ReInitFromComponent(); 1824 } 1825 1826 1827 sal_Bool SfxDocumentTemplates::HasUserContents( sal_uInt16 nRegion, sal_uInt16 nIdx ) const 1828 { 1829 DocTemplLocker_Impl aLocker( *pImp ); 1830 1831 sal_Bool bResult = sal_False; 1832 1833 RegionData_Impl* pRegion = pImp->GetRegion( nRegion ); 1834 1835 if ( pRegion ) 1836 { 1837 ::rtl::OUString aRegionTargetURL = pRegion->GetTargetURL(); 1838 if ( aRegionTargetURL.getLength() ) 1839 { 1840 sal_uInt16 nLen = 0; 1841 sal_uInt16 nStartInd = 0; 1842 1843 if( nIdx == USHRT_MAX ) 1844 { 1845 // this is a folder 1846 // check whether there is at least one editable template 1847 nLen = ( sal_uInt16 )pRegion->GetCount(); 1848 nStartInd = 0; 1849 if ( nLen == 0 ) 1850 bResult = sal_True; // the writing part of empty folder with writing URL can be removed 1851 } 1852 else 1853 { 1854 // this is a template 1855 // check whether the template is inserted by user 1856 nLen = 1; 1857 nStartInd = nIdx; 1858 } 1859 1860 for ( sal_uInt16 nInd = nStartInd; nInd < nStartInd + nLen; nInd++ ) 1861 { 1862 DocTempl_EntryData_Impl* pEntryData = pRegion->GetEntry( nInd ); 1863 if ( pEntryData ) 1864 { 1865 ::rtl::OUString aEntryTargetURL = pEntryData->GetTargetURL(); 1866 if ( aEntryTargetURL.getLength() 1867 && ::utl::UCBContentHelper::IsSubPath( aRegionTargetURL, aEntryTargetURL ) ) 1868 { 1869 bResult = sal_True; 1870 break; 1871 } 1872 } 1873 } 1874 } 1875 } 1876 1877 return bResult; 1878 } 1879 1880 // ----------------------------------------------------------------------- 1881 // ----------------------------------------------------------------------- 1882 // ----------------------------------------------------------------------- 1883 DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent, 1884 const OUString& rTitle ) 1885 { 1886 mpParent = pParent; 1887 maTitle = rTitle; 1888 mbIsOwner = sal_False; 1889 mbDidConvert= sal_False; 1890 } 1891 1892 // ----------------------------------------------------------------------- 1893 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const 1894 { 1895 return maTitle.compareTo( rTitle ); 1896 } 1897 1898 //------------------------------------------------------------------------ 1899 SfxObjectShellRef DocTempl_EntryData_Impl::CreateObjectShell() 1900 { 1901 if( ! mxObjShell.Is() ) 1902 { 1903 mbIsOwner = sal_False; 1904 sal_Bool bDum = sal_False; 1905 SfxApplication *pSfxApp = SFX_APP(); 1906 String aTargetURL = GetTargetURL(); 1907 1908 mxObjShell = pSfxApp->DocAlreadyLoaded( aTargetURL, sal_True, bDum ); 1909 1910 if( ! mxObjShell.Is() ) 1911 { 1912 mbIsOwner = sal_True; 1913 SfxMedium *pMed=new SfxMedium( 1914 aTargetURL,(STREAM_STD_READWRITE | STREAM_SHARE_DENYALL), sal_False, 0 ); 1915 const SfxFilter* pFilter = NULL; 1916 pMed->UseInteractionHandler(sal_True); 1917 if( pSfxApp->GetFilterMatcher().GuessFilter( 1918 *pMed, &pFilter, SFX_FILTER_TEMPLATE, 0 ) || 1919 (pFilter && !pFilter->IsOwnFormat()) || 1920 (pFilter && !pFilter->UsesStorage()) ) 1921 { 1922 SfxErrorContext aEc( ERRCTX_SFX_LOADTEMPLATE, 1923 aTargetURL ); 1924 delete pMed; 1925 mbDidConvert=sal_True; 1926 sal_uIntPtr lErr; 1927 if ( mxObjShell.Is() ) { 1928 lErr = pSfxApp->LoadTemplate( mxObjShell,aTargetURL); 1929 if( lErr != ERRCODE_NONE ) 1930 ErrorHandler::HandleError(lErr); 1931 } 1932 1933 } 1934 else if (pFilter) 1935 { 1936 mbDidConvert=sal_False; 1937 mxObjShell = SfxObjectShell::CreateObject( pFilter->GetServiceName(), SFX_CREATE_MODE_ORGANIZER ); 1938 if ( mxObjShell.Is() ) 1939 { 1940 mxObjShell->DoInitNew(0); 1941 // TODO/LATER: make sure that we don't use binary templates! 1942 if( mxObjShell->LoadFrom( *pMed ) ) 1943 { 1944 mxObjShell->DoSaveCompleted( pMed ); 1945 } 1946 else 1947 mxObjShell.Clear(); 1948 } 1949 } 1950 } 1951 } 1952 1953 return (SfxObjectShellRef)(SfxObjectShell*) mxObjShell; 1954 } 1955 1956 //------------------------------------------------------------------------ 1957 sal_Bool DocTempl_EntryData_Impl::DeleteObjectShell() 1958 { 1959 sal_Bool bRet = sal_True; 1960 1961 if ( mxObjShell.Is() ) 1962 { 1963 if( mxObjShell->IsModified() ) 1964 { 1965 //Hier speichern wir auch, falls die Vorlage in Bearbeitung ist... 1966 bRet = sal_False; 1967 1968 if ( mbIsOwner ) 1969 { 1970 if( mbDidConvert ) 1971 { 1972 bRet=mxObjShell->PreDoSaveAs_Impl( 1973 GetTargetURL(), 1974 mxObjShell->GetFactory().GetFilterContainer()->GetAnyFilter( SFX_FILTER_EXPORT | SFX_FILTER_IMPORT, SFX_FILTER_INTERNAL )->GetFilterName(), 0 ); 1975 } 1976 else 1977 { 1978 if( mxObjShell->Save() ) 1979 { 1980 uno::Reference< embed::XTransactedObject > xTransacted( mxObjShell->GetStorage(), uno::UNO_QUERY ); 1981 DBG_ASSERT( xTransacted.is(), "Storage must implement XTransactedObject!\n" ); 1982 if ( xTransacted.is() ) 1983 { 1984 try 1985 { 1986 xTransacted->commit(); 1987 bRet = sal_True; 1988 } 1989 catch( uno::Exception& ) 1990 { 1991 } 1992 } 1993 } 1994 } 1995 } 1996 } 1997 1998 if( bRet ) 1999 { 2000 mxObjShell.Clear(); 2001 } 2002 } 2003 return bRet; 2004 } 2005 2006 // ----------------------------------------------------------------------- 2007 const OUString& DocTempl_EntryData_Impl::GetHierarchyURL() 2008 { 2009 if ( !maOwnURL.getLength() ) 2010 { 2011 INetURLObject aTemplateObj( GetParent()->GetHierarchyURL() ); 2012 2013 aTemplateObj.insertName( GetTitle(), false, 2014 INetURLObject::LAST_SEGMENT, true, 2015 INetURLObject::ENCODE_ALL ); 2016 2017 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::NO_DECODE ); 2018 DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" ); 2019 } 2020 2021 return maOwnURL; 2022 } 2023 2024 // ----------------------------------------------------------------------- 2025 const OUString& DocTempl_EntryData_Impl::GetTargetURL() 2026 { 2027 if ( !maTargetURL.getLength() ) 2028 { 2029 uno::Reference< XCommandEnvironment > aCmdEnv; 2030 Content aRegion; 2031 2032 if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) ) 2033 { 2034 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_URL ) ); 2035 2036 getTextProperty_Impl( aRegion, aPropName, maTargetURL ); 2037 } 2038 else 2039 { 2040 DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" ); 2041 } 2042 } 2043 2044 return maTargetURL; 2045 } 2046 2047 // ----------------------------------------------------------------------- 2048 // ----------------------------------------------------------------------- 2049 // ----------------------------------------------------------------------- 2050 // ----------------------------------------------------------------------- 2051 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent, 2052 const OUString& rTitle ) 2053 { 2054 maTitle = rTitle; 2055 mpParent = pParent; 2056 } 2057 2058 // ----------------------------------------------------------------------- 2059 RegionData_Impl::~RegionData_Impl() 2060 { 2061 DocTempl_EntryData_Impl *pData = maEntries.First(); 2062 2063 while ( pData ) 2064 { 2065 delete pData; 2066 pData = maEntries.Next(); 2067 } 2068 } 2069 2070 // ----------------------------------------------------------------------- 2071 long RegionData_Impl::GetEntryPos( const OUString& rTitle, 2072 sal_Bool& rFound ) const 2073 { 2074 #if 1 // Don't use binary search today 2075 sal_uIntPtr i; 2076 sal_uIntPtr nCount = maEntries.Count(); 2077 2078 for ( i=0; i<nCount; i++ ) 2079 { 2080 DocTempl_EntryData_Impl *pData = maEntries.GetObject( i ); 2081 2082 if ( pData->Compare( rTitle ) == 0 ) 2083 { 2084 rFound = sal_True; 2085 return i; 2086 } 2087 } 2088 2089 rFound = sal_False; 2090 return i; 2091 2092 #else 2093 // use binary search to find the correct position 2094 // in the maEntries list 2095 2096 int nCompVal = 1; 2097 long nStart = 0; 2098 long nEnd = maEntries.Count() - 1; 2099 long nMid; 2100 2101 DocTempl_EntryData_Impl* pMid; 2102 2103 rFound = sal_False; 2104 2105 while ( nCompVal && ( nStart <= nEnd ) ) 2106 { 2107 nMid = ( nEnd - nStart ) / 2 + nStart; 2108 pMid = maEntries.GetObject( nMid ); 2109 2110 nCompVal = pMid->Compare( rTitle ); 2111 2112 if ( nCompVal < 0 ) // pMid < pData 2113 nStart = nMid + 1; 2114 else 2115 nEnd = nMid - 1; 2116 } 2117 2118 if ( nCompVal == 0 ) 2119 { 2120 rFound = sal_True; 2121 } 2122 else 2123 { 2124 if ( nCompVal < 0 ) // pMid < pData 2125 nMid++; 2126 } 2127 2128 return nMid; 2129 #endif 2130 } 2131 2132 // ----------------------------------------------------------------------- 2133 void RegionData_Impl::AddEntry( const OUString& rTitle, 2134 const OUString& rTargetURL, 2135 sal_uInt16 *pPos ) 2136 { 2137 INetURLObject aLinkObj( GetHierarchyURL() ); 2138 aLinkObj.insertName( rTitle, false, 2139 INetURLObject::LAST_SEGMENT, true, 2140 INetURLObject::ENCODE_ALL ); 2141 OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE ); 2142 2143 DocTempl_EntryData_Impl *pEntry; 2144 sal_Bool bFound = sal_False; 2145 long nPos = GetEntryPos( rTitle, bFound ); 2146 2147 if ( bFound ) 2148 { 2149 pEntry = maEntries.GetObject( nPos ); 2150 } 2151 else 2152 { 2153 if ( pPos ) 2154 nPos = *pPos; 2155 2156 pEntry = new DocTempl_EntryData_Impl( this, rTitle ); 2157 pEntry->SetTargetURL( rTargetURL ); 2158 pEntry->SetHierarchyURL( aLinkURL ); 2159 maEntries.Insert( pEntry, nPos ); 2160 } 2161 } 2162 2163 // ----------------------------------------------------------------------- 2164 sal_uIntPtr RegionData_Impl::GetCount() const 2165 { 2166 return maEntries.Count(); 2167 } 2168 2169 // ----------------------------------------------------------------------- 2170 const OUString& RegionData_Impl::GetHierarchyURL() 2171 { 2172 if ( !maOwnURL.getLength() ) 2173 { 2174 INetURLObject aRegionObj( GetParent()->GetRootURL() ); 2175 2176 aRegionObj.insertName( GetTitle(), false, 2177 INetURLObject::LAST_SEGMENT, true, 2178 INetURLObject::ENCODE_ALL ); 2179 2180 maOwnURL = aRegionObj.GetMainURL( INetURLObject::NO_DECODE ); 2181 DBG_ASSERT( maOwnURL.getLength(), "GetHierarchyURL(): Could not create URL!" ); 2182 } 2183 2184 return maOwnURL; 2185 } 2186 2187 // ----------------------------------------------------------------------- 2188 const OUString& RegionData_Impl::GetTargetURL() 2189 { 2190 if ( !maTargetURL.getLength() ) 2191 { 2192 uno::Reference< XCommandEnvironment > aCmdEnv; 2193 Content aRegion; 2194 2195 if ( Content::create( GetHierarchyURL(), aCmdEnv, aRegion ) ) 2196 { 2197 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TARGET_DIR_URL ) ); 2198 2199 getTextProperty_Impl( aRegion, aPropName, maTargetURL ); 2200 // --> PB 2004-10-27 #i32656# - the targeturl must be substituted: $(baseinsturl) 2201 maTargetURL = SvtPathOptions().SubstituteVariable( maTargetURL ); 2202 // <-- 2203 } 2204 else 2205 { 2206 DBG_ERRORFILE( "GetTargetURL(): Could not create hierarchy content!" ); 2207 } 2208 } 2209 2210 return maTargetURL; 2211 } 2212 2213 // ----------------------------------------------------------------------- 2214 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( const OUString& rName ) const 2215 { 2216 sal_Bool bFound = sal_False; 2217 long nPos = GetEntryPos( rName, bFound ); 2218 2219 if ( bFound ) 2220 return maEntries.GetObject( nPos ); 2221 else 2222 return NULL; 2223 } 2224 2225 // ----------------------------------------------------------------------- 2226 DocTempl_EntryData_Impl* RegionData_Impl::GetByTargetURL( const OUString& rName ) const 2227 { 2228 DocTempl_EntryData_Impl *pEntry; 2229 2230 sal_uIntPtr nCount = maEntries.Count(); 2231 2232 for ( sal_uIntPtr i=0; i<nCount; i++ ) 2233 { 2234 pEntry = maEntries.GetObject( i ); 2235 if ( pEntry && ( pEntry->GetTargetURL() == rName ) ) 2236 return pEntry; 2237 } 2238 2239 return NULL; 2240 } 2241 2242 // ----------------------------------------------------------------------- 2243 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( sal_uIntPtr nIndex ) const 2244 { 2245 return maEntries.GetObject( nIndex ); 2246 } 2247 2248 // ----------------------------------------------------------------------- 2249 void RegionData_Impl::DeleteEntry( sal_uIntPtr nIndex ) 2250 { 2251 DocTempl_EntryData_Impl *pEntry = maEntries.GetObject( nIndex ); 2252 2253 if ( pEntry ) 2254 { 2255 delete pEntry; 2256 maEntries.Remove( (sal_uIntPtr) nIndex ); 2257 } 2258 } 2259 2260 // ----------------------------------------------------------------------- 2261 int RegionData_Impl::Compare( RegionData_Impl* pCompare ) const 2262 { 2263 int nCompare = maTitle.compareTo( pCompare->maTitle ); 2264 2265 return nCompare; 2266 } 2267 2268 // ----------------------------------------------------------------------- 2269 // ----------------------------------------------------------------------- 2270 // ----------------------------------------------------------------------- 2271 2272 SfxDocTemplate_Impl::SfxDocTemplate_Impl() 2273 : mbConstructed( sal_False ) 2274 , mnLockCounter( 0 ) 2275 { 2276 } 2277 2278 // ----------------------------------------------------------------------- 2279 SfxDocTemplate_Impl::~SfxDocTemplate_Impl() 2280 { 2281 Clear(); 2282 2283 gpTemplateData = NULL; 2284 } 2285 2286 // ----------------------------------------------------------------------- 2287 void SfxDocTemplate_Impl::IncrementLock() 2288 { 2289 ::osl::MutexGuard aGuard( maMutex ); 2290 mnLockCounter++; 2291 } 2292 2293 // ----------------------------------------------------------------------- 2294 void SfxDocTemplate_Impl::DecrementLock() 2295 { 2296 ::osl::MutexGuard aGuard( maMutex ); 2297 if ( mnLockCounter ) 2298 mnLockCounter--; 2299 } 2300 2301 // ----------------------------------------------------------------------- 2302 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( sal_uIntPtr nIndex ) const 2303 { 2304 return maRegions.GetObject( nIndex ); 2305 } 2306 2307 // ----------------------------------------------------------------------- 2308 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( const OUString& rName ) 2309 const 2310 { 2311 sal_uIntPtr nCount = maRegions.Count(); 2312 RegionData_Impl *pData; 2313 2314 for ( sal_uIntPtr i=0; i<nCount; i++ ) 2315 { 2316 pData = maRegions.GetObject( i ); 2317 2318 if ( pData->GetTitle() == rName ) 2319 return pData; 2320 } 2321 2322 return NULL; 2323 } 2324 2325 // ----------------------------------------------------------------------- 2326 void SfxDocTemplate_Impl::DeleteRegion( sal_uIntPtr nIndex ) 2327 { 2328 RegionData_Impl* pRegion = maRegions.GetObject( nIndex ); 2329 2330 if ( pRegion ) 2331 { 2332 delete pRegion; 2333 maRegions.Remove( (sal_uIntPtr) nIndex ); 2334 } 2335 } 2336 2337 // ----------------------------------------------------------------------- 2338 /* AddRegion adds a Region to the RegionList 2339 */ 2340 void SfxDocTemplate_Impl::AddRegion( const OUString& rTitle, 2341 Content& rContent ) 2342 { 2343 RegionData_Impl* pRegion; 2344 pRegion = new RegionData_Impl( this, rTitle ); 2345 2346 if ( ! InsertRegion( pRegion ) ) 2347 { 2348 delete pRegion; 2349 return; 2350 } 2351 2352 // now get the content of the region 2353 uno::Reference< XResultSet > xResultSet; 2354 Sequence< OUString > aProps(2); 2355 aProps[0] = OUString::createFromAscii( TITLE ); 2356 aProps[1] = OUString::createFromAscii( TARGET_URL ); 2357 2358 try 2359 { 2360 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY; 2361 Sequence< NumberedSortingInfo > aSortingInfo(1); 2362 aSortingInfo.getArray()->ColumnIndex = 1; 2363 aSortingInfo.getArray()->Ascending = sal_True; 2364 xResultSet = rContent.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude ); 2365 } 2366 catch ( Exception& ) {} 2367 2368 if ( xResultSet.is() ) 2369 { 2370 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 2371 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY ); 2372 2373 try 2374 { 2375 while ( xResultSet->next() ) 2376 { 2377 OUString aTitle( xRow->getString( 1 ) ); 2378 OUString aTargetDir( xRow->getString( 2 ) ); 2379 2380 pRegion->AddEntry( aTitle, aTargetDir ); 2381 } 2382 } 2383 catch ( Exception& ) {} 2384 } 2385 } 2386 2387 // ----------------------------------------------------------------------- 2388 void SfxDocTemplate_Impl::CreateFromHierarchy( Content &rTemplRoot ) 2389 { 2390 uno::Reference< XResultSet > xResultSet; 2391 Sequence< OUString > aProps(1); 2392 aProps[0] = OUString::createFromAscii( TITLE ); 2393 2394 try 2395 { 2396 ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY; 2397 Sequence< NumberedSortingInfo > aSortingInfo(1); 2398 aSortingInfo.getArray()->ColumnIndex = 1; 2399 aSortingInfo.getArray()->Ascending = sal_True; 2400 xResultSet = rTemplRoot.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude ); 2401 } 2402 catch ( Exception& ) {} 2403 2404 if ( xResultSet.is() ) 2405 { 2406 uno::Reference< XCommandEnvironment > aCmdEnv; 2407 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 2408 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY ); 2409 2410 try 2411 { 2412 while ( xResultSet->next() ) 2413 { 2414 OUString aTitle( xRow->getString( 1 ) ); 2415 2416 OUString aId = xContentAccess->queryContentIdentifierString(); 2417 Content aContent = Content( aId, aCmdEnv ); 2418 2419 AddRegion( aTitle, aContent ); 2420 } 2421 } 2422 catch ( Exception& ) {} 2423 } 2424 } 2425 2426 // ------------------------------------------------------------------------ 2427 sal_Bool SfxDocTemplate_Impl::Construct( ) 2428 { 2429 ::osl::MutexGuard aGuard( maMutex ); 2430 2431 if ( mbConstructed ) 2432 return sal_True; 2433 2434 uno::Reference< XMultiServiceFactory > xFactory; 2435 xFactory = ::comphelper::getProcessServiceFactory(); 2436 2437 OUString aService( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCINFO ) ); 2438 uno::Reference< XPersist > xInfo( xFactory->createInstance( aService ), UNO_QUERY ); 2439 mxInfo = xInfo; 2440 2441 aService = OUString( RTL_CONSTASCII_USTRINGPARAM( SERVICENAME_DOCTEMPLATES ) ); 2442 uno::Reference< XDocumentTemplates > xTemplates( xFactory->createInstance( aService ), UNO_QUERY ); 2443 2444 if ( xTemplates.is() ) 2445 mxTemplates = xTemplates; 2446 else 2447 return sal_False; 2448 2449 uno::Reference< XLocalizable > xLocalizable( xTemplates, UNO_QUERY ); 2450 2451 Sequence< Any > aCompareArg(1); 2452 *(aCompareArg.getArray()) <<= xLocalizable->getLocale();; 2453 m_rCompareFactory = uno::Reference< XAnyCompareFactory >( 2454 xFactory->createInstanceWithArguments( OUString::createFromAscii( "com.sun.star.ucb.AnyCompareFactory" ), 2455 aCompareArg ), 2456 UNO_QUERY ); 2457 2458 uno::Reference < XContent > aRootContent = xTemplates->getContent(); 2459 uno::Reference < XCommandEnvironment > aCmdEnv; 2460 2461 if ( ! aRootContent.is() ) 2462 return sal_False; 2463 2464 mbConstructed = sal_True; 2465 maRootURL = aRootContent->getIdentifier()->getContentIdentifier(); 2466 2467 ResStringArray aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) ); 2468 2469 if ( aLongNames.Count() ) 2470 maStandardGroup = aLongNames.GetString( 0 ); 2471 2472 Content aTemplRoot( aRootContent, aCmdEnv ); 2473 CreateFromHierarchy( aTemplRoot ); 2474 2475 return sal_True; 2476 } 2477 2478 // ----------------------------------------------------------------------- 2479 void SfxDocTemplate_Impl::ReInitFromComponent() 2480 { 2481 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates(); 2482 if ( xTemplates.is() ) 2483 { 2484 uno::Reference < XContent > aRootContent = xTemplates->getContent(); 2485 uno::Reference < XCommandEnvironment > aCmdEnv; 2486 Content aTemplRoot( aRootContent, aCmdEnv ); 2487 Clear(); 2488 CreateFromHierarchy( aTemplRoot ); 2489 } 2490 } 2491 2492 // ----------------------------------------------------------------------- 2493 void SfxDocTemplate_Impl::GetTemplates( Content& rTargetFolder, 2494 Content& /*rParentFolder*/, 2495 RegionData_Impl* pRegion ) 2496 { 2497 uno::Reference< XResultSet > xResultSet; 2498 Sequence< OUString > aProps(1); 2499 2500 aProps[0] = OUString::createFromAscii( TITLE ); 2501 2502 try 2503 { 2504 ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY; 2505 Sequence< NumberedSortingInfo > aSortingInfo(1); 2506 aSortingInfo.getArray()->ColumnIndex = 1; 2507 aSortingInfo.getArray()->Ascending = sal_True; 2508 xResultSet = rTargetFolder.createSortedCursor( aProps, aSortingInfo, m_rCompareFactory, eInclude ); 2509 } 2510 catch ( Exception& ) {} 2511 2512 if ( xResultSet.is() ) 2513 { 2514 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY ); 2515 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY ); 2516 2517 try 2518 { 2519 while ( xResultSet->next() ) 2520 { 2521 OUString aTitle( xRow->getString(1) ); 2522 2523 if ( aTitle.compareToAscii( "sfx.tlx" ) == 0 ) 2524 continue; 2525 2526 OUString aId = xContentAccess->queryContentIdentifierString(); 2527 2528 DocTempl_EntryData_Impl* pEntry = pRegion->GetByTargetURL( aId ); 2529 2530 if ( ! pEntry ) 2531 { 2532 OUString aFullTitle; 2533 if( !GetTitleFromURL( aId, aFullTitle ) ) 2534 { 2535 DBG_ERRORFILE( "GetTemplates(): template of alien format" ); 2536 continue; 2537 } 2538 2539 if ( aFullTitle.getLength() ) 2540 aTitle = aFullTitle; 2541 2542 pRegion->AddEntry( aTitle, aId ); 2543 } 2544 } 2545 } 2546 catch ( Exception& ) {} 2547 } 2548 } 2549 2550 2551 // ----------------------------------------------------------------------- 2552 long SfxDocTemplate_Impl::GetRegionPos( const OUString& rTitle, 2553 sal_Bool& rFound ) const 2554 { 2555 int nCompVal = 1; 2556 long nStart = 0; 2557 long nEnd = maRegions.Count() - 1; 2558 long nMid = 0; 2559 2560 RegionData_Impl* pMid; 2561 2562 while ( nCompVal && ( nStart <= nEnd ) ) 2563 { 2564 nMid = ( nEnd - nStart ) / 2 + nStart; 2565 pMid = maRegions.GetObject( nMid ); 2566 2567 nCompVal = pMid->Compare( rTitle ); 2568 2569 if ( nCompVal < 0 ) // pMid < pData 2570 nStart = nMid + 1; 2571 else 2572 nEnd = nMid - 1; 2573 } 2574 2575 if ( nCompVal == 0 ) 2576 rFound = sal_True; 2577 else 2578 { 2579 if ( nCompVal < 0 ) // pMid < pData 2580 nMid++; 2581 2582 rFound = sal_False; 2583 } 2584 2585 return nMid; 2586 } 2587 2588 // ----------------------------------------------------------------------- 2589 sal_Bool SfxDocTemplate_Impl::InsertRegion( RegionData_Impl *pNew, 2590 sal_uIntPtr nPos ) 2591 { 2592 ::osl::MutexGuard aGuard( maMutex ); 2593 RegionData_Impl *pData = maRegions.First(); 2594 2595 while ( pData && ( pData->Compare( pNew ) != 0 ) ) 2596 pData = maRegions.Next(); 2597 2598 if ( ! pData ) 2599 { 2600 // compare with the name of the standard group here to insert it 2601 // first 2602 2603 if ( pNew->GetTitle() == maStandardGroup ) 2604 maRegions.Insert( pNew, (sal_uIntPtr) 0 ); 2605 else 2606 maRegions.Insert( pNew, nPos ); 2607 } 2608 2609 return ( pData == NULL ); 2610 } 2611 2612 // ----------------------------------------------------------------------- 2613 void SfxDocTemplate_Impl::Rescan() 2614 { 2615 Clear(); 2616 2617 try 2618 { 2619 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates(); 2620 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" ); 2621 if ( xTemplates.is() ) 2622 { 2623 xTemplates->update(); 2624 2625 uno::Reference < XContent > aRootContent = xTemplates->getContent(); 2626 uno::Reference < XCommandEnvironment > aCmdEnv; 2627 2628 Content aTemplRoot( aRootContent, aCmdEnv ); 2629 CreateFromHierarchy( aTemplRoot ); 2630 } 2631 } 2632 catch( const Exception& ) 2633 { 2634 DBG_ERRORFILE( "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update!" ); 2635 } 2636 } 2637 2638 // ----------------------------------------------------------------------- 2639 sal_Bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL, 2640 OUString& aTitle ) 2641 { 2642 if ( mxInfo.is() ) 2643 { 2644 try 2645 { 2646 mxInfo->read( rURL ); 2647 } 2648 catch ( Exception& ) 2649 { 2650 // the document is not a StarOffice document 2651 return sal_False; 2652 } 2653 2654 2655 try 2656 { 2657 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY ); 2658 if ( aPropSet.is() ) 2659 { 2660 OUString aPropName( RTL_CONSTASCII_USTRINGPARAM( TITLE ) ); 2661 Any aValue = aPropSet->getPropertyValue( aPropName ); 2662 aValue >>= aTitle; 2663 } 2664 } 2665 catch ( IOException& ) {} 2666 catch ( UnknownPropertyException& ) {} 2667 catch ( Exception& ) {} 2668 } 2669 2670 if ( ! aTitle.getLength() ) 2671 { 2672 INetURLObject aURL( rURL ); 2673 aURL.CutExtension(); 2674 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true, 2675 INetURLObject::DECODE_WITH_CHARSET ); 2676 } 2677 2678 return sal_True; 2679 } 2680 2681 2682 // ----------------------------------------------------------------------- 2683 void SfxDocTemplate_Impl::Clear() 2684 { 2685 ::osl::MutexGuard aGuard( maMutex ); 2686 if ( mnLockCounter ) 2687 return; 2688 2689 RegionData_Impl *pRegData = maRegions.First(); 2690 2691 while ( pRegData ) 2692 { 2693 delete pRegData; 2694 pRegData = maRegions.Next(); 2695 } 2696 2697 maRegions.Clear(); 2698 } 2699 2700 // ----------------------------------------------------------------------- 2701 // ----------------------------------------------------------------------- 2702 // ----------------------------------------------------------------------- 2703 sal_Bool getTextProperty_Impl( Content& rContent, 2704 const OUString& rPropName, 2705 OUString& rPropValue ) 2706 { 2707 sal_Bool bGotProperty = sal_False; 2708 2709 // Get the property 2710 try 2711 { 2712 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties(); 2713 2714 // check, wether or not the property exists 2715 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) ) 2716 { 2717 return sal_False; 2718 } 2719 2720 // now get the property 2721 Any aAnyValue; 2722 2723 aAnyValue = rContent.getPropertyValue( rPropName ); 2724 aAnyValue >>= rPropValue; 2725 2726 if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) ) 2727 { 2728 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessServiceFactory() ); 2729 aRelocImpl.makeAbsoluteURL( rPropValue ); 2730 } 2731 2732 bGotProperty = sal_True; 2733 } 2734 catch ( RuntimeException& ) {} 2735 catch ( Exception& ) {} 2736 2737 return bGotProperty; 2738 } 2739 2740