StelFileMgr.cpp   StelFileMgr.cpp 
skipping to change at line 20 skipping to change at line 20
* This program is distributed in the hope that it will be useful, * This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of * but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details. * GNU General Public License for more details.
* *
* You should have received a copy of the GNU General Public License * You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software * along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA. * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
*/ */
#include "StelUtils.hpp"
#include <cstdlib> #include <cstdlib>
#include <QCoreApplication> #include <QCoreApplication>
#include <QFileInfo> #include <QFileInfo>
#include <QDir> #include <QDir>
#include <QString> #include <QString>
#include <QDebug> #include <QDebug>
#include <QDesktopServices> #include <QStandardPaths>
#include "StelUtils.hpp" #include <stdio.h>
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
# include <windows.h> # include <windows.h>
# ifndef _SHOBJ_H # ifndef _SHOBJ_H
# include <shlobj.h> # include <shlobj.h>
# include <QLibrary> # include <QLibrary>
# endif # endif
#endif #endif
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
// Initialize static members. // Initialize static members.
QStringList StelFileMgr::fileLocations; QStringList StelFileMgr::fileLocations;
QString StelFileMgr::userDir; QString StelFileMgr::userDir;
QString StelFileMgr::screenshotDir; QString StelFileMgr::screenshotDir;
QString StelFileMgr::installDir;
void StelFileMgr::init() void StelFileMgr::init()
{ {
// Set the userDir member. // Set the userDir member.
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QString winApiPath = getWin32SpecialDirPath(CSIDL_APPDATA); QString winApiPath = getWin32SpecialDirPath(CSIDL_APPDATA);
if (!winApiPath.isEmpty()) if (!winApiPath.isEmpty())
{ {
userDir = winApiPath + "\\Stellarium"; userDir = winApiPath + "\\Stellarium";
} }
skipping to change at line 76 skipping to change at line 79
makeSureDirExistsAndIsWritable(userDir); makeSureDirExistsAndIsWritable(userDir);
} }
catch (std::runtime_error &e) catch (std::runtime_error &e)
{ {
qFatal("Error: cannot create user config directory: %s", e.w hat()); qFatal("Error: cannot create user config directory: %s", e.w hat());
} }
// OK, now we have the userDir set, add it to the search path // OK, now we have the userDir set, add it to the search path
fileLocations.append(userDir); fileLocations.append(userDir);
// Then add the installation directory to the search path // Determine install data directory location
try
// If we are running from the build tree, we use the files from the
current directory
if (QFileInfo(CHECK_FILE).exists())
{ {
fileLocations.append(getInstallationDir()); installDir = ".";
} }
catch (std::runtime_error &e) else
{ {
qWarning() << "WARNING: could not locate installation direct #ifdef Q_OS_MAC
ory"; QString relativePath = "/../Resources";
if (QCoreApplication::applicationDirPath().contains("src"))
{
relativePath = "/../..";
}
QFileInfo MacOSdir(QCoreApplication::applicationDirPath() +
relativePath);
// These two lines are used to see if the Qt bug still exist
s.
// The output from C: should simply be the parent of what is
show for B:
qDebug() << "B: " << MacOSdir.absolutePath();
qDebug() << "C: " << MacOSdir.dir().absolutePath();
QDir ResourcesDir(MacOSdir.absolutePath());
if (!QCoreApplication::applicationDirPath().contains("src"))
{
ResourcesDir.cd(QString("Resources"));
}
QFileInfo installLocation(ResourcesDir.absolutePath());
QFileInfo checkFile(installLocation.filePath() + QString("/"
) + QString(CHECK_FILE));
#else
// Linux, BSD, Solaris etc.
// We use the value from the config.h filesystem
QFileInfo installLocation(QFile::decodeName(INSTALL_DATADIR)
);
QFileInfo checkFile(QFile::decodeName(INSTALL_DATADIR "/" CH
ECK_FILE));
#endif
if (checkFile.exists())
{
installDir = installLocation.filePath();
}
else
{
qWarning() << "WARNING StelFileMgr::StelFileMgr: cou
ld not find install location:" <<
QDir::toNativeSeparators(installLocation.fil
ePath()) << " (we checked for " <<
QDir::toNativeSeparators(checkFile.filePath(
)) << ").";
qFatal("Couldn't find install directory location.");
}
} }
screenshotDir = QDesktopServices::storageLocation(QDesktopServices:: // Then add the installation directory to the search path
PicturesLocation); fileLocations.append(installDir);
QString screenshotDirSuffix = "/Stellarium";
if (!QStandardPaths::standardLocations(QStandardPaths::PicturesLocat
ion).isEmpty())
screenshotDir = QStandardPaths::standardLocations(QStandardP
aths::PicturesLocation)[0].append(screenshotDirSuffix);
else
screenshotDir = userDir.append(screenshotDirSuffix);
makeSureDirExistsAndIsWritable(screenshotDir);
} }
QString StelFileMgr::findFile(const QString& path, const Flags& flags) QString StelFileMgr::findFile(const QString& path, Flags flags)
{ {
if (path.isEmpty()) if (path.isEmpty())
throw std::runtime_error("Empty file path"); {
qWarning() << "Empty file path";
return "";
}
// Qt resource files
if (path.startsWith(":/"))
return path;
// explicitly specified relative paths // explicitly specified relative paths
if (path[0] == '.') if (path[0] == '.')
{ {
if (fileFlagsCheck(path, flags)) if (fileFlagsCheck(path, flags))
return path; return path;
else else
throw std::runtime_error(QString("file does not matc {
h flags: %1").arg(path).toLocal8Bit().constData()); qWarning() << QString("file does not match flags: %1
").arg(path);
return "";
}
} }
// Qt resource files
if (path.startsWith(":/"))
return path;
// explicitly specified absolute paths // explicitly specified absolute paths
if ( isAbsolute(path) ) if (isAbsolute(path))
{ {
if (fileFlagsCheck(path, flags)) if (fileFlagsCheck(path, flags))
return path; return path;
else else
throw std::runtime_error(QString("file does not matc {
h flags: %1").arg(path).toLocal8Bit().constData()); qWarning() << QString("file does not match flags: %1
").arg(path);
return "";
}
} }
foreach (QString i, fileLocations) foreach (const QString& i, fileLocations)
{ {
if (fileFlagsCheck(i + "/" + path, flags)) const QFileInfo finfo(i + "/" + path);
if (fileFlagsCheck(finfo, flags))
return i + "/" + path; return i + "/" + path;
} }
throw std::runtime_error(QString("file not found: %1").arg(path).toL //FIXME: This line give false positive values for static plugins (tr
ocal8Bit().constData()); ying search dynamic plugin first)
//qWarning() << QString("file not found: %1").arg(path);
return "";
} }
QStringList StelFileMgr::findFileInAllPaths(const QString &path, const Flag s &flags) QStringList StelFileMgr::findFileInAllPaths(const QString &path, const Flag s &flags)
{ {
QStringList filePaths;
if (path.isEmpty()) if (path.isEmpty())
throw std::runtime_error("Empty file path"); return filePaths;
QStringList filePaths; // Qt resource files
if (path.startsWith(":/"))
{
filePaths.append(path);
return filePaths;
}
// explicitly specified relative paths // explicitly specified relative paths
if (path[0] == '.') if (path[0] == '.')
{ {
if (fileFlagsCheck(path, flags)) if (fileFlagsCheck(path, flags))
{
filePaths.append(path); filePaths.append(path);
return filePaths;
}
else
throw std::runtime_error(QString("file does not matc
h flags: %1").arg(path).toLocal8Bit().constData());
}
// Qt resource files
if (path.startsWith(":/"))
{
filePaths.append(path);
return filePaths; return filePaths;
} }
// explicitly specified absolute paths // explicitly specified absolute paths
if ( isAbsolute(path) ) if ( isAbsolute(path) )
{ {
if (fileFlagsCheck(path, flags)) if (fileFlagsCheck(path, flags))
{
filePaths.append(path); filePaths.append(path);
return filePaths; return filePaths;
}
else
throw std::runtime_error(QString("file does not matc
h flags: %1").arg(path).toLocal8Bit().constData());
} }
foreach (QString locationPath, fileLocations) foreach (const QString& locationPath, fileLocations)
{ {
if (fileFlagsCheck(locationPath + "/" + path, flags)) const QFileInfo finfo(locationPath + "/" + path);
{ if (fileFlagsCheck(finfo, flags))
filePaths.append(locationPath + "/" + path); filePaths.append(locationPath + "/" + path);
}
} }
if (filePaths.isEmpty()) return filePaths;
throw std::runtime_error(QString("file not found: %1").arg(p
ath).toLocal8Bit().constData());
else
return filePaths;
} }
QSet<QString> StelFileMgr::listContents(const QString& path, const StelFile Mgr::Flags& flags, bool recursive) QSet<QString> StelFileMgr::listContents(const QString& path, const StelFile Mgr::Flags& flags, bool recursive)
{ {
QSet<QString> result; QSet<QString> result;
QStringList listPaths;
if (recursive) if (recursive)
{ {
QSet<QString> dirs = listContents(path, Directory, false); QSet<QString> dirs = listContents(path, Directory, false);
result = listContents(path, flags, false); // root result = listContents(path, flags, false); // root
// add results for each sub-directory // add results for each sub-directory
foreach (const QString& d, dirs) foreach (const QString& d, dirs)
{ {
QSet<QString> subDirResult = listContents(path + "/" + d, flags, true); QSet<QString> subDirResult = listContents(path + "/" + d, flags, true);
foreach (const QString& r, subDirResult) foreach (const QString& r, subDirResult)
{ {
result.insert(d + "/" + r); result.insert(d + "/" + r);
} }
} }
return result; return result;
} }
// If path is "complete" (a full path), we just look in there, else // If path is "complete" (a full path), we just look in there, else
// we append relative paths to the search paths maintained by this c lass. // we append relative paths to the search paths maintained by this c lass.
if (QFileInfo(path).isAbsolute()) QStringList listPaths = QFileInfo(path).isAbsolute() ? QStringList("
listPaths.append(""); /") : fileLocations;
else
listPaths = fileLocations;
foreach (const QString& li, listPaths) foreach (const QString& li, listPaths)
{ {
QFileInfo thisPath; QFileInfo thisPath(QDir(li).filePath(path));
if (QFileInfo(path).isAbsolute()) if (!thisPath.isDir())
thisPath.setFile(path); continue;
else
thisPath.setFile(li+"/"+path); QDir thisDir(thisPath.absoluteFilePath());
foreach (const QString& fileIt, thisDir.entryList())
if (thisPath.isDir()) {
{ if (fileIt == ".." || fileIt == ".")
QDir thisDir(thisPath.absoluteFilePath()); continue;
foreach (const QString& fileIt, thisDir.entryList()) QFileInfo fullPath(thisDir.filePath(fileIt));
{ if (fileFlagsCheck(fullPath, flags))
if (fileIt != ".." && fileIt != ".") result.insert(fileIt);
{
QFileInfo fullPath;
if (QFileInfo(path).isAbsolute())
fullPath.setFile(path+"/"+fi
leIt);
else
fullPath.setFile(li+"/"+path
+"/"+fileIt);
// default is to return all objects
in this directory
bool returnThisOne = true;
// but if we have flags set, that wi
ll filter the result
if ((flags & Writable) && !fullPath.
isWritable())
returnThisOne = false;
if ((flags & Directory) && !fullPath
.isDir())
returnThisOne = false;
if ((flags & File) && !fullPath.isFi
le())
returnThisOne = false;
// we only want to return "hidden" r
esults if the Hidden flag is set
if (!(flags & Hidden))
if (fileIt.at(0) == '.')
returnThisOne = fals
e;
// OK, add the ones we want to the r
esult
if (returnThisOne)
{
result.insert(fileIt);
}
}
}
} }
} }
return result; return result;
} }
void StelFileMgr::setSearchPaths(const QStringList& paths) void StelFileMgr::setSearchPaths(const QStringList& paths)
{ {
fileLocations = paths; fileLocations = paths;
} }
skipping to change at line 306 skipping to change at line 318
QString StelFileMgr::dirName(const QString& path) QString StelFileMgr::dirName(const QString& path)
{ {
return QFileInfo(path).dir().canonicalPath(); return QFileInfo(path).dir().canonicalPath();
} }
QString StelFileMgr::baseName(const QString& path) QString StelFileMgr::baseName(const QString& path)
{ {
return QFileInfo(path).baseName(); return QFileInfo(path).baseName();
} }
bool StelFileMgr::fileFlagsCheck(const QString& path, const Flags& flags) bool StelFileMgr::fileFlagsCheck(const QFileInfo& thePath, const Flags& fla gs)
{ {
if (!(flags & Hidden)) const bool exists = thePath.exists();
{
// Files are considered Hidden on POSIX systems if the file
name begins with
// a "." character. Unless we have the Hidden flag set, rej
ect and path
// where the basename starts with a .
if (baseName(path).startsWith('.'))
{
return false;
}
}
QFileInfo thePath(path);
if (flags & New) if (flags & New)
{ {
// if the file already exists, it is not a new file // if the file already exists, it is not a new file
if (thePath.exists()) if (exists)
return false; return false;
// To be able to create a new file, we need to have a // To be able to create a new file, we need to have a
// parent directory which is writable. // parent directory which is writable.
QFileInfo pInfo(thePath.dir().absolutePath()); QFileInfo pInfo(thePath.dir().absolutePath());
if (!pInfo.exists() || !pInfo.isWritable()) if (!pInfo.exists() || !pInfo.isWritable())
{ {
return false; return false;
} }
} }
else if (thePath.exists()) else if (exists)
{ {
if (flags==0)
return true;
if ((flags & Writable) && !thePath.isWritable()) if ((flags & Writable) && !thePath.isWritable())
return false; return false;
if ((flags & Directory) && !thePath.isDir()) if ((flags & Directory) && !thePath.isDir())
return false; return false;
if ((flags & File) && !thePath.isFile()) if ((flags & File) && !thePath.isFile())
return false; return false;
} }
else else
{ {
// doesn't exist and New flag wasn't requested // doesn't exist and New flag wasn't requested
return false ; return false ;
} }
return true; return true;
} }
QString StelFileMgr::getDesktopDir() QString StelFileMgr::getDesktopDir()
{ {
QString result = QDesktopServices::storageLocation(QDesktopServices: :DesktopLocation);
if (QStandardPaths::standardLocations(QStandardPaths::DesktopLocatio
n).isEmpty())
return "";
QString result = QStandardPaths::standardLocations(QStandardPaths::D
esktopLocation)[0];
if (!QFileInfo(result).isDir()) if (!QFileInfo(result).isDir())
{ return "";
throw std::runtime_error("Can't find Desktop directory");
}
return result; return result;
} }
QString StelFileMgr::getUserDir() QString StelFileMgr::getUserDir()
{ {
return userDir; return userDir;
} }
void StelFileMgr::setUserDir(const QString& newDir) void StelFileMgr::setUserDir(const QString& newDir)
{ {
makeSureDirExistsAndIsWritable(newDir); makeSureDirExistsAndIsWritable(newDir);
QFileInfo userDirFI(newDir); QFileInfo userDirFI(newDir);
userDir = userDirFI.filePath(); userDir = userDirFI.filePath();
fileLocations.replace(0, userDir); fileLocations.replace(0, userDir);
} }
QString StelFileMgr::getInstallationDir() QString StelFileMgr::getInstallationDir()
{ {
// If we are running from the build tree, we use the files from ther return installDir;
e...
if (QFileInfo(CHECK_FILE).exists()){
return ".";
}
#ifdef Q_OS_MAC
QString relativePath = "/../Resources";
if (QCoreApplication::applicationDirPath().contains("src")) {
relativePath = "/../../../../..";
}
QFileInfo MacOSdir(QCoreApplication::applicationDirPath() + relative
Path);
QDir ResourcesDir = MacOSdir.dir();
if (!QCoreApplication::applicationDirPath().contains("src")) {
ResourcesDir.cd(QString("Resources"));
}
QFileInfo installLocation(ResourcesDir.absolutePath());
QFileInfo checkFile(installLocation.filePath() + QString("/") + QStr
ing(CHECK_FILE));
#else
// Linux, BSD, Solaris etc.
// We use the value from the config.h filesystem
QFileInfo installLocation(QFile::decodeName(INSTALL_DATADIR));
QFileInfo checkFile(QFile::decodeName(INSTALL_DATADIR "/" CHECK_FILE
));
#endif
if (checkFile.exists())
{
return installLocation.filePath();
}
else
{
qWarning() << "WARNING StelFileMgr::StelFileMgr: could not f
ind install location:"
<< QDir::toNativeSeparators(installLocation.filePath
())
<< " (we checked for " << QDir::toNativeSeparators(c
heckFile.filePath())
<< ").";
throw (std::runtime_error("NOT FOUND"));
}
} }
QString StelFileMgr::getScreenshotDir() QString StelFileMgr::getScreenshotDir()
{ {
return screenshotDir; return screenshotDir;
} }
void StelFileMgr::setScreenshotDir(const QString& newDir) void StelFileMgr::setScreenshotDir(const QString& newDir)
{ {
QFileInfo userDirFI(newDir); QFileInfo userDirFI(newDir);
skipping to change at line 443 skipping to change at line 414
{ {
qWarning() << "WARNING StelFileMgr::setScreenshotDir dir is not writable: " << QDir::toNativeSeparators(userDirFI.filePath()); qWarning() << "WARNING StelFileMgr::setScreenshotDir dir is not writable: " << QDir::toNativeSeparators(userDirFI.filePath());
throw std::runtime_error("NOT_VALID"); throw std::runtime_error("NOT_VALID");
} }
screenshotDir = userDirFI.filePath(); screenshotDir = userDirFI.filePath();
} }
QString StelFileMgr::getLocaleDir() QString StelFileMgr::getLocaleDir()
{ {
#ifdef ENABLE_NLS #ifdef ENABLE_NLS
QFileInfo localePath; QFileInfo localePath = QFileInfo(getInstallationDir() + "/translatio
#if defined(Q_OS_WIN) || defined(Q_OS_MAC) ns");
// Windows and MacOS X have the locale dir in the installation folde
r
localePath = QFileInfo(getInstallationDir() + "/locale");
// or MacosxDirs::getApplicationResourcesDirectory().append( "/local
e" );
#else
// Linux, BSD etc, the locale dir is set in the config.h
// but first, if we are in the development tree, don't rely on an
// install having been done.
if (getInstallationDir() == ".")
{
localePath = QFileInfo("./locale");
if (!localePath.exists())
localePath = QFileInfo(QFile::decodeName(INSTALL_LOC
ALEDIR));
}
else
localePath = QFileInfo(QFile::decodeName(INSTALL_LOCALEDIR))
;
#endif
if (localePath.exists()) if (localePath.exists())
{ {
return localePath.filePath(); return localePath.filePath();
} }
else else
{ {
qWarning() << "WARNING StelFileMgr::getLocaleDir() - could n // If not found, try to look in the standard build directory
ot determine locale directory, returning \"\""; (useful for developer)
return ""; localePath = QCoreApplication::applicationDirPath() + "/../t
ranslations";
if (localePath.exists())
{
return localePath.filePath();
}
else
{
qWarning() << "WARNING StelFileMgr::getLocaleDir() -
could not determine locale directory";
return "";
}
} }
#else #else
return QString(); return QString();
#endif #endif
} }
// Returns the path to the cache directory. Note that subdirectories may ne ed to be created for specific caches. // Returns the path to the cache directory. Note that subdirectories may ne ed to be created for specific caches.
QString StelFileMgr::getCacheDir() QString StelFileMgr::getCacheDir()
{ {
const QString& cachePath = QDesktopServices::storageLocation(QDeskto return (QStandardPaths::standardLocations(QStandardPaths::CacheLocat
pServices::CacheLocation); ion) << getUserDir() + "/cache")[0];
if (cachePath.isEmpty())
{
return getUserDir()+"/cache";
}
return cachePath;
} }
void StelFileMgr::makeSureDirExistsAndIsWritable(const QString& dirFullPath ) void StelFileMgr::makeSureDirExistsAndIsWritable(const QString& dirFullPath )
{ {
// Check that the dirFullPath directory exists // Check that the dirFullPath directory exists
QFileInfo uDir(dirFullPath); QFileInfo uDir(dirFullPath);
if (!uDir.exists()) if (!uDir.exists())
{ {
// The modules directory doesn't exist, lets create it. // The modules directory doesn't exist, lets create it.
qDebug() << "Creating directory " << QDir::toNativeSeparator s(uDir.filePath()); qDebug() << "Creating directory " << QDir::toNativeSeparator s(uDir.filePath());
skipping to change at line 515 skipping to change at line 473
{ {
throw std::runtime_error(QString("Directory is not writable: " +uDir.filePath()).toStdString()); throw std::runtime_error(QString("Directory is not writable: " +uDir.filePath()).toStdString());
} }
} }
#ifdef Q_OS_WIN #ifdef Q_OS_WIN
QString StelFileMgr::getWin32SpecialDirPath(int csidlId) QString StelFileMgr::getWin32SpecialDirPath(int csidlId)
{ {
// This function is implemented using code from QSettings implementa tion in QT // This function is implemented using code from QSettings implementa tion in QT
// (GPL edition, version 4.3). // (GPL edition, version 4.3).
// Stellarium works only on wide-character versions of Windows anywa
y,
// therefore it's using only the wide-char version of the code. --BM
QLibrary library(QLatin1String("shell32")); QLibrary library(QLatin1String("shell32"));
QT_WA( { typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int, BOOL);
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFolderPath)
, BOOL); library.resolve("SHGetSpecialFolderPathW");
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFol if (SHGetSpecialFolderPath)
derPath)library.resolve("SHGetSpecialFolderPathW"); {
if (SHGetSpecialFolderPath) TCHAR tpath[MAX_PATH];
{ SHGetSpecialFolderPath(0, tpath, csidlId, FALSE);
TCHAR tpath[MAX_PATH]; return QString::fromUtf16((ushort*)tpath);
SHGetSpecialFolderPath(0, tpath, csidlId, FALSE); }
return QString::fromUtf16((ushort*)tpath);
}
} , {
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, char*, int,
BOOL);
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFol
derPath)library.resolve("SHGetSpecialFolderPathA");
if (SHGetSpecialFolderPath)
{
char cpath[MAX_PATH];
SHGetSpecialFolderPath(0, cpath, csidlId, FALSE);
return QString::fromLocal8Bit(cpath);
}
} );
return QString(); return QString();
} }
#endif #endif
 End of changes. 47 change blocks. 
232 lines changed or deleted 172 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/