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