tdf#130857 qt weld: Implement QtInstanceWidget::strip_mnemonic
[LibreOffice.git] / vcl / unx / generic / fontmanager / helper.cxx
blob65365e2cc91c6dfbc4d4a5142840b680cff833a6
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
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/.
9 * This file incorporates work covered by the following license notice:
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 .
20 #include <config_folders.h>
22 #include <sys/stat.h>
23 #include <limits.h>
24 #include <osl/file.hxx>
25 #include <osl/process.h>
26 #include <osl/thread.h>
27 #include <rtl/bootstrap.hxx>
28 #include <rtl/ustring.hxx>
29 #include <sal/log.hxx>
30 #include <tools/urlobj.hxx>
31 #include <unx/helper.hxx>
33 #include <tuple>
35 using ::rtl::Bootstrap;
37 namespace psp {
39 OUString getOfficePath( whichOfficePath ePath )
41 static const auto aPaths = [] {
42 OUString sRoot, sUser, sConfig;
43 Bootstrap::get(u"BRAND_BASE_DIR"_ustr, sRoot);
44 Bootstrap aBootstrap(sRoot + "/" LIBO_ETC_FOLDER "/" SAL_CONFIGFILE("bootstrap"));
45 aBootstrap.getFrom(u"UserInstallation"_ustr, sUser);
46 aBootstrap.getFrom(u"CustomDataUrl"_ustr, sConfig);
47 OUString aUPath = sUser + "/user/psprint";
48 if (sRoot.startsWith("file://"))
50 OUString aSysPath;
51 if (osl::FileBase::getSystemPathFromFileURL(sRoot, aSysPath) == osl::FileBase::E_None)
52 sRoot = aSysPath;
54 if (sUser.startsWith("file://"))
56 OUString aSysPath;
57 if (osl::FileBase::getSystemPathFromFileURL(sUser, aSysPath) == osl::FileBase::E_None)
58 sUser = aSysPath;
60 if (sConfig.startsWith("file://"))
62 OUString aSysPath;
63 if (osl::FileBase::getSystemPathFromFileURL(sConfig, aSysPath) == osl::FileBase::E_None)
64 sConfig = aSysPath;
67 // ensure user path exists
68 SAL_INFO("vcl.fonts", "Trying to create: " << aUPath);
69 osl::Directory::createPath(aUPath);
71 return std::make_tuple(sRoot, sUser, sConfig);
72 }();
73 const auto& [aInstallationRootPath, aUserPath, aConfigPath] = aPaths;
75 switch( ePath )
77 case whichOfficePath::ConfigPath: return aConfigPath;
78 case whichOfficePath::InstallationRootPath: return aInstallationRootPath;
79 case whichOfficePath::UserPath: return aUserPath;
81 return OUString();
84 static OString getEnvironmentPath( const char* pKey )
86 OString aPath;
88 const char* pValue = getenv( pKey );
89 if( pValue && *pValue )
91 aPath = OString( pValue );
93 return aPath;
96 } // namespace psp
98 void psp::getPrinterPathList( std::vector< OUString >& rPathList, const char* pSubDir )
100 rPathList.clear();
101 rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
103 OUStringBuffer aPathBuffer( 256 );
105 // append net path
106 aPathBuffer.append( getOfficePath( whichOfficePath::InstallationRootPath ) );
107 if( !aPathBuffer.isEmpty() )
109 aPathBuffer.append( "/" LIBO_SHARE_FOLDER "/psprint" );
110 if( pSubDir )
112 aPathBuffer.append( '/' );
113 aPathBuffer.appendAscii( pSubDir );
115 rPathList.push_back( aPathBuffer.makeStringAndClear() );
117 // append user path
118 aPathBuffer.append( getOfficePath( whichOfficePath::UserPath ) );
119 if( !aPathBuffer.isEmpty() )
121 aPathBuffer.append( "/user/psprint" );
122 if( pSubDir )
124 aPathBuffer.append( '/' );
125 aPathBuffer.appendAscii( pSubDir );
127 rPathList.push_back( aPathBuffer.makeStringAndClear() );
130 OString aPath( getEnvironmentPath("SAL_PSPRINT") );
131 sal_Int32 nIndex = 0;
134 OString aDir( aPath.getToken( 0, ':', nIndex ) );
135 if( aDir.isEmpty() )
136 continue;
138 if( pSubDir )
140 aDir += OString::Concat("/") + pSubDir;
142 struct stat aStat;
143 if( stat( aDir.getStr(), &aStat ) || ! S_ISDIR( aStat.st_mode ) )
144 continue;
146 rPathList.push_back( OStringToOUString( aDir, aEncoding ) );
147 } while( nIndex != -1 );
149 #ifdef SYSTEM_PPD_DIR
150 if( pSubDir && rtl_str_compare( pSubDir, PRINTER_PPDDIR ) == 0 )
152 rPathList.push_back( OStringToOUString( OString( SYSTEM_PPD_DIR ), RTL_TEXTENCODING_UTF8 ) );
154 #endif
156 if( !rPathList.empty() )
157 return;
159 // last resort: next to program file (mainly for setup)
160 OUString aExe;
161 if( osl_getExecutableFile( &aExe.pData ) == osl_Process_E_None )
163 INetURLObject aDir( aExe );
164 aDir.removeSegment();
165 aExe = aDir.GetMainURL( INetURLObject::DecodeMechanism::NONE );
166 OUString aSysPath;
167 if( osl_getSystemPathFromFileURL( aExe.pData, &aSysPath.pData ) == osl_File_E_None )
169 rPathList.push_back( aSysPath );
174 OUString const & psp::getFontPath()
176 static OUString aPath;
178 if (aPath.isEmpty())
180 OUStringBuffer aPathBuffer( 512 );
182 OUString aConfigPath( getOfficePath( whichOfficePath::ConfigPath ) );
183 OUString aInstallationRootPath( getOfficePath( whichOfficePath::InstallationRootPath ) );
184 OUString aUserPath( getOfficePath( whichOfficePath::UserPath ) );
185 if (!aInstallationRootPath.isEmpty())
187 // internal font resources, required for normal operation, like OpenSymbol
188 aPathBuffer.append(aInstallationRootPath
189 + "/" LIBO_SHARE_RESOURCE_FOLDER "/common/fonts;");
191 if( !aConfigPath.isEmpty() )
193 // #i53530# Path from CustomDataUrl will completely
194 // replace net share and user paths if the path exists
195 OUString sPath = aConfigPath + "/" LIBO_SHARE_FOLDER "/fonts";
196 // check existence of config path
197 struct stat aStat;
198 if( 0 != stat( OUStringToOString( sPath, osl_getThreadTextEncoding() ).getStr(), &aStat )
199 || ! S_ISDIR( aStat.st_mode ) )
200 aConfigPath.clear();
201 else
203 aPathBuffer.append(sPath);
206 if( aConfigPath.isEmpty() )
208 if( !aInstallationRootPath.isEmpty() )
210 aPathBuffer.append( aInstallationRootPath
211 + "/" LIBO_SHARE_FOLDER "/fonts/truetype;");
213 if( !aUserPath.isEmpty() )
215 aPathBuffer.append( aUserPath + "/user/fonts" );
219 aPath = aPathBuffer.makeStringAndClear();
220 SAL_INFO("vcl.fonts", "Initializing font path to: " << aPath);
222 return aPath;
225 void psp::normPath( OString& rPath )
227 char buf[PATH_MAX];
229 // double slashes and slash at end are probably
230 // removed by realpath anyway, but since this runs
231 // on many different platforms let's play it safe
232 OString aPath = rPath.replaceAll("//"_ostr, "/"_ostr);
234 if( aPath.endsWith("/") )
235 aPath = aPath.copy(0, aPath.getLength()-1);
237 if( ( aPath.indexOf("./") != -1 ||
238 aPath.indexOf( '~' ) != -1 )
239 && realpath( aPath.getStr(), buf ) )
241 rPath = buf;
243 else
245 rPath = aPath;
249 void psp::splitPath( OString& rPath, OString& rDir, OString& rBase )
251 normPath( rPath );
252 sal_Int32 nIndex = rPath.lastIndexOf( '/' );
253 if( nIndex > 0 )
254 rDir = rPath.copy( 0, nIndex );
255 else if( nIndex == 0 ) // root dir
256 rDir = rPath.copy( 0, 1 );
257 if( rPath.getLength() > nIndex+1 )
258 rBase = rPath.copy( nIndex+1 );
261 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */