LibreOffice Module sfx2 (master) 1
doctempl.cxx
Go to the documentation of this file.
1/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2/*
3 * This file is part of the LibreOffice project.
4 *
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8 *
9 * This file incorporates work covered by the following license notice:
10 *
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18 */
19
20
21#include <limits.h>
22#include <mutex>
23#include <string_view>
24
25#include <com/sun/star/uno/Any.h>
26#include <sal/log.hxx>
27
29#include <tools/urlobj.hxx>
30#include <tools/debug.hxx>
34#include <ucbhelper/content.hxx>
35#include <com/sun/star/beans/PropertyValue.hpp>
36#include <com/sun/star/beans/XPropertySet.hpp>
37#include <com/sun/star/beans/XPropertySetInfo.hpp>
38#include <com/sun/star/document/XTypeDetection.hpp>
39#include <com/sun/star/document/DocumentProperties.hpp>
40#include <com/sun/star/document/XDocumentPropertiesSupplier.hpp>
41#include <com/sun/star/frame/Desktop.hpp>
42#include <com/sun/star/frame/DocumentTemplates.hpp>
43#include <com/sun/star/frame/XDocumentTemplates.hpp>
44#include <com/sun/star/io/IOException.hpp>
45#include <com/sun/star/io/XPersist.hpp>
46#include <com/sun/star/lang/XLocalizable.hpp>
47#include <com/sun/star/sdbc/XResultSet.hpp>
48#include <com/sun/star/sdbc/XRow.hpp>
49#include <com/sun/star/ucb/ContentCreationException.hpp>
50#include <com/sun/star/ucb/NameClash.hpp>
51#include <com/sun/star/ucb/TransferInfo.hpp>
52#include <com/sun/star/ucb/XContent.hpp>
53#include <com/sun/star/ucb/XContentAccess.hpp>
54#include <com/sun/star/ucb/AnyCompareFactory.hpp>
55#include <com/sun/star/ucb/NumberedSortingInfo.hpp>
56
57#include "doctemplateslocal.hxx"
58#include <sfxurlrelocator.hxx>
59
60using namespace ::com::sun::star;
61using namespace ::com::sun::star::beans;
62using namespace ::com::sun::star::frame;
63using namespace ::com::sun::star::io;
64using namespace ::com::sun::star::lang;
65using namespace ::com::sun::star::sdbc;
66using namespace ::com::sun::star::uno;
67using namespace ::com::sun::star::ucb;
68using namespace ::com::sun::star::document;
69using namespace ::rtl;
70using namespace ::ucbhelper;
71
72
73#include <sfx2/doctempl.hxx>
74#include <sfx2/objsh.hxx>
75#include <sfx2/sfxresid.hxx>
76#include <sfx2/strings.hrc>
77#include <strings.hxx>
79
80#include <memory>
81#include <utility>
82#include <vector>
83
84
85constexpr OUStringLiteral TITLE = u"Title";
86constexpr OUStringLiteral TARGET_URL = u"TargetURL";
87
88constexpr OUStringLiteral COMMAND_TRANSFER = u"transfer";
89
90namespace {
91
92class RegionData_Impl;
93
94}
95
96namespace DocTempl {
97
98namespace {
99
100class DocTempl_EntryData_Impl
101{
102 RegionData_Impl* mpParent;
103
104 // the following member must be SfxObjectShellLock since it controls that SfxObjectShell lifetime by design
105 // and users of this class expect it to be so.
107
108 OUString maTitle;
109 OUString maOwnURL;
110 OUString maTargetURL;
111
112public:
113 DocTempl_EntryData_Impl( RegionData_Impl* pParent,
114 const OUString& rTitle );
115
116 const OUString& GetTitle() const { return maTitle; }
117 const OUString& GetTargetURL();
118 const OUString& GetHierarchyURL();
119
120 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
121 void SetTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
122 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
123
124 int Compare( std::u16string_view rTitle ) const;
125};
126
127}
128
129}
130
131using namespace ::DocTempl;
132
133namespace {
134
135class RegionData_Impl
136{
138 std::vector<std::unique_ptr<DocTempl_EntryData_Impl>> maEntries;
139 OUString maTitle;
140 OUString maOwnURL;
141
142private:
143 size_t GetEntryPos( std::u16string_view rTitle,
144 bool& rFound ) const;
145
146public:
147 RegionData_Impl( const SfxDocTemplate_Impl* pParent,
148 OUString aTitle );
149
150 void SetHierarchyURL( const OUString& rURL) { maOwnURL = rURL; }
151
152 DocTempl_EntryData_Impl* GetEntry( size_t nIndex ) const;
153 DocTempl_EntryData_Impl* GetEntry( std::u16string_view rName ) const;
154
155 const OUString& GetTitle() const { return maTitle; }
156 const OUString& GetHierarchyURL();
157
158 size_t GetCount() const;
159
160 void SetTitle( const OUString& rTitle ) { maTitle = rTitle; }
161
162 void AddEntry( const OUString& rTitle,
163 const OUString& rTargetURL,
164 const size_t *pPos );
165 void DeleteEntry( size_t nIndex );
166
167 int Compare( RegionData_Impl const * pCompareWith ) const;
168};
169
170}
171
173{
174 uno::Reference< XPersist > mxInfo;
175 uno::Reference< XDocumentTemplates > mxTemplates;
176
177 std::mutex maMutex;
178 OUString maRootURL;
180 std::vector<std::unique_ptr<RegionData_Impl>> maRegions;
182
183 uno::Reference< XAnyCompareFactory > m_rCompareFactory;
184
185 // the following member is intended to prevent clearing of the global data when it is in use
186 // TODO/LATER: it still does not make the implementation complete thread-safe
187 sal_Int32 mnLockCounter;
188
189private:
190 void Clear();
191
192public:
194 virtual ~SfxDocTemplate_Impl() override;
195
196 void IncrementLock();
197 void DecrementLock();
198
199 bool Construct( );
200 void CreateFromHierarchy( std::unique_lock<std::mutex>& rGuard, Content &rTemplRoot );
201 void ReInitFromComponent();
202 void AddRegion( std::unique_lock<std::mutex>& rGuard,
203 const OUString& rTitle,
204 Content& rContent );
205
206 void Rescan();
207
208 void DeleteRegion( size_t nIndex );
209
210 size_t GetRegionCount() const
211 { return maRegions.size(); }
212 RegionData_Impl* GetRegion( std::u16string_view rName ) const;
213 RegionData_Impl* GetRegion( size_t nIndex ) const;
214
215 bool GetTitleFromURL( const OUString& rURL, OUString& aTitle );
216 bool InsertRegion( std::unique_ptr<RegionData_Impl> pData, size_t nPos );
217 const OUString& GetRootURL() const { return maRootURL; }
218
219 const uno::Reference< XDocumentTemplates >& getDocTemplates() const { return mxTemplates; }
220};
221
222namespace {
223
224class DocTemplLocker_Impl
225{
226 SfxDocTemplate_Impl& m_aDocTempl;
227public:
228 explicit DocTemplLocker_Impl( SfxDocTemplate_Impl& aDocTempl )
229 : m_aDocTempl( aDocTempl )
230 {
231 m_aDocTempl.IncrementLock();
232 }
233
234 ~DocTemplLocker_Impl()
235 {
236 m_aDocTempl.DecrementLock();
237 }
238};
239
240}
241
243
244
245static bool getTextProperty_Impl( Content& rContent,
246 const OUString& rPropName,
247 OUString& rPropValue );
248
249
251(
252 sal_uInt16 nIdx // Region Index
253) const
254
255/* [Description]
256
257 Returns the logical name of a region and its path
258
259 [Return value] Reference to the Region name
260
261*/
262
263{
264 // First: find the RegionData for the index
265
266 DocTemplLocker_Impl aLocker( *pImp );
267
268 if ( pImp->Construct() )
269 {
270 RegionData_Impl *pData1 = pImp->GetRegion( nIdx );
271
272 if ( pData1 )
273 return pData1->GetTitle();
274
275 // --**-- here was some code which appended the path to the
276 // group if there was more than one with the same name.
277 // this should not happen anymore
278 }
279
280 return OUString();
281}
282
283
285(
286 sal_uInt16 nIdx // Region Index
287) const
288
289/* [Description]
290
291 Returns the logical name of a region
292
293 [Return value]
294
295 const String& Reference to the Region name
296
297*/
298{
299 DocTemplLocker_Impl aLocker( *pImp );
300
301 if ( pImp->Construct() )
302 {
303 RegionData_Impl *pData = pImp->GetRegion( nIdx );
304
305 if ( pData )
306 return pData->GetTitle();
307 }
308
309 return OUString();
310}
311
312
314
315/* [Description]
316
317 Returns the number of Regions
318
319 [Return value]
320
321 sal_uInt16 Number of Regions
322*/
323{
324 DocTemplLocker_Impl aLocker( *pImp );
325
326 if ( !pImp->Construct() )
327 return 0;
328
329 return pImp->GetRegionCount();
330}
331
332
334(
335 sal_uInt16 nRegion /* Region index whose number is
336 to be determined */
337
338) const
339
340/* [Description]
341
342 Number of entries in Region
343
344 [Return value] Number of entries
345*/
346
347{
348 DocTemplLocker_Impl aLocker( *pImp );
349
350 if ( !pImp->Construct() )
351 return 0;
352
353 RegionData_Impl *pData = pImp->GetRegion( nRegion );
354
355 if ( !pData )
356 return 0;
357
358 return pData->GetCount();
359}
360
361
363(
364 sal_uInt16 nRegion, // Region Index, in which the entry lies
365 sal_uInt16 nIdx // Index of the entry
366) const
367
368/* [Description]
369
370 Returns the logical name of an entry in Region
371
372 [Return value]
373
374 const String& Entry Name
375*/
376
377{
378 DocTemplLocker_Impl aLocker( *pImp );
379
380 if ( pImp->Construct() )
381 {
382 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
383
384 if ( pRegion )
385 {
386 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
387 if ( pEntry )
388 return pEntry->GetTitle();
389 }
390 }
391
392 return OUString();
393}
394
395
397(
398 sal_uInt16 nRegion, // Region Index, in which the entry lies
399 sal_uInt16 nIdx // Index of the entry
400) const
401
402/* [Description]
403
404 Returns the file name with full path to the file assigned to an entry
405
406 [Return value]
407
408 String File name with full path
409*/
410{
411 DocTemplLocker_Impl aLocker( *pImp );
412
413 if ( !pImp->Construct() )
414 return OUString();
415
416 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
417
418 if ( pRegion )
419 {
420 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
421 if ( pEntry )
422 return pEntry->GetTargetURL();
423 }
424
425 return OUString();
426}
427
428
429OUString SfxDocumentTemplates::GetTemplateTargetURLFromComponent( std::u16string_view aGroupName,
430 std::u16string_view aTitle )
431{
432 DocTemplLocker_Impl aLocker( *pImp );
433
434 INetURLObject aTemplateObj( pImp->GetRootURL() );
435
436 aTemplateObj.insertName( aGroupName, false,
439
440 aTemplateObj.insertName( aTitle, false,
443
444
445 Content aTemplate;
446 uno::Reference< XCommandEnvironment > aCmdEnv;
447 if ( Content::create( aTemplateObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ), aCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
448 {
449 OUString aResult;
450 getTextProperty_Impl( aTemplate, TARGET_URL, aResult );
451 return SvtPathOptions().SubstituteVariable( aResult );
452 }
453
454 return OUString();
455}
456
457
464OUString SfxDocumentTemplates::ConvertResourceString(const OUString& rString)
465{
466 static constexpr rtl::OUStringConstExpr aTemplateNames[] =
467 {
501 };
502
503 TranslateId STR_TEMPLATE_NAME[] =
504 {
505 STR_TEMPLATE_NAME1,
506 STR_TEMPLATE_NAME2,
507 STR_TEMPLATE_NAME3,
508 STR_TEMPLATE_NAME4,
509 STR_TEMPLATE_NAME5,
510 STR_TEMPLATE_NAME6,
511 STR_TEMPLATE_NAME7,
512 STR_TEMPLATE_NAME8,
513 STR_TEMPLATE_NAME9,
514 STR_TEMPLATE_NAME10,
515 STR_TEMPLATE_NAME11,
516 STR_TEMPLATE_NAME12,
517 STR_TEMPLATE_NAME13,
518 STR_TEMPLATE_NAME14,
519 STR_TEMPLATE_NAME15,
520 STR_TEMPLATE_NAME16,
521 STR_TEMPLATE_NAME17,
522 STR_TEMPLATE_NAME18,
523 STR_TEMPLATE_NAME19,
524 STR_TEMPLATE_NAME20,
525 STR_TEMPLATE_NAME21,
526 STR_TEMPLATE_NAME22,
527 STR_TEMPLATE_NAME23,
528 STR_TEMPLATE_NAME24,
529 STR_TEMPLATE_NAME25,
530 STR_TEMPLATE_NAME26,
531 STR_TEMPLATE_NAME27,
532 STR_TEMPLATE_NAME28,
533 STR_TEMPLATE_NAME29,
534 STR_TEMPLATE_NAME30,
535 STR_TEMPLATE_NAME31,
536 STR_TEMPLATE_NAME32,
537 STR_TEMPLATE_NAME33
538 };
539
540 static_assert(SAL_N_ELEMENTS(aTemplateNames) == SAL_N_ELEMENTS(STR_TEMPLATE_NAME));
541
542 for (size_t i = 0; i < SAL_N_ELEMENTS(STR_TEMPLATE_NAME); ++i)
543 {
544 if (rString == aTemplateNames[i])
545 return SfxResId(STR_TEMPLATE_NAME[i]);
546 }
547 return rString;
548}
549
550
552(
553 sal_uInt16 nTargetRegion, // Target Region Index
554 sal_uInt16 nTargetIdx, // Target position Index
555 sal_uInt16 nSourceRegion, // Source Region Index
556 sal_uInt16 nSourceIdx, /* Index to be copied / to moved template */
557 bool bMove // Copy / Move
558)
559
560/* [Description]
561
562 Copy or move a document template
563
564 [Return value]
565
566 sal_Bool sal_True, Action could be performed
567 sal_False, Action could not be performed
568
569 [Cross-references]
570
571 <SfxDocumentTemplates::Move(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
572 <SfxDocumentTemplates::Copy(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16)>
573*/
574
575{
576 /* to perform a copy or move, we need to send a transfer command to
577 the destination folder with the URL of the source as parameter.
578 ( If the destination content doesn't support the transfer command,
579 we could try a copy ( and delete ) instead. )
580 We need two transfers ( one for the real template and one for its
581 representation in the hierarchy )
582 ...
583 */
584
585 DocTemplLocker_Impl aLocker( *pImp );
586
587 if ( !pImp->Construct() )
588 return false;
589
590 // Don't copy or move any folders
591 if( nSourceIdx == USHRT_MAX )
592 return false ;
593
594 if ( nSourceRegion == nTargetRegion )
595 {
596 SAL_WARN( "sfx.doc", "Don't know, what to do!" );
597 return false;
598 }
599
600 RegionData_Impl *pSourceRgn = pImp->GetRegion( nSourceRegion );
601 if ( !pSourceRgn )
602 return false;
603
604 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nSourceIdx );
605 if ( !pSource )
606 return false;
607
608 RegionData_Impl *pTargetRgn = pImp->GetRegion( nTargetRegion );
609 if ( !pTargetRgn )
610 return false;
611
612 const OUString aTitle = pSource->GetTitle();
613
614 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
615
616 if ( xTemplates->addTemplate( pTargetRgn->GetTitle(),
617 aTitle,
618 pSource->GetTargetURL() ) )
619 {
620 const OUString aNewTargetURL = GetTemplateTargetURLFromComponent( pTargetRgn->GetTitle(), aTitle );
621 if ( aNewTargetURL.isEmpty() )
622 return false;
623
624 if ( bMove )
625 {
626 // --**-- delete the original file
627 bool bDeleted = xTemplates->removeTemplate( pSourceRgn->GetTitle(),
628 pSource->GetTitle() );
629 if ( bDeleted )
630 pSourceRgn->DeleteEntry( nSourceIdx );
631 else
632 {
633 if ( xTemplates->removeTemplate( pTargetRgn->GetTitle(), aTitle ) )
634 return false; // will trigger retry with copy instead of move
635
636 // if it is not possible to remove just created template ( must be possible! )
637 // it is better to report success here, since at least the copy has succeeded
638 // TODO/LATER: solve it more gracefully in future
639 }
640 }
641
642 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
643 size_t temp_nTargetIdx = nTargetIdx;
644 pTargetRgn->AddEntry( aTitle, aNewTargetURL, &temp_nTargetIdx );
645
646 return true;
647 }
648
649 // --**-- if the current file is opened,
650 // it must be re-opened afterwards.
651
652 return false;
653}
654
655
657(
658 sal_uInt16 nTargetRegion, // Target Region Index
659 sal_uInt16 nTargetIdx, // Target position Index
660 sal_uInt16 nSourceRegion, // Source Region Index
661 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
662)
663
664/* [Description]
665
666 Moving a template
667
668 [Return value]
669
670 sal_Bool sal_True, Action could be performed
671 sal_False, Action could not be performed
672
673 [Cross-references]
674
675 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
676*/
677{
678 DocTemplLocker_Impl aLocker( *pImp );
679
680 return CopyOrMove( nTargetRegion, nTargetIdx,
681 nSourceRegion, nSourceIdx, true );
682}
683
684
686(
687 sal_uInt16 nTargetRegion, // Target Region Index
688 sal_uInt16 nTargetIdx, // Target position Index
689 sal_uInt16 nSourceRegion, // Source Region Index
690 sal_uInt16 nSourceIdx /* Index to be copied / to moved template */
691)
692
693/* [Description]
694
695 Copying a template
696
697 [Return value]
698
699 sal_Bool sal_True, Action could be performed
700 sal_False, Action could not be performed
701
702 [Cross-references]
703
704 <SfxDocumentTemplates::CopyOrMove(sal_uInt16,sal_uInt16,sal_uInt16,sal_uInt16,sal_Bool)>
705*/
706
707{
708 DocTemplLocker_Impl aLocker( *pImp );
709
710 return CopyOrMove( nTargetRegion, nTargetIdx,
711 nSourceRegion, nSourceIdx, false );
712}
713
714
716(
717 sal_uInt16 nRegion, // Region of the template to be exported
718 sal_uInt16 nIdx, // Index of the template to be exported
719 std::u16string_view rName /* File name under which the template is to
720 be created */
721) const
722
723/* [Description]
724
725 Exporting a template into the file system
726
727 [Return value]
728
729 sal_Bool sal_True, Action could be performed
730 sal_False, Action could not be performed
731
732 [Cross-references]
733
734 <SfxDocumentTemplates::CopyFrom(sal_uInt16,sal_uInt16,String&)>
735*/
736
737{
738 DocTemplLocker_Impl aLocker( *pImp );
739
740 if ( ! pImp->Construct() )
741 return false;
742
743 RegionData_Impl *pSourceRgn = pImp->GetRegion( nRegion );
744 if ( !pSourceRgn )
745 return false;
746
747 DocTempl_EntryData_Impl *pSource = pSourceRgn->GetEntry( nIdx );
748 if ( !pSource )
749 return false;
750
751 INetURLObject aTargetURL( rName );
752
753 const OUString aTitle( aTargetURL.getName( INetURLObject::LAST_SEGMENT, true,
755 aTargetURL.removeSegment();
756
757 const OUString aParentURL = aTargetURL.GetMainURL( INetURLObject::DecodeMechanism::NONE );
758
759 uno::Reference< XCommandEnvironment > aCmdEnv;
760 Content aTarget;
761
762 try
763 {
764 aTarget = Content( aParentURL, aCmdEnv, comphelper::getProcessComponentContext() );
765
766 TransferInfo aTransferInfo;
767 aTransferInfo.MoveData = false;
768 aTransferInfo.SourceURL = pSource->GetTargetURL();
769 aTransferInfo.NewTitle = aTitle;
770 aTransferInfo.NameClash = NameClash::RENAME;
771
772 Any aArg( aTransferInfo );
773 aTarget.executeCommand( COMMAND_TRANSFER, aArg );
774 }
775 catch ( ContentCreationException& )
776 { return false; }
777 catch ( Exception& )
778 { return false; }
779
780 return true;
781}
782
783
785(
786 sal_uInt16 nRegion, /* Region in which the template is to be
787 imported */
788 sal_uInt16 nIdx, // Index of the new template in this Region
789 OUString& rName /* File name of the template to be imported
790 as an out parameter of the (automatically
791 generated from the file name) logical name
792 of the template */
793)
794
795/* [Description]
796
797 Import a template from the file system
798
799 [Return value] Success (sal_True) or serfpTargetDirectory->GetContent());
800
801 sal_Bool sal_True, Action could be performed
802 sal_False, Action could not be performed
803
804 [Cross-references]
805
806 <SfxDocumentTemplates::CopyTo(sal_uInt16,sal_uInt16,const String&)>
807*/
808
809{
810 DocTemplLocker_Impl aLocker( *pImp );
811
812 if ( ! pImp->Construct() )
813 return false;
814
815 RegionData_Impl *pTargetRgn = pImp->GetRegion( nRegion );
816
817 if ( !pTargetRgn )
818 return false;
819
820 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
821 if ( !xTemplates.is() )
822 return false;
823
824 OUString aTitle;
825 bool bTemplateAdded = false;
826
827 if( pImp->GetTitleFromURL( rName, aTitle ) )
828 {
829 bTemplateAdded = xTemplates->addTemplate( pTargetRgn->GetTitle(), aTitle, rName );
830 }
831 else
832 {
833 uno::Reference< XDesktop2 > xDesktop = Desktop::create( ::comphelper::getProcessComponentContext() );
834
835 Sequence< PropertyValue > aArgs{ comphelper::makePropertyValue("Hidden", true) };
836
837 INetURLObject aTemplURL( rName );
838 uno::Reference< XDocumentPropertiesSupplier > xDocPropsSupplier;
839 uno::Reference< XStorable > xStorable;
840 try
841 {
842 xStorable.set(
843 xDesktop->loadComponentFromURL( aTemplURL.GetMainURL(INetURLObject::DecodeMechanism::NONE),
844 "_blank",
845 0,
846 aArgs ),
847 UNO_QUERY );
848
849 xDocPropsSupplier.set( xStorable, UNO_QUERY );
850 }
851 catch( Exception& )
852 {
853 }
854
855 if( xStorable.is() )
856 {
857 // get Title from XDocumentPropertiesSupplier
858 if( xDocPropsSupplier.is() )
859 {
860 uno::Reference< XDocumentProperties > xDocProps
861 = xDocPropsSupplier->getDocumentProperties();
862 if (xDocProps.is() ) {
863 aTitle = xDocProps->getTitle();
864 }
865 }
866
867 if( aTitle.isEmpty() )
868 {
869 INetURLObject aURL( aTemplURL );
870 aURL.CutExtension();
871 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
873 }
874
875 // write a template using XStorable interface
876 bTemplateAdded = xTemplates->storeTemplate( pTargetRgn->GetTitle(), aTitle, xStorable );
877 }
878 }
879
880
881 if( bTemplateAdded )
882 {
883 INetURLObject aTemplObj( pTargetRgn->GetHierarchyURL() );
884 aTemplObj.insertName( aTitle, false,
887 const OUString aTemplURL = aTemplObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
888
889 uno::Reference< XCommandEnvironment > aCmdEnv;
890 Content aTemplCont;
891
892 if( Content::create( aTemplURL, aCmdEnv, comphelper::getProcessComponentContext(), aTemplCont ) )
893 {
894 OUString aTemplName;
895 if( getTextProperty_Impl( aTemplCont, TARGET_URL, aTemplName ) )
896 {
897 if ( nIdx == USHRT_MAX )
898 nIdx = 0;
899 else
900 ++nIdx;
901
902 // todo: fix SfxDocumentTemplates to handle size_t instead of sal_uInt16
903 size_t temp_nIdx = nIdx;
904 pTargetRgn->AddEntry( aTitle, aTemplName, &temp_nIdx );
905 rName = aTitle;
906 return true;
907 }
908 else
909 {
910 SAL_WARN( "sfx.doc", "CopyFrom(): The content should contain target URL!" );
911 }
912 }
913 else
914 {
915 SAL_WARN( "sfx.doc", "CopyFrom(): The content just was created!" );
916 }
917 }
918
919 return false;
920}
921
922
924(
925 sal_uInt16 nRegion, // Region Index
926 sal_uInt16 nIdx /* Index of the entry or USHRT_MAX,
927 if a directory is meant. */
928)
929
930/* [Description]
931
932 Deleting an entry or a directory
933
934 [Return value]
935
936 sal_Bool sal_True, Action could be performed
937 sal_False, Action could not be performed
938
939 [Cross-references]
940
941 <SfxDocumentTemplates::InsertDir(const String&,sal_uInt16)>
942 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
943*/
944
945{
946 DocTemplLocker_Impl aLocker( *pImp );
947
948 /* delete the template or folder in the hierarchy and in the
949 template folder by sending a delete command to the content.
950 Then remove the data from the lists
951 */
952 if ( ! pImp->Construct() )
953 return false;
954
955 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
956
957 if ( !pRegion )
958 return false;
959
960 bool bRet;
961 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
962
963 if ( nIdx == USHRT_MAX )
964 {
965 bRet = xTemplates->removeGroup( pRegion->GetTitle() );
966 if ( bRet )
967 pImp->DeleteRegion( nRegion );
968 }
969 else
970 {
971 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
972
973 if ( !pEntry )
974 return false;
975
976 bRet = xTemplates->removeTemplate( pRegion->GetTitle(),
977 pEntry->GetTitle() );
978 if( bRet )
979 pRegion->DeleteEntry( nIdx );
980 }
981
982 return bRet;
983}
984
985
987(
988 const OUString& rText, // the logical name of the new Region
989 sal_uInt16 nRegion // Region Index
990)
991
992/* [Description]
993
994 Insert an index
995
996 [Return value]
997
998 sal_Bool sal_True, Action could be performed
999 sal_False, Action could not be performed
1000
1001 [Cross-references]
1002
1003 <SfxDocumentTemplates::KillDir(SfxTemplateDir&)>
1004*/
1005{
1006 DocTemplLocker_Impl aLocker( *pImp );
1007
1008 if ( ! pImp->Construct() )
1009 return false;
1010
1011 RegionData_Impl *pRegion = pImp->GetRegion( rText );
1012
1013 if ( pRegion )
1014 return false;
1015
1016 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1017
1018 if ( xTemplates->addGroup( rText ) )
1019 {
1020 return pImp->InsertRegion( std::make_unique<RegionData_Impl>( pImp.get(), rText ), nRegion );
1021 }
1022
1023 return false;
1024}
1025
1026bool SfxDocumentTemplates::InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath)
1027{
1028 DocTemplLocker_Impl aLocker( *pImp );
1029
1030 if ( ! pImp->Construct() )
1031 return false;
1032
1033 RegionData_Impl *pRegion = pImp->GetRegion( nSourceRegion );
1034
1035 if ( !pRegion )
1036 return false;
1037
1038 size_t pos = nIdx;
1039 pRegion->AddEntry( rName, rPath, &pos );
1040
1041 return true;
1042}
1043
1044bool SfxDocumentTemplates::SetName( const OUString& rName, sal_uInt16 nRegion, sal_uInt16 nIdx )
1045
1046{
1047 DocTemplLocker_Impl aLocker( *pImp );
1048
1049 if ( ! pImp->Construct() )
1050 return false;
1051
1052 RegionData_Impl *pRegion = pImp->GetRegion( nRegion );
1053
1054 if ( !pRegion )
1055 return false;
1056
1057 uno::Reference< XDocumentTemplates > xTemplates = pImp->getDocTemplates();
1058
1059 if ( nIdx == USHRT_MAX )
1060 {
1061 if ( pRegion->GetTitle() == rName )
1062 return true;
1063
1064 // we have to rename a region
1065 if ( xTemplates->renameGroup( pRegion->GetTitle(), rName ) )
1066 {
1067 pRegion->SetTitle( rName );
1068 pRegion->SetHierarchyURL( "" );
1069 return true;
1070 }
1071 }
1072 else
1073 {
1074 DocTempl_EntryData_Impl *pEntry = pRegion->GetEntry( nIdx );
1075
1076 if ( !pEntry )
1077 return false;
1078
1079 if ( pEntry->GetTitle() == rName )
1080 return true;
1081
1082 if ( xTemplates->renameTemplate( pRegion->GetTitle(),
1083 pEntry->GetTitle(),
1084 rName ) )
1085 {
1086 pEntry->SetTitle( rName );
1087 pEntry->SetTargetURL( "" );
1088 pEntry->SetHierarchyURL( "" );
1089 return true;
1090 }
1091 }
1092
1093 return false;
1094}
1095
1096
1098(
1099 std::u16string_view rRegion, // Region Name
1100 std::u16string_view rName, // Template Name
1101 OUString &rPath // Out: Path + File name
1102)
1103
1104/* [Description]
1105
1106 Returns Path + File name of the template specified by rRegion and rName.
1107
1108 [Return value]
1109
1110 sal_Bool sal_True, Action could be performed
1111 sal_False, Action could not be performed
1112
1113 [Cross-references]
1114
1115 <SfxDocumentTemplates::GetLogicNames(const String&,String&,String&)>
1116*/
1117
1118{
1119 DocTemplLocker_Impl aLocker( *pImp );
1120
1121 // We don't search for empty names!
1122 if ( rName.empty() )
1123 return false;
1124
1125 if ( ! pImp->Construct() )
1126 return false;
1127
1128 DocTempl_EntryData_Impl* pEntry = nullptr;
1129 const sal_uInt16 nCount = GetRegionCount();
1130
1131 for ( sal_uInt16 i = 0; i < nCount; ++i )
1132 {
1133 RegionData_Impl *pRegion = pImp->GetRegion( i );
1134
1135 if( pRegion &&
1136 ( rRegion.empty() || ( rRegion == pRegion->GetTitle() ) ) )
1137 {
1138 pEntry = pRegion->GetEntry( rName );
1139
1140 if ( pEntry )
1141 {
1142 rPath = pEntry->GetTargetURL();
1143 break;
1144 }
1145 }
1146 }
1147
1148 return ( pEntry != nullptr );
1149}
1150
1151
1153(
1154 std::u16string_view rPath, // Full Path to the template
1155 OUString &rRegion, // Out: Region name
1156 OUString &rName // Out: Template name
1157) const
1158
1159/* [Description]
1160
1161 Returns and logical path name to the template specified by rPath
1162
1163 [Return value]
1164
1165 sal_Bool sal_True, Action could be performed
1166 sal_False, Action could not be performed
1167
1168 [Cross-references]
1169
1170 <SfxDocumentTemplates::GetFull(const String&,const String&,DirEntry&)>
1171*/
1172
1173{
1174 DocTemplLocker_Impl aLocker( *pImp );
1175
1176 if ( ! pImp->Construct() )
1177 return false;
1178
1179 INetURLObject aFullPath;
1180
1181 aFullPath.SetSmartProtocol( INetProtocol::File );
1182 aFullPath.SetURL( rPath );
1183 const OUString aPath( aFullPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) );
1184
1185 const sal_uInt16 nCount = GetRegionCount();
1186
1187 for ( sal_uInt16 i=0; i<nCount; ++i )
1188 {
1189 RegionData_Impl *pData = pImp->GetRegion( i );
1190 if ( pData )
1191 {
1192 const sal_uInt16 nChildCount = pData->GetCount();
1193
1194 for ( sal_uInt16 j=0; j<nChildCount; ++j )
1195 {
1196 DocTempl_EntryData_Impl *pEntry = pData->GetEntry( j );
1197 if ( pEntry && pEntry->GetTargetURL() == aPath )
1198 {
1199 rRegion = pData->GetTitle();
1200 rName = pEntry->GetTitle();
1201 return true;
1202 }
1203 }
1204 }
1205 }
1206
1207 return false;
1208}
1209
1210
1212
1213/* [Description]
1214
1215 Constructor
1216*/
1217{
1218 if ( !gpTemplateData )
1220
1222}
1223
1224
1226
1227/* [Description]
1228
1229 Destructor
1230 Release of administrative data
1231*/
1232
1233{
1234 pImp = nullptr;
1235}
1236
1238{
1239 if ( ::svt::TemplateFolderCache( true ).needsUpdate() ) // update is really necessary
1240 {
1241 if ( pImp->Construct() )
1242 pImp->Rescan();
1243 }
1244}
1245
1247{
1248 pImp->ReInitFromComponent();
1249}
1250
1251DocTempl_EntryData_Impl::DocTempl_EntryData_Impl( RegionData_Impl* pParent,
1252 const OUString& rTitle )
1253{
1254 mpParent = pParent;
1256}
1257
1258
1259int DocTempl_EntryData_Impl::Compare( std::u16string_view rTitle ) const
1260{
1261 return maTitle.compareTo( rTitle );
1262}
1263
1264
1265const OUString& DocTempl_EntryData_Impl::GetHierarchyURL()
1266{
1267 if ( maOwnURL.isEmpty() )
1268 {
1269 INetURLObject aTemplateObj( mpParent->GetHierarchyURL() );
1270
1271 aTemplateObj.insertName( GetTitle(), false,
1274
1275 maOwnURL = aTemplateObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1276 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1277 }
1278
1279 return maOwnURL;
1280}
1281
1282
1283const OUString& DocTempl_EntryData_Impl::GetTargetURL()
1284{
1285 if ( maTargetURL.isEmpty() )
1286 {
1287 uno::Reference< XCommandEnvironment > aCmdEnv;
1288 Content aRegion;
1289
1290 if ( Content::create( GetHierarchyURL(), aCmdEnv, comphelper::getProcessComponentContext(), aRegion ) )
1291 {
1293 }
1294 else
1295 {
1296 SAL_WARN( "sfx.doc", "GetTargetURL(): Could not create hierarchy content!" );
1297 }
1298 }
1299
1300 return maTargetURL;
1301}
1302
1303
1304RegionData_Impl::RegionData_Impl( const SfxDocTemplate_Impl* pParent,
1305 OUString aTitle )
1306 : mpParent(pParent), maTitle(std::move(aTitle))
1307{
1308}
1309
1310
1311size_t RegionData_Impl::GetEntryPos( std::u16string_view rTitle, bool& rFound ) const
1312{
1313 const size_t nCount = maEntries.size();
1314
1315 for ( size_t i=0; i<nCount; ++i )
1316 {
1317 auto &pData = maEntries[ i ];
1318
1319 if ( pData->Compare( rTitle ) == 0 )
1320 {
1321 rFound = true;
1322 return i;
1323 }
1324 }
1325
1326 rFound = false;
1327 return nCount;
1328}
1329
1330
1331void RegionData_Impl::AddEntry( const OUString& rTitle,
1332 const OUString& rTargetURL,
1333 const size_t *pPos )
1334{
1335 INetURLObject aLinkObj( GetHierarchyURL() );
1336 aLinkObj.insertName( rTitle, false,
1339 const OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1340
1341 bool bFound = false;
1342 size_t nPos = GetEntryPos( rTitle, bFound );
1343
1344 if ( bFound )
1345 return;
1346
1347 if ( pPos )
1348 nPos = *pPos;
1349
1350 auto pEntry = std::make_unique<DocTempl_EntryData_Impl>(
1351 this, rTitle );
1352 pEntry->SetTargetURL( rTargetURL );
1353 pEntry->SetHierarchyURL( aLinkURL );
1354 if ( nPos < maEntries.size() ) {
1355 auto it = maEntries.begin();
1356 std::advance( it, nPos );
1357 maEntries.insert( it, std::move(pEntry) );
1358 }
1359 else
1360 maEntries.push_back( std::move(pEntry) );
1361}
1362
1363
1364size_t RegionData_Impl::GetCount() const
1365{
1366 return maEntries.size();
1367}
1368
1369
1370const OUString& RegionData_Impl::GetHierarchyURL()
1371{
1372 if ( maOwnURL.isEmpty() )
1373 {
1374 INetURLObject aRegionObj( mpParent->GetRootURL() );
1375
1376 aRegionObj.insertName( GetTitle(), false,
1379
1380 maOwnURL = aRegionObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
1381 DBG_ASSERT( !maOwnURL.isEmpty(), "GetHierarchyURL(): Could not create URL!" );
1382 }
1383
1384 return maOwnURL;
1385}
1386
1387
1388DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( std::u16string_view rName ) const
1389{
1390 bool bFound = false;
1391 tools::Long nPos = GetEntryPos( rName, bFound );
1392
1393 if ( bFound )
1394 return maEntries[ nPos ].get();
1395 return nullptr;
1396}
1397
1398
1399DocTempl_EntryData_Impl* RegionData_Impl::GetEntry( size_t nIndex ) const
1400{
1401 if ( nIndex < maEntries.size() )
1402 return maEntries[ nIndex ].get();
1403 return nullptr;
1404}
1405
1406
1407void RegionData_Impl::DeleteEntry( size_t nIndex )
1408{
1409 if ( nIndex < maEntries.size() )
1410 {
1411 auto it = maEntries.begin();
1412 std::advance( it, nIndex );
1413 maEntries.erase( it );
1414 }
1415}
1416
1417
1418int RegionData_Impl::Compare( RegionData_Impl const * pCompare ) const
1419{
1420 return maTitle.compareTo( pCompare->maTitle );
1421}
1422
1423
1425: mbConstructed( false )
1426, mnLockCounter( 0 )
1427{
1428}
1429
1430
1432{
1433 gpTemplateData = nullptr;
1434}
1435
1436
1438{
1439 std::unique_lock aGuard( maMutex );
1440 mnLockCounter++;
1441}
1442
1443
1445{
1446 std::unique_lock aGuard( maMutex );
1447 if ( mnLockCounter )
1448 mnLockCounter--;
1449}
1450
1451
1452RegionData_Impl* SfxDocTemplate_Impl::GetRegion( size_t nIndex ) const
1453{
1454 if ( nIndex < maRegions.size() )
1455 return maRegions[ nIndex ].get();
1456 return nullptr;
1457}
1458
1459
1460RegionData_Impl* SfxDocTemplate_Impl::GetRegion( std::u16string_view rName )
1461 const
1462{
1463 for (auto& pData : maRegions)
1464 {
1465 if( pData->GetTitle() == rName )
1466 return pData.get();
1467 }
1468 return nullptr;
1469}
1470
1471
1473{
1474 if ( nIndex < maRegions.size() )
1475 {
1476 auto it = maRegions.begin();
1477 std::advance( it, nIndex );
1478 maRegions.erase( it );
1479 }
1480}
1481
1482
1483/* AddRegion adds a Region to the RegionList
1484*/
1485void SfxDocTemplate_Impl::AddRegion( std::unique_lock<std::mutex>& /*rGuard*/,
1486 const OUString& rTitle,
1487 Content& rContent )
1488{
1489 auto pRegion = std::make_unique<RegionData_Impl>( this, rTitle );
1490 auto pRegionTmp = pRegion.get();
1491
1492 if ( ! InsertRegion( std::move(pRegion), size_t(-1) ) )
1493 {
1494 return;
1495 }
1496
1497 // now get the content of the region
1498 uno::Reference< XResultSet > xResultSet;
1499
1500 try
1501 {
1502 xResultSet = rContent.createSortedCursor( { TITLE, TARGET_URL }, { { 1, true } }, m_rCompareFactory, INCLUDE_DOCUMENTS_ONLY );
1503 }
1504 catch ( Exception& ) {}
1505
1506 if ( !xResultSet.is() )
1507 return;
1508
1509 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1510
1511 try
1512 {
1513 while ( xResultSet->next() )
1514 {
1515 pRegionTmp->AddEntry( xRow->getString( 1 ), xRow->getString( 2 ), nullptr );
1516 }
1517 }
1518 catch ( Exception& ) {}
1519}
1520
1521
1522void SfxDocTemplate_Impl::CreateFromHierarchy( std::unique_lock<std::mutex>& rGuard, Content &rTemplRoot )
1523{
1524 uno::Reference< XResultSet > xResultSet;
1525 Sequence< OUString > aProps { TITLE };
1526
1527 try
1528 {
1529 xResultSet = rTemplRoot.createSortedCursor(
1530 aProps,
1531 { // Sequence
1532 { // NumberedSortingInfo
1533 /* ColumnIndex */ 1, /* Ascending */ true
1534 }
1535 },
1538 );
1539 }
1540 catch ( Exception& ) {}
1541
1542 if ( !xResultSet.is() )
1543 return;
1544
1545 uno::Reference< XCommandEnvironment > aCmdEnv;
1546 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
1547 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
1548
1549 try
1550 {
1551 while ( xResultSet->next() )
1552 {
1553 const OUString aId = xContentAccess->queryContentIdentifierString();
1554 Content aContent( aId, aCmdEnv, comphelper::getProcessComponentContext() );
1555
1556 AddRegion( rGuard, xRow->getString( 1 ), aContent );
1557 }
1558 }
1559 catch ( Exception& ) {}
1560}
1561
1562
1564{
1565 std::unique_lock aGuard( maMutex );
1566
1567 if ( mbConstructed )
1568 return true;
1569
1570 uno::Reference< XComponentContext > xContext = ::comphelper::getProcessComponentContext();
1571
1572 uno::Reference< XPersist > xInfo( document::DocumentProperties::create(xContext), UNO_QUERY );
1573 mxInfo = xInfo;
1574
1575 mxTemplates = frame::DocumentTemplates::create(xContext);
1576
1577 uno::Reference< XLocalizable > xLocalizable( mxTemplates, UNO_QUERY );
1578
1579 m_rCompareFactory = AnyCompareFactory::createWithLocale(xContext, xLocalizable->getLocale());
1580
1581 uno::Reference < XContent > aRootContent = mxTemplates->getContent();
1582 uno::Reference < XCommandEnvironment > aCmdEnv;
1583
1584 if ( ! aRootContent.is() )
1585 return false;
1586
1587 mbConstructed = true;
1588 maRootURL = aRootContent->getIdentifier()->getContentIdentifier();
1589
1591 Content aTemplRoot( aRootContent, aCmdEnv, xContext );
1592 CreateFromHierarchy( aGuard, aTemplRoot );
1593
1594 return true;
1595}
1596
1597
1599{
1600 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1601 if ( xTemplates.is() )
1602 {
1603 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1604 uno::Reference < XCommandEnvironment > aCmdEnv;
1605 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1606 Clear();
1607 std::unique_lock aGuard(maMutex);
1608 CreateFromHierarchy( aGuard, aTemplRoot );
1609 }
1610}
1611
1612
1613bool SfxDocTemplate_Impl::InsertRegion( std::unique_ptr<RegionData_Impl> pNew, size_t nPos )
1614{
1615 // return false (not inserted) if the entry already exists
1616 for (auto const& pRegion : maRegions)
1617 if ( pRegion->Compare( pNew.get() ) == 0 )
1618 return false;
1619
1620 size_t newPos = nPos;
1621 if ( pNew->GetTitle() == maStandardGroup )
1622 newPos = 0;
1623
1624 if ( newPos < maRegions.size() )
1625 {
1626 auto it = maRegions.begin();
1627 std::advance( it, newPos );
1628 maRegions.emplace( it, std::move(pNew) );
1629 }
1630 else
1631 maRegions.emplace_back( std::move(pNew) );
1632
1633 return true;
1634}
1635
1636
1638{
1639 Clear();
1640
1641 try
1642 {
1643 uno::Reference< XDocumentTemplates > xTemplates = getDocTemplates();
1644 DBG_ASSERT( xTemplates.is(), "SfxDocTemplate_Impl::Rescan:invalid template instance!" );
1645 if ( xTemplates.is() )
1646 {
1647 xTemplates->update();
1648
1649 uno::Reference < XContent > aRootContent = xTemplates->getContent();
1650 uno::Reference < XCommandEnvironment > aCmdEnv;
1651
1652 Content aTemplRoot( aRootContent, aCmdEnv, comphelper::getProcessComponentContext() );
1653 std::unique_lock aGuard(maMutex);
1654 CreateFromHierarchy( aGuard, aTemplRoot );
1655 }
1656 }
1657 catch( const Exception& )
1658 {
1659 TOOLS_WARN_EXCEPTION( "sfx.doc", "SfxDocTemplate_Impl::Rescan: caught an exception while doing the update" );
1660 }
1661}
1662
1663
1664bool SfxDocTemplate_Impl::GetTitleFromURL( const OUString& rURL,
1665 OUString& aTitle )
1666{
1667 if ( mxInfo.is() )
1668 {
1669 try
1670 {
1671 mxInfo->read( rURL );
1672 }
1673 catch ( Exception& )
1674 {
1675 // the document is not a StarOffice document
1676 return false;
1677 }
1678
1679
1680 try
1681 {
1682 uno::Reference< XPropertySet > aPropSet( mxInfo, UNO_QUERY );
1683 if ( aPropSet.is() )
1684 {
1685 Any aValue = aPropSet->getPropertyValue( TITLE );
1686 aValue >>= aTitle;
1687 }
1688 }
1689 catch ( IOException& ) {}
1690 catch ( UnknownPropertyException& ) {}
1691 catch ( Exception& ) {}
1692 }
1693
1694 if ( aTitle.isEmpty() )
1695 {
1696 INetURLObject aURL( rURL );
1697 aURL.CutExtension();
1698 aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
1700 }
1701
1702 return true;
1703}
1704
1705
1707{
1708 std::unique_lock aGuard( maMutex );
1709 if ( mnLockCounter )
1710 return;
1711 maRegions.clear();
1712}
1713
1714
1715bool getTextProperty_Impl( Content& rContent,
1716 const OUString& rPropName,
1717 OUString& rPropValue )
1718{
1719 bool bGotProperty = false;
1720
1721 // Get the property
1722 try
1723 {
1724 uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
1725
1726 // check, whether or not the property exists
1727 if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
1728 {
1729 return false;
1730 }
1731
1732 // now get the property
1733 Any aAnyValue = rContent.getPropertyValue( rPropName );
1734 aAnyValue >>= rPropValue;
1735
1737 {
1738 SfxURLRelocator_Impl aRelocImpl( ::comphelper::getProcessComponentContext() );
1739 aRelocImpl.makeAbsoluteURL( rPropValue );
1740 }
1741
1742 bGotProperty = true;
1743 }
1744 catch ( RuntimeException& ) {}
1745 catch ( Exception& ) {}
1746
1747 return bGotProperty;
1748}
1749
1750/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static OUString GetStandardGroupString()
void SetSmartProtocol(INetProtocol eTheSmartScheme)
OUString GetMainURL(DecodeMechanism eMechanism, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8) const
bool insertName(std::u16string_view rTheName, bool bAppendFinalSlash=false, sal_Int32 nIndex=LAST_SEGMENT, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
bool SetURL(std::u16string_view rTheAbsURIRef, EncodeMechanism eMechanism=EncodeMechanism::WasEncoded, rtl_TextEncoding eCharset=RTL_TEXTENCODING_UTF8)
size_t GetRegionCount() const
Definition: doctempl.cxx:210
const uno::Reference< XDocumentTemplates > & getDocTemplates() const
Definition: doctempl.cxx:219
uno::Reference< XPersist > mxInfo
Definition: doctempl.cxx:174
void ReInitFromComponent()
Definition: doctempl.cxx:1598
void CreateFromHierarchy(std::unique_lock< std::mutex > &rGuard, Content &rTemplRoot)
Definition: doctempl.cxx:1522
std::vector< std::unique_ptr< RegionData_Impl > > maRegions
Definition: doctempl.cxx:180
void AddRegion(std::unique_lock< std::mutex > &rGuard, const OUString &rTitle, Content &rContent)
Definition: doctempl.cxx:1485
std::mutex maMutex
Definition: doctempl.cxx:177
sal_Int32 mnLockCounter
Definition: doctempl.cxx:187
uno::Reference< XAnyCompareFactory > m_rCompareFactory
Definition: doctempl.cxx:183
bool GetTitleFromURL(const OUString &rURL, OUString &aTitle)
Definition: doctempl.cxx:1664
OUString maStandardGroup
Definition: doctempl.cxx:179
RegionData_Impl * GetRegion(std::u16string_view rName) const
Definition: doctempl.cxx:1460
bool InsertRegion(std::unique_ptr< RegionData_Impl > pData, size_t nPos)
Definition: doctempl.cxx:1613
virtual ~SfxDocTemplate_Impl() override
Definition: doctempl.cxx:1431
const OUString & GetRootURL() const
Definition: doctempl.cxx:217
void DeleteRegion(size_t nIndex)
Definition: doctempl.cxx:1472
uno::Reference< XDocumentTemplates > mxTemplates
Definition: doctempl.cxx:175
OUString GetPath(sal_uInt16 nRegion, sal_uInt16 nIdx) const
Definition: doctempl.cxx:397
OUString GetRegionName(sal_uInt16 nIdx) const
Definition: doctempl.cxx:285
static OUString ConvertResourceString(const OUString &rString)
Convert a template name to its localised pair if it exists.
Definition: doctempl.cxx:464
bool CopyTo(sal_uInt16 nRegion, sal_uInt16 nIdx, std::u16string_view rName) const
Definition: doctempl.cxx:716
bool InsertTemplate(sal_uInt16 nSourceRegion, sal_uInt16 nIdx, const OUString &rName, const OUString &rPath)
Definition: doctempl.cxx:1026
void Update()
updates the configuration where the document templates structure is stored.
Definition: doctempl.cxx:1237
bool InsertDir(const OUString &rText, sal_uInt16 nRegion)
Definition: doctempl.cxx:987
bool GetFull(std::u16string_view rRegion, std::u16string_view rName, OUString &rPath)
Definition: doctempl.cxx:1098
bool GetLogicNames(std::u16string_view rPath, OUString &rRegion, OUString &rName) const
Definition: doctempl.cxx:1153
SAL_DLLPRIVATE bool CopyOrMove(sal_uInt16 nTargetRegion, sal_uInt16 nTargetIdx, sal_uInt16 nSourceRegion, sal_uInt16 nSourceIdx, bool bMove)
Definition: doctempl.cxx:552
sal_uInt16 GetRegionCount() const
Definition: doctempl.cxx:313
bool CopyFrom(sal_uInt16 nRegion, sal_uInt16 nIdx, OUString &rName)
Definition: doctempl.cxx:785
tools::SvRef< SfxDocTemplate_Impl > pImp
Definition: doctempl.hxx:40
sal_uInt16 GetCount(sal_uInt16 nRegion) const
Definition: doctempl.cxx:334
bool SetName(const OUString &rName, sal_uInt16 nRegion, sal_uInt16 nIdx)
Change the name of an entry or a directory.
Definition: doctempl.cxx:1044
bool Delete(sal_uInt16 nRegion, sal_uInt16 nIdx)
Definition: doctempl.cxx:924
bool Copy(sal_uInt16 nTargetRegion, sal_uInt16 nTargetIdx, sal_uInt16 nSourceRegion, sal_uInt16 nSourceIdx)
Definition: doctempl.cxx:686
bool Move(sal_uInt16 nTargetRegion, sal_uInt16 nTargetIdx, sal_uInt16 nSourceRegion, sal_uInt16 nSourceIdx)
Definition: doctempl.cxx:657
OUString GetFullRegionName(sal_uInt16 nIdx) const
Definition: doctempl.cxx:251
OUString GetTemplateTargetURLFromComponent(std::u16string_view aGroupName, std::u16string_view aTitle)
Definition: doctempl.cxx:429
OUString GetName(sal_uInt16 nRegion, sal_uInt16 nIdx) const
Definition: doctempl.cxx:363
void makeAbsoluteURL(OUString &rURL)
static bool propertyCanContainOfficeDir(std::u16string_view rPropName)
OUString SubstituteVariable(const OUString &rVar) const
T * get() const
int nCount
#define DBG_ASSERT(sCon, aError)
#define TOOLS_WARN_EXCEPTION(area, stream)
URL aURL
virtual void SetTitle(const OUString &rNewTitle) override
RegionData_Impl * mpParent
Definition: doctempl.cxx:102
OUString maTargetURL
Definition: doctempl.cxx:110
constexpr OUStringLiteral COMMAND_TRANSFER
Definition: doctempl.cxx:88
SfxObjectShellLock mxObjShell
Definition: doctempl.cxx:106
constexpr OUStringLiteral TITLE
Definition: doctempl.cxx:85
static bool getTextProperty_Impl(Content &rContent, const OUString &rPropName, OUString &rPropValue)
Definition: doctempl.cxx:1715
OUString maTitle
Definition: doctempl.cxx:108
OUString maOwnURL
Definition: doctempl.cxx:109
static SfxDocTemplate_Impl * gpTemplateData
Definition: doctempl.cxx:242
constexpr OUStringLiteral TARGET_URL
Definition: doctempl.cxx:86
float u
sal_Int32 nIndex
sal_uInt16 nPos
Definition: linksrc.cxx:118
#define SAL_WARN(area, stream)
#define SAL_N_ELEMENTS(arr)
std::unique_ptr< sal_Int32[]> pData
@ Exception
Reference< XComponentContext > getProcessComponentContext()
css::beans::PropertyValue makePropertyValue(const OUString &rName, T &&rValue)
int i
long Long
INCLUDE_FOLDERS_ONLY
INCLUDE_DOCUMENTS_ONLY
UNOTOOLS_DLLPUBLIC bool GetTitle(OUString const &url, OUString *title)
OUString SfxResId(TranslateId aId)
Definition: sfxresid.cxx:22
constexpr OUStringLiteral STR_TEMPLATE_NAME13_DEF
Definition: strings.hxx:30
constexpr OUStringLiteral STR_TEMPLATE_NAME1_DEF
Definition: strings.hxx:18
constexpr OUStringLiteral STR_TEMPLATE_NAME30_DEF
Definition: strings.hxx:47
constexpr OUStringLiteral STR_TEMPLATE_NAME10_DEF
Definition: strings.hxx:27
constexpr OUStringLiteral STR_TEMPLATE_NAME16_DEF
Definition: strings.hxx:33
constexpr OUStringLiteral STR_TEMPLATE_NAME31_DEF
Definition: strings.hxx:48
constexpr OUStringLiteral STR_TEMPLATE_NAME23_DEF
Definition: strings.hxx:40
constexpr OUStringLiteral STR_TEMPLATE_NAME4_DEF
Definition: strings.hxx:21
constexpr OUStringLiteral STR_TEMPLATE_NAME25_DEF
Definition: strings.hxx:42
constexpr OUStringLiteral STR_TEMPLATE_NAME19_DEF
Definition: strings.hxx:36
constexpr OUStringLiteral STR_TEMPLATE_NAME3_DEF
Definition: strings.hxx:20
constexpr OUStringLiteral STR_TEMPLATE_NAME17_DEF
Definition: strings.hxx:34
constexpr OUStringLiteral STR_TEMPLATE_NAME26_DEF
Definition: strings.hxx:43
constexpr OUStringLiteral STR_TEMPLATE_NAME28_DEF
Definition: strings.hxx:45
constexpr OUStringLiteral STR_TEMPLATE_NAME18_DEF
Definition: strings.hxx:35
constexpr OUStringLiteral STR_TEMPLATE_NAME12_DEF
Definition: strings.hxx:29
constexpr OUStringLiteral STR_TEMPLATE_NAME7_DEF
Definition: strings.hxx:24
constexpr OUStringLiteral STR_TEMPLATE_NAME32_DEF
Definition: strings.hxx:49
constexpr OUStringLiteral STR_TEMPLATE_NAME11_DEF
Definition: strings.hxx:28
constexpr OUStringLiteral STR_TEMPLATE_NAME9_DEF
Definition: strings.hxx:26
constexpr OUStringLiteral STR_TEMPLATE_NAME27_DEF
Definition: strings.hxx:44
constexpr OUStringLiteral STR_TEMPLATE_NAME24_DEF
Definition: strings.hxx:41
constexpr OUStringLiteral STR_TEMPLATE_NAME22_DEF
Definition: strings.hxx:39
constexpr OUStringLiteral STR_TEMPLATE_NAME2_DEF
Definition: strings.hxx:19
constexpr OUStringLiteral STR_TEMPLATE_NAME20_DEF
Definition: strings.hxx:37
constexpr OUStringLiteral STR_TEMPLATE_NAME29_DEF
Definition: strings.hxx:46
constexpr OUStringLiteral STR_TEMPLATE_NAME6_DEF
Definition: strings.hxx:23
constexpr OUStringLiteral STR_TEMPLATE_NAME5_DEF
Definition: strings.hxx:22
constexpr OUStringLiteral STR_TEMPLATE_NAME21_DEF
Definition: strings.hxx:38
constexpr OUStringLiteral STR_TEMPLATE_NAME8_DEF
Definition: strings.hxx:25
constexpr OUStringLiteral STR_TEMPLATE_NAME14_DEF
Definition: strings.hxx:31
constexpr OUStringLiteral STR_TEMPLATE_NAME33_DEF
Definition: strings.hxx:50
constexpr OUStringLiteral STR_TEMPLATE_NAME15_DEF
Definition: strings.hxx:32
OUString aTargetURL
size_t pos