9444845
From 6805be76c930312d18e732f4572b6c2611cc8e0f Mon Sep 17 00:00:00 2001
12f43bd
From: =?UTF-8?q?Caol=C3=A1n=20McNamara?= <caolanm@redhat.com>
12f43bd
Date: Mon, 24 Feb 2014 15:27:36 +0000
9444845
Subject: [PATCH 2/4] Related: rhbz#1065807 rework #i66157# for multiple
9444845
 writable template dirs
12f43bd
12f43bd
if there are multiple user-level template dirs then we should be able to
12f43bd
remove/rename content in all of them, not just the default writable target.
12f43bd
12f43bd
The target scenario here is to default to ~/Templates when it exists as the
12f43bd
template dir, but to retain ~/.config/libreoffice/user/template in the dir for
12f43bd
any pre-existing templates and to treat both as equivalent in terms of removing
12f43bd
their content etc.
12f43bd
12f43bd
i#66157# wanted to avoid remove extensions templates and other internal
12f43bd
ones, so rework that logic to instead just be hands off internal templates
12f43bd
and allow modification of the remainder
12f43bd
12f43bd
Change-Id: I56afe991d4297ba692e914ae95ea02d68553f60a
12f43bd
---
12f43bd
 sfx2/source/doc/doctemplates.cxx | 80 +++++++++++++++++++++++++++++++++-------
12f43bd
 1 file changed, 66 insertions(+), 14 deletions(-)
12f43bd
12f43bd
diff --git a/sfx2/source/doc/doctemplates.cxx b/sfx2/source/doc/doctemplates.cxx
9444845
index ff07ef3..4cf76c4 100644
12f43bd
--- a/sfx2/source/doc/doctemplates.cxx
12f43bd
+++ b/sfx2/source/doc/doctemplates.cxx
9444845
@@ -55,6 +55,7 @@
9444845
 #include <com/sun/star/ucb/XContentAccess.hpp>
9444845
 #include <com/sun/star/frame/ModuleManager.hpp>
9444845
 #include <com/sun/star/uno/Exception.hpp>
9444845
+#include <com/sun/star/util/PathSettings.hpp>
12f43bd
 
12f43bd
 #include <svtools/templatefoldercache.hxx>
9444845
 #include <unotools/configmgr.hxx>
9444845
@@ -181,6 +182,7 @@
12f43bd
 
12f43bd
     ::osl::Mutex                maMutex;
12f43bd
     Sequence< OUString >        maTemplateDirs;
12f43bd
+    Sequence< OUString >        maInternalTemplateDirs;
12f43bd
     OUString                    maRootURL;
12f43bd
     NameList_Impl               maNames;
12f43bd
     Locale                      maLocale;
9444845
@@ -265,8 +267,16 @@
12f43bd
 
12f43bd
     void                        updateData( DocTemplates_EntryData_Impl *pData );
12f43bd
 
12f43bd
+    //See: #i66157# and rhbz#1065807
12f43bd
+    //return which template dir the rURL is a subpath of
12f43bd
+    OUString                    findParentTemplateDir(const OUString& rURL) const;
12f43bd
+
12f43bd
+    //See: #i66157# and rhbz#1065807
12f43bd
+    //return true if rURL is a path (or subpath of) a dir which is not a user path
12f43bd
+    //which implies neither it or its contents can be removed
12f43bd
+    bool                        isInternalTemplateDir(const OUString& rURL) const;
12f43bd
 public:
12f43bd
-                                 SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext );
12f43bd
+                                SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext );
12f43bd
                                 ~SfxDocTplService_Impl();
12f43bd
 
12f43bd
     sal_Bool                    init() { if ( !mbIsInitialized ) init_Impl(); return mbIsInitialized; }
9444845
@@ -574,7 +584,7 @@
12f43bd
     // TODO/LATER: let use service, register listener
12f43bd
     INetURLObject   aURL;
9444845
     String          aDirs = SvtPathOptions().GetTemplatePath();
12f43bd
-    sal_uInt16  nCount = comphelper::string::getTokenCount(aDirs, C_DELIM);
12f43bd
+    sal_Int32 nCount = comphelper::string::getTokenCount(aDirs, C_DELIM);
12f43bd
 
12f43bd
     maTemplateDirs = Sequence< OUString >( nCount );
12f43bd
 
9444845
@@ -582,7 +592,7 @@
12f43bd
     const OUString aPrefix(
12f43bd
         "vnd.sun.star.expand:"  );
12f43bd
 
12f43bd
-    for ( sal_uInt16 i=0; i
12f43bd
+    for (sal_Int32 i = 0; i < nCount; ++i)
12f43bd
     {
12f43bd
         aURL.SetSmartProtocol( INET_PROT_FILE );
9444845
         aURL.SetURL( aDirs.GetToken( i, C_DELIM ) );
9444845
@@ -600,6 +610,23 @@
12f43bd
 
12f43bd
     aValue <<= maTemplateDirs;
12f43bd
 
12f43bd
+    css::uno::Reference< css::util::XPathSettings > xPathSettings =
d38513b
+        css::util::PathSettings::create( mxContext );
12f43bd
+
12f43bd
+    // load internal paths
12f43bd
+    OUString sProp( "Template_internal" );
12f43bd
+    Any aAny = xPathSettings->getPropertyValue( sProp );
12f43bd
+    aAny >>= maInternalTemplateDirs;
12f43bd
+
12f43bd
+    nCount = maInternalTemplateDirs.getLength();
12f43bd
+    for (sal_Int32 i = 0; i < nCount; ++i)
12f43bd
+    {
12f43bd
+        //expand vnd.sun.star.expand: and remove "..." from them
12f43bd
+        //to normalize into the expected url patterns
12f43bd
+        maRelocator.makeRelocatableURL(maInternalTemplateDirs[i]);
12f43bd
+        maRelocator.makeAbsoluteURL(maInternalTemplateDirs[i]);
12f43bd
+    }
12f43bd
+
12f43bd
     // Store the template dir list
12f43bd
     setProperty( maRootContent, aPropName, aValue );
12f43bd
 }
9444845
@@ -1575,13 +1602,16 @@
12f43bd
 
12f43bd
         if ( !maTemplateDirs.getLength() )
12f43bd
             return sal_False;
12f43bd
-        OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
12f43bd
 
12f43bd
         // check that the fs location is in writeble folder and this is not a "My templates" folder
12f43bd
         INetURLObject aGroupParentFolder( aGroupTargetURL );
12f43bd
-        if ( !aGroupParentFolder.removeSegment()
12f43bd
-          || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
12f43bd
-                                                      aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
12f43bd
+        if (!aGroupParentFolder.removeSegment())
12f43bd
+            return sal_False;
12f43bd
+
12f43bd
+        OUString aGeneralTempPath = findParentTemplateDir(
12f43bd
+            aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE));
12f43bd
+
12f43bd
+        if (aGeneralTempPath.isEmpty())
12f43bd
             return sal_False;
12f43bd
 
12f43bd
         // now get the content of the Group
9444845
@@ -1689,14 +1719,14 @@
12f43bd
 
12f43bd
     if ( !maTemplateDirs.getLength() )
12f43bd
         return sal_False;
12f43bd
-    OUString aGeneralTempPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
12f43bd
 
12f43bd
     // check that the fs location is in writeble folder and this is not a "My templates" folder
12f43bd
     INetURLObject aGroupParentFolder( aGroupTargetURL );
12f43bd
-    if ( !aGroupParentFolder.removeSegment()
12f43bd
-      || !::utl::UCBContentHelper::IsSubPath( aGeneralTempPath,
12f43bd
-                                                  aGroupParentFolder.GetMainURL( INetURLObject::NO_DECODE ) ) )
12f43bd
+    if (!aGroupParentFolder.removeSegment() ||
12f43bd
+        isInternalTemplateDir(aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE)))
12f43bd
+    {
12f43bd
         return sal_False;
12f43bd
+    }
12f43bd
 
12f43bd
     // check that the group can be renamed ( all the contents must be in target location )
12f43bd
     sal_Bool bCanBeRenamed = sal_False;
9444845
@@ -1798,7 +1828,7 @@
12f43bd
             aValue >>= aTemplateToRemoveTargetURL;
12f43bd
 
12f43bd
         if ( aGroupTargetURL.isEmpty() || !maTemplateDirs.getLength()
12f43bd
-          || (!aTemplateToRemoveTargetURL.isEmpty() && !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTemplateToRemoveTargetURL )) )
12f43bd
+          || (!aTemplateToRemoveTargetURL.isEmpty() && isInternalTemplateDir(aTemplateToRemoveTargetURL)) )
12f43bd
             return sal_False; // it is not allowed to remove the template
12f43bd
     }
12f43bd
 
d38513b
@@ -1937,6 +1967,30 @@
d38513b
     }
d38513b
 }
12f43bd
 
12f43bd
+bool SfxDocTplService_Impl::isInternalTemplateDir(const OUString& rURL) const
12f43bd
+{
12f43bd
+    const sal_Int32 nDirs = maInternalTemplateDirs.getLength();
12f43bd
+    const OUString* pDirs = maInternalTemplateDirs.getConstArray();
12f43bd
+    for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs)
12f43bd
+    {
12f43bd
+        if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL))
12f43bd
+            return true;
12f43bd
+    }
12f43bd
+    return false;
12f43bd
+}
12f43bd
+
12f43bd
+OUString SfxDocTplService_Impl::findParentTemplateDir(const OUString& rURL) const
12f43bd
+{
12f43bd
+    const sal_Int32 nDirs = maTemplateDirs.getLength();
12f43bd
+    const OUString* pDirs = maTemplateDirs.getConstArray();
12f43bd
+    for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs)
12f43bd
+    {
12f43bd
+        if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL))
12f43bd
+            return *pDirs;
12f43bd
+    }
12f43bd
+    return OUString();
12f43bd
+}
d38513b
+
d38513b
 //-----------------------------------------------------------------------------
d38513b
 sal_Bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName,
d38513b
                                              const OUString& rTemplateName,
d38513b
@@ -2060,7 +2114,6 @@
d38513b
     catch ( Exception& )
d38513b
     { return sal_False; }
12f43bd
 
d38513b
-
9444845
     // either the document has title and it is the same as requested, or we have to set it
9444845
     sal_Bool bCorrectTitle = ( bDocHasTitle && aTitle.equals( rTemplateName ) );
d38513b
     if ( !bCorrectTitle )
9444845
@@ -2129,8 +2182,7 @@
12f43bd
     // delete the target template
12f43bd
     if ( !aTargetURL.isEmpty() )
12f43bd
     {
12f43bd
-        if ( !maTemplateDirs.getLength()
12f43bd
-          || !::utl::UCBContentHelper::IsSubPath( maTemplateDirs[ maTemplateDirs.getLength() - 1 ], aTargetURL ) )
12f43bd
+        if (isInternalTemplateDir(aTargetURL))
12f43bd
             return sal_False;
12f43bd
 
12f43bd
         removeContent( aTargetURL );