LCOV - code coverage report
Current view: top level - sfx2/source/doc - doctemplates.cxx (source / functions) Hit Total Coverage
Test: commit e02a6cb2c3e2b23b203b422e4e0680877f232636 Lines: 0 1280 0.0 %
Date: 2014-04-14 Functions: 0 120 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : #include <osl/mutex.hxx>
      21             : #include <tools/debug.hxx>
      22             : #include <tools/diagnose_ex.h>
      23             : #include <tools/urlobj.hxx>
      24             : #include <rtl/ustring.hxx>
      25             : #include <rtl/ustrbuf.hxx>
      26             : #include <tools/resary.hxx>
      27             : #include <vcl/svapp.hxx>
      28             : #include <vcl/wrkwin.hxx>
      29             : #include <unotools/pathoptions.hxx>
      30             : #include <comphelper/processfactory.hxx>
      31             : #include <comphelper/sequenceashashmap.hxx>
      32             : #include <comphelper/storagehelper.hxx>
      33             : #include <comphelper/string.hxx>
      34             : #include <cppuhelper/implbase3.hxx>
      35             : #include <cppuhelper/supportsservice.hxx>
      36             : #include <com/sun/star/beans/PropertyAttribute.hpp>
      37             : #include <com/sun/star/beans/XPropertySet.hpp>
      38             : #include <com/sun/star/beans/XPropertySetInfo.hpp>
      39             : #include <com/sun/star/beans/XPropertyContainer.hpp>
      40             : #include <com/sun/star/beans/StringPair.hpp>
      41             : #include <com/sun/star/util/theMacroExpander.hpp>
      42             : #include <com/sun/star/util/theOfficeInstallationDirectories.hpp>
      43             : #include <com/sun/star/configuration/theDefaultProvider.hpp>
      44             : #include <com/sun/star/container/XContainerQuery.hpp>
      45             : #include <com/sun/star/document/XTypeDetection.hpp>
      46             : #include <com/sun/star/document/DocumentProperties.hpp>
      47             : #include <com/sun/star/io/TempFile.hpp>
      48             : #include <com/sun/star/sdbc/XResultSet.hpp>
      49             : #include <com/sun/star/sdbc/XRow.hpp>
      50             : #include <com/sun/star/ucb/NameClash.hpp>
      51             : #include <com/sun/star/ucb/NameClashException.hpp>
      52             : #include <com/sun/star/ucb/TransferInfo.hpp>
      53             : #include <com/sun/star/ucb/XCommandEnvironment.hpp>
      54             : #include <com/sun/star/ucb/XContentAccess.hpp>
      55             : #include <com/sun/star/frame/ModuleManager.hpp>
      56             : #include <com/sun/star/uno/Exception.hpp>
      57             : #include <com/sun/star/task/InteractionHandler.hpp>
      58             : #include <com/sun/star/ucb/XProgressHandler.hpp>
      59             : #include <com/sun/star/container/XNameAccess.hpp>
      60             : #include <com/sun/star/frame/XDocumentTemplates.hpp>
      61             : #include <com/sun/star/frame/XStorable.hpp>
      62             : #include <com/sun/star/lang/Locale.hpp>
      63             : #include <com/sun/star/lang/XLocalizable.hpp>
      64             : #include <com/sun/star/lang/XServiceInfo.hpp>
      65             : #include <com/sun/star/lang/XMultiServiceFactory.hpp>
      66             : #include <com/sun/star/ucb/XContent.hpp>
      67             : #include <com/sun/star/beans/PropertyValue.hpp>
      68             : #include <com/sun/star/uno/RuntimeException.hpp>
      69             : #include <com/sun/star/uno/XComponentContext.hpp>
      70             : #include <com/sun/star/util/thePathSettings.hpp>
      71             : 
      72             : #include <rtl/ref.hxx>
      73             : #include <svtools/templatefoldercache.hxx>
      74             : #include <unotools/configmgr.hxx>
      75             : #include <unotools/ucbhelper.hxx>
      76             : 
      77             : #include <sfx2/sfxresid.hxx>
      78             : #include "sfxurlrelocator.hxx"
      79             : #include "doctemplateslocal.hxx"
      80             : #include <sfx2/docfac.hxx>
      81             : #include <sfx2/docfile.hxx>
      82             : #include "doc.hrc"
      83             : 
      84             : #include <vector>
      85             : 
      86             : 
      87             : 
      88             : 
      89             : #define SERVICENAME_TYPEDETECTION           "com.sun.star.document.TypeDetection"
      90             : 
      91             : #define TEMPLATE_ROOT_URL       "vnd.sun.star.hier:/templates"
      92             : #define TITLE                   "Title"
      93             : #define IS_FOLDER               "IsFolder"
      94             : #define IS_DOCUMENT             "IsDocument"
      95             : #define TARGET_URL              "TargetURL"
      96             : #define TEMPLATE_VERSION        "TemplateComponentVersion"
      97             : #define TEMPLATE_VERSION_VALUE  "2"
      98             : #define TYPE_FOLDER             "application/vnd.sun.star.hier-folder"
      99             : #define TYPE_LINK               "application/vnd.sun.star.hier-link"
     100             : #define TYPE_FSYS_FOLDER        "application/vnd.sun.staroffice.fsys-folder"
     101             : #define TYPE_FSYS_FILE          "application/vnd.sun.staroffice.fsys-file"
     102             : 
     103             : #define PROPERTY_DIRLIST        "DirectoryList"
     104             : #define PROPERTY_NEEDSUPDATE    "NeedsUpdate"
     105             : #define PROPERTY_TYPE           "TypeDescription"
     106             : 
     107             : #define TARGET_DIR_URL          "TargetDirURL"
     108             : #define COMMAND_DELETE          "delete"
     109             : 
     110             : #define STANDARD_FOLDER         "standard"
     111             : 
     112             : #define C_DELIM                 ';'
     113             : 
     114             : 
     115             : 
     116             : using namespace ::com::sun::star;
     117             : using namespace ::com::sun::star::beans;
     118             : using namespace ::com::sun::star::document;
     119             : using namespace ::com::sun::star::io;
     120             : using namespace ::com::sun::star::lang;
     121             : using namespace ::com::sun::star::sdbc;
     122             : using namespace ::com::sun::star::ucb;
     123             : using namespace ::com::sun::star::uno;
     124             : using namespace ::com::sun::star::container;
     125             : using namespace ::com::sun::star::util;
     126             : 
     127             : using namespace ::ucbhelper;
     128             : using namespace ::comphelper;
     129             : 
     130             : using ::std::vector;
     131             : 
     132             : namespace {
     133             : 
     134             : class WaitWindow_Impl : public WorkWindow
     135             : {
     136             :     Rectangle   _aRect;
     137             :     sal_uInt16  _nTextStyle;
     138             :     OUString    _aText;
     139             : 
     140             :     public:
     141             :                      WaitWindow_Impl();
     142             :                     virtual ~WaitWindow_Impl();
     143             :     virtual void     Paint( const Rectangle& rRect ) SAL_OVERRIDE;
     144             : };
     145             : 
     146             : #define X_OFFSET 15
     147             : #define Y_OFFSET 15
     148             : 
     149             : 
     150             : 
     151           0 : struct NamePair_Impl
     152             : {
     153             :     OUString maShortName;
     154             :     OUString maLongName;
     155             : };
     156             : 
     157             : class Updater_Impl;
     158             : class DocTemplates_EntryData_Impl;
     159             : class GroupData_Impl;
     160             : 
     161             : typedef vector< NamePair_Impl* > NameList_Impl;
     162             : typedef vector< GroupData_Impl* > GroupList_Impl;
     163             : 
     164             : 
     165           0 : class TplTaskEnvironment : public ::cppu::WeakImplHelper1< ucb::XCommandEnvironment >
     166             : {
     167             :     uno::Reference< task::XInteractionHandler >               m_xInteractionHandler;
     168             :     uno::Reference< ucb::XProgressHandler >                   m_xProgressHandler;
     169             : 
     170             : public:
     171           0 :     TplTaskEnvironment( const uno::Reference< task::XInteractionHandler>& rxInteractionHandler )
     172           0 :                                 : m_xInteractionHandler( rxInteractionHandler )
     173           0 :                             {}
     174             : 
     175           0 :     virtual uno::Reference<task::XInteractionHandler> SAL_CALL getInteractionHandler() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     176           0 :     { return m_xInteractionHandler; }
     177             : 
     178           0 :     virtual uno::Reference<ucb::XProgressHandler> SAL_CALL    getProgressHandler() throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     179           0 :     { return m_xProgressHandler; }
     180             : };
     181             : 
     182             : class SfxDocTplService_Impl
     183             : {
     184             :     uno::Reference< XComponentContext >              mxContext;
     185             :     uno::Reference< XCommandEnvironment >            maCmdEnv;
     186             :     uno::Reference< XDocumentProperties>             m_xDocProps;
     187             :     uno::Reference< XTypeDetection >                 mxType;
     188             : 
     189             :     ::osl::Mutex                maMutex;
     190             :     Sequence< OUString >        maTemplateDirs;
     191             :     Sequence< OUString >        maInternalTemplateDirs;
     192             :     OUString                    maRootURL;
     193             :     NameList_Impl               maNames;
     194             :     Locale                      maLocale;
     195             :     Content                     maRootContent;
     196             :     Updater_Impl*               mpUpdater;
     197             :     bool                    mbIsInitialized : 1;
     198             :     bool                    mbLocaleSet     : 1;
     199             : 
     200             :     SfxURLRelocator_Impl        maRelocator;
     201             : 
     202             :     void                        init_Impl();
     203             :     void                        getDefaultLocale();
     204             :     void                        getDirList();
     205             :     void                        readFolderList();
     206             :     bool                    needsUpdate();
     207             :     OUString                    getLongName( const OUString& rShortName );
     208             :     bool                    setTitleForURL( const OUString& rURL, const OUString& aTitle );
     209             :     bool                    getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, bool& bDocHasTitle );
     210             : 
     211             :     bool                    addEntry( Content& rParentFolder,
     212             :                                           const OUString& rTitle,
     213             :                                           const OUString& rTargetURL,
     214             :                                           const OUString& rType );
     215             : 
     216             :     bool                    createFolder( const OUString& rNewFolderURL,
     217             :                                               bool  bCreateParent,
     218             :                                               bool  bFsysFolder,
     219             :                                               Content   &rNewFolder );
     220             : 
     221             :     bool                    CreateNewUniqueFolderWithPrefix( const OUString& aPath,
     222             :                                                                 const OUString& aPrefix,
     223             :                                                                 OUString& aNewFolderName,
     224             :                                                                 OUString& aNewFolderURL,
     225             :                                                                 Content& aNewFolder );
     226             :     OUString             CreateNewUniqueFileWithPrefix( const OUString& aPath,
     227             :                                                                 const OUString& aPrefix,
     228             :                                                                 const OUString& aExt );
     229             : 
     230             :     uno::Sequence< beans::StringPair > ReadUINamesForTemplateDir_Impl( const OUString& aUserPath );
     231             :     bool                    UpdateUINamesForTemplateDir_Impl( const OUString& aUserPath,
     232             :                                                                   const OUString& aGroupName,
     233             :                                                                   const OUString& aNewFolderName );
     234             :     bool                    ReplaceUINamesForTemplateDir_Impl( const OUString& aUserPath,
     235             :                                                                   const OUString& aFsysGroupName,
     236             :                                                                   const OUString& aOldGroupName,
     237             :                                                                   const OUString& aNewGroupName );
     238             :     bool                    RemoveUINamesForTemplateDir_Impl( const OUString& aUserPath,
     239             :                                                                   const OUString& aGroupName );
     240             :     bool                    WriteUINamesForTemplateDir_Impl( const OUString& aUserPath,
     241             :                                                                 const uno::Sequence< beans::StringPair >& aUINames );
     242             : 
     243             :     OUString             CreateNewGroupFsys( const OUString& rGroupName, Content& aGroup );
     244             : 
     245             :     bool                    removeContent( Content& rContent );
     246             :     bool                    removeContent( const OUString& rContentURL );
     247             : 
     248             :     bool                    setProperty( Content& rContent,
     249             :                                              const OUString& rPropName,
     250             :                                              const Any& rPropValue );
     251             :     bool                    getProperty( Content& rContent,
     252             :                                              const OUString& rPropName,
     253             :                                              Any& rPropValue );
     254             : 
     255             :     void                        createFromContent( GroupList_Impl& rList,
     256             :                                                    Content &rContent,
     257             :                                                    bool bHierarchy,
     258             :                                                    bool bWriteableContent = false );
     259             :     void                        addHierGroup( GroupList_Impl& rList,
     260             :                                               const OUString& rTitle,
     261             :                                               const OUString& rOwnURL );
     262             :     void                        addFsysGroup( GroupList_Impl& rList,
     263             :                                               const OUString& rTitle,
     264             :                                               const OUString& rUITitle,
     265             :                                               const OUString& rOwnURL,
     266             :                                               bool bWriteableGroup = false );
     267             :     void                        removeFromHierarchy( DocTemplates_EntryData_Impl *pData );
     268             :     void                        addToHierarchy( GroupData_Impl *pGroup,
     269             :                                                 DocTemplates_EntryData_Impl *pData );
     270             : 
     271             :     void                        removeFromHierarchy( GroupData_Impl *pGroup );
     272             :     void                        addGroupToHierarchy( GroupData_Impl *pGroup );
     273             : 
     274             :     void                        updateData( DocTemplates_EntryData_Impl *pData );
     275             : 
     276             :     //See: #i66157# and rhbz#1065807
     277             :     //return which template dir the rURL is a subpath of
     278             :     OUString                    findParentTemplateDir(const OUString& rURL) const;
     279             : 
     280             :     //See: #i66157# and rhbz#1065807
     281             :     //return true if rURL is a path (or subpath of) a dir which is not a user path
     282             :     //which implies neither it or its contents can be removed
     283             :     bool                        isInternalTemplateDir(const OUString& rURL) const;
     284             : public:
     285             :                                 SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext );
     286             :                                 ~SfxDocTplService_Impl();
     287             : 
     288           0 :     bool                    init() { if ( !mbIsInitialized ) init_Impl(); return mbIsInitialized; }
     289           0 :     Content                     getContent() const { return maRootContent; }
     290             : 
     291             :     void                        setLocale( const Locale & rLocale );
     292             :     Locale                      getLocale();
     293             : 
     294             :     bool                    storeTemplate( const OUString& rGroupName,
     295             :                                                const OUString& rTemplateName,
     296             :                                                const uno::Reference< frame::XStorable >& rStorable );
     297             : 
     298             :     bool                    addTemplate( const OUString& rGroupName,
     299             :                                              const OUString& rTemplateName,
     300             :                                              const OUString& rSourceURL );
     301             :     bool                    removeTemplate( const OUString& rGroupName,
     302             :                                                 const OUString& rTemplateName );
     303             :     bool                    renameTemplate( const OUString& rGroupName,
     304             :                                                 const OUString& rOldName,
     305             :                                                 const OUString& rNewName );
     306             : 
     307             :     bool                    addGroup( const OUString& rGroupName );
     308             :     bool                    removeGroup( const OUString& rGroupName );
     309             :     bool                    renameGroup( const OUString& rOldName,
     310             :                                              const OUString& rNewName );
     311             : 
     312             :     void                        update( bool bUpdateNow );
     313             :     void                        doUpdate();
     314           0 :     void                        finished() { mpUpdater = NULL; }
     315             : };
     316             : 
     317             : 
     318             : 
     319             : class Updater_Impl : public ::osl::Thread
     320             : {
     321             : private:
     322             :     SfxDocTplService_Impl   *mpDocTemplates;
     323             : 
     324             : public:
     325             :                              Updater_Impl( SfxDocTplService_Impl* pTemplates );
     326             :                             virtual ~Updater_Impl();
     327             : 
     328             :     virtual void SAL_CALL   run() SAL_OVERRIDE;
     329             :     virtual void SAL_CALL   onTerminated() SAL_OVERRIDE;
     330             : };
     331             : 
     332             : 
     333             : 
     334           0 : class DocTemplates_EntryData_Impl
     335             : {
     336             :     OUString            maTitle;
     337             :     OUString            maType;
     338             :     OUString            maTargetURL;
     339             :     OUString            maHierarchyURL;
     340             : 
     341             :     bool            mbInHierarchy   : 1;
     342             :     bool            mbInUse         : 1;
     343             :     bool            mbUpdateType    : 1;
     344             :     bool            mbUpdateLink    : 1;
     345             : 
     346             : public:
     347             :                         DocTemplates_EntryData_Impl( const OUString& rTitle );
     348             : 
     349           0 :     void                setInUse() { mbInUse = true; }
     350           0 :     void                setHierarchy( bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
     351           0 :     void                setUpdateLink( bool bUpdateLink ) { mbUpdateLink = bUpdateLink; }
     352           0 :     void                setUpdateType( bool bUpdateType ) { mbUpdateType = bUpdateType; }
     353             : 
     354           0 :     bool            getInUse() const { return mbInUse; }
     355           0 :     bool            getInHierarchy() const { return mbInHierarchy; }
     356           0 :     bool            getUpdateLink() const { return mbUpdateLink; }
     357           0 :     bool            getUpdateType() const { return mbUpdateType; }
     358             : 
     359           0 :     const OUString&     getHierarchyURL() const { return maHierarchyURL; }
     360           0 :     const OUString&     getTargetURL() const { return maTargetURL; }
     361           0 :     const OUString&     getTitle() const { return maTitle; }
     362           0 :     const OUString&     getType() const { return maType; }
     363             : 
     364           0 :     void                setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
     365           0 :     void                setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
     366           0 :     void                setType( const OUString& rType ) { maType = rType; }
     367             : };
     368             : 
     369             : 
     370             : 
     371             : class GroupData_Impl
     372             : {
     373             :     vector< DocTemplates_EntryData_Impl* > maEntries;
     374             :     OUString            maTitle;
     375             :     OUString            maHierarchyURL;
     376             :     OUString            maTargetURL;
     377             :     bool            mbInUse         : 1;
     378             :     bool            mbInHierarchy   : 1;
     379             : 
     380             : public:
     381             :                         GroupData_Impl( const OUString& rTitle );
     382             :                         ~GroupData_Impl();
     383             : 
     384           0 :     void                setInUse() { mbInUse = true; }
     385           0 :     void                setHierarchy( bool bInHierarchy ) { mbInHierarchy = bInHierarchy; }
     386           0 :     void                setHierarchyURL( const OUString& rURL ) { maHierarchyURL = rURL; }
     387           0 :     void                setTargetURL( const OUString& rURL ) { maTargetURL = rURL; }
     388             : 
     389           0 :     bool            getInUse() const { return mbInUse; }
     390           0 :     bool            getInHierarchy() const { return mbInHierarchy; }
     391           0 :     const OUString&     getHierarchyURL() const { return maHierarchyURL; }
     392           0 :     const OUString&     getTargetURL() const { return maTargetURL; }
     393           0 :     const OUString&     getTitle() const { return maTitle; }
     394             : 
     395             :     DocTemplates_EntryData_Impl*     addEntry( const OUString& rTitle,
     396             :                                   const OUString& rTargetURL,
     397             :                                   const OUString& rType,
     398             :                                   const OUString& rHierURL );
     399           0 :     size_t                          count() { return maEntries.size(); }
     400           0 :     DocTemplates_EntryData_Impl*    getEntry( size_t nPos ) { return maEntries[ nPos ]; }
     401             : };
     402             : 
     403             : 
     404             : // private SfxDocTplService_Impl
     405             : 
     406           0 : void SfxDocTplService_Impl::init_Impl()
     407             : {
     408           0 :     uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
     409             :     uno::Reference < task::XInteractionHandler > xInteractionHandler(
     410           0 :         task::InteractionHandler::createWithParent(xContext, 0), uno::UNO_QUERY_THROW );
     411           0 :     maCmdEnv = new TplTaskEnvironment( xInteractionHandler );
     412             : 
     413           0 :     ::osl::ClearableMutexGuard aGuard( maMutex );
     414           0 :     bool bIsInitialized = false;
     415           0 :     bool bNeedsUpdate   = false;
     416             : 
     417           0 :     if ( !mbLocaleSet )
     418           0 :         getDefaultLocale();
     419             : 
     420             :     // convert locale to string
     421           0 :     OUString aLang = LanguageTag::convertToBcp47( maLocale);
     422             : 
     423             :     // set maRootContent to the root of the templates hierarchy. Create the
     424             :     // entry if necessary
     425             : 
     426           0 :     maRootURL = ( TEMPLATE_ROOT_URL "/" ) + aLang;
     427             : 
     428           0 :     OUString aTemplVersPropName( TEMPLATE_VERSION  );
     429           0 :     OUString aTemplVers( TEMPLATE_VERSION_VALUE  );
     430           0 :     if ( Content::create( maRootURL, maCmdEnv, comphelper::getProcessComponentContext(), maRootContent ) )
     431             :     {
     432           0 :         uno::Any aValue;
     433           0 :         OUString aPropValue;
     434           0 :         if ( getProperty( maRootContent, aTemplVersPropName, aValue )
     435           0 :           && ( aValue >>= aPropValue )
     436           0 :           && aPropValue.equals( aTemplVers ) )
     437             :         {
     438           0 :             bIsInitialized = true;
     439             :         }
     440             :         else
     441           0 :             removeContent( maRootContent );
     442             :     }
     443             : 
     444           0 :     if ( !bIsInitialized )
     445             :     {
     446           0 :         if ( createFolder( maRootURL, true, false, maRootContent )
     447           0 :           && setProperty( maRootContent, aTemplVersPropName, uno::makeAny( aTemplVers ) ) )
     448           0 :             bIsInitialized = true;
     449             : 
     450           0 :         bNeedsUpdate = true;
     451             :     }
     452             : 
     453           0 :     if ( bIsInitialized )
     454             :     {
     455             :         try {
     456             :             m_xDocProps.set(document::DocumentProperties::create(
     457           0 :                         ::comphelper::getProcessComponentContext()));
     458           0 :         } catch (uno::RuntimeException const& e) {
     459             :             SAL_WARN("sfx.doc", "SfxDocTplService_Impl::init_Impl: "
     460             :                 "cannot create DocumentProperties service:" << e.Message);
     461             :         }
     462             : 
     463           0 :         OUString const aService = SERVICENAME_TYPEDETECTION;
     464           0 :         mxType = uno::Reference< XTypeDetection > ( mxContext->getServiceManager()->createInstanceWithContext(aService, mxContext), UNO_QUERY );
     465             : 
     466           0 :         getDirList();
     467           0 :         readFolderList();
     468             : 
     469           0 :         if ( bNeedsUpdate )
     470             :         {
     471           0 :             aGuard.clear();
     472           0 :             SolarMutexClearableGuard aSolarGuard;
     473             : 
     474           0 :             WaitWindow_Impl* pWin = new WaitWindow_Impl();
     475             : 
     476           0 :             aSolarGuard.clear();
     477           0 :             ::osl::ClearableMutexGuard anotherGuard( maMutex );
     478             : 
     479           0 :             update( true );
     480             : 
     481           0 :             anotherGuard.clear();
     482           0 :             SolarMutexGuard aSecondSolarGuard;
     483             : 
     484           0 :             delete pWin;
     485             :         }
     486           0 :         else if ( needsUpdate() )
     487             :             // the UI should be shown only on the first update
     488           0 :             update( true );
     489             :     }
     490             :     else
     491             :     {
     492             :         SAL_WARN( "sfx.doc", "init_Impl(): Could not create root" );
     493             :     }
     494             : 
     495           0 :     mbIsInitialized = bIsInitialized;
     496           0 : }
     497             : 
     498             : 
     499           0 : void SfxDocTplService_Impl::getDefaultLocale()
     500             : {
     501           0 :     if ( !mbLocaleSet )
     502             :     {
     503           0 :         ::osl::MutexGuard aGuard( maMutex );
     504           0 :         if ( !mbLocaleSet )
     505             :         {
     506           0 :             maLocale = LanguageTag( utl::ConfigManager::getLocale()).getLocale( false);
     507           0 :             mbLocaleSet = true;
     508           0 :         }
     509             :     }
     510           0 : }
     511             : 
     512             : 
     513           0 : void SfxDocTplService_Impl::readFolderList()
     514             : {
     515           0 :     SolarMutexGuard aGuard;
     516             : 
     517           0 :     ResStringArray  aShortNames( SfxResId( TEMPLATE_SHORT_NAMES_ARY ) );
     518           0 :     ResStringArray  aLongNames( SfxResId( TEMPLATE_LONG_NAMES_ARY ) );
     519             : 
     520             :     NamePair_Impl*  pPair;
     521             : 
     522           0 :     sal_uInt16 nCount = (sal_uInt16)( std::min( aShortNames.Count(), aLongNames.Count() ) );
     523             : 
     524           0 :     for ( sal_uInt16 i=0; i<nCount; i++ )
     525             :     {
     526           0 :         pPair = new NamePair_Impl;
     527           0 :         pPair->maShortName  = aShortNames.GetString( i );
     528           0 :         pPair->maLongName   = aLongNames.GetString( i );
     529             : 
     530           0 :         maNames.push_back( pPair );
     531           0 :     }
     532           0 : }
     533             : 
     534             : 
     535           0 : OUString SfxDocTplService_Impl::getLongName( const OUString& rShortName )
     536             : {
     537           0 :     OUString         aRet;
     538             : 
     539           0 :     for ( size_t i = 0, n = maNames.size(); i < n; ++i )
     540             :     {
     541           0 :         NamePair_Impl* pPair = maNames[ i ];
     542           0 :         if ( pPair->maShortName == rShortName )
     543             :         {
     544           0 :             aRet = pPair->maLongName;
     545           0 :             break;
     546             :         }
     547             :     }
     548             : 
     549           0 :     if ( aRet.isEmpty() )
     550           0 :         aRet = rShortName;
     551             : 
     552           0 :     return aRet;
     553             : }
     554             : 
     555             : 
     556           0 : void SfxDocTplService_Impl::getDirList()
     557             : {
     558           0 :     OUString aPropName( PROPERTY_DIRLIST  );
     559           0 :     Any      aValue;
     560             : 
     561             :     // Get the template dir list
     562             :     // TODO/LATER: let use service, register listener
     563           0 :     INetURLObject   aURL;
     564           0 :     OUString    aDirs = SvtPathOptions().GetTemplatePath();
     565           0 :     sal_Int32 nCount = comphelper::string::getTokenCount(aDirs, C_DELIM);
     566             : 
     567           0 :     maTemplateDirs = Sequence< OUString >( nCount );
     568             : 
     569           0 :     uno::Reference< util::XMacroExpander > xExpander = util::theMacroExpander::get(mxContext);
     570             :     const OUString aPrefix(
     571           0 :         "vnd.sun.star.expand:"  );
     572             : 
     573           0 :     for (sal_Int32 i = 0; i < nCount; ++i)
     574             :     {
     575           0 :         aURL.SetSmartProtocol( INET_PROT_FILE );
     576           0 :         aURL.SetURL( aDirs.getToken( i, C_DELIM ) );
     577           0 :         maTemplateDirs[i] = aURL.GetMainURL( INetURLObject::NO_DECODE );
     578             : 
     579           0 :         sal_Int32 nIndex = maTemplateDirs[i].indexOf( aPrefix );
     580           0 :         if ( nIndex != -1 && xExpander.is() )
     581             :         {
     582           0 :             maTemplateDirs[i] = maTemplateDirs[i].replaceAt(nIndex,
     583             :                                                             aPrefix.getLength(),
     584           0 :                                                             OUString());
     585           0 :             maTemplateDirs[i] = xExpander->expandMacros( maTemplateDirs[i] );
     586             :         }
     587             :     }
     588             : 
     589           0 :     aValue <<= maTemplateDirs;
     590             : 
     591             :     css::uno::Reference< css::util::XPathSettings > xPathSettings =
     592           0 :         css::util::thePathSettings::get(mxContext);
     593             : 
     594             :     // load internal paths
     595           0 :     OUString sProp( "Template_internal" );
     596           0 :     Any aAny = xPathSettings->getPropertyValue( sProp );
     597           0 :     aAny >>= maInternalTemplateDirs;
     598             : 
     599           0 :     nCount = maInternalTemplateDirs.getLength();
     600           0 :     for (sal_Int32 i = 0; i < nCount; ++i)
     601             :     {
     602             :         //expand vnd.sun.star.expand: and remove "..." from them
     603             :         //to normalize into the expected url patterns
     604           0 :         maRelocator.makeRelocatableURL(maInternalTemplateDirs[i]);
     605           0 :         maRelocator.makeAbsoluteURL(maInternalTemplateDirs[i]);
     606             :     }
     607             : 
     608             :     // Store the template dir list
     609           0 :     setProperty( maRootContent, aPropName, aValue );
     610           0 : }
     611             : 
     612             : 
     613           0 : bool SfxDocTplService_Impl::needsUpdate()
     614             : {
     615           0 :     OUString aPropName( PROPERTY_NEEDSUPDATE  );
     616           0 :     bool bNeedsUpdate = true;
     617           0 :     Any      aValue;
     618             : 
     619             :     // Get the template dir list
     620           0 :     bool bHasProperty = getProperty( maRootContent, aPropName, aValue );
     621             : 
     622           0 :     if ( bHasProperty )
     623           0 :         aValue >>= bNeedsUpdate;
     624             : 
     625             :     // the old template component also checks this state, but it is initialized from this component
     626             :     // so if this componend was already updated the old component does not need such an update
     627           0 :     ::svt::TemplateFolderCache aTempCache;
     628           0 :     if ( !bNeedsUpdate )
     629           0 :         bNeedsUpdate = aTempCache.needsUpdate();
     630             : 
     631           0 :     if ( bNeedsUpdate )
     632           0 :         aTempCache.storeState();
     633             : 
     634           0 :     return bNeedsUpdate;
     635             : }
     636             : 
     637             : 
     638           0 : bool SfxDocTplService_Impl::setTitleForURL( const OUString& rURL, const OUString& aTitle )
     639             : {
     640           0 :     if (m_xDocProps.is())
     641             :     {
     642             :         try
     643             :         {
     644           0 :             m_xDocProps->loadFromMedium(rURL, Sequence<PropertyValue>());
     645           0 :             m_xDocProps->setTitle(aTitle);
     646             : 
     647             :             uno::Reference< embed::XStorage > xStorage = ::comphelper::OStorageHelper::GetStorageFromURL(
     648           0 :                     rURL, embed::ElementModes::READWRITE);
     649             : 
     650           0 :             uno::Sequence<beans::PropertyValue> medium(2);
     651           0 :             medium[0].Name = "DocumentBaseURL";
     652           0 :             medium[0].Value <<= rURL;
     653           0 :             medium[1].Name = "URL";
     654           0 :             medium[1].Value <<= rURL;
     655             : 
     656           0 :             m_xDocProps->storeToStorage(xStorage, medium);
     657           0 :             return true;
     658             :         }
     659           0 :         catch ( Exception& )
     660             :         {
     661             :         }
     662             :     }
     663           0 :     return false;
     664             : }
     665             : 
     666             : 
     667           0 : bool SfxDocTplService_Impl::getTitleFromURL( const OUString& rURL, OUString& aTitle, OUString& aType, bool& bDocHasTitle )
     668             : {
     669           0 :     bDocHasTitle = false;
     670             : 
     671           0 :     if (m_xDocProps.is())
     672             :     {
     673             :         try
     674             :         {
     675           0 :             m_xDocProps->loadFromMedium(rURL, Sequence<PropertyValue>());
     676           0 :             aTitle = m_xDocProps->getTitle();
     677             :         }
     678           0 :         catch ( Exception& )
     679             :         {
     680             :         }
     681             :     }
     682             : 
     683           0 :     if ( aType.isEmpty() && mxType.is() )
     684             :     {
     685           0 :         OUString aDocType = mxType->queryTypeByURL( rURL );
     686           0 :         if ( !aDocType.isEmpty() )
     687             :             try
     688             :             {
     689           0 :                 uno::Reference< container::XNameAccess > xTypeDetection( mxType, uno::UNO_QUERY_THROW );
     690           0 :                 SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aDocType ) );
     691           0 :                 aType = aTypeProps.getUnpackedValueOrDefault(
     692             :                             OUString("MediaType"),
     693           0 :                             OUString() );
     694             :             }
     695           0 :             catch( uno::Exception& )
     696           0 :             {}
     697             :     }
     698             : 
     699           0 :     if ( aTitle.isEmpty() )
     700             :     {
     701           0 :         INetURLObject aURL( rURL );
     702           0 :         aURL.CutExtension();
     703           0 :         aTitle = aURL.getName( INetURLObject::LAST_SEGMENT, true,
     704           0 :                                INetURLObject::DECODE_WITH_CHARSET );
     705             :     }
     706             :     else
     707           0 :         bDocHasTitle = true;
     708             : 
     709           0 :     return true;
     710             : }
     711             : 
     712             : 
     713           0 : bool SfxDocTplService_Impl::addEntry( Content& rParentFolder,
     714             :                                           const OUString& rTitle,
     715             :                                           const OUString& rTargetURL,
     716             :                                           const OUString& rType )
     717             : {
     718           0 :     bool bAddedEntry = false;
     719             : 
     720           0 :     INetURLObject aLinkObj( rParentFolder.getURL() );
     721             :     aLinkObj.insertName( rTitle, false,
     722             :                       INetURLObject::LAST_SEGMENT, true,
     723           0 :                       INetURLObject::ENCODE_ALL );
     724           0 :     OUString aLinkURL = aLinkObj.GetMainURL( INetURLObject::NO_DECODE );
     725             : 
     726           0 :     Content aLink;
     727             : 
     728           0 :     if ( ! Content::create( aLinkURL, maCmdEnv, comphelper::getProcessComponentContext(), aLink ) )
     729             :     {
     730           0 :         Sequence< OUString > aNames(3);
     731           0 :         aNames[0] = TITLE;
     732           0 :         aNames[1] = IS_FOLDER;
     733           0 :         aNames[2] = TARGET_URL;
     734             : 
     735           0 :         Sequence< Any > aValues(3);
     736           0 :         aValues[0] = makeAny( rTitle );
     737           0 :         aValues[1] = makeAny( false );
     738           0 :         aValues[2] = makeAny( rTargetURL );
     739             : 
     740           0 :         OUString aType( TYPE_LINK  );
     741           0 :         OUString aAdditionalProp( PROPERTY_TYPE  );
     742             : 
     743             :         try
     744             :         {
     745           0 :             rParentFolder.insertNewContent( aType, aNames, aValues, aLink );
     746           0 :             setProperty( aLink, aAdditionalProp, makeAny( rType ) );
     747           0 :             bAddedEntry = true;
     748             :         }
     749           0 :         catch( Exception& )
     750           0 :         {}
     751             :     }
     752           0 :     return bAddedEntry;
     753             : }
     754             : 
     755             : 
     756           0 : bool SfxDocTplService_Impl::createFolder( const OUString& rNewFolderURL,
     757             :                                               bool  bCreateParent,
     758             :                                               bool  bFsysFolder,
     759             :                                               Content   &rNewFolder )
     760             : {
     761           0 :     Content         aParent;
     762           0 :     bool        bCreatedFolder = false;
     763           0 :     INetURLObject   aParentURL( rNewFolderURL );
     764             :     OUString        aFolderName = aParentURL.getName( INetURLObject::LAST_SEGMENT, true,
     765           0 :                                                       INetURLObject::DECODE_WITH_CHARSET );
     766             : 
     767             :     // compute the parent folder url from the new folder url
     768             :     // and remove the final slash, because Content::create doesn't
     769             :     // like it
     770           0 :     aParentURL.removeSegment();
     771           0 :     if ( aParentURL.getSegmentCount() >= 1 )
     772           0 :         aParentURL.removeFinalSlash();
     773             : 
     774             :     // if the parent exists, we can continue with the creation of the
     775             :     // new folder, we have to create the parent otherwise ( as long as
     776             :     // bCreateParent is set to true )
     777           0 :     if ( Content::create( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), maCmdEnv, comphelper::getProcessComponentContext(), aParent ) )
     778             :     {
     779             :         try
     780             :         {
     781           0 :             Sequence< OUString > aNames(2);
     782           0 :             aNames[0] = TITLE;
     783           0 :             aNames[1] = IS_FOLDER;
     784             : 
     785           0 :             Sequence< Any > aValues(2);
     786           0 :             aValues[0] = makeAny( aFolderName );
     787           0 :             aValues[1] = makeAny( true );
     788             : 
     789           0 :             OUString aType;
     790             : 
     791           0 :             if ( bFsysFolder )
     792           0 :                 aType = TYPE_FSYS_FOLDER;
     793             :             else
     794           0 :                 aType = TYPE_FOLDER;
     795             : 
     796           0 :             aParent.insertNewContent( aType, aNames, aValues, rNewFolder );
     797           0 :             bCreatedFolder = true;
     798             :         }
     799           0 :         catch( RuntimeException& )
     800             :         {
     801             :             SAL_WARN( "sfx.doc", "createFolder(): got runtime exception" );
     802             :         }
     803           0 :         catch( Exception& )
     804             :         {
     805             :             SAL_WARN( "sfx.doc", "createFolder(): Could not create new folder" );
     806             :         }
     807             :     }
     808           0 :     else if ( bCreateParent )
     809             :     {
     810             :         // if the parent doesn't exists and bCreateParent is set to true,
     811             :         // we try to create the parent and if this was successful, we
     812             :         // try to create the new folder again ( but this time, we set
     813             :         // bCreateParent to false to avoid endless recusions )
     814           0 :         if ( ( aParentURL.getSegmentCount() >= 1 ) &&
     815           0 :                createFolder( aParentURL.GetMainURL( INetURLObject::NO_DECODE ), bCreateParent, bFsysFolder, aParent ) )
     816             :         {
     817           0 :             bCreatedFolder = createFolder( rNewFolderURL, false, bFsysFolder, rNewFolder );
     818             :         }
     819             :     }
     820             : 
     821           0 :     return bCreatedFolder;
     822             : }
     823             : 
     824             : 
     825           0 : bool SfxDocTplService_Impl::CreateNewUniqueFolderWithPrefix( const OUString& aPath,
     826             :                                                                 const OUString& aPrefix,
     827             :                                                                 OUString& aNewFolderName,
     828             :                                                                 OUString& aNewFolderURL,
     829             :                                                                 Content& aNewFolder )
     830             : {
     831           0 :     bool bCreated = false;
     832           0 :     INetURLObject aDirPath( aPath );
     833             : 
     834           0 :     Content aParent;
     835           0 :     uno::Reference< XCommandEnvironment > aQuietEnv;
     836           0 :        if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), aQuietEnv, comphelper::getProcessComponentContext(), aParent ) )
     837             :        {
     838           0 :         for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
     839             :         {
     840           0 :             OUString aTryName = aPrefix;
     841           0 :             if ( nInd )
     842           0 :                 aTryName += OUString::number( nInd );
     843             : 
     844             :             try
     845             :             {
     846           0 :                 Sequence< OUString > aNames(2);
     847           0 :                 aNames[0] = TITLE;
     848           0 :                 aNames[1] = IS_FOLDER;
     849             : 
     850           0 :                 Sequence< Any > aValues(2);
     851           0 :                 aValues[0] = makeAny( aTryName );
     852           0 :                 aValues[1] = makeAny( true );
     853             : 
     854           0 :                 OUString aType( TYPE_FSYS_FOLDER  );
     855             : 
     856           0 :                 bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFolder );
     857             :             }
     858           0 :             catch( ucb::NameClashException& )
     859             :             {
     860             :                 // if there is already an element, retry
     861             :             }
     862           0 :             catch( Exception& )
     863             :             {
     864           0 :                 INetURLObject aObjPath( aDirPath );
     865             :                 aObjPath.insertName( aTryName, false,
     866             :                       INetURLObject::LAST_SEGMENT, true,
     867           0 :                       INetURLObject::ENCODE_ALL );
     868             :                 // if there is already an element, retry
     869             :                 // if there was another error, do not try any more
     870           0 :                 if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
     871           0 :                     break;
     872           0 :             }
     873             : 
     874           0 :             if ( bCreated )
     875             :             {
     876           0 :                 aNewFolderName = aTryName;
     877           0 :                 aNewFolderURL = aNewFolder.get()->getIdentifier()->getContentIdentifier();
     878           0 :                 break;
     879             :             }
     880           0 :         }
     881             :     }
     882             : 
     883           0 :     return bCreated;
     884             : }
     885             : 
     886             : 
     887           0 : OUString SfxDocTplService_Impl::CreateNewUniqueFileWithPrefix( const OUString& aPath,
     888             :                                                                         const OUString& aPrefix,
     889             :                                                                         const OUString& aExt )
     890             : {
     891           0 :     OUString aNewFileURL;
     892           0 :     INetURLObject aDirPath( aPath );
     893             : 
     894           0 :        Content aParent;
     895             : 
     896           0 :     uno::Reference< XCommandEnvironment > aQuietEnv;
     897           0 :     if ( Content::create( aDirPath.GetMainURL( INetURLObject::NO_DECODE ), aQuietEnv, comphelper::getProcessComponentContext(), aParent ) )
     898             :        {
     899           0 :         for ( sal_Int32 nInd = 0; nInd < 32000; nInd++ )
     900             :         {
     901           0 :             Content aNewFile;
     902           0 :             bool bCreated = false;
     903           0 :             OUString aTryName = aPrefix;
     904           0 :             if ( nInd )
     905           0 :                 aTryName += OUString::number( nInd );
     906           0 :             if ( aExt.toChar() != '.' )
     907           0 :                 aTryName += ".";
     908           0 :             aTryName += aExt;
     909             : 
     910             :             try
     911             :             {
     912           0 :                 Sequence< OUString > aNames(2);
     913           0 :                 aNames[0] = TITLE;
     914           0 :                 aNames[1] = IS_DOCUMENT;
     915             : 
     916           0 :                 Sequence< Any > aValues(2);
     917           0 :                 aValues[0] = makeAny( aTryName );
     918           0 :                 aValues[1] = makeAny( true );
     919             : 
     920           0 :                 OUString aType( TYPE_FSYS_FILE  );
     921             : 
     922           0 :                 bCreated = aParent.insertNewContent( aType, aNames, aValues, aNewFile );
     923             :             }
     924           0 :             catch( ucb::NameClashException& )
     925             :             {
     926             :                 // if there is already an element, retry
     927             :             }
     928           0 :             catch( Exception& )
     929             :             {
     930           0 :                 INetURLObject aObjPath( aPath );
     931             :                 aObjPath.insertName( aTryName, false,
     932             :                       INetURLObject::LAST_SEGMENT, true,
     933           0 :                       INetURLObject::ENCODE_ALL );
     934             :                 // if there is already an element, retry
     935             :                 // if there was another error, do not try any more
     936           0 :                 if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::NO_DECODE ) ) )
     937           0 :                     break;
     938           0 :             }
     939             : 
     940           0 :             if ( bCreated )
     941             :             {
     942           0 :                 aNewFileURL = aNewFile.get()->getIdentifier()->getContentIdentifier();
     943           0 :                 break;
     944             :             }
     945           0 :         }
     946             :     }
     947             : 
     948           0 :     return aNewFileURL;
     949             : }
     950             : 
     951             : 
     952           0 : bool SfxDocTplService_Impl::removeContent( Content& rContent )
     953             : {
     954           0 :     bool bRemoved = false;
     955             :     try
     956             :     {
     957           0 :         OUString aCmd( COMMAND_DELETE  );
     958           0 :         Any aArg = makeAny( true );
     959             : 
     960           0 :         rContent.executeCommand( aCmd, aArg );
     961           0 :         bRemoved = true;
     962             :     }
     963           0 :     catch ( RuntimeException& ) {}
     964           0 :     catch ( Exception& ) {}
     965             : 
     966           0 :     return bRemoved;
     967             : }
     968             : 
     969             : 
     970           0 : bool SfxDocTplService_Impl::removeContent( const OUString& rContentURL )
     971             : {
     972           0 :     Content aContent;
     973             : 
     974           0 :     if ( Content::create( rContentURL, maCmdEnv, comphelper::getProcessComponentContext(), aContent ) )
     975           0 :         return removeContent( aContent );
     976             :     else
     977           0 :         return false;
     978             : }
     979             : 
     980             : 
     981           0 : bool SfxDocTplService_Impl::setProperty( Content& rContent,
     982             :                                              const OUString& rPropName,
     983             :                                              const Any& rPropValue )
     984             : {
     985           0 :     bool bPropertySet = false;
     986             : 
     987             :     // Store the property
     988             :     try
     989             :     {
     990           0 :         Any aPropValue( rPropValue );
     991           0 :         uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
     992             : 
     993             :         // check, whether or not the property exists, create it, when not
     994           0 :         if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
     995             :         {
     996           0 :             uno::Reference< XPropertyContainer > xProperties( rContent.get(), UNO_QUERY );
     997           0 :             if ( xProperties.is() )
     998             :             {
     999             :                 try
    1000             :                 {
    1001           0 :                     xProperties->addProperty( rPropName, PropertyAttribute::MAYBEVOID, rPropValue );
    1002             :                 }
    1003           0 :                 catch( PropertyExistException& ) {}
    1004           0 :                 catch( IllegalTypeException& ) {
    1005             :                     SAL_WARN( "sfx.doc", "IllegalTypeException" );
    1006             :                 }
    1007           0 :                 catch( IllegalArgumentException& ) {
    1008             :                     SAL_WARN( "sfx.doc", "IllegalArgumentException" );
    1009             :                 }
    1010           0 :             }
    1011             :         }
    1012             : 
    1013             :         // To ensure a reloctable office installation, the path to the
    1014             :         // office installtion directory must never be stored directly.
    1015           0 :         if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
    1016             :         {
    1017           0 :             OUString aValue;
    1018           0 :             if ( rPropValue >>= aValue )
    1019             :             {
    1020           0 :                 maRelocator.makeRelocatableURL( aValue );
    1021           0 :                 aPropValue = makeAny( aValue );
    1022             :             }
    1023             :             else
    1024             :             {
    1025           0 :                 Sequence< OUString > aValues;
    1026           0 :                 if ( rPropValue >>= aValues )
    1027             :                 {
    1028           0 :                     for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
    1029             :                     {
    1030           0 :                         maRelocator.makeRelocatableURL( aValues[ n ] );
    1031             :                     }
    1032           0 :                     aPropValue = makeAny( aValues );
    1033             :                 }
    1034             :                 else
    1035             :                 {
    1036             :                     OSL_FAIL( "Unsupported property value type" );
    1037           0 :                 }
    1038           0 :             }
    1039             :         }
    1040             : 
    1041             :         // now set the property
    1042             : 
    1043           0 :         rContent.setPropertyValue( rPropName, aPropValue );
    1044           0 :         bPropertySet = true;
    1045             :     }
    1046           0 :     catch ( RuntimeException& ) {}
    1047           0 :     catch ( Exception& ) {}
    1048             : 
    1049           0 :     return bPropertySet;
    1050             : }
    1051             : 
    1052             : 
    1053           0 : bool SfxDocTplService_Impl::getProperty( Content& rContent,
    1054             :                                              const OUString& rPropName,
    1055             :                                              Any& rPropValue )
    1056             : {
    1057           0 :     bool bGotProperty = false;
    1058             : 
    1059             :     // Get the property
    1060             :     try
    1061             :     {
    1062           0 :         uno::Reference< XPropertySetInfo > aPropInfo = rContent.getProperties();
    1063             : 
    1064             :         // check, whether or not the property exists
    1065           0 :         if ( !aPropInfo.is() || !aPropInfo->hasPropertyByName( rPropName ) )
    1066             :         {
    1067           0 :             return false;
    1068             :         }
    1069             : 
    1070             :         // now get the property
    1071             : 
    1072           0 :         rPropValue = rContent.getPropertyValue( rPropName );
    1073             : 
    1074             :         // To ensure a reloctable office installation, the path to the
    1075             :         // office installtion directory must never be stored directly.
    1076           0 :         if ( SfxURLRelocator_Impl::propertyCanContainOfficeDir( rPropName ) )
    1077             :         {
    1078           0 :             OUString aValue;
    1079           0 :             if ( rPropValue >>= aValue )
    1080             :             {
    1081           0 :                 maRelocator.makeAbsoluteURL( aValue );
    1082           0 :                 rPropValue = makeAny( aValue );
    1083             :             }
    1084             :             else
    1085             :             {
    1086           0 :                 Sequence< OUString > aValues;
    1087           0 :                 if ( rPropValue >>= aValues )
    1088             :                 {
    1089           0 :                     for ( sal_Int32 n = 0; n < aValues.getLength(); n++ )
    1090             :                     {
    1091           0 :                         maRelocator.makeAbsoluteURL( aValues[ n ] );
    1092             :                     }
    1093           0 :                     rPropValue = makeAny( aValues );
    1094             :                 }
    1095             :                 else
    1096             :                 {
    1097             :                     OSL_FAIL( "Unsupported property value type" );
    1098           0 :                 }
    1099           0 :             }
    1100             :         }
    1101             : 
    1102           0 :         bGotProperty = true;
    1103             :     }
    1104           0 :     catch ( RuntimeException& ) {}
    1105           0 :     catch ( Exception& ) {}
    1106             : 
    1107           0 :     return bGotProperty;
    1108             : }
    1109             : 
    1110           0 : SfxDocTplService_Impl::SfxDocTplService_Impl( const uno::Reference< XComponentContext > & xContext )
    1111           0 : : maRelocator( xContext )
    1112             : {
    1113           0 :     mxContext       = xContext;
    1114           0 :     mpUpdater       = NULL;
    1115           0 :     mbIsInitialized = false;
    1116           0 :     mbLocaleSet     = false;
    1117           0 : }
    1118             : 
    1119             : 
    1120           0 : SfxDocTplService_Impl::~SfxDocTplService_Impl()
    1121             : {
    1122           0 :     ::osl::MutexGuard aGuard( maMutex );
    1123             : 
    1124           0 :     if ( mpUpdater )
    1125             :     {
    1126           0 :         mpUpdater->terminate();
    1127           0 :         mpUpdater->join();
    1128           0 :         delete mpUpdater;
    1129             :     }
    1130             : 
    1131           0 :     for ( size_t i = 0, n = maNames.size(); i < n; ++i )
    1132           0 :         delete maNames[ i ];
    1133           0 :     maNames.clear();
    1134           0 : }
    1135             : 
    1136             : 
    1137           0 : Locale SfxDocTplService_Impl::getLocale()
    1138             : {
    1139           0 :     ::osl::MutexGuard aGuard( maMutex );
    1140             : 
    1141           0 :     if ( !mbLocaleSet )
    1142           0 :         getDefaultLocale();
    1143             : 
    1144           0 :     return maLocale;
    1145             : }
    1146             : 
    1147             : 
    1148           0 : void SfxDocTplService_Impl::setLocale( const Locale &rLocale )
    1149             : {
    1150           0 :     ::osl::MutexGuard aGuard( maMutex );
    1151             : 
    1152           0 :     if ( mbLocaleSet && (
    1153           0 :          ( maLocale.Language != rLocale.Language ) ||
    1154           0 :          ( maLocale.Country  != rLocale.Country  ) ||
    1155           0 :          ( maLocale.Variant  != rLocale.Variant  ) ) )
    1156           0 :         mbIsInitialized = false;
    1157             : 
    1158           0 :     maLocale    = rLocale;
    1159           0 :     mbLocaleSet = true;
    1160           0 : }
    1161             : 
    1162             : 
    1163           0 : void SfxDocTplService_Impl::update( bool bUpdateNow )
    1164             : {
    1165           0 :     ::osl::MutexGuard aGuard( maMutex );
    1166             : 
    1167           0 :     if ( bUpdateNow )
    1168           0 :         doUpdate();
    1169             :     else
    1170             :     {
    1171           0 :         mpUpdater = new Updater_Impl( this );
    1172           0 :         mpUpdater->create();
    1173           0 :     }
    1174           0 : }
    1175             : 
    1176             : 
    1177           0 : void SfxDocTplService_Impl::doUpdate()
    1178             : {
    1179           0 :     ::osl::MutexGuard aGuard( maMutex );
    1180             : 
    1181           0 :     OUString aPropName( PROPERTY_NEEDSUPDATE  );
    1182           0 :     Any      aValue;
    1183             : 
    1184           0 :     aValue <<= sal_True;
    1185           0 :     setProperty( maRootContent, aPropName, aValue );
    1186             : 
    1187           0 :     GroupList_Impl  aGroupList;
    1188             : 
    1189             :     // get the entries from the hierarchy
    1190           0 :     createFromContent( aGroupList, maRootContent, true );
    1191             : 
    1192             :     // get the entries from the template directories
    1193           0 :     sal_Int32   nCountDir = maTemplateDirs.getLength();
    1194           0 :     OUString*   pDirs = maTemplateDirs.getArray();
    1195           0 :     Content     aDirContent;
    1196             : 
    1197             :     // the last directory in the list must be writable
    1198           0 :     bool bWriteableDirectory = true;
    1199             : 
    1200             :     // the target folder might not exist, for this reason no interaction handler should be used
    1201           0 :     uno::Reference< XCommandEnvironment > aQuietEnv;
    1202             : 
    1203           0 :     while ( nCountDir )
    1204             :     {
    1205           0 :         nCountDir--;
    1206           0 :         if ( Content::create( pDirs[ nCountDir ], aQuietEnv, comphelper::getProcessComponentContext(), aDirContent ) )
    1207             :         {
    1208           0 :             createFromContent( aGroupList, aDirContent, false, bWriteableDirectory );
    1209             :         }
    1210             : 
    1211           0 :         bWriteableDirectory = false;
    1212             :     }
    1213             : 
    1214             :     // now check the list
    1215           0 :     for( size_t j = 0, n = aGroupList.size(); j < n; ++j )
    1216             :     {
    1217           0 :         GroupData_Impl *pGroup = aGroupList[ j ];
    1218           0 :         if ( pGroup->getInUse() )
    1219             :         {
    1220           0 :             if ( pGroup->getInHierarchy() )
    1221             :             {
    1222           0 :                 Content aGroup;
    1223           0 :                 if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1224             :                     setProperty( aGroup,
    1225             :                                  OUString( TARGET_DIR_URL  ),
    1226           0 :                                  makeAny( pGroup->getTargetURL() ) );
    1227             : 
    1228           0 :                 size_t nCount = pGroup->count();
    1229           0 :                 for ( size_t i=0; i<nCount; i++ )
    1230             :                 {
    1231           0 :                     DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
    1232           0 :                     if ( ! pData->getInUse() )
    1233             :                     {
    1234           0 :                         if ( pData->getInHierarchy() )
    1235           0 :                             removeFromHierarchy( pData ); // delete entry in hierarchy
    1236             :                         else
    1237           0 :                             addToHierarchy( pGroup, pData ); // add entry to hierarchy
    1238             :                     }
    1239           0 :                     else if ( pData->getUpdateType() ||
    1240           0 :                               pData->getUpdateLink() )
    1241             :                     {
    1242           0 :                         updateData( pData );
    1243             :                     }
    1244           0 :                 }
    1245             :             }
    1246             :             else
    1247             :             {
    1248           0 :                 addGroupToHierarchy( pGroup ); // add group to hierarchy
    1249             :             }
    1250             :         }
    1251             :         else
    1252           0 :             removeFromHierarchy( pGroup ); // delete group from hierarchy
    1253             : 
    1254           0 :         delete pGroup;
    1255             :     }
    1256           0 :     aGroupList.clear();
    1257             : 
    1258           0 :     aValue <<= sal_False;
    1259           0 :     setProperty( maRootContent, aPropName, aValue );
    1260           0 : }
    1261             : 
    1262             : 
    1263           0 : uno::Sequence< beans::StringPair > SfxDocTplService_Impl::ReadUINamesForTemplateDir_Impl( const OUString& aUserPath )
    1264             : {
    1265           0 :     INetURLObject aLocObj( aUserPath );
    1266             :     aLocObj.insertName( OUString( "groupuinames.xml"  ), false,
    1267             :                       INetURLObject::LAST_SEGMENT, true,
    1268           0 :                       INetURLObject::ENCODE_ALL );
    1269           0 :     Content aLocContent;
    1270             : 
    1271             :     // TODO/LATER: Use hashmap in future
    1272           0 :     uno::Sequence< beans::StringPair > aUINames;
    1273           0 :     if ( Content::create( aLocObj.GetMainURL( INetURLObject::NO_DECODE ), uno::Reference < ucb::XCommandEnvironment >(), comphelper::getProcessComponentContext(), aLocContent ) )
    1274             :     {
    1275             :         try
    1276             :         {
    1277           0 :             uno::Reference< io::XInputStream > xLocStream = aLocContent.openStream();
    1278           0 :             if ( xLocStream.is() )
    1279           0 :                 aUINames = DocTemplLocaleHelper::ReadGroupLocalizationSequence( xLocStream, mxContext );
    1280             :         }
    1281           0 :         catch( uno::Exception& )
    1282             :         {}
    1283             :     }
    1284             : 
    1285           0 :     return aUINames;
    1286             : }
    1287             : 
    1288             : 
    1289           0 : bool SfxDocTplService_Impl::UpdateUINamesForTemplateDir_Impl( const OUString& aUserPath,
    1290             :                                                                   const OUString& aGroupName,
    1291             :                                                                   const OUString& aNewFolderName )
    1292             : {
    1293           0 :     uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
    1294           0 :     sal_Int32 nLen = aUINames.getLength();
    1295             : 
    1296             :     // it is possible that the name is used already, but it should be checked before
    1297           0 :     for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
    1298           0 :         if ( aUINames[nInd].First.equals( aNewFolderName ) )
    1299           0 :             return false;
    1300             : 
    1301           0 :     aUINames.realloc( ++nLen );
    1302           0 :     aUINames[nLen-1].First = aNewFolderName;
    1303           0 :     aUINames[nLen-1].Second = aGroupName;
    1304             : 
    1305           0 :     return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
    1306             : }
    1307             : 
    1308             : 
    1309           0 : bool SfxDocTplService_Impl::ReplaceUINamesForTemplateDir_Impl( const OUString& aUserPath,
    1310             :                                                                   const OUString& aDefaultFsysGroupName,
    1311             :                                                                   const OUString& aOldGroupName,
    1312             :                                                                   const OUString& aNewGroupName )
    1313             : {
    1314           0 :     uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
    1315           0 :     sal_Int32 nLen = aUINames.getLength();
    1316             : 
    1317           0 :     bool bChanged = false;
    1318           0 :     for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
    1319           0 :         if ( aUINames[nInd].Second.equals( aOldGroupName ) )
    1320             :         {
    1321           0 :             aUINames[nInd].Second = aNewGroupName;
    1322           0 :             bChanged = true;
    1323             :         }
    1324             : 
    1325           0 :     if ( !bChanged )
    1326             :     {
    1327           0 :         aUINames.realloc( ++nLen );
    1328           0 :         aUINames[nLen-1].First = aDefaultFsysGroupName;
    1329           0 :         aUINames[nLen-1].Second = aNewGroupName;
    1330             :     }
    1331           0 :     return WriteUINamesForTemplateDir_Impl( aUserPath, aUINames );
    1332             : }
    1333             : 
    1334             : 
    1335           0 : bool SfxDocTplService_Impl::RemoveUINamesForTemplateDir_Impl( const OUString& aUserPath,
    1336             :                                                                   const OUString& aGroupName )
    1337             : {
    1338           0 :     uno::Sequence< beans::StringPair > aUINames = ReadUINamesForTemplateDir_Impl( aUserPath );
    1339           0 :     sal_Int32 nLen = aUINames.getLength();
    1340           0 :     uno::Sequence< beans::StringPair > aNewUINames( nLen );
    1341           0 :     sal_Int32 nNewLen = 0;
    1342             : 
    1343           0 :     bool bChanged = false;
    1344           0 :     for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ )
    1345           0 :         if ( aUINames[nInd].Second.equals( aGroupName ) )
    1346           0 :             bChanged = true;
    1347             :         else
    1348             :         {
    1349           0 :             nNewLen++;
    1350           0 :             aNewUINames[nNewLen-1].First = aUINames[nInd].First;
    1351           0 :             aNewUINames[nNewLen-1].Second = aUINames[nInd].Second;
    1352             :         }
    1353             : 
    1354           0 :     aNewUINames.realloc( nNewLen );
    1355             : 
    1356           0 :     return bChanged ? WriteUINamesForTemplateDir_Impl( aUserPath, aNewUINames ) : sal_True;
    1357             : }
    1358             : 
    1359             : 
    1360             : 
    1361           0 : bool SfxDocTplService_Impl::WriteUINamesForTemplateDir_Impl( const OUString& aUserPath,
    1362             :                                                                 const uno::Sequence< beans::StringPair >& aUINames )
    1363             : {
    1364           0 :     bool bResult = false;
    1365             :     try {
    1366             :         uno::Reference< beans::XPropertySet > xTempFile(
    1367             :                 io::TempFile::create(mxContext),
    1368           0 :                 uno::UNO_QUERY_THROW );
    1369             : 
    1370           0 :         OUString aTempURL;
    1371           0 :         uno::Any aUrl = xTempFile->getPropertyValue("Uri");
    1372           0 :         aUrl >>= aTempURL;
    1373             : 
    1374           0 :         uno::Reference< io::XStream > xStream( xTempFile, uno::UNO_QUERY_THROW );
    1375           0 :         uno::Reference< io::XOutputStream > xOutStream = xStream->getOutputStream();
    1376           0 :         if ( !xOutStream.is() )
    1377           0 :             throw uno::RuntimeException();
    1378             : 
    1379           0 :         DocTemplLocaleHelper::WriteGroupLocalizationSequence( xOutStream, aUINames, mxContext);
    1380             :         try {
    1381             :             // the SAX writer might close the stream
    1382           0 :             xOutStream->closeOutput();
    1383           0 :         } catch( uno::Exception& )
    1384             :         {}
    1385             : 
    1386           0 :         Content aTargetContent( aUserPath, maCmdEnv, comphelper::getProcessComponentContext() );
    1387           0 :         Content aSourceContent( aTempURL, maCmdEnv, comphelper::getProcessComponentContext() );
    1388             :         aTargetContent.transferContent( aSourceContent,
    1389             :                                         InsertOperation_COPY,
    1390             :                                         OUString( "groupuinames.xml"  ),
    1391             :                                         ucb::NameClash::OVERWRITE,
    1392           0 :                                         OUString( "text/xml" ) );
    1393           0 :         bResult = true;
    1394             :     }
    1395           0 :     catch ( uno::Exception& )
    1396             :     {
    1397             :     }
    1398             : 
    1399           0 :     return bResult;
    1400             : }
    1401             : 
    1402             : 
    1403           0 : OUString SfxDocTplService_Impl::CreateNewGroupFsys( const OUString& rGroupName, Content& aGroup )
    1404             : {
    1405           0 :     OUString aResultURL;
    1406             : 
    1407           0 :     if ( maTemplateDirs.getLength() )
    1408             :     {
    1409           0 :         OUString aTargetPath = maTemplateDirs[ maTemplateDirs.getLength() - 1 ];
    1410             : 
    1411             :         // create a new folder with the given name
    1412           0 :         Content aNewFolder;
    1413           0 :         OUString aNewFolderName;
    1414             : 
    1415             :         // the Fsys name instead of GroupName should be used, the groupuinames must be added also
    1416           0 :         if ( !CreateNewUniqueFolderWithPrefix( aTargetPath,
    1417             :                                                 rGroupName,
    1418             :                                                 aNewFolderName,
    1419             :                                                 aResultURL,
    1420           0 :                                                 aNewFolder )
    1421           0 :           && !CreateNewUniqueFolderWithPrefix( aTargetPath,
    1422             :                                                 OUString( "UserGroup"  ),
    1423             :                                                 aNewFolderName,
    1424             :                                                 aResultURL,
    1425           0 :                                                 aNewFolder ) )
    1426             : 
    1427           0 :             return OUString();
    1428             : 
    1429           0 :         if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath, rGroupName, aNewFolderName ) )
    1430             :         {
    1431             :             // we could not create the groupuinames for the folder, so we delete the group in the
    1432             :             // the folder and return
    1433           0 :             removeContent( aNewFolder );
    1434           0 :             return OUString();
    1435             :         }
    1436             : 
    1437             :         // Now set the target url for this group and we are done
    1438           0 :         OUString aPropName( TARGET_DIR_URL  );
    1439           0 :         Any aValue = makeAny( aResultURL );
    1440             : 
    1441           0 :         if ( ! setProperty( aGroup, aPropName, aValue ) )
    1442             :         {
    1443           0 :             removeContent( aNewFolder );
    1444           0 :             return OUString();
    1445           0 :         }
    1446             :     }
    1447             : 
    1448           0 :     return aResultURL;
    1449             : }
    1450             : 
    1451             : 
    1452           0 : bool SfxDocTplService_Impl::addGroup( const OUString& rGroupName )
    1453             : {
    1454           0 :     ::osl::MutexGuard aGuard( maMutex );
    1455             : 
    1456             :     // Check, whether or not there is a group with this name
    1457           0 :     Content      aNewGroup;
    1458           0 :     OUString        aNewGroupURL;
    1459           0 :     INetURLObject   aNewGroupObj( maRootURL );
    1460             : 
    1461             :     aNewGroupObj.insertName( rGroupName, false,
    1462             :                       INetURLObject::LAST_SEGMENT, true,
    1463           0 :                       INetURLObject::ENCODE_ALL );
    1464             : 
    1465           0 :     aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1466             : 
    1467           0 :     if ( Content::create( aNewGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aNewGroup ) ||
    1468           0 :          ! createFolder( aNewGroupURL, false, false, aNewGroup ) )
    1469             :     {
    1470             :         // if there already was a group with this name or the new group
    1471             :         // could not be created, we return here
    1472           0 :         return false;
    1473             :     }
    1474             : 
    1475             :     // Get the user template path entry ( new group will always
    1476             :     // be added in the user template path )
    1477             :     sal_Int32   nIndex;
    1478           0 :     OUString    aUserPath;
    1479             : 
    1480           0 :     nIndex = maTemplateDirs.getLength();
    1481           0 :     if ( nIndex )
    1482           0 :         nIndex--;
    1483             :     else
    1484           0 :         return false;   // We don't know where to add the group
    1485             : 
    1486           0 :     aUserPath = maTemplateDirs[ nIndex ];
    1487             : 
    1488             :     // create a new folder with the given name
    1489           0 :     Content      aNewFolder;
    1490           0 :     OUString        aNewFolderName;
    1491           0 :     OUString        aNewFolderURL;
    1492             : 
    1493             :     // the Fsys name instead of GroupName should be used, the groupuinames must be added also
    1494           0 :     if ( !CreateNewUniqueFolderWithPrefix( aUserPath,
    1495             :                                             rGroupName,
    1496             :                                             aNewFolderName,
    1497             :                                             aNewFolderURL,
    1498           0 :                                             aNewFolder )
    1499           0 :       && !CreateNewUniqueFolderWithPrefix( aUserPath,
    1500             :                                             OUString( "UserGroup"  ),
    1501             :                                             aNewFolderName,
    1502             :                                             aNewFolderURL,
    1503           0 :                                             aNewFolder ) )
    1504             :     {
    1505             :         // we could not create the folder, so we delete the group in the
    1506             :         // hierarchy and return
    1507           0 :         removeContent( aNewGroup );
    1508           0 :         return false;
    1509             :     }
    1510             : 
    1511           0 :     if ( !UpdateUINamesForTemplateDir_Impl( aUserPath, rGroupName, aNewFolderName ) )
    1512             :     {
    1513             :         // we could not create the groupuinames for the folder, so we delete the group in the
    1514             :         // hierarchy, the folder and return
    1515           0 :         removeContent( aNewGroup );
    1516           0 :         removeContent( aNewFolder );
    1517           0 :         return false;
    1518             :     }
    1519             : 
    1520             :     // Now set the target url for this group and we are done
    1521           0 :     OUString aPropName( TARGET_DIR_URL  );
    1522           0 :     Any aValue = makeAny( aNewFolderURL );
    1523             : 
    1524           0 :     if ( ! setProperty( aNewGroup, aPropName, aValue ) )
    1525             :     {
    1526           0 :         removeContent( aNewGroup );
    1527           0 :         removeContent( aNewFolder );
    1528           0 :         return false;
    1529             :     }
    1530             : 
    1531           0 :     return true;
    1532             : }
    1533             : 
    1534             : 
    1535           0 : bool SfxDocTplService_Impl::removeGroup( const OUString& rGroupName )
    1536             : {
    1537             :     // remove all the elements that have the prefix aTargetURL
    1538             :     // if the group does not have other elements remove it
    1539             : 
    1540           0 :     ::osl::MutexGuard aGuard( maMutex );
    1541             : 
    1542           0 :     bool bResult = false;
    1543             : 
    1544             :     // create the group url
    1545           0 :     INetURLObject aGroupObj( maRootURL );
    1546             :     aGroupObj.insertName( rGroupName, false,
    1547             :                       INetURLObject::LAST_SEGMENT, true,
    1548           0 :                       INetURLObject::ENCODE_ALL );
    1549             : 
    1550             :     // Get the target url
    1551           0 :     Content  aGroup;
    1552           0 :     OUString    aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1553             : 
    1554           0 :     if ( Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1555             :     {
    1556           0 :         OUString    aPropName( TARGET_DIR_URL  );
    1557           0 :         Any      aValue;
    1558             : 
    1559           0 :         OUString    aGroupTargetURL;
    1560           0 :         if ( getProperty( aGroup, aPropName, aValue ) )
    1561           0 :             aValue >>= aGroupTargetURL;
    1562             : 
    1563           0 :         if ( aGroupTargetURL.isEmpty() )
    1564           0 :             return false; // nothing is allowed to be removed
    1565             : 
    1566           0 :         if ( !maTemplateDirs.getLength() )
    1567           0 :             return false;
    1568             : 
    1569             :         // check that the fs location is in writable folder and this is not a "My templates" folder
    1570           0 :         INetURLObject aGroupParentFolder( aGroupTargetURL );
    1571           0 :         if (!aGroupParentFolder.removeSegment())
    1572           0 :             return false;
    1573             : 
    1574             :         OUString aGeneralTempPath = findParentTemplateDir(
    1575           0 :             aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE));
    1576             : 
    1577           0 :         if (aGeneralTempPath.isEmpty())
    1578           0 :             return false;
    1579             : 
    1580             :         // now get the content of the Group
    1581           0 :         uno::Reference< XResultSet > xResultSet;
    1582           0 :         Sequence< OUString > aProps( 1 );
    1583             : 
    1584           0 :         aProps[0] = TARGET_URL;
    1585             : 
    1586             :         try
    1587             :         {
    1588           0 :             bool bHasNonRemovable = false;
    1589           0 :             bool bHasShared = false;
    1590             : 
    1591           0 :             ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
    1592           0 :             xResultSet = aGroup.createCursor( aProps, eInclude );
    1593             : 
    1594           0 :             if ( xResultSet.is() )
    1595             :             {
    1596           0 :                 uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
    1597           0 :                 uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
    1598             : 
    1599           0 :                 while ( xResultSet->next() )
    1600             :                 {
    1601           0 :                     OUString aTemplTargetURL( xRow->getString( 1 ) );
    1602           0 :                     OUString aHierURL = xContentAccess->queryContentIdentifierString();
    1603             : 
    1604           0 :                     if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
    1605             :                     {
    1606             :                         // this is a user template, and it can be removed
    1607           0 :                         if ( removeContent( aTemplTargetURL ) )
    1608           0 :                             removeContent( aHierURL );
    1609             :                         else
    1610           0 :                             bHasNonRemovable = true;
    1611             :                     }
    1612             :                     else
    1613           0 :                         bHasShared = true;
    1614           0 :                 }
    1615             : 
    1616           0 :                 if ( !bHasNonRemovable && !bHasShared )
    1617             :                 {
    1618           0 :                     if ( removeContent( aGroupTargetURL )
    1619           0 :                       || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
    1620             :                     {
    1621           0 :                         removeContent( aGroupURL );
    1622           0 :                         RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
    1623           0 :                         bResult = true; // the operation is successful only if the whole group is removed
    1624             :                     }
    1625             :                 }
    1626           0 :                 else if ( !bHasNonRemovable )
    1627             :                 {
    1628           0 :                     if ( removeContent( aGroupTargetURL )
    1629           0 :                       || !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
    1630             :                     {
    1631           0 :                         RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
    1632           0 :                         setProperty( aGroup, aPropName, uno::makeAny( OUString() ) );
    1633             :                     }
    1634           0 :                 }
    1635             :             }
    1636             :         }
    1637           0 :         catch ( Exception& ) {}
    1638             :     }
    1639             : 
    1640           0 :     return bResult;
    1641             : }
    1642             : 
    1643             : 
    1644           0 : bool SfxDocTplService_Impl::renameGroup( const OUString& rOldName,
    1645             :                                              const OUString& rNewName )
    1646             : {
    1647           0 :     ::osl::MutexGuard aGuard( maMutex );
    1648             : 
    1649             :     // create the group url
    1650           0 :     Content         aGroup;
    1651           0 :     INetURLObject   aGroupObj( maRootURL );
    1652             :                     aGroupObj.insertName( rNewName, false,
    1653             :                                           INetURLObject::LAST_SEGMENT, true,
    1654           0 :                                           INetURLObject::ENCODE_ALL );
    1655           0 :     OUString        aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1656             : 
    1657             :     // Check, if there is a group with the new name, return false
    1658             :     // if there is one.
    1659           0 :     if ( Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1660           0 :         return false;
    1661             : 
    1662           0 :     aGroupObj.removeSegment();
    1663             :     aGroupObj.insertName( rOldName, false,
    1664             :                       INetURLObject::LAST_SEGMENT, true,
    1665           0 :                       INetURLObject::ENCODE_ALL );
    1666           0 :     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1667             : 
    1668             :     // When there is no group with the old name, we can't rename it
    1669           0 :     if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1670           0 :         return false;
    1671             : 
    1672           0 :     OUString aGroupTargetURL;
    1673             :     // there is no need to check whether target dir url is in target path, since if the target path is changed
    1674             :     // the target dir url should be already generated new
    1675           0 :     OUString    aPropName( TARGET_DIR_URL  );
    1676           0 :     Any      aValue;
    1677           0 :     if ( getProperty( aGroup, aPropName, aValue ) )
    1678           0 :         aValue >>= aGroupTargetURL;
    1679             : 
    1680           0 :     if ( aGroupTargetURL.isEmpty() )
    1681           0 :         return false;
    1682             : 
    1683           0 :     if ( !maTemplateDirs.getLength() )
    1684           0 :         return false;
    1685             : 
    1686             :     // check that the fs location is in writable folder and this is not a "My templates" folder
    1687           0 :     INetURLObject aGroupParentFolder( aGroupTargetURL );
    1688           0 :     if (!aGroupParentFolder.removeSegment() ||
    1689           0 :         isInternalTemplateDir(aGroupParentFolder.GetMainURL(INetURLObject::NO_DECODE)))
    1690             :     {
    1691           0 :         return false;
    1692             :     }
    1693             : 
    1694             :     // check that the group can be renamed ( all the contents must be in target location )
    1695           0 :     bool bCanBeRenamed = false;
    1696             :        try
    1697             :        {
    1698           0 :         uno::Reference< XResultSet > xResultSet;
    1699           0 :         Sequence< OUString > aProps( 1 );
    1700             : 
    1701           0 :         aProps[0] = TARGET_URL;
    1702           0 :         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
    1703           0 :         xResultSet = aGroup.createCursor( aProps, eInclude );
    1704             : 
    1705           0 :         if ( xResultSet.is() )
    1706             :         {
    1707           0 :                uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY_THROW );
    1708           0 :                uno::Reference< XRow > xRow( xResultSet, UNO_QUERY_THROW );
    1709             : 
    1710           0 :                while ( xResultSet->next() )
    1711             :                {
    1712           0 :                    OUString aTemplTargetURL( xRow->getString( 1 ) );
    1713             : 
    1714           0 :                 if ( !::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
    1715           0 :                     throw uno::Exception();
    1716           0 :             }
    1717             : 
    1718           0 :             bCanBeRenamed = true;
    1719           0 :         }
    1720             :     }
    1721           0 :     catch ( Exception& ) {}
    1722             : 
    1723           0 :     if ( bCanBeRenamed )
    1724             :     {
    1725           0 :         INetURLObject aGroupTargetObj( aGroupTargetURL );
    1726           0 :         OUString aFsysName = aGroupTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    1727             : 
    1728           0 :         if ( aGroupTargetObj.removeSegment()
    1729           0 :           && ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj.GetMainURL( INetURLObject::NO_DECODE ),
    1730             :                                                   aFsysName,
    1731             :                                                 rOldName,
    1732           0 :                                                 rNewName ) )
    1733             :         {
    1734             :             // rename the group in the hierarchy
    1735           0 :             OUString aTitleProp( TITLE  );
    1736           0 :             Any aTitleValue;
    1737           0 :             aTitleValue <<= rNewName;
    1738             : 
    1739           0 :             return setProperty( aGroup, aTitleProp, aTitleValue );
    1740           0 :         }
    1741             :     }
    1742             : 
    1743           0 :     return false;
    1744             : }
    1745             : 
    1746             : 
    1747           0 : bool SfxDocTplService_Impl::storeTemplate( const OUString& rGroupName,
    1748             :                                                const OUString& rTemplateName,
    1749             :                                                const uno::Reference< frame::XStorable >& rStorable )
    1750             : {
    1751           0 :     ::osl::MutexGuard aGuard( maMutex );
    1752             : 
    1753             :     // Check, whether or not there is a group with this name
    1754             :     // Return false, if there is no group with the given name
    1755           0 :     Content         aGroup, aTemplate, aTargetGroup, aTemplateToRemove;
    1756           0 :     OUString        aGroupURL, aTemplateURL, aTemplateToRemoveTargetURL;
    1757           0 :     INetURLObject   aGroupObj( maRootURL );
    1758           0 :     bool        bRemoveOldTemplateContent = false;
    1759           0 :     OUString sDocServiceName;
    1760             : 
    1761             :     aGroupObj.insertName( rGroupName, false,
    1762             :                       INetURLObject::LAST_SEGMENT, true,
    1763           0 :                       INetURLObject::ENCODE_ALL );
    1764           0 :     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1765             : 
    1766           0 :     if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1767           0 :         return false;
    1768             : 
    1769           0 :     OUString aGroupTargetURL;
    1770           0 :     OUString aPropName( TARGET_DIR_URL  );
    1771           0 :     Any      aValue;
    1772           0 :     if ( getProperty( aGroup, aPropName, aValue ) )
    1773           0 :         aValue >>= aGroupTargetURL;
    1774             : 
    1775             : 
    1776             :     // Check, if there's a template with the given name in this group
    1777             :     // the target template should be overwritten if it is imported by user
    1778             :     // in case the template is installed by office installation of by an add-in
    1779             :     // it can not be replaced
    1780             :     aGroupObj.insertName( rTemplateName, false,
    1781             :                       INetURLObject::LAST_SEGMENT, true,
    1782           0 :                       INetURLObject::ENCODE_ALL );
    1783           0 :     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1784             : 
    1785           0 :     if ( Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplateToRemove ) )
    1786             :     {
    1787           0 :         OUString    aTargetTemplPropName( TARGET_URL  );
    1788             : 
    1789           0 :         bRemoveOldTemplateContent = true;
    1790           0 :         if ( getProperty( aTemplateToRemove, aTargetTemplPropName, aValue ) )
    1791           0 :             aValue >>= aTemplateToRemoveTargetURL;
    1792             : 
    1793           0 :         if ( aGroupTargetURL.isEmpty() || !maTemplateDirs.getLength()
    1794           0 :           || (!aTemplateToRemoveTargetURL.isEmpty() && isInternalTemplateDir(aTemplateToRemoveTargetURL)) )
    1795           0 :             return false; // it is not allowed to remove the template
    1796             :     }
    1797             : 
    1798             :     try
    1799             :     {
    1800           0 :         uno::Reference< uno::XComponentContext > xContext = ::comphelper::getProcessComponentContext();
    1801             : 
    1802             :         // get document service name
    1803           0 :         uno::Reference< frame::XModuleManager2 > xModuleManager( frame::ModuleManager::create(xContext) );
    1804           0 :         sDocServiceName = xModuleManager->identify( uno::Reference< uno::XInterface >( rStorable, uno::UNO_QUERY ) );
    1805           0 :         if ( sDocServiceName.isEmpty() )
    1806           0 :             throw uno::RuntimeException();
    1807             : 
    1808             :         // get the actual filter name
    1809           0 :         OUString aFilterName;
    1810             : 
    1811             :         uno::Reference< lang::XMultiServiceFactory > xConfigProvider =
    1812           0 :                 configuration::theDefaultProvider::get( xContext );
    1813             : 
    1814           0 :         uno::Sequence< uno::Any > aArgs( 1 );
    1815           0 :         beans::PropertyValue aPathProp;
    1816           0 :         aPathProp.Name = "nodepath";
    1817           0 :         aPathProp.Value <<= OUString( "/org.openoffice.Setup/Office/Factories/"  );
    1818           0 :         aArgs[0] <<= aPathProp;
    1819             : 
    1820             :         uno::Reference< container::XNameAccess > xSOFConfig(
    1821           0 :             xConfigProvider->createInstanceWithArguments(
    1822             :                                     OUString("com.sun.star.configuration.ConfigurationAccess"),
    1823           0 :                                     aArgs ),
    1824           0 :             uno::UNO_QUERY_THROW );
    1825             : 
    1826           0 :         uno::Reference< container::XNameAccess > xApplConfig;
    1827           0 :         xSOFConfig->getByName( sDocServiceName ) >>= xApplConfig;
    1828           0 :         if ( !xApplConfig.is() )
    1829           0 :             throw uno::RuntimeException();
    1830             : 
    1831           0 :         xApplConfig->getByName("ooSetupFactoryActualTemplateFilter") >>= aFilterName;
    1832           0 :         if ( aFilterName.isEmpty() )
    1833           0 :             throw uno::RuntimeException();
    1834             : 
    1835             :         // find the related type name
    1836           0 :         OUString aTypeName;
    1837             :         uno::Reference< container::XNameAccess > xFilterFactory(
    1838           0 :             mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.FilterFactory", mxContext),
    1839           0 :             uno::UNO_QUERY_THROW );
    1840             : 
    1841           0 :         uno::Sequence< beans::PropertyValue > aFilterData;
    1842           0 :         xFilterFactory->getByName( aFilterName ) >>= aFilterData;
    1843           0 :         for ( sal_Int32 nInd = 0; nInd < aFilterData.getLength(); nInd++ )
    1844           0 :             if ( aFilterData[nInd].Name == "Type" )
    1845           0 :                 aFilterData[nInd].Value >>= aTypeName;
    1846             : 
    1847           0 :         if ( aTypeName.isEmpty() )
    1848           0 :             throw uno::RuntimeException();
    1849             : 
    1850             :         // find the mediatype and extension
    1851           0 :         uno::Reference< container::XNameAccess > xTypeDetection;
    1852             : 
    1853           0 :         xTypeDetection =
    1854           0 :             mxType.is() ?
    1855             :                 uno::Reference< container::XNameAccess >( mxType, uno::UNO_QUERY_THROW ) :
    1856             :                 uno::Reference< container::XNameAccess >(
    1857           0 :                     mxContext->getServiceManager()->createInstanceWithContext("com.sun.star.document.TypeDetection", mxContext),
    1858           0 :                     uno::UNO_QUERY_THROW );
    1859             : 
    1860           0 :         SequenceAsHashMap aTypeProps( xTypeDetection->getByName( aTypeName ) );
    1861             :         uno::Sequence< OUString > aAllExt =
    1862           0 :             aTypeProps.getUnpackedValueOrDefault("Extensions", Sequence< OUString >() );
    1863           0 :         if ( !aAllExt.getLength() )
    1864           0 :             throw uno::RuntimeException();
    1865             : 
    1866           0 :         OUString aMediaType = aTypeProps.getUnpackedValueOrDefault("MediaType", OUString() );
    1867           0 :         OUString aExt = aAllExt[0];
    1868             : 
    1869           0 :         if ( aMediaType.isEmpty() || aExt.isEmpty() )
    1870           0 :             throw uno::RuntimeException();
    1871             : 
    1872             :         // construct destination url
    1873           0 :         if ( aGroupTargetURL.isEmpty() )
    1874             :         {
    1875           0 :             aGroupTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
    1876             : 
    1877           0 :             if ( aGroupTargetURL.isEmpty() )
    1878           0 :                 throw uno::RuntimeException();
    1879             :         }
    1880             : 
    1881           0 :         OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, rTemplateName, aExt );
    1882           0 :         if ( aNewTemplateTargetURL.isEmpty() )
    1883             :         {
    1884           0 :             aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aGroupTargetURL, OUString( "UserTemplate"  ), aExt );
    1885             : 
    1886           0 :             if ( aNewTemplateTargetURL.isEmpty() )
    1887           0 :                 throw uno::RuntimeException();
    1888             :         }
    1889             : 
    1890             :         // store template
    1891           0 :         uno::Sequence< PropertyValue > aStoreArgs( 2 );
    1892           0 :         aStoreArgs[0].Name = "FilterName";
    1893           0 :         aStoreArgs[0].Value <<= aFilterName;
    1894           0 :         aStoreArgs[1].Name = "DocumentTitle";
    1895           0 :         aStoreArgs[1].Value <<= rTemplateName;
    1896             : 
    1897           0 :         if( !::utl::UCBContentHelper::EqualURLs( aNewTemplateTargetURL, rStorable->getLocation() ))
    1898           0 :             rStorable->storeToURL( aNewTemplateTargetURL, aStoreArgs );
    1899             :         else
    1900           0 :             rStorable->store();
    1901             : 
    1902             :         // the storing was successful, now the old template with the same name can be removed if it existed
    1903           0 :         if ( !aTemplateToRemoveTargetURL.isEmpty() )
    1904             :         {
    1905           0 :             removeContent( aTemplateToRemoveTargetURL );
    1906             : 
    1907             :             /*
    1908             :              * pb: #i79496#
    1909             :              * if the old template was the standard template
    1910             :              * it is necessary to change the standard template with the new file name
    1911             :              */
    1912           0 :             OUString sStdTmplFile = SfxObjectFactory::GetStandardTemplate( sDocServiceName );
    1913           0 :             if ( INetURLObject( sStdTmplFile ) == INetURLObject( aTemplateToRemoveTargetURL ) )
    1914             :             {
    1915           0 :                 SfxObjectFactory::SetStandardTemplate( sDocServiceName, aNewTemplateTargetURL );
    1916           0 :             }
    1917             :         }
    1918             : 
    1919           0 :         if ( bRemoveOldTemplateContent )
    1920           0 :             removeContent( aTemplateToRemove );
    1921             : 
    1922             :         // add the template to hierarchy
    1923           0 :         return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aMediaType );
    1924             :     }
    1925           0 :     catch( Exception& )
    1926             :     {
    1927             :         // the template was not stored
    1928           0 :         return false;
    1929           0 :     }
    1930             : }
    1931             : 
    1932             : 
    1933           0 : bool SfxDocTplService_Impl::addTemplate( const OUString& rGroupName,
    1934             :                                              const OUString& rTemplateName,
    1935             :                                              const OUString& rSourceURL )
    1936             : {
    1937           0 :     ::osl::MutexGuard aGuard( maMutex );
    1938             : 
    1939             :     // Check, whether or not there is a group with this name
    1940             :     // Return false, if there is no group with the given name
    1941           0 :     Content         aGroup, aTemplate, aTargetGroup;
    1942           0 :     OUString        aGroupURL, aTemplateURL;
    1943           0 :     INetURLObject   aGroupObj( maRootURL );
    1944             : 
    1945             :     aGroupObj.insertName( rGroupName, false,
    1946             :                       INetURLObject::LAST_SEGMENT, true,
    1947           0 :                       INetURLObject::ENCODE_ALL );
    1948           0 :     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1949             : 
    1950           0 :     if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    1951           0 :         return false;
    1952             : 
    1953             :     // Check, if there's a template with the given name in this group
    1954             :     // Return false, if there already is a template
    1955             :     aGroupObj.insertName( rTemplateName, false,
    1956             :                       INetURLObject::LAST_SEGMENT, true,
    1957           0 :                       INetURLObject::ENCODE_ALL );
    1958           0 :     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    1959             : 
    1960           0 :     if ( Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    1961           0 :         return false;
    1962             : 
    1963             :     // get the target url of the group
    1964           0 :     OUString    aTargetURL;
    1965           0 :     OUString    aPropName( TARGET_DIR_URL  );
    1966           0 :     Any         aValue;
    1967             : 
    1968           0 :     if ( getProperty( aGroup, aPropName, aValue ) )
    1969           0 :         aValue >>= aTargetURL;
    1970             : 
    1971           0 :     if ( aTargetURL.isEmpty() )
    1972             :     {
    1973           0 :         aTargetURL = CreateNewGroupFsys( rGroupName, aGroup );
    1974             : 
    1975           0 :         if ( aTargetURL.isEmpty() )
    1976           0 :             return false;
    1977             :     }
    1978             : 
    1979             :     // Get the content type
    1980           0 :     OUString aTitle, aType, aTargetURL2;
    1981             : 
    1982           0 :     bool bDocHasTitle = false;
    1983           0 :     if( !getTitleFromURL( rSourceURL, aTitle, aType, bDocHasTitle ) )
    1984           0 :         return false;
    1985             : 
    1986           0 :     INetURLObject   aSourceObj( rSourceURL );
    1987           0 :     if ( rTemplateName.equals( aTitle ) )
    1988             :     {
    1989             :         // addTemplate will sometimes be called just to add an entry in the
    1990             :         // hierarchy; the target URL and the source URL will be the same in
    1991             :         // this scenario
    1992             :         // TODO/LATER: get rid of this old hack
    1993             : 
    1994           0 :         INetURLObject   aTargetObj( aTargetURL );
    1995             : 
    1996             :         aTargetObj.insertName( rTemplateName, false,
    1997             :                       INetURLObject::LAST_SEGMENT, true,
    1998           0 :                       INetURLObject::ENCODE_ALL );
    1999           0 :         aTargetObj.setExtension( aSourceObj.getExtension() );
    2000             : 
    2001           0 :         aTargetURL2 = aTargetObj.GetMainURL( INetURLObject::NO_DECODE );
    2002             : 
    2003           0 :         if ( aTargetURL2 == rSourceURL )
    2004           0 :             return addEntry( aGroup, rTemplateName, aTargetURL2, aType );
    2005             :     }
    2006             : 
    2007             :     // copy the template into the new group (targeturl)
    2008             : 
    2009           0 :     INetURLObject aTmpURL( aSourceObj );
    2010           0 :     aTmpURL.CutExtension();
    2011           0 :     OUString aPattern = aTmpURL.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    2012             : 
    2013           0 :     OUString aNewTemplateTargetURL = CreateNewUniqueFileWithPrefix( aTargetURL, aPattern, aSourceObj.getExtension() );
    2014           0 :     INetURLObject aNewTemplateTargetObj( aNewTemplateTargetURL );
    2015           0 :     OUString aNewTemplateTargetName = aNewTemplateTargetObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET );
    2016           0 :     if ( aNewTemplateTargetURL.isEmpty() || aNewTemplateTargetName.isEmpty() )
    2017           0 :         return false;
    2018             : 
    2019             :     // get access to source file
    2020           0 :     Content aSourceContent;
    2021           0 :     uno::Reference < ucb::XCommandEnvironment > xEnv;
    2022           0 :     INetURLObject   aSourceURL( rSourceURL );
    2023           0 :     if( ! Content::create( aSourceURL.GetMainURL( INetURLObject::NO_DECODE ), xEnv, comphelper::getProcessComponentContext(), aSourceContent ) )
    2024           0 :         return false;
    2025             : 
    2026           0 :     if( ! Content::create( aTargetURL, xEnv, comphelper::getProcessComponentContext(), aTargetGroup ) )
    2027           0 :         return false;
    2028             : 
    2029             :     // transfer source file
    2030             :     try
    2031             :     {
    2032           0 :         if( ! aTargetGroup.transferContent( aSourceContent,
    2033             :                                                 InsertOperation_COPY,
    2034             :                                                 aNewTemplateTargetName,
    2035             :                                                 NameClash::OVERWRITE,
    2036           0 :                                                 aType ) )
    2037           0 :             return false;
    2038             : 
    2039             :         // allow to edit the added template
    2040           0 :         Content aResultContent;
    2041           0 :         if ( Content::create( aNewTemplateTargetURL, xEnv, comphelper::getProcessComponentContext(), aResultContent ) )
    2042             :         {
    2043           0 :             OUString aPropertyName( "IsReadOnly"  );
    2044           0 :             uno::Any aProperty;
    2045           0 :             bool bReadOnly = false;
    2046           0 :             if ( getProperty( aResultContent, aPropertyName, aProperty ) && ( aProperty >>= bReadOnly ) && bReadOnly )
    2047           0 :                 setProperty( aResultContent, aPropertyName, uno::makeAny( false ) );
    2048           0 :         }
    2049             :     }
    2050           0 :     catch ( ContentCreationException& )
    2051           0 :     { return false; }
    2052           0 :     catch ( Exception& )
    2053           0 :     { return false; }
    2054             : 
    2055             : 
    2056             :     // either the document has title and it is the same as requested, or we have to set it
    2057           0 :     bool bCorrectTitle = ( bDocHasTitle && aTitle.equals( rTemplateName ) );
    2058           0 :     if ( !bCorrectTitle )
    2059             :     {
    2060           0 :         if ( !bDocHasTitle )
    2061             :         {
    2062           0 :             INetURLObject aNewTmpObj( aNewTemplateTargetObj );
    2063           0 :             aNewTmpObj.CutExtension();
    2064           0 :             bCorrectTitle = ( aNewTmpObj.getName( INetURLObject::LAST_SEGMENT, true, INetURLObject::DECODE_WITH_CHARSET ).equals( rTemplateName ) );
    2065             :         }
    2066             : 
    2067           0 :         if ( !bCorrectTitle )
    2068           0 :             bCorrectTitle = setTitleForURL( aNewTemplateTargetURL, rTemplateName );
    2069             :     }
    2070             : 
    2071           0 :     if ( bCorrectTitle )
    2072             :     {
    2073             :         // create a new entry in the hierarchy
    2074           0 :         return addEntry( aGroup, rTemplateName, aNewTemplateTargetURL, aType );
    2075             :     }
    2076             : 
    2077             :     // TODO/LATER: The user could be notified here that the renaming has failed
    2078             :     // create a new entry in the hierarchy
    2079           0 :     addEntry( aGroup, aTitle, aNewTemplateTargetURL, aType );
    2080           0 :     return false;
    2081             : }
    2082             : 
    2083           0 : bool SfxDocTplService_Impl::isInternalTemplateDir(const OUString& rURL) const
    2084             : {
    2085           0 :     const sal_Int32 nDirs = maInternalTemplateDirs.getLength();
    2086           0 :     const OUString* pDirs = maInternalTemplateDirs.getConstArray();
    2087           0 :     for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs)
    2088             :     {
    2089           0 :         if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL))
    2090           0 :             return true;
    2091             :     }
    2092           0 :     return false;
    2093             : }
    2094             : 
    2095           0 : OUString SfxDocTplService_Impl::findParentTemplateDir(const OUString& rURL) const
    2096             : {
    2097           0 :     const sal_Int32 nDirs = maTemplateDirs.getLength();
    2098           0 :     const OUString* pDirs = maTemplateDirs.getConstArray();
    2099           0 :     for (sal_Int32 i = 0; i < nDirs; ++i, ++pDirs)
    2100             :     {
    2101           0 :         if (::utl::UCBContentHelper::IsSubPath(*pDirs, rURL))
    2102           0 :             return *pDirs;
    2103             :     }
    2104           0 :     return OUString();
    2105             : }
    2106             : 
    2107           0 : bool SfxDocTplService_Impl::removeTemplate( const OUString& rGroupName,
    2108             :                                                 const OUString& rTemplateName )
    2109             : {
    2110           0 :     ::osl::MutexGuard aGuard( maMutex );
    2111             : 
    2112             :     // Check, whether or not there is a group with this name
    2113             :     // Return false, if there is no group with the given name
    2114           0 :     Content         aGroup, aTemplate;
    2115           0 :     OUString        aGroupURL, aTemplateURL;
    2116           0 :     INetURLObject   aGroupObj( maRootURL );
    2117             : 
    2118             :     aGroupObj.insertName( rGroupName, false,
    2119             :                       INetURLObject::LAST_SEGMENT, true,
    2120           0 :                       INetURLObject::ENCODE_ALL );
    2121           0 :     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2122             : 
    2123           0 :     if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    2124           0 :         return false;
    2125             : 
    2126             :     // Check, if there's a template with the given name in this group
    2127             :     // Return false, if there is no template
    2128             :     aGroupObj.insertName( rTemplateName, false,
    2129             :                       INetURLObject::LAST_SEGMENT, true,
    2130           0 :                       INetURLObject::ENCODE_ALL );
    2131           0 :     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2132             : 
    2133           0 :     if ( !Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2134           0 :         return false;
    2135             : 
    2136             :     // get the target URL from the template
    2137           0 :     OUString    aTargetURL;
    2138           0 :     OUString    aPropName( TARGET_URL  );
    2139           0 :     Any         aValue;
    2140             : 
    2141           0 :     if ( getProperty( aTemplate, aPropName, aValue ) )
    2142           0 :         aValue >>= aTargetURL;
    2143             : 
    2144             :     // delete the target template
    2145           0 :     if ( !aTargetURL.isEmpty() )
    2146             :     {
    2147           0 :         if (isInternalTemplateDir(aTargetURL))
    2148           0 :             return false;
    2149             : 
    2150           0 :         removeContent( aTargetURL );
    2151             :     }
    2152             : 
    2153             :     // delete the template entry
    2154           0 :     return removeContent( aTemplate );
    2155             : }
    2156             : 
    2157             : 
    2158           0 : bool SfxDocTplService_Impl::renameTemplate( const OUString& rGroupName,
    2159             :                                                 const OUString& rOldName,
    2160             :                                                 const OUString& rNewName )
    2161             : {
    2162           0 :     ::osl::MutexGuard aGuard( maMutex );
    2163             : 
    2164             :     // Check, whether or not there is a group with this name
    2165             :     // Return false, if there is no group with the given name
    2166           0 :     Content         aGroup, aTemplate;
    2167           0 :     OUString        aGroupURL, aTemplateURL;
    2168           0 :     INetURLObject   aGroupObj( maRootURL );
    2169             : 
    2170             :     aGroupObj.insertName( rGroupName, false,
    2171             :                       INetURLObject::LAST_SEGMENT, true,
    2172           0 :                       INetURLObject::ENCODE_ALL );
    2173           0 :     aGroupURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2174             : 
    2175           0 :     if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    2176           0 :         return false;
    2177             : 
    2178             :     // Check, if there's a template with the new name in this group
    2179             :     // Return false, if there is one
    2180             :     aGroupObj.insertName( rNewName, false,
    2181             :                       INetURLObject::LAST_SEGMENT, true,
    2182           0 :                       INetURLObject::ENCODE_ALL );
    2183           0 :     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2184             : 
    2185           0 :     if ( Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2186           0 :         return false;
    2187             : 
    2188             :     // Check, if there's a template with the old name in this group
    2189             :     // Return false, if there is no template
    2190           0 :     aGroupObj.removeSegment();
    2191             :     aGroupObj.insertName( rOldName, false,
    2192             :                       INetURLObject::LAST_SEGMENT, true,
    2193           0 :                       INetURLObject::ENCODE_ALL );
    2194           0 :     aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2195             : 
    2196           0 :     if ( !Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2197           0 :         return false;
    2198             : 
    2199           0 :     OUString    aTemplateTargetURL;
    2200           0 :     OUString    aTargetProp( TARGET_URL  );
    2201           0 :     Any         aTargetValue;
    2202             : 
    2203           0 :     if ( getProperty( aTemplate, aTargetProp, aTargetValue ) )
    2204           0 :         aTargetValue >>= aTemplateTargetURL;
    2205             : 
    2206           0 :     if ( !setTitleForURL( aTemplateTargetURL, rNewName ) )
    2207           0 :         return false;
    2208             : 
    2209             :     // rename the template entry in the cache
    2210           0 :     OUString    aTitleProp( TITLE  );
    2211           0 :     Any         aTitleValue;
    2212           0 :     aTitleValue <<= rNewName;
    2213             : 
    2214           0 :     return setProperty( aTemplate, aTitleProp, aTitleValue );
    2215             : }
    2216             : 
    2217             : 
    2218             : class SfxDocTplService: public ::cppu::WeakImplHelper3< css::lang::XLocalizable, css::frame::XDocumentTemplates, css::lang::XServiceInfo >
    2219             : {
    2220             :     SfxDocTplService_Impl       *pImp;
    2221             : 
    2222             : public:
    2223             :     SfxDocTplService( const css::uno::Reference < uno::XComponentContext >& xContext );
    2224             :     virtual ~SfxDocTplService();
    2225             : 
    2226           0 :     virtual OUString SAL_CALL getImplementationName()
    2227             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    2228             :     {
    2229           0 :         return OUString("com.sun.star.comp.sfx2.DocumentTemplates");
    2230             :     }
    2231             : 
    2232           0 :     virtual sal_Bool SAL_CALL supportsService(OUString const & ServiceName)
    2233             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    2234             :     {
    2235           0 :         return cppu::supportsService(this, ServiceName);
    2236             :     }
    2237             : 
    2238           0 :     virtual css::uno::Sequence<OUString> SAL_CALL getSupportedServiceNames()
    2239             :         throw (css::uno::RuntimeException, std::exception) SAL_OVERRIDE
    2240             :     {
    2241           0 :         css::uno::Sequence< OUString > aSeq(1);
    2242           0 :         aSeq[0] = OUString("com.sun.star.frame.DocumentTemplates");
    2243           0 :         return aSeq;
    2244             :     }
    2245             : 
    2246             : 
    2247             :     // --- XLocalizable ---
    2248             :     void SAL_CALL                   setLocale( const css::lang::Locale & eLocale ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2249             :     css::lang::Locale SAL_CALL              getLocale() throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2250             : 
    2251             :     // --- XDocumentTemplates ---
    2252             :     css::uno::Reference< css::ucb::XContent > SAL_CALL  getContent() throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2253             :     sal_Bool SAL_CALL               storeTemplate( const OUString& GroupName,
    2254             :                                                    const OUString& TemplateName,
    2255             :                                                    const css::uno::Reference< css::frame::XStorable >& Storable ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2256             :     sal_Bool SAL_CALL               addTemplate( const OUString& GroupName,
    2257             :                                                  const OUString& TemplateName,
    2258             :                                                  const OUString& SourceURL ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2259             :     sal_Bool SAL_CALL               removeTemplate( const OUString& GroupName,
    2260             :                                                     const OUString& TemplateName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2261             :     sal_Bool SAL_CALL               renameTemplate( const OUString& GroupName,
    2262             :                                                     const OUString& OldTemplateName,
    2263             :                                                     const OUString& NewTemplateName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2264             :     sal_Bool SAL_CALL               addGroup( const OUString& GroupName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2265             :     sal_Bool SAL_CALL               removeGroup( const OUString& GroupName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2266             :     sal_Bool SAL_CALL               renameGroup( const OUString& OldGroupName,
    2267             :                                                  const OUString& NewGroupName ) throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2268             :     void SAL_CALL                   update() throw( css::uno::RuntimeException, std::exception ) SAL_OVERRIDE;
    2269             : };
    2270             : 
    2271             : 
    2272           0 : SfxDocTplService::SfxDocTplService( const uno::Reference< XComponentContext >& xContext )
    2273             : {
    2274           0 :     pImp = new SfxDocTplService_Impl(xContext);
    2275           0 : }
    2276             : 
    2277             : 
    2278             : 
    2279           0 : SfxDocTplService::~SfxDocTplService()
    2280             : {
    2281           0 :     delete pImp;
    2282           0 : }
    2283             : 
    2284             : 
    2285             : //--- XLocalizable ---
    2286             : 
    2287             : 
    2288           0 : Locale SAL_CALL SfxDocTplService::getLocale()
    2289             :     throw( uno::RuntimeException, std::exception )
    2290             : {
    2291           0 :     return pImp->getLocale();
    2292             : }
    2293             : 
    2294             : 
    2295             : 
    2296           0 : void SAL_CALL SfxDocTplService::setLocale( const Locale & rLocale )
    2297             :     throw( uno::RuntimeException, std::exception )
    2298             : {
    2299           0 :     pImp->setLocale( rLocale );
    2300           0 : }
    2301             : 
    2302             : 
    2303             : //--- XDocumentTemplates ---
    2304             : 
    2305           0 : uno::Reference< ucb::XContent > SAL_CALL SfxDocTplService::getContent()
    2306             :     throw( uno::RuntimeException, std::exception )
    2307             : {
    2308           0 :     if ( pImp->init() )
    2309           0 :         return pImp->getContent().get();
    2310             :     else
    2311           0 :         return NULL;
    2312             : }
    2313             : 
    2314             : 
    2315           0 : sal_Bool SAL_CALL SfxDocTplService::storeTemplate( const OUString& GroupName,
    2316             :                                                    const OUString& TemplateName,
    2317             :                                                    const uno::Reference< frame::XStorable >& Storable )
    2318             :     throw( uno::RuntimeException, std::exception )
    2319             : {
    2320           0 :     if ( pImp->init() )
    2321           0 :         return pImp->storeTemplate( GroupName, TemplateName, Storable );
    2322             :     else
    2323           0 :         return sal_False;
    2324             : }
    2325             : 
    2326             : 
    2327           0 : sal_Bool SAL_CALL SfxDocTplService::addTemplate( const OUString& rGroupName,
    2328             :                                                  const OUString& rTemplateName,
    2329             :                                                  const OUString& rSourceURL )
    2330             :     throw( uno::RuntimeException, std::exception )
    2331             : {
    2332           0 :     if ( pImp->init() )
    2333           0 :         return pImp->addTemplate( rGroupName, rTemplateName, rSourceURL );
    2334             :     else
    2335           0 :         return sal_False;
    2336             : }
    2337             : 
    2338             : 
    2339           0 : sal_Bool SAL_CALL SfxDocTplService::removeTemplate( const OUString& rGroupName,
    2340             :                                                     const OUString& rTemplateName )
    2341             :     throw( uno::RuntimeException, std::exception )
    2342             : {
    2343           0 :     if ( pImp->init() )
    2344           0 :         return pImp->removeTemplate( rGroupName, rTemplateName );
    2345             :     else
    2346           0 :         return sal_False;
    2347             : }
    2348             : 
    2349             : 
    2350           0 : sal_Bool SAL_CALL SfxDocTplService::renameTemplate( const OUString& rGroupName,
    2351             :                                                     const OUString& rOldName,
    2352             :                                                     const OUString& rNewName )
    2353             :     throw( uno::RuntimeException, std::exception )
    2354             : {
    2355           0 :     if ( rOldName == rNewName )
    2356           0 :         return sal_True;
    2357             : 
    2358           0 :     if ( pImp->init() )
    2359           0 :         return pImp->renameTemplate( rGroupName, rOldName, rNewName );
    2360             :     else
    2361           0 :         return sal_False;
    2362             : }
    2363             : 
    2364             : 
    2365           0 : sal_Bool SAL_CALL SfxDocTplService::addGroup( const OUString& rGroupName )
    2366             :     throw( uno::RuntimeException, std::exception )
    2367             : {
    2368           0 :     if ( pImp->init() )
    2369           0 :         return pImp->addGroup( rGroupName );
    2370             :     else
    2371           0 :         return sal_False;
    2372             : }
    2373             : 
    2374             : 
    2375           0 : sal_Bool SAL_CALL SfxDocTplService::removeGroup( const OUString& rGroupName )
    2376             :     throw( uno::RuntimeException, std::exception )
    2377             : {
    2378           0 :     if ( pImp->init() )
    2379           0 :         return pImp->removeGroup( rGroupName );
    2380             :     else
    2381           0 :         return sal_False;
    2382             : }
    2383             : 
    2384             : 
    2385           0 : sal_Bool SAL_CALL SfxDocTplService::renameGroup( const OUString& rOldName,
    2386             :                                                  const OUString& rNewName )
    2387             :     throw( uno::RuntimeException, std::exception )
    2388             : {
    2389           0 :     if ( rOldName == rNewName )
    2390           0 :         return sal_True;
    2391             : 
    2392           0 :     if ( pImp->init() )
    2393           0 :         return pImp->renameGroup( rOldName, rNewName );
    2394             :     else
    2395           0 :         return sal_False;
    2396             : }
    2397             : 
    2398             : 
    2399           0 : void SAL_CALL SfxDocTplService::update()
    2400             :     throw( uno::RuntimeException, std::exception )
    2401             : {
    2402           0 :     if ( pImp->init() )
    2403           0 :         pImp->update( true );
    2404           0 : }
    2405             : 
    2406             : 
    2407             : 
    2408           0 : Updater_Impl::Updater_Impl( SfxDocTplService_Impl* pTemplates )
    2409             : {
    2410           0 :     mpDocTemplates = pTemplates;
    2411           0 : }
    2412             : 
    2413             : 
    2414           0 : Updater_Impl::~Updater_Impl()
    2415             : {
    2416           0 : }
    2417             : 
    2418             : 
    2419           0 : void SAL_CALL Updater_Impl::run()
    2420             : {
    2421           0 :     mpDocTemplates->doUpdate();
    2422           0 : }
    2423             : 
    2424             : 
    2425           0 : void SAL_CALL Updater_Impl::onTerminated()
    2426             : {
    2427           0 :     mpDocTemplates->finished();
    2428           0 :     delete this;
    2429           0 : }
    2430             : 
    2431             : 
    2432           0 : WaitWindow_Impl::WaitWindow_Impl()
    2433           0 :     : WorkWindow( NULL, WB_BORDER | WB_3DLOOK )
    2434             : {
    2435           0 :     Rectangle aRect = Rectangle( 0, 0, 300, 30000 );
    2436           0 :     _nTextStyle = TEXT_DRAW_CENTER | TEXT_DRAW_VCENTER | TEXT_DRAW_WORDBREAK | TEXT_DRAW_MULTILINE;
    2437           0 :     _aText = SfxResId( RID_CNT_STR_WAITING ).toString();
    2438           0 :     _aRect = GetTextRect( aRect, _aText, _nTextStyle );
    2439           0 :     aRect = _aRect;
    2440           0 :     aRect.Right() += 2*X_OFFSET;
    2441           0 :     aRect.Bottom() += 2*Y_OFFSET;
    2442           0 :     _aRect.SetPos( Point( X_OFFSET, Y_OFFSET ) );
    2443           0 :     SetOutputSizePixel( aRect.GetSize() );
    2444           0 :     Show();
    2445           0 :     Update();
    2446           0 :     Flush();
    2447           0 : }
    2448             : 
    2449             : 
    2450           0 : WaitWindow_Impl::~WaitWindow_Impl()
    2451             : {
    2452           0 :     Hide();
    2453           0 : }
    2454             : 
    2455             : 
    2456           0 : void WaitWindow_Impl::Paint( const Rectangle& /*rRect*/ )
    2457             : {
    2458           0 :     DrawText( _aRect, _aText, _nTextStyle );
    2459           0 : }
    2460             : 
    2461             : 
    2462           0 : void SfxDocTplService_Impl::addHierGroup( GroupList_Impl& rList,
    2463             :                                           const OUString& rTitle,
    2464             :                                           const OUString& rOwnURL )
    2465             : {
    2466             :     // now get the content of the Group
    2467           0 :     Content                 aContent;
    2468           0 :     uno::Reference< XResultSet > xResultSet;
    2469           0 :     Sequence< OUString >    aProps(3);
    2470             : 
    2471           0 :     aProps[0] = TITLE ;
    2472           0 :     aProps[1] = TARGET_URL;
    2473           0 :     aProps[2] = PROPERTY_TYPE;
    2474             : 
    2475             :     try
    2476             :     {
    2477           0 :         aContent = Content( rOwnURL, maCmdEnv, comphelper::getProcessComponentContext() );
    2478           0 :         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
    2479           0 :         xResultSet = aContent.createCursor( aProps, eInclude );
    2480             :     }
    2481           0 :     catch ( ContentCreationException& )
    2482             :     {
    2483             :         SAL_WARN( "sfx.doc", "addHierGroup: ContentCreationException" );
    2484             :     }
    2485           0 :     catch ( Exception& ) {}
    2486             : 
    2487           0 :     if ( xResultSet.is() )
    2488             :     {
    2489           0 :         GroupData_Impl *pGroup = new GroupData_Impl( rTitle );
    2490           0 :         pGroup->setHierarchy( true );
    2491           0 :         pGroup->setHierarchyURL( rOwnURL );
    2492           0 :         rList.push_back( pGroup );
    2493             : 
    2494           0 :         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
    2495           0 :         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
    2496             : 
    2497             :         try
    2498             :         {
    2499           0 :             while ( xResultSet->next() )
    2500             :             {
    2501           0 :                 bool             bUpdateType = false;
    2502             :                 DocTemplates_EntryData_Impl  *pData;
    2503             : 
    2504           0 :                 OUString aTitle( xRow->getString( 1 ) );
    2505           0 :                 OUString aTargetDir( xRow->getString( 2 ) );
    2506           0 :                 OUString aType( xRow->getString( 3 ) );
    2507           0 :                 OUString aHierURL = xContentAccess->queryContentIdentifierString();
    2508             : 
    2509           0 :                 if ( aType.isEmpty() )
    2510             :                 {
    2511           0 :                     OUString aTmpTitle;
    2512             : 
    2513           0 :                     bool bDocHasTitle = false;
    2514           0 :                     if( !getTitleFromURL( aTargetDir, aTmpTitle, aType, bDocHasTitle ) )
    2515             :                     {
    2516             :                         SAL_WARN( "sfx.doc", "addHierGroup(): template of alien format" );
    2517           0 :                         continue;
    2518             :                     }
    2519             : 
    2520           0 :                     if ( !aType.isEmpty() )
    2521           0 :                         bUpdateType = true;
    2522             :                 }
    2523             : 
    2524           0 :                 pData = pGroup->addEntry( aTitle, aTargetDir, aType, aHierURL );
    2525           0 :                 pData->setUpdateType( bUpdateType );
    2526           0 :             }
    2527             :         }
    2528           0 :         catch ( Exception& ) {}
    2529           0 :     }
    2530           0 : }
    2531             : 
    2532             : 
    2533           0 : void SfxDocTplService_Impl::addFsysGroup( GroupList_Impl& rList,
    2534             :                                           const OUString& rTitle,
    2535             :                                           const OUString& rUITitle,
    2536             :                                           const OUString& rOwnURL,
    2537             :                                           bool bWriteableGroup )
    2538             : {
    2539           0 :     OUString aTitle;
    2540             : 
    2541           0 :     if ( rUITitle.isEmpty() )
    2542             :     {
    2543             :         // reserved FS names that should not be used
    2544           0 :         if ( rTitle.equalsAscii( "wizard" ) )
    2545           0 :             return;
    2546           0 :         else if ( rTitle.equalsAscii( "internal" ) )
    2547           0 :             return;
    2548             : 
    2549           0 :         aTitle = getLongName( rTitle );
    2550             :     }
    2551             :     else
    2552           0 :         aTitle = rUITitle;
    2553             : 
    2554           0 :     if ( aTitle.isEmpty() )
    2555           0 :         return;
    2556             : 
    2557           0 :     GroupData_Impl* pGroup = NULL;
    2558           0 :     for ( size_t i = 0, n = rList.size(); i < n; ++i )
    2559             :     {
    2560           0 :         if ( rList[ i ]->getTitle() == aTitle )
    2561             :         {
    2562           0 :             pGroup = rList[ i ];
    2563           0 :             break;
    2564             :         }
    2565             :     }
    2566             : 
    2567           0 :     if ( !pGroup )
    2568             :     {
    2569           0 :         pGroup = new GroupData_Impl( aTitle );
    2570           0 :         rList.push_back( pGroup );
    2571             :     }
    2572             : 
    2573           0 :     if ( bWriteableGroup )
    2574           0 :         pGroup->setTargetURL( rOwnURL );
    2575             : 
    2576           0 :     pGroup->setInUse();
    2577             : 
    2578             :     // now get the content of the Group
    2579           0 :     Content                 aContent;
    2580           0 :     uno::Reference< XResultSet > xResultSet;
    2581           0 :     Sequence< OUString >    aProps(1);
    2582           0 :     aProps[0] = TITLE;
    2583             : 
    2584             :     try
    2585             :     {
    2586             :         // this method is only used during checking of the available template-folders
    2587             :         // that should happen quietly
    2588           0 :         uno::Reference< XCommandEnvironment > aQuietEnv;
    2589           0 :         aContent = Content( rOwnURL, aQuietEnv, comphelper::getProcessComponentContext() );
    2590           0 :         ResultSetInclude eInclude = INCLUDE_DOCUMENTS_ONLY;
    2591           0 :         xResultSet = aContent.createCursor( aProps, eInclude );
    2592             :     }
    2593           0 :     catch ( Exception& ) {}
    2594             : 
    2595           0 :     if ( xResultSet.is() )
    2596             :     {
    2597           0 :         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
    2598           0 :         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
    2599             : 
    2600             :         try
    2601             :         {
    2602           0 :             while ( xResultSet->next() )
    2603             :             {
    2604           0 :                 OUString aChildTitle( xRow->getString( 1 ) );
    2605           0 :                 OUString aTargetURL = xContentAccess->queryContentIdentifierString();
    2606           0 :                 OUString aType;
    2607           0 :                 OUString aHierURL;
    2608             : 
    2609           0 :                 if ( aChildTitle.equalsAscii( "sfx.tlx" ) || aChildTitle == "groupuinames.xml" )
    2610           0 :                     continue;
    2611             : 
    2612           0 :                 bool bDocHasTitle = false;
    2613           0 :                 if( !getTitleFromURL( aTargetURL, aChildTitle, aType, bDocHasTitle ) )
    2614           0 :                     continue;
    2615             : 
    2616           0 :                 pGroup->addEntry( aChildTitle, aTargetURL, aType, aHierURL );
    2617           0 :             }
    2618             :         }
    2619           0 :         catch ( Exception& ) {}
    2620           0 :     }
    2621             : }
    2622             : 
    2623             : 
    2624           0 : void SfxDocTplService_Impl::createFromContent( GroupList_Impl& rList,
    2625             :                                                Content &rContent,
    2626             :                                                bool bHierarchy,
    2627             :                                                bool bWriteableContent )
    2628             : {
    2629           0 :     OUString aTargetURL = rContent.get()->getIdentifier()->getContentIdentifier();
    2630             : 
    2631             :     // when scanning the file system, we have to add the 'standard' group, too
    2632           0 :     if ( ! bHierarchy )
    2633             :     {
    2634           0 :         OUString aUIStdTitle = getLongName( OUString( STANDARD_FOLDER  ) );
    2635           0 :         addFsysGroup( rList, OUString(), aUIStdTitle, aTargetURL, bWriteableContent );
    2636             :     }
    2637             : 
    2638             :     // search for predefined UI names
    2639           0 :     INetURLObject aLayerObj( aTargetURL );
    2640             : 
    2641             :     // TODO/LATER: Use hashmap in future
    2642           0 :     uno::Sequence< beans::StringPair > aUINames;
    2643           0 :     if ( !bHierarchy )
    2644           0 :         aUINames = ReadUINamesForTemplateDir_Impl( aLayerObj.GetMainURL( INetURLObject::NO_DECODE ) );
    2645             : 
    2646           0 :     uno::Reference< XResultSet > xResultSet;
    2647           0 :     Sequence< OUString > aProps(1);
    2648           0 :     aProps[0] = TITLE;
    2649             : 
    2650             :     try
    2651             :     {
    2652           0 :         ResultSetInclude eInclude = INCLUDE_FOLDERS_ONLY;
    2653           0 :         xResultSet = rContent.createCursor( aProps, eInclude );
    2654             :     }
    2655           0 :     catch ( Exception& ) {}
    2656             : 
    2657           0 :     if ( xResultSet.is() )
    2658             :     {
    2659           0 :         uno::Reference< XContentAccess > xContentAccess( xResultSet, UNO_QUERY );
    2660           0 :         uno::Reference< XRow > xRow( xResultSet, UNO_QUERY );
    2661             : 
    2662             :         try
    2663             :         {
    2664           0 :             while ( xResultSet->next() )
    2665             :             {
    2666             :                 // TODO/LATER: clarify the encoding of the Title
    2667           0 :                 OUString aTitle( xRow->getString( 1 ) );
    2668           0 :                 OUString aTargetSubfolderURL( xContentAccess->queryContentIdentifierString() );
    2669             : 
    2670           0 :                 if ( bHierarchy )
    2671           0 :                     addHierGroup( rList, aTitle, aTargetSubfolderURL );
    2672             :                 else
    2673             :                 {
    2674           0 :                     OUString aUITitle;
    2675           0 :                     for ( sal_Int32 nInd = 0; nInd < aUINames.getLength(); nInd++ )
    2676           0 :                         if ( aUINames[nInd].First.equals( aTitle ) )
    2677             :                         {
    2678           0 :                             aUITitle = aUINames[nInd].Second;
    2679           0 :                             break;
    2680             :                         }
    2681             : 
    2682           0 :                     addFsysGroup( rList, aTitle, aUITitle, aTargetSubfolderURL, bWriteableContent );
    2683             :                 }
    2684           0 :             }
    2685             :         }
    2686           0 :         catch ( Exception& ) {}
    2687           0 :     }
    2688           0 : }
    2689             : 
    2690             : 
    2691           0 : void SfxDocTplService_Impl::removeFromHierarchy( DocTemplates_EntryData_Impl *pData )
    2692             : {
    2693           0 :     Content aTemplate;
    2694             : 
    2695           0 :     if ( Content::create( pData->getHierarchyURL(), maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2696             :     {
    2697           0 :         removeContent( aTemplate );
    2698           0 :     }
    2699           0 : }
    2700             : 
    2701             : 
    2702           0 : void SfxDocTplService_Impl::addToHierarchy( GroupData_Impl *pGroup,
    2703             :                                             DocTemplates_EntryData_Impl *pData )
    2704             : {
    2705           0 :     Content aGroup, aTemplate;
    2706             : 
    2707           0 :     if ( ! Content::create( pGroup->getHierarchyURL(), maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    2708           0 :         return;
    2709             : 
    2710             :     // Check, if there's a template with the given name in this group
    2711             :     // Return if there is already a template
    2712           0 :     INetURLObject aGroupObj( pGroup->getHierarchyURL() );
    2713             : 
    2714           0 :     aGroupObj.insertName( pData->getTitle(), false,
    2715             :                       INetURLObject::LAST_SEGMENT, true,
    2716           0 :                       INetURLObject::ENCODE_ALL );
    2717             : 
    2718           0 :     OUString aTemplateURL = aGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2719             : 
    2720           0 :     if ( Content::create( aTemplateURL, maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2721           0 :         return;
    2722             : 
    2723           0 :     addEntry( aGroup, pData->getTitle(),
    2724           0 :               pData->getTargetURL(),
    2725           0 :               pData->getType() );
    2726             : }
    2727             : 
    2728             : 
    2729           0 : void SfxDocTplService_Impl::updateData( DocTemplates_EntryData_Impl *pData )
    2730             : {
    2731           0 :     Content aTemplate;
    2732             : 
    2733           0 :     if ( ! Content::create( pData->getHierarchyURL(), maCmdEnv, comphelper::getProcessComponentContext(), aTemplate ) )
    2734           0 :         return;
    2735             : 
    2736           0 :     OUString aPropName;
    2737             : 
    2738           0 :     if ( pData->getUpdateType() )
    2739             :     {
    2740           0 :         aPropName =  PROPERTY_TYPE;
    2741           0 :         setProperty( aTemplate, aPropName, makeAny( pData->getType() ) );
    2742             :     }
    2743             : 
    2744           0 :     if ( pData->getUpdateLink() )
    2745             :     {
    2746           0 :         aPropName = TARGET_URL;
    2747           0 :         setProperty( aTemplate, aPropName, makeAny( pData->getTargetURL() ) );
    2748           0 :     }
    2749             : }
    2750             : 
    2751             : 
    2752           0 : void SfxDocTplService_Impl::addGroupToHierarchy( GroupData_Impl *pGroup )
    2753             : {
    2754           0 :     OUString aAdditionalProp( TARGET_DIR_URL  );
    2755           0 :     Content aGroup;
    2756             : 
    2757           0 :     INetURLObject aNewGroupObj( maRootURL );
    2758           0 :     aNewGroupObj.insertName( pGroup->getTitle(), false,
    2759             :           INetURLObject::LAST_SEGMENT, true,
    2760           0 :           INetURLObject::ENCODE_ALL );
    2761             : 
    2762           0 :     OUString aNewGroupURL = aNewGroupObj.GetMainURL( INetURLObject::NO_DECODE );
    2763             : 
    2764           0 :     if ( createFolder( aNewGroupURL, false, false, aGroup ) )
    2765             :     {
    2766           0 :         setProperty( aGroup, aAdditionalProp, makeAny( pGroup->getTargetURL() ) );
    2767           0 :         pGroup->setHierarchyURL( aNewGroupURL );
    2768             : 
    2769           0 :         sal_uIntPtr nCount = pGroup->count();
    2770           0 :         for ( sal_uIntPtr i=0; i<nCount; i++ )
    2771             :         {
    2772           0 :             DocTemplates_EntryData_Impl *pData = pGroup->getEntry( i );
    2773           0 :             addToHierarchy( pGroup, pData ); // add entry to hierarchy
    2774             :         }
    2775           0 :     }
    2776           0 : }
    2777             : 
    2778             : 
    2779           0 : void SfxDocTplService_Impl::removeFromHierarchy( GroupData_Impl *pGroup )
    2780             : {
    2781           0 :     Content aGroup;
    2782             : 
    2783           0 :     if ( Content::create( pGroup->getHierarchyURL(), maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
    2784             :     {
    2785           0 :         removeContent( aGroup );
    2786           0 :     }
    2787           0 : }
    2788             : 
    2789             : 
    2790           0 : GroupData_Impl::GroupData_Impl( const OUString& rTitle )
    2791             : {
    2792           0 :     maTitle = rTitle;
    2793           0 :     mbInUse = false;
    2794           0 :     mbInHierarchy = false;
    2795           0 : }
    2796             : 
    2797             : 
    2798           0 : GroupData_Impl::~GroupData_Impl()
    2799             : {
    2800           0 :     for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
    2801           0 :         delete maEntries[ i ];
    2802           0 :     maEntries.clear();
    2803           0 : }
    2804             : 
    2805             : 
    2806           0 : DocTemplates_EntryData_Impl* GroupData_Impl::addEntry( const OUString& rTitle,
    2807             :                                           const OUString& rTargetURL,
    2808             :                                           const OUString& rType,
    2809             :                                           const OUString& rHierURL )
    2810             : {
    2811           0 :     DocTemplates_EntryData_Impl* pData = NULL;
    2812           0 :     bool EntryFound = false;
    2813             : 
    2814           0 :     for ( size_t i = 0, n = maEntries.size(); i < n; ++i )
    2815             :     {
    2816           0 :         pData = maEntries[ i ];
    2817           0 :         if ( pData->getTitle() == rTitle )
    2818             :         {
    2819           0 :             EntryFound = true;
    2820           0 :             break;
    2821             :         }
    2822             :     }
    2823             : 
    2824           0 :     if ( !EntryFound )
    2825             :     {
    2826           0 :         pData = new DocTemplates_EntryData_Impl( rTitle );
    2827           0 :         pData->setTargetURL( rTargetURL );
    2828           0 :         pData->setType( rType );
    2829           0 :         if ( !rHierURL.isEmpty() )
    2830             :         {
    2831           0 :             pData->setHierarchyURL( rHierURL );
    2832           0 :             pData->setHierarchy( true );
    2833             :         }
    2834           0 :         maEntries.push_back( pData );
    2835             :     }
    2836             :     else
    2837             :     {
    2838           0 :         if ( !rHierURL.isEmpty() )
    2839             :         {
    2840           0 :             pData->setHierarchyURL( rHierURL );
    2841           0 :             pData->setHierarchy( true );
    2842             :         }
    2843             : 
    2844           0 :         if ( pData->getInHierarchy() )
    2845           0 :             pData->setInUse();
    2846             : 
    2847           0 :         if ( rTargetURL != pData->getTargetURL() )
    2848             :         {
    2849           0 :             pData->setTargetURL( rTargetURL );
    2850           0 :             pData->setUpdateLink( true );
    2851             :         }
    2852             :     }
    2853             : 
    2854           0 :     return pData;
    2855             : }
    2856             : 
    2857             : 
    2858           0 : DocTemplates_EntryData_Impl::DocTemplates_EntryData_Impl( const OUString& rTitle )
    2859             : {
    2860           0 :     maTitle         = rTitle;
    2861           0 :     mbInUse         = false;
    2862           0 :     mbInHierarchy   = false;
    2863           0 :     mbUpdateType    = false;
    2864           0 :     mbUpdateLink    = false;
    2865           0 : }
    2866             : 
    2867             : }
    2868             : 
    2869             : // static
    2870           0 : bool SfxURLRelocator_Impl::propertyCanContainOfficeDir(
    2871             :                                         const OUString & rPropName )
    2872             : {
    2873             :     // Note: TargetURL is handled by UCB itself (because it is a property
    2874             :     //       with a predefined semantic). Additional Core properties introduced
    2875             :     //       be a client app must be handled by the client app itself, because
    2876             :     //       the UCB does not know the semantics of those properties.
    2877           0 :     return ( rPropName == TARGET_DIR_URL || rPropName == PROPERTY_DIRLIST );
    2878             : }
    2879             : 
    2880             : 
    2881           0 : SfxURLRelocator_Impl::SfxURLRelocator_Impl( const uno::Reference< XComponentContext > & xContext )
    2882           0 : : mxContext( xContext )
    2883             : {
    2884           0 : }
    2885             : 
    2886             : 
    2887           0 : SfxURLRelocator_Impl::~SfxURLRelocator_Impl()
    2888             : {
    2889           0 : }
    2890             : 
    2891             : 
    2892           0 : void SfxURLRelocator_Impl::initOfficeInstDirs()
    2893             : {
    2894           0 :     if ( !mxOfficeInstDirs.is() )
    2895             :     {
    2896           0 :         osl::MutexGuard aGuard( maMutex );
    2897           0 :         if ( !mxOfficeInstDirs.is() )
    2898             :         {
    2899             :             OSL_ENSURE( mxContext.is(), "No service manager!" );
    2900             : 
    2901           0 :             mxOfficeInstDirs = theOfficeInstallationDirectories::get(mxContext);
    2902           0 :         }
    2903             :     }
    2904           0 : }
    2905             : 
    2906             : 
    2907           0 : void SfxURLRelocator_Impl::implExpandURL( OUString& io_url )
    2908             : {
    2909           0 :     const INetURLObject aParser( io_url );
    2910           0 :     if ( aParser.GetProtocol() != INET_PROT_VND_SUN_STAR_EXPAND )
    2911           0 :         return;
    2912             : 
    2913           0 :     io_url = aParser.GetURLPath( INetURLObject::DECODE_WITH_CHARSET );
    2914             :     try
    2915             :     {
    2916           0 :         if ( !mxMacroExpander.is() )
    2917             :         {
    2918           0 :             mxMacroExpander.set( theMacroExpander::get(mxContext), UNO_QUERY_THROW );
    2919             :         }
    2920           0 :         io_url = mxMacroExpander->expandMacros( io_url );
    2921             :     }
    2922           0 :     catch( const Exception& )
    2923             :     {
    2924             :         DBG_UNHANDLED_EXCEPTION();
    2925           0 :     }
    2926             : }
    2927             : 
    2928             : 
    2929           0 : void SfxURLRelocator_Impl::makeRelocatableURL( OUString & rURL )
    2930             : {
    2931           0 :     if ( !rURL.isEmpty() )
    2932             :     {
    2933           0 :         initOfficeInstDirs();
    2934           0 :         implExpandURL( rURL );
    2935           0 :         rURL = mxOfficeInstDirs->makeRelocatableURL( rURL );
    2936             :     }
    2937           0 : }
    2938             : 
    2939             : 
    2940           0 : void SfxURLRelocator_Impl::makeAbsoluteURL( OUString & rURL )
    2941             : {
    2942           0 :     if ( !rURL.isEmpty() )
    2943             :     {
    2944           0 :         initOfficeInstDirs();
    2945           0 :         implExpandURL( rURL );
    2946           0 :         rURL = mxOfficeInstDirs->makeAbsoluteURL( rURL );
    2947             :     }
    2948           0 : }
    2949             : 
    2950             : extern "C" SAL_DLLPUBLIC_EXPORT css::uno::XInterface * SAL_CALL
    2951           0 : com_sun_star_comp_sfx2_DocumentTemplates_get_implementation(
    2952             :     css::uno::XComponentContext *context,
    2953             :     css::uno::Sequence<css::uno::Any> const &)
    2954             : {
    2955           0 :     return cppu::acquire(new SfxDocTplService(context));
    2956             : }
    2957             : 
    2958             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10