1 |
From 2fc88c27a7c329753f2c58ec5ee1caa3678200ae Mon Sep 17 00:00:00 2001 |
2 |
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com> |
3 |
Date: Mon, 24 Feb 2014 15:27:36 +0000 |
4 |
Subject: [PATCH] Related: rhbz#1065807 rework #i66157# for multiple writable |
5 |
template dirs |
6 |
|
7 |
if there are multiple user-level template dirs then we should be able to |
8 |
remove/rename content in all of them, not just the default writable target. |
9 |
|
10 |
The target scenario here is to default to ~/Templates when it exists as the |
11 |
template dir, but to retain ~/.config/libreoffice/user/template in the dir for |
12 |
any pre-existing templates and to treat both as equivalent in terms of removing |
13 |
their content etc. |
14 |
|
15 |
i#66157# wanted to avoid remove extensions templates and other internal |
16 |
ones, so rework that logic to instead just be hands off internal templates |
17 |
and allow modification of the remainder |
18 |
|
19 |
Change-Id: I56afe991d4297ba692e914ae95ea02d68553f60a |
20 |
--- |
21 |
sfx2/source/doc/doctemplates.cxx | 82 ++++++++++++++++++++++++++++++++-------- |
22 |
1 file changed, 67 insertions(+), 15 deletions(-) |
23 |
|
24 |
diff --git a/sfx2/source/doc/doctemplates.cxx b/sfx2/source/doc/doctemplates.cxx |
25 |
index ff07ef3..fe43a40 100644 |
26 |
--- a/sfx2/source/doc/doctemplates.cxx |
27 |
+++ b/sfx2/source/doc/doctemplates.cxx |
28 |
@@ -54,6 +54,7 @@ |
29 |
#include <com/sun/star/ucb/XContentAccess.hpp> |
30 |
#include <com/sun/star/frame/ModuleManager.hpp> |
31 |
#include <com/sun/star/uno/Exception.hpp> |
32 |
+#include <com/sun/star/util/PathSettings.hpp> |
33 |
|
34 |
#include <svtools/templatefoldercache.hxx> |
35 |
#include <unotools/configmgr.hxx> |
36 |
@@ -180,6 +181,7 @@ class SfxDocTplService_Impl |
37 |
|
38 |
::osl::Mutex maMutex; |
39 |
Sequence< OUString > maTemplateDirs; |
40 |
+ Sequence< OUString > maInternalTemplateDirs; |
41 |
OUString maRootURL; |
42 |
NameList_Impl maNames; |
43 |
Locale maLocale; |
44 |
@@ -264,8 +266,16 @@ class SfxDocTplService_Impl |
45 |
|
46 |
void updateData( DocTemplates_EntryData_Impl *pData ); |
47 |
|
48 |
+ //See: #i66157# and rhbz#1065807 |
49 |
+ //return which template dir the rURL is a subpath of |
50 |
+ OUString findParentTemplateDir(const OUString& rURL) const; |
51 |
+ |
52 |
+ //See: #i66157# and rhbz#1065807 |
53 |
+ //return true if rURL is a path (or subpath of) a dir which is not a user path |
54 |
+ //which implies neither it or its contents can be removed |
55 |
+ bool isInternalTemplateDir(const OUString& rURL) const; |
56 |
public: |
57 |
- SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext ); |
58 |
+ SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext ); |
59 |
~SfxDocTplService_Impl(); |
60 |
|
61 |
sal_Bool init() { if ( !mbIsInitialized ) init_Impl(); return mbIsInitialized; } |
62 |
@@ -545,7 +555,7 @@ void SfxDocTplService_Impl::getDirList() |
63 |
// TODO/LATER: let use service, register listener |
64 |
INetURLObject aURL; |
65 |
OUString aDirs = SvtPathOptions().GetTemplatePath(); |
66 |
- sal_uInt16 nCount = comphelper::string::getTokenCount(aDirs, C_DELIM); |
67 |
+ sal_Int32 nCount = comphelper::string::getTokenCount(aDirs, C_DELIM); |
68 |
|
69 |
maTemplateDirs = Sequence< OUString >( nCount ); |
70 |
|
71 |
@@ -553,7 +563,7 @@ void SfxDocTplService_Impl::getDirList() |
72 |
const OUString aPrefix( |
73 |
"vnd.sun.star.expand:" ); |
74 |
|
75 |
- for ( sal_uInt16 i=0; i<nCount; i++ ) |
76 |
+ for (sal_Int32 i = 0; i < nCount; ++i) |
77 |
{ |
78 |
aURL.SetSmartProtocol( INET_PROT_FILE ); |
79 |
aURL.SetURL( aDirs.getToken( i, C_DELIM ) ); |
80 |
@@ -571,6 +581,23 @@ void SfxDocTplService_Impl::getDirList() |
81 |
|
82 |
aValue <<= maTemplateDirs; |
83 |
|
84 |
+ css::uno::Reference< css::util::XPathSettings > xPathSettings = |
85 |
+ css::util::PathSettings::create( mxContext ); |
86 |
+ |
87 |
+ // load internal paths |
88 |
+ OUString sProp( "Template_internal" ); |
89 |
+ Any aAny = xPathSettings->getPropertyValue( sProp ); |
90 |
+ aAny >>= maInternalTemplateDirs; |
91 |
+ |
92 |
+ nCount = maInternalTemplateDirs.getLength(); |
93 |
+ for (sal_Int32 i = 0; i < nCount; ++i) |
94 |
+ { |
95 |
+ //expand vnd.sun.star.expand: and remove "..." from them |
96 |
+ //to normalize into the expected url patterns |
97 |
+ maRelocator.makeRelocatableURL(maInternalTemplateDirs[i]); |
98 |
+ maRelocator.makeAbsoluteURL(maInternalTemplateDirs[i]); |
99 |
+ } |
100 |
+ |
101 |
// Store the template dir list |
102 |
setProperty( maRootContent, aPropName, aValue ); |
103 |
} |
104 |
@@ -1547,13 +1574,16 @@ sal_Bool SfxDocTplService_Impl::removeGroup( const OUString& rGroupName ) |
105 |
|
106 |
if ( !maTemplateDirs.getLength() ) |
107 |
return sal_False; |
108 |
- OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ]; |
109 |
|
110 |
// check that the fs location is in writeble folder and this is not a "My templates" folder |
111 |
INetURLObject aGroupParentFolder( aGroupTargetURL ); |
112 |
- if ( !aGroupParentFolder.removeSegment() |
113 |
- || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath, |
114 |
- aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) ) |
115 |
+ if (!aGroupParentFolder.removeSegment()) |
116 |
+ return sal_False; |
117 |
+ |
118 |
+ OUString aGeneralTempPath = findParentTemplateDir( |
119 |
+ aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE)); |
120 |
+ |
121 |
+ if (aGeneralTempPath.isEmpty()) |
122 |
return sal_False; |
123 |
|
124 |
// now get the content of the Group |
125 |
@@ -1661,14 +1691,14 @@ sal_Bool SfxDocTplService_Impl::renameGroup( const OUString& rOldName, |
126 |
|
127 |
if ( !maTemplateDirs.getLength() ) |
128 |
return sal_False; |
129 |
- OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ]; |
130 |
|
131 |
// check that the fs location is in writeble folder and this is not a "My templates" folder |
132 |
INetURLObject aGroupParentFolder( aGroupTargetURL ); |
133 |
- if ( !aGroupParentFolder.removeSegment() |
134 |
- || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath, |
135 |
- aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) ) |
136 |
+ if (!aGroupParentFolder.removeSegment() || |
137 |
+ isInternalTemplateDir(aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE))) |
138 |
+ { |
139 |
return sal_False; |
140 |
+ } |
141 |
|
142 |
// check that the group can be renamed ( all the contents must be in target location ) |
143 |
sal_Bool bCanBeRenamed = sal_False; |
144 |
@@ -1770,7 +1800,7 @@ sal_Bool SfxDocTplService_Impl::storeTemplate( const OUString& rGroupName, |
145 |
aValue >>= aTemplateToRemoveTargetURL; |
146 |
|
147 |
if ( aGroupTargetURL.isEmpty() || !maTemplateDirs.getLength() |
148 |
- || (!aTemplateToRemoveTargetURL.isEmpty() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTemplateToRemoveTargetURL )) ) |
149 |
+ || (!aTemplateToRemoveTargetURL.isEmpty() && isInternalTemplateDir(aTemplateToRemoveTargetURL)) ) |
150 |
return sal_False; // it is not allowed to remove the template |
151 |
} |
152 |
|
153 |
@@ -1909,6 +1939,30 @@ sal_Bool SfxDocTplService_Impl::storeTemplate( const OUString& rGroupName, |
154 |
} |
155 |
} |
156 |
|
157 |
+bool SfxDocTplService_Impl::isInternalTemplateDir(const OUString& rURL) const |
158 |
+{ |
159 |
+ const sal_Int32 nDirs = maInternalTemplateDirs.getLength(); |
160 |
+ const OUString* pDirs = maInternalTemplateDirs.getConstArray(); |
161 |
+ for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs) |
162 |
+ { |
163 |
+ if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL)) |
164 |
+ return true; |
165 |
+ } |
166 |
+ return false; |
167 |
+} |
168 |
+ |
169 |
+OUString SfxDocTplService_Impl::findParentTemplateDir(const OUString& rURL) const |
170 |
+{ |
171 |
+ const sal_Int32 nDirs = maTemplateDirs.getLength(); |
172 |
+ const OUString* pDirs = maTemplateDirs.getConstArray(); |
173 |
+ for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs) |
174 |
+ { |
175 |
+ if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL)) |
176 |
+ return *pDirs; |
177 |
+ } |
178 |
+ return OUString(); |
179 |
+} |
180 |
+ |
181 |
//----------------------------------------------------------------------------- |
182 |
sal_Bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName, |
183 |
const OUString& rTemplateName, |
184 |
@@ -2032,7 +2086,6 @@ sal_Bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName, |
185 |
catch ( Exception& ) |
186 |
{ return sal_False; } |
187 |
|
188 |
- |
189 |
// either the document has title and it is the same as requested, or we have to set it |
190 |
sal_Bool bCorrectTitle = ( bDocHasTitle && aTitle.equals( rTemplateName ) ); |
191 |
if ( !bCorrectTitle ) |
192 |
@@ -2101,8 +2154,7 @@ sal_Bool SfxDocTplService_Impl::removeTemplate( const OUString& rGroupName, |
193 |
// delete the target template |
194 |
if ( !aTargetURL.isEmpty() ) |
195 |
{ |
196 |
- if ( !maTemplateDirs.getLength() |
197 |
- || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTargetURL ) ) |
198 |
+ if (isInternalTemplateDir(aTargetURL)) |
199 |
return sal_False; |
200 |
|
201 |
removeContent( aTargetURL ); |
202 |
-- |
203 |
1.8.5.3 |
204 |
|