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 controls 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:
GetParent() const148 RegionData_Impl* GetParent() const { return mpParent; }
149
150 public:
151 DocTempl_EntryData_Impl( RegionData_Impl* pParent,
152 const OUString& rTitle );
153
GetTitle() const154 const OUString& GetTitle() const { return maTitle; }
155 const OUString& GetTargetURL();
156 const OUString& GetHierarchyURL();
157
SetTitle(const OUString & rTitle)158 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
SetTargetURL(const OUString & rURL)159 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
SetHierarchyURL(const OUString & 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;
GetParent() const186 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
SetTargetURL(const OUString & rURL)193 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
SetHierarchyURL(const OUString & 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
GetTitle() const200 const OUString& GetTitle() const { return maTitle; }
201 const OUString& GetTargetURL();
202 const OUString& GetHierarchyURL();
203
204 sal_uIntPtr GetCount() const;
205
SetTitle(const OUString & rTitle)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
Compare(const OUString & rTitle) const213 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
GetRegionCount() const259 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 );
GetRootURL() const272 OUString GetRootURL() const { return maRootURL; }
273
getDocTemplates()274 uno::Reference< XDocumentTemplates > getDocTemplates() { return mxTemplates; }
275 };
276
277 // ------------------------------------------------------------------------
278
279 class DocTemplLocker_Impl
280 {
281 SfxDocTemplate_Impl& m_aDocTempl;
282 public:
DocTemplLocker_Impl(SfxDocTemplate_Impl & aDocTempl)283 DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
284 : m_aDocTempl( aDocTempl )
285 {
286 m_aDocTempl.IncrementLock();
287 }
288
~DocTemplLocker_Impl()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
GetFullRegionName(sal_uInt16 nIdx) const318 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
GetRegionName(sal_uInt16 nIdx) const355 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
GetRegionNo(const String & rRegion) const393 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
GetRegionCount() const426 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
IsRegionLoaded(sal_uInt16 nIdx) const451 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
GetCount(const String & rName) const468 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
GetCount(sal_uInt16 nRegion) const503 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
GetName(sal_uInt16 nRegion,sal_uInt16 nIdx) const536 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
GetFileName(sal_uInt16 nRegion,sal_uInt16 nIdx) const579 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
GetPath(sal_uInt16 nRegion,sal_uInt16 nIdx) const616 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
GetTemplatePath(sal_uInt16 nRegion,const String & rLongName) const653 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
GetDefaultTemplatePath(const String & rLongName)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
GetTemplateTargetURLFromComponent(const::rtl::OUString & aGroupName,const::rtl::OUString & aTitle)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
SaveDir()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
NewTemplate(sal_uInt16 nRegion,const String & rLongName,const String & rFileName)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
CopyOrMove(sal_uInt16 nTargetRegion,sal_uInt16 nTargetIdx,sal_uInt16 nSourceRegion,sal_uInt16 nSourceIdx,sal_Bool bMove)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
Move(sal_uInt16 nTargetRegion,sal_uInt16 nTargetIdx,sal_uInt16 nSourceRegion,sal_uInt16 nSourceIdx)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
Copy(sal_uInt16 nTargetRegion,sal_uInt16 nTargetIdx,sal_uInt16 nSourceRegion,sal_uInt16 nSourceIdx)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
CopyTo(sal_uInt16 nRegion,sal_uInt16 nIdx,const String & rName) const1082 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
CopyFrom(sal_uInt16 nRegion,sal_uInt16 nIdx,String & rName)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
Delete(sal_uInt16 nRegion,sal_uInt16 nIdx)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
InsertDir(const String & rText,sal_uInt16 nRegion)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
SetName(const String & rName,sal_uInt16 nRegion,sal_uInt16 nIdx)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
Rescan()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
CreateObjectShell(sal_uInt16 nRegion,sal_uInt16 nIdx)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
DeleteObjectShell(sal_uInt16 nRegion,sal_uInt16 nIdx)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
GetFull(const String & rRegion,const String & rName,String & rPath)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
GetLogicNames(const String & rPath,String & rRegion,String & rName) const1696 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
SfxDocumentTemplates()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
Construct()1784 void SfxDocumentTemplates::Construct()
1785
1786 // verz"ogerter Aufbau der Verwaltungsdaten
1787
1788 {
1789 // pImp->Construct();
1790 }
1791
1792 //------------------------------------------------------------------------
1793
~SfxDocumentTemplates()1794 SfxDocumentTemplates::~SfxDocumentTemplates()
1795
1796 /* [Beschreibung]
1797
1798 Destruktor
1799 Freigeben der Verwaltungsdaten
1800 */
1801
1802 {
1803 pImp = NULL;
1804 }
1805
Update(sal_Bool _bSmart)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
ReInitFromComponent()1817 void SfxDocumentTemplates::ReInitFromComponent()
1818 {
1819 pImp->ReInitFromComponent();
1820 }
1821
1822
HasUserContents(sal_uInt16 nRegion,sal_uInt16 nIdx) const1823 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 // -----------------------------------------------------------------------
DocTempl_EntryData_Impl(RegionData_Impl * pParent,const OUString & rTitle)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 // -----------------------------------------------------------------------
Compare(const OUString & rTitle) const1889 int DocTempl_EntryData_Impl::Compare( const OUString& rTitle ) const
1890 {
1891 return maTitle.compareTo( rTitle );
1892 }
1893
1894 //------------------------------------------------------------------------
CreateObjectShell()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 //------------------------------------------------------------------------
DeleteObjectShell()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 // -----------------------------------------------------------------------
GetHierarchyURL()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 // -----------------------------------------------------------------------
GetTargetURL()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 // -----------------------------------------------------------------------
RegionData_Impl(const SfxDocTemplate_Impl * pParent,const OUString & rTitle)2047 RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
2048 const OUString& rTitle )
2049 {
2050 maTitle = rTitle;
2051 mpParent = pParent;
2052 }
2053
2054 // -----------------------------------------------------------------------
~RegionData_Impl()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 // -----------------------------------------------------------------------
GetEntryPos(const OUString & rTitle,sal_Bool & rFound) const2067 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 // -----------------------------------------------------------------------
AddEntry(const OUString & rTitle,const OUString & rTargetURL,sal_uInt16 * pPos)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 // -----------------------------------------------------------------------
GetCount() const2160 sal_uIntPtr RegionData_Impl::GetCount() const
2161 {
2162 return maEntries.Count();
2163 }
2164
2165 // -----------------------------------------------------------------------
GetHierarchyURL()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 // -----------------------------------------------------------------------
GetTargetURL()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 // -----------------------------------------------------------------------
GetEntry(const OUString & rName) const2210 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 // -----------------------------------------------------------------------
GetByTargetURL(const OUString & rName) const2222 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 // -----------------------------------------------------------------------
GetEntry(sal_uIntPtr nIndex) const2239 DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( sal_uIntPtr nIndex ) const
2240 {
2241 return maEntries.GetObject( nIndex );
2242 }
2243
2244 // -----------------------------------------------------------------------
DeleteEntry(sal_uIntPtr nIndex)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 // -----------------------------------------------------------------------
Compare(RegionData_Impl * pCompare) const2257 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
SfxDocTemplate_Impl()2268 SfxDocTemplate_Impl::SfxDocTemplate_Impl()
2269 : mbConstructed( sal_False )
2270 , mnLockCounter( 0 )
2271 {
2272 }
2273
2274 // -----------------------------------------------------------------------
~SfxDocTemplate_Impl()2275 SfxDocTemplate_Impl::~SfxDocTemplate_Impl()
2276 {
2277 Clear();
2278
2279 gpTemplateData = NULL;
2280 }
2281
2282 // -----------------------------------------------------------------------
IncrementLock()2283 void SfxDocTemplate_Impl::IncrementLock()
2284 {
2285 ::osl::MutexGuard aGuard( maMutex );
2286 mnLockCounter++;
2287 }
2288
2289 // -----------------------------------------------------------------------
DecrementLock()2290 void SfxDocTemplate_Impl::DecrementLock()
2291 {
2292 ::osl::MutexGuard aGuard( maMutex );
2293 if ( mnLockCounter )
2294 mnLockCounter--;
2295 }
2296
2297 // -----------------------------------------------------------------------
GetRegion(sal_uIntPtr nIndex) const2298 RegionData_Impl* SfxDocTemplate_Impl::GetRegion( sal_uIntPtr nIndex ) const
2299 {
2300 return maRegions.GetObject( nIndex );
2301 }
2302
2303 // -----------------------------------------------------------------------
GetRegion(const OUString & rName) const2304 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 // -----------------------------------------------------------------------
DeleteRegion(sal_uIntPtr nIndex)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 */
AddRegion(const OUString & rTitle,Content & rContent)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 // -----------------------------------------------------------------------
CreateFromHierarchy(Content & rTemplRoot)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 // ------------------------------------------------------------------------
Construct()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 // -----------------------------------------------------------------------
ReInitFromComponent()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 // -----------------------------------------------------------------------
GetTemplates(Content & rTargetFolder,Content &,RegionData_Impl * pRegion)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 // -----------------------------------------------------------------------
GetRegionPos(const OUString & rTitle,sal_Bool & rFound) const2548 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 // -----------------------------------------------------------------------
InsertRegion(RegionData_Impl * pNew,sal_uIntPtr nPos)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 // -----------------------------------------------------------------------
Rescan()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 // -----------------------------------------------------------------------
GetTitleFromURL(const OUString & rURL,OUString & aTitle)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 // -----------------------------------------------------------------------
Clear()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 // -----------------------------------------------------------------------
getTextProperty_Impl(Content & rContent,const OUString & rPropName,OUString & rPropValue)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, whether 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