/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ /* * This file is part of the LibreOffice project. * * This Source Code Form is subject to the terms of the Mozilla Public * License, v. 2.0. If a copy of the MPL was not distributed with this * file, You can obtain one at http://mozilla.org/MPL/2.0/. * * This file incorporates work covered by the following license notice: * * Licensed to the Apache Software Foundation (ASF) under one or more * contributor license agreements. See the NOTICE file distributed * with this work for additional information regarding copyright * ownership. The ASF licenses this file to you under the Apache * License, Version 2.0 (the "License"); you may not use this file * except in compliance with the License. You may obtain a copy of * the License at http://www.apache.org/licenses/LICENSE-2.0 .
*/
//See: #i66157# and rhbz#1065807 //return which template dir the rURL is a subpath of
OUString findParentTemplateDir(const OUString& rURL) const;
//See: #i66157# and rhbz#1065807 //return true if rURL is a path (or subpath of) a dir which is not a user path //which implies neither it or its contents can be removed bool isInternalTemplateDir(const OUString& rURL) const;
};
pWin.disposeAndClear();
} elseif ( needsUpdate() ) // the UI should be shown only on the first update
doUpdate();
} else
{
SAL_WARN( "sfx.doc", "init_Impl(): Could not create root" );
}
for (autoconst & rPair : maNames)
{ if ( rPair.maShortName == rShortName )
{
aRet = rPair.maLongName; break;
}
}
if ( aRet.isEmpty() )
aRet = rShortName;
return aRet;
}
void SfxDocTplService::getDirList()
{
Any aValue;
// Get the template dir list // TODO/LATER: let use service, register listener
INetURLObject aURL;
OUString aDirs = SvtPathOptions().GetTemplatePath();
sal_Int32 nCount = comphelper::string::getTokenCount(aDirs, C_DELIM);
for (auto& rInternalTemplateDir : asNonConstRange(maInternalTemplateDirs))
{ //expand vnd.sun.star.expand: and remove "..." from them //to normalize into the expected url patterns
maRelocator.makeRelocatableURL(rInternalTemplateDir);
maRelocator.makeAbsoluteURL(rInternalTemplateDir);
}
// Store the template dir list
setProperty( maRootContent, PROPERTY_DIRLIST, aValue );
}
bool SfxDocTplService::needsUpdate()
{ bool bNeedsUpdate = true;
Any aValue;
// Get the template dir list bool bHasProperty = getProperty( maRootContent, PROPERTY_NEEDSUPDATE, aValue );
if ( bHasProperty )
aValue >>= bNeedsUpdate;
// the old template component also checks this state, but it is initialized from this component // so if this component was already updated the old component does not need such an update
::svt::TemplateFolderCache aTempCache; if ( !bNeedsUpdate )
bNeedsUpdate = aTempCache.needsUpdate();
// compute the parent folder url from the new folder url // and remove the final slash, because Content::create doesn't // like it
aParentURL.removeSegment(); if ( aParentURL.getSegmentCount() >= 1 )
aParentURL.removeFinalSlash();
// if the parent exists, we can continue with the creation of the // new folder, we have to create the parent otherwise ( as long as // bCreateParent is set to true ) if ( Content::create( aParentURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), maCmdEnv, comphelper::getProcessComponentContext(), aParent ) )
{ try
{
Sequence< Any > aValues{ Any(aFolderName), Any(true) };
OUString aType;
aParent.insertNewContent( aType, { TITLE, IS_FOLDER }, aValues, rNewFolder );
bCreatedFolder = true;
} catch( Exception const & )
{
TOOLS_WARN_EXCEPTION( "sfx.doc", "createFolder(): Could not create new folder" );
}
} elseif ( bCreateParent )
{ // if the parent doesn't exists and bCreateParent is set to true, // we try to create the parent and if this was successful, we // try to create the new folder again ( but this time, we set // bCreateParent to false to avoid endless recursions ) if ( ( aParentURL.getSegmentCount() >= 1 ) &&
createFolder( aParentURL.GetMainURL( INetURLObject::DecodeMechanism::NONE ), bCreateParent, bFsysFolder, aParent ) )
{
bCreatedFolder = createFolder( rNewFolderURL, false, bFsysFolder, rNewFolder );
}
}
try
{
Sequence< Any > aValues{ Any(aTryName), Any(true) };
bCreated = aParent.insertNewContent( TYPE_FSYS_FOLDER, { TITLE, IS_FOLDER }, aValues, aNewFolder );
} catch( ucb::NameClashException& )
{ // if there is already an element, retry
} catch( Exception& )
{
INetURLObject aObjPath( aDirPath );
aObjPath.insertName( aTryName, false,
INetURLObject::LAST_SEGMENT,
INetURLObject::EncodeMechanism::All ); // if there is already an element, retry // if there was another error, do not try any more if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) ) break;
}
try
{
Sequence< Any > aValues{ Any(aTryName), Any(true) };
bCreated = aParent.insertNewContent( TYPE_FSYS_FILE, { TITLE, IS_DOCUMENT }, aValues, aNewFile );
} catch( ucb::NameClashException& )
{ // if there is already an element, retry
} catch( Exception& )
{
INetURLObject aObjPath( aPath );
aObjPath.insertName( aTryName, false,
INetURLObject::LAST_SEGMENT,
INetURLObject::EncodeMechanism::All ); // if there is already an element, retry // if there was another error, do not try any more if ( !::utl::UCBContentHelper::Exists( aObjPath.GetMainURL( INetURLObject::DecodeMechanism::NONE ) ) ) break;
}
// get the entries from the hierarchy
createFromContent( aGroupList, maRootContent, true, false );
// get the entries from the template directories
sal_Int32 nCountDir = maTemplateDirs.getLength(); const OUString* pDirs = maTemplateDirs.getConstArray();
Content aDirContent;
// the last directory in the list must be writable bool bWriteableDirectory = true;
// the target folder might not exist, for this reason no interaction handler should be used
uno::Reference< XCommandEnvironment > aQuietEnv;
// it is possible that the name is used already, but it should be checked before for ( sal_Int32 nInd = 0; nInd < nLen; nInd++ ) if ( aUINames[nInd].First == aNewFolderName ) returnfalse;
// create a new folder with the given name
Content aNewFolder;
OUString aNewFolderName;
// the Fsys name instead of GroupName should be used, the groupuinames must be added also if ( !CreateNewUniqueFolderWithPrefix( aTargetPath,
rGroupName,
aNewFolderName,
aResultURL,
aNewFolder )
&& !CreateNewUniqueFolderWithPrefix( aTargetPath,
u"UserGroup"_ustr,
aNewFolderName,
aResultURL,
aNewFolder ) )
return OUString();
if ( !UpdateUINamesForTemplateDir_Impl( aTargetPath, rGroupName, aNewFolderName ) )
{ // we could not create the groupuinames for the folder, so we delete the group in // the folder and return
removeContent( aNewFolder ); return OUString();
}
// Now set the target url for this group and we are done
Any aValue( aResultURL );
if ( Content::create( aNewGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aNewGroup ) ||
! createFolder( aNewGroupURL, false, false, aNewGroup ) )
{ // if there already was a group with this name or the new group // could not be created, we return here returnfalse;
}
// Get the user template path entry ( new group will always // be added in the user template path )
sal_Int32 nIndex;
OUString aUserPath;
nIndex = maTemplateDirs.getLength(); if ( nIndex )
nIndex--; else returnfalse; // We don't know where to add the group
aUserPath = maTemplateDirs[ nIndex ];
// create a new folder with the given name
Content aNewFolder;
OUString aNewFolderName;
OUString aNewFolderURL;
// the Fsys name instead of GroupName should be used, the groupuinames must be added also if ( !CreateNewUniqueFolderWithPrefix( aUserPath,
rGroupName,
aNewFolderName,
aNewFolderURL,
aNewFolder )
&& !CreateNewUniqueFolderWithPrefix( aUserPath,
u"UserGroup"_ustr,
aNewFolderName,
aNewFolderURL,
aNewFolder ) )
{ // we could not create the folder, so we delete the group in the // hierarchy and return
removeContent( aNewGroup ); returnfalse;
}
if ( !UpdateUINamesForTemplateDir_Impl( aUserPath, rGroupName, aNewFolderName ) )
{ // we could not create the groupuinames for the folder, so we delete the group in the // hierarchy, the folder and return
removeContent( aNewGroup );
removeContent( aNewFolder ); returnfalse;
}
// Now set the target url for this group and we are done
Any aValue( aNewFolderURL );
sal_Bool SfxDocTplService::removeGroup( const OUString& rGroupName )
{ // remove all the elements that have the prefix aTargetURL // if the group does not have other elements remove it
if (!init()) returnfalse;
::osl::MutexGuard aGuard( maMutex );
bool bResult = false;
// create the group url
INetURLObject aGroupObj( maRootURL );
aGroupObj.insertName( rGroupName, false,
INetURLObject::LAST_SEGMENT,
INetURLObject::EncodeMechanism::All );
// Get the target url
Content aGroup; const OUString aGroupURL = aGroupObj.GetMainURL( INetURLObject::DecodeMechanism::NONE );
if ( Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) )
{ const OUString aPropName( TARGET_DIR_URL );
Any aValue;
if ( aGroupTargetURL.isEmpty() ) returnfalse; // nothing is allowed to be removed
if ( !maTemplateDirs.hasElements() ) returnfalse;
// check that the fs location is in writable folder and this is not a "My templates" folder
INetURLObject aGroupParentFolder( aGroupTargetURL ); if (!aGroupParentFolder.removeSegment()) returnfalse;
if ( ::utl::UCBContentHelper::IsSubPath( aGroupTargetURL, aTemplTargetURL ) )
{ // this is a user template, and it can be removed if ( removeContent( aTemplTargetURL ) )
removeContent( aHierURL ); else
bHasNonRemovable = true;
} else
bHasShared = true;
}
if ( !bHasNonRemovable && !bHasShared )
{ if ( removeContent( aGroupTargetURL )
|| !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
{
removeContent( aGroupURL );
RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
bResult = true; // the operation is successful only if the whole group is removed
}
} elseif ( !bHasNonRemovable )
{ if ( removeContent( aGroupTargetURL )
|| !::utl::UCBContentHelper::Exists( aGroupTargetURL ) )
{
RemoveUINamesForTemplateDir_Impl( aGeneralTempPath, rGroupName );
setProperty( aGroup, aPropName, uno::Any( OUString() ) );
}
}
}
} catch ( Exception& ) {}
}
// Check, if there is a group with the new name, return false // if there is one. if ( Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) ) returnfalse;
// When there is no group with the old name, we can't rename it if ( ! Content::create( aGroupURL, maCmdEnv, comphelper::getProcessComponentContext(), aGroup ) ) returnfalse;
OUString aGroupTargetURL; // there is no need to check whether target dir url is in target path, since if the target path is changed // the target dir url should be already generated new
Any aValue; if ( getProperty( aGroup, TARGET_DIR_URL, aValue ) )
aValue >>= aGroupTargetURL;
if ( aGroupTargetURL.isEmpty() ) returnfalse;
if ( !maTemplateDirs.hasElements() ) returnfalse;
// check that the fs location is in writable folder and this is not a "My templates" folder
INetURLObject aGroupParentFolder( aGroupTargetURL ); if (!aGroupParentFolder.removeSegment() ||
isInternalTemplateDir(aGroupParentFolder.GetMainURL(INetURLObject::DecodeMechanism::NONE)))
{ returnfalse;
}
// check that the group can be renamed ( all the contents must be in target location ) bool bCanBeRenamed = false; try
{
uno::Reference< XResultSet > xResultSet;
Sequence< OUString > aProps { TARGET_URL };
xResultSet = aGroup.createCursor( aProps, INCLUDE_DOCUMENTS_ONLY );
if ( aGroupTargetObj.removeSegment()
&& ReplaceUINamesForTemplateDir_Impl( aGroupTargetObj.GetMainURL( INetURLObject::DecodeMechanism::NONE ),
aFsysName,
rOldName,
rNewName ) )
{ // rename the group in the hierarchy
Any aTitleValue;
aTitleValue <<= rNewName;
// Check, whether or not there is a group with this name // Return false, if there is no group with the given name
Content aGroup, aTemplateToRemove;
INetURLObject aGroupObj( maRootURL ); bool bRemoveOldTemplateContent = false;
OUString aGroupTargetURL;
Any aValue; if ( getProperty( aGroup, TARGET_DIR_URL, aValue ) )
aValue >>= aGroupTargetURL;
// Check, if there's a template with the given name in this group // the target template should be overwritten if it is imported by user // in case the template is installed by office installation of by an add-in // it can not be replaced
aGroupObj.insertName( rTemplateName, false,
INetURLObject::LAST_SEGMENT,
INetURLObject::EncodeMechanism::All ); const OUString aTemplateURL {aGroupObj.GetMainURL( INetURLObject::DecodeMechanism::NONE )};
if ( aGroupTargetURL.isEmpty() || !maTemplateDirs.hasElements()
|| (!aTemplateToRemoveTargetURL.isEmpty() && isInternalTemplateDir(aTemplateToRemoveTargetURL)) ) returnfalse; // it is not allowed to remove the template
}
// find the related type name
uno::Reference< container::XNameAccess > xFilterFactory(
mxContext->getServiceManager()->createInstanceWithContext(u"com.sun.star.document.FilterFactory"_ustr, mxContext),
uno::UNO_QUERY_THROW );
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.