Marble

MarbleDirs.cpp
1// SPDX-License-Identifier: LGPL-2.1-or-later
2//
3// SPDX-FileCopyrightText: 2004-2007 Torsten Rahn <tackat@kde.org>
4// SPDX-FileCopyrightText: 2007 Inge Wallin <ingwa@kde.org>
5//
6
7
8#include "MarbleDirs.h"
9#include "MarbleDebug.h"
10
11#include <QFile>
12#include <QString>
13#include <QStringList>
14#include <QCoreApplication>
15
16#include <cstdlib>
17
18#include <QStandardPaths>
19
20#ifdef Q_OS_WIN
21//for getting appdata path
22//mingw-w64 Internet Explorer 5.01
23#define _WIN32_IE 0x0501
24#include <shlobj.h>
25#endif
26
27#ifdef Q_OS_MACX
28//for getting app bundle path
29#include <ApplicationServices/ApplicationServices.h>
30#endif
31
32#include <config-marble.h>
33
34using namespace Marble;
35
36namespace
37{
38 QString runTimeMarbleDataPath;
39
40 QString runTimeMarblePluginPath;
41}
42
43MarbleDirs::MarbleDirs()
44 : d( nullptr )
45{
46}
47
48
49QString MarbleDirs::path( const QString& relativePath )
50{
51 QString localpath = localPath() + QLatin1Char('/') + relativePath; // local path
52 QString systempath = systemPath() + QLatin1Char('/') + relativePath; // system path
53
54
55 QString fullpath = systempath;
56 if ( QFile::exists( localpath ) ) {
57 fullpath = localpath;
58 }
59 return QDir( fullpath ).canonicalPath();
60}
61
62
63QString MarbleDirs::pluginPath( const QString& relativePath )
64{
65 const QString localpath = pluginLocalPath() + QDir::separator() + relativePath; // local path
66 const QString systempath = pluginSystemPath() + QDir::separator() + relativePath; // system path
67
68
69 QString fullpath = systempath;
70 if ( QFile::exists( localpath ) ) {
71 fullpath = localpath;
72 }
73
74 return QDir( fullpath ).canonicalPath();
75}
76
77QStringList MarbleDirs::entryList( const QString& relativePath, QDir::Filters filters )
78{
79 QStringList filesLocal = QDir(MarbleDirs::localPath() + QLatin1Char('/') + relativePath).entryList(filters);
80 QStringList filesSystem = QDir(MarbleDirs::systemPath() + QLatin1Char('/') + relativePath).entryList(filters);
81 QStringList allFiles( filesLocal );
82 allFiles << filesSystem;
83
84 // remove duplicate entries
85 allFiles.sort();
86 for ( int i = 1; i < allFiles.size(); ++i ) {
87 if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
88 allFiles.removeAt(i);
89 --i;
90 }
91 }
92
93 return allFiles;
94}
95
96QStringList MarbleDirs::pluginEntryList( const QString& relativePath, QDir::Filters filters )
97{
98 QStringList allFiles = QDir(MarbleDirs::pluginLocalPath() + QLatin1Char('/') + relativePath).entryList(filters);
99 auto const pluginSystemPath = MarbleDirs::pluginSystemPath();
100 if (!pluginSystemPath.isEmpty()) {
101 allFiles << QDir(pluginSystemPath + QLatin1Char('/') + relativePath).entryList(filters);
102 }
103
104 // remove duplicate entries
105 allFiles.sort();
106 for ( int i = 1; i < allFiles.size(); ++i ) {
107 if ( allFiles.at(i) == allFiles.at( i - 1 ) ) {
108 allFiles.removeAt(i);
109 --i;
110 }
111 }
112
113 return allFiles;
114}
115
116QString MarbleDirs::systemPath()
117{
118 if (!runTimeMarbleDataPath.isEmpty()) {
119 return runTimeMarbleDataPath;
120 }
121
122 QString systempath;
123
124#ifdef MARBLE_DATA_PATH
125 //MARBLE_DATA_PATH is a compiler define set by cmake
126 QString compileTimeMarbleDataPath(MARBLE_DATA_PATH);
127
128 if(QDir(compileTimeMarbleDataPath).exists())
129 return compileTimeMarbleDataPath;
130#endif // MARBLE_DATA_PATH
131
132
133#ifdef Q_OS_WIN
135#endif
136
137#ifdef Q_OS_MACX
138 //
139 // On OSX lets try to find any file first in the bundle
140 // before branching out to home and sys dirs
141 //
142 CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
143 CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
144 const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
145 CFRelease(myBundleRef);
146 QString myPath(mypPathPtr);
147 CFRelease(myMacPath);
148 //do some magick so that we can still find data dir if
149 //marble was not built as a bundle
150 if (myPath.contains(QLatin1String(".app"))) { //its a bundle!
151 systempath = myPath + QLatin1String("/Contents/Resources/data");
152 }
153
154 if ( QFile::exists( systempath ) ){
155 return systempath;
156 }
157#endif // mac bundle
158
159#ifdef Q_OS_ANDROID
160 systempath = "assets:/data";
161 return systempath;
162#endif
163
164 // This is the preferred fallback location if no marbleDataPath is set.
166
167 if ( QFile::exists( systempath ) ){
168 return systempath;
169 }
170
171 // This fallback location is for compatibility with KDE installations.
173 + QLatin1String( "/../share/apps/marble/data" )
174 ).canonicalPath();
175}
176
177QString MarbleDirs::pluginSystemPath()
178{
179 if (!runTimeMarblePluginPath.isEmpty()) {
180 return runTimeMarblePluginPath;
181 }
182
183 QString systempath;
184
185#ifdef MARBLE_PLUGIN_PATH
186 //MARBLE_PLUGIN_PATH is a compiler define set by cmake
187 QString compileTimeMarblePluginPath(MARBLE_PLUGIN_PATH);
188
189 if(QDir(compileTimeMarblePluginPath).exists())
190 return compileTimeMarblePluginPath;
191#endif // MARBLE_PLUGIN_PATH
192
193#ifdef Q_OS_MACX
194 //
195 // On OSX lets try to find any file first in the bundle
196 // before branching out to home and sys dirs
197 //
198 CFURLRef myBundleRef = CFBundleCopyBundleURL(CFBundleGetMainBundle());
199 CFStringRef myMacPath = CFURLCopyFileSystemPath(myBundleRef, kCFURLPOSIXPathStyle);
200 const char *mypPathPtr = CFStringGetCStringPtr(myMacPath,CFStringGetSystemEncoding());
201 CFRelease(myBundleRef);
202 CFRelease(myMacPath);
203 QString myPath(mypPathPtr);
204 //do some magick so that we can still find data dir if
205 //marble was not built as a bundle
206 if (myPath.contains(QLatin1String(".app"))) { //its a bundle!
207 systempath = myPath + QLatin1String("/Contents/Resources/plugins");
208 }
209
210 if ( QFile::exists( systempath ) ){
211 return systempath;
212 }
213#endif // mac bundle
214
215#ifdef Q_OS_WIN
217#endif
218
219#ifdef Q_OS_ANDROID
220 return "assets:/plugins";
221#endif
222
223 // This is the preferred fallback location if no marblePluginPath is set.
224 systempath = QDir( QCoreApplication::applicationDirPath() + QLatin1String( "/plugins" ) ).canonicalPath();
225
226 if ( QFile::exists( systempath ) ){
227 return systempath;
228 }
229
230 // This ultimate fallback location is for compatibility with KDE installations.
232 + QLatin1String( "/../lib/kde4/plugins/marble" )
233 ).canonicalPath();
234}
235
236QString MarbleDirs::localPath()
237{
238#ifndef Q_OS_WIN
239 QString dataHome = getenv( "XDG_DATA_HOME" );
240 if( dataHome.isEmpty() )
241 dataHome = QDir::homePath() + QLatin1String("/.local/share");
242
243 return dataHome + QLatin1String("/marble"); // local path
244#else
246#endif
247}
248
249QStringList MarbleDirs::oldLocalPaths()
250{
251 QStringList possibleOldPaths;
252
253#ifndef Q_OS_WIN
254 const QString oldDefault = QDir::homePath() + QLatin1String("/.marble/data");
255 possibleOldPaths.append( oldDefault );
256
257 const QString xdgDefault = QDir::homePath() + QLatin1String("/.local/share/marble");
258 possibleOldPaths.append( xdgDefault );
259
260 QString xdg = getenv( "XDG_DATA_HOME" );
261 xdg += QLatin1String("/marble/");
262 possibleOldPaths.append( xdg );
263#endif
264
265#ifdef Q_OS_WIN
266 HWND hwnd = 0;
267 WCHAR *appdata_path = new WCHAR[MAX_PATH + 1];
268
269 SHGetSpecialFolderPathW(hwnd, appdata_path, CSIDL_APPDATA, 0);
270 QString appdata = QString::fromUtf16(reinterpret_cast<ushort*>(appdata_path));
271 delete[] appdata_path;
272 possibleOldPaths << QString(QDir::fromNativeSeparators(appdata) + QLatin1String("/.marble/data")); // local path
273#endif
274
275 QString currentLocalPath = QDir( MarbleDirs::localPath() ).canonicalPath();
276 QStringList oldPaths;
277 for( const QString& possibleOldPath: possibleOldPaths ) {
278 if( !QDir().exists( possibleOldPath ) ) {
279 continue;
280 }
281
282 QString canonicalPossibleOldPath = QDir( possibleOldPath ).canonicalPath();
283 if( canonicalPossibleOldPath == currentLocalPath ) {
284 continue;
285 }
286
287 oldPaths.append( canonicalPossibleOldPath );
288 }
289
290 return oldPaths;
291}
292
293QString MarbleDirs::pluginLocalPath()
294{
295#ifndef Q_OS_WIN
296 return QDir::homePath() + QLatin1String("/.marble/plugins"); // local path
297#else
299#endif
300}
301
302QString MarbleDirs::marbleDataPath()
303{
304 return runTimeMarbleDataPath;
305}
306
307QString MarbleDirs::marblePluginPath()
308{
309 return runTimeMarblePluginPath;
310}
311
312void MarbleDirs::setMarbleDataPath( const QString& adaptedPath )
313{
314 if ( !QDir::root().exists( adaptedPath ) )
315 {
316 qWarning() << QString( "Invalid MarbleDataPath \"%1\". Using \"%2\" instead." ).arg( adaptedPath, systemPath() );
317 return;
318 }
319
320 runTimeMarbleDataPath = adaptedPath;
321}
322
323void MarbleDirs::setMarblePluginPath( const QString& adaptedPath )
324{
325 if ( !QDir::root().exists( adaptedPath ) )
326 {
327 qWarning() << QString( "Invalid MarblePluginPath \"%1\". Using \"%2\" instead." ).arg( adaptedPath, pluginSystemPath() );
328 return;
329 }
330
331 runTimeMarblePluginPath = adaptedPath;
332}
333
334
335void MarbleDirs::debug()
336{
337 mDebug() << "=== MarbleDirs: ===";
338 mDebug() << "Local Path:" << localPath();
339 mDebug() << "Plugin Local Path:" << pluginLocalPath();
340 mDebug() << "";
341 mDebug() << "Marble Data Path (Run Time) :" << runTimeMarbleDataPath;
342 mDebug() << "Marble Data Path (Compile Time):" << QString(MARBLE_DATA_PATH);
343 mDebug() << "";
344 mDebug() << "Marble Plugin Path (Run Time) :" << runTimeMarblePluginPath;
345 mDebug() << "Marble Plugin Path (Compile Time):" << QString(MARBLE_PLUGIN_PATH);
346 mDebug() << "";
347 mDebug() << "System Path:" << systemPath();
348 mDebug() << "Plugin System Path:" << pluginSystemPath();
349 mDebug() << "===================";
350}
Binds a QML item to a specific geodetic location in screen coordinates.
QString applicationDirPath()
typedef Filters
QString canonicalPath() const const
QStringList entryList(Filters filters, SortFlags sort) const const
QString fromNativeSeparators(const QString &pathName)
QString homePath()
QDir root()
QChar separator()
bool exists() const const
void append(QList< T > &&value)
const_reference at(qsizetype i) const const
void removeAt(qsizetype i)
qsizetype size() const const
QString writableLocation(StandardLocation type)
QString arg(Args &&... args) const const
QString fromUtf16(const char16_t *unicode, qsizetype size)
bool isEmpty() const const
void sort(Qt::CaseSensitivity cs)
This file is part of the KDE documentation.
Documentation copyright © 1996-2024 The KDE developers.
Generated on Tue Mar 26 2024 11:18:17 by doxygen 1.10.0 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.