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

Generated by: LCOV version 1.10