StelFileMgr.cpp   StelFileMgr.cpp 
#include <config.h> #include <config.h>
#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 "StelUtils.hpp" #include "StelUtils.hpp"
#ifdef WIN32 #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
#ifdef MACOSX #ifdef Q_OS_MAC
#include "StelMacosxDirs.hpp" #include "StelMacosxDirs.hpp"
#endif #endif
#include "StelFileMgr.hpp" #include "StelFileMgr.hpp"
StelFileMgr::StelFileMgr() // Initialize static members.
QStringList StelFileMgr::fileLocations;
QString StelFileMgr::userDir;
QString StelFileMgr::screenshotDir;
void StelFileMgr::init()
{ {
// Set the userDir member. // Set the userDir member.
QFileInfo userDirFI; #ifdef Q_OS_WIN
#if defined(WIN32)
QString winApiPath = getWin32SpecialDirPath(CSIDL_APPDATA); QString winApiPath = getWin32SpecialDirPath(CSIDL_APPDATA);
if (!winApiPath.isEmpty()) if (!winApiPath.isEmpty())
{ {
userDirFI = QFileInfo(winApiPath + "\\Stellarium"); userDir = winApiPath + "\\Stellarium";
} }
#elif defined(Q_OS_MAC)
#elif defined(MACOSX) userDir = QDir::homePath() + "/Library/Application Support/Stellariu
userDirFI.setFile(QDir::homePath() + "/Library/Preferences/Stellariu m";
m");
#else #else
userDirFI.setFile(QDir::homePath() + "/.stellarium"); userDir = QDir::homePath() + "/.stellarium";
#endif #endif
if (!userDirFI.exists() || !userDirFI.isDir())
if (!QFile(userDir).exists())
{ {
qWarning() << "WARNING StelFileMgr::StelFileMgr user dir doe qWarning() << "User config directory does not exist: " << us
s not exist: " erDir;
<< userDirFI.filePath();
} }
else if (!userDirFI.isWritable()) try
{ {
qWarning() << "WARNING StelFileMgr::StelFileMgr user dir is makeSureDirExistsAndIsWritable(userDir);
not writable: " }
<< userDirFI.filePath(); catch (std::runtime_error &e)
{
qFatal("Error: cannot create user config directory: %s", e.w
hat());
} }
userDir = userDirFI.filePath();
// OK, now we have the userDir set, we will add it and the installat // OK, now we have the userDir set, add it to the search path
ion
// dir to the search path. The user directory is first.
fileLocations.append(userDir); fileLocations.append(userDir);
// then the installation directory // Then add the installation directory to the search path
try try
{ {
fileLocations.append(getInstallationDir()); fileLocations.append(getInstallationDir());
} }
catch(std::runtime_error &e) catch (std::runtime_error &e)
{ {
qWarning() << "WARNING: could not locate installation direct ory"; qWarning() << "WARNING: could not locate installation direct ory";
} }
#if defined(WIN32) || defined(CYGWIN) || defined(__MINGW32__) || defined(MI NGW32) || defined(MACOSX) #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
screenshotDir = getDesktopDir(); screenshotDir = getDesktopDir();
#else #else
screenshotDir = QDir::homePath(); screenshotDir = QDir::homePath();
#endif #endif
} #ifdef Q_OS_MAC
StelMacosxDirs::addApplicationPluginDirectory();
StelFileMgr::~StelFileMgr() #endif
{ }
}
QString StelFileMgr::findFile(const QString& path, const Flags& flags) QString StelFileMgr::findFile(const QString& path, const Flags& flags)
{ {
if (path.isEmpty()) if (path.isEmpty())
throw (std::runtime_error("Empty file path")); throw std::runtime_error("Empty file 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 mat ch flags: %1").arg(path).toLocal8Bit().constData())); throw std::runtime_error(QString("file does not matc h flags: %1").arg(path).toLocal8Bit().constData());
} }
// Qt resource files // Qt resource files
if (path.startsWith(":/")) if (path.startsWith(":/"))
return path; return path;
// explicitly specified absolute paths // explicitly specified absolute paths
QFileInfo thePath(path); if ( isAbsolute(path) )
if ( thePath.isAbsolute() )
{ {
if (fileFlagsCheck(path, flags)) if (fileFlagsCheck(path, flags))
return path; return path;
else else
throw (std::runtime_error(QString("file does not mat ch flags: %1").arg(path).toLocal8Bit().constData())); throw std::runtime_error(QString("file does not matc h flags: %1").arg(path).toLocal8Bit().constData());
} }
foreach (QString i, fileLocations) foreach (QString i, fileLocations)
{ {
if (fileFlagsCheck(i + "/" + path, flags)) if (fileFlagsCheck(i + "/" + path, flags))
return i + "/" + path; return i + "/" + path;
} }
throw(std::runtime_error(QString("file not found: %1").arg(path).toL ocal8Bit().constData())); throw std::runtime_error(QString("file not found: %1").arg(path).toL ocal8Bit().constData());
} }
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; 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(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(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()) if (QFileInfo(path).isAbsolute())
listPaths.append(""); listPaths.append("");
else else
listPaths = fileLocations; listPaths = fileLocations;
foreach (QString li, listPaths) foreach (const QString& li, listPaths)
{ {
QFileInfo thisPath(li+"/"+path); QFileInfo thisPath;
if (QFileInfo(path).isAbsolute())
thisPath.setFile(path);
else
thisPath.setFile(li+"/"+path);
if (thisPath.isDir()) if (thisPath.isDir())
{ {
QDir thisDir(thisPath.absoluteFilePath()); QDir thisDir(thisPath.absoluteFilePath());
QStringList lsOut = thisDir.entryList(); foreach (const QString& fileIt, thisDir.entryList())
for (QStringList::const_iterator fileIt = lsOut.cons
tBegin(); fileIt != lsOut.constEnd(); ++fileIt)
{ {
if ((*fileIt != "..") && (*fileIt != ".")) if (fileIt != ".." && fileIt != ".")
{ {
QFileInfo fullPath(li+"/"+path+"/"+* QFileInfo fullPath;
fileIt); if (QFileInfo(path).isAbsolute())
fullPath.setFile(path+"/"+fi
leIt);
else
fullPath.setFile(li+"/"+path
+"/"+fileIt);
// default is to return all objects in this directory // default is to return all objects in this directory
bool returnThisOne = true; bool returnThisOne = true;
// but if we have flags set, that wi ll filter the result // but if we have flags set, that wi ll filter the result
if ((flags & Writable) && !fullPath. isWritable()) if ((flags & Writable) && !fullPath. isWritable())
returnThisOne = false; returnThisOne = false;
if ((flags & Directory) && !fullPath .isDir()) if ((flags & Directory) && !fullPath .isDir())
returnThisOne = false; returnThisOne = false;
if ((flags & File) && !fullPath.isFi le()) if ((flags & File) && !fullPath.isFi le())
returnThisOne = false; returnThisOne = false;
// we only want to return "hidden" r esults if the Hidden flag is set // we only want to return "hidden" r esults if the Hidden flag is set
if (!(flags & Hidden)) if (!(flags & Hidden))
if ((*fileIt)[0] == '.') if (fileIt.at(0) == '.')
returnThisOne = fals e; returnThisOne = fals e;
// OK, add the ones we want to the r esult // OK, add the ones we want to the r esult
if (returnThisOne) if (returnThisOne)
{ {
result.insert(*fileIt); result.insert(fileIt);
} }
} }
} }
} }
} }
return result; return result;
} }
void StelFileMgr::setSearchPaths(const QStringList& paths) void StelFileMgr::setSearchPaths(const QStringList& paths)
{ {
fileLocations = paths; fileLocations = paths;
} }
bool StelFileMgr::exists(const QString& path) bool StelFileMgr::exists(const QString& path)
{ {
return QFileInfo(path).exists(); return QFileInfo(path).exists();
} }
bool StelFileMgr::isAbsolute(const QString& path)
{
return QFileInfo(path).isAbsolute();
}
bool StelFileMgr::isReadable(const QString& path)
{
return QFileInfo(path).isReadable();
}
bool StelFileMgr::isWritable(const QString& path) bool StelFileMgr::isWritable(const QString& path)
{ {
return QFileInfo(path).isWritable(); return QFileInfo(path).isWritable();
} }
bool StelFileMgr::isDirectory(const QString& path) bool StelFileMgr::isDirectory(const QString& path)
{ {
return QFileInfo(path).isDir(); return QFileInfo(path).isDir();
} }
skipping to change at line 226 skipping to change at line 248
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();
} }
void StelFileMgr::checkUserDir()
{
try {
QFileInfo uDir(getUserDir());
if (uDir.exists())
{
if (uDir.isDir() && uDir.isWritable())
{
// everything checks out fine.
return;
}
else
{
qCritical() << "ERROR: User directory is not
a writable directory: " << uDir.filePath() ;
}
}
else
{
// The user directory doesn't exist, lets create it.
if (!QDir("/").mkpath(uDir.filePath()))
{
qCritical() << "ERROR: Could not create user
directory: " << uDir.filePath();
}
}
}
catch(std::runtime_error& e)
{
// This should never happen ;)
qCritical() << "ERROR: cannot work out the user directory: "
<< e.what();
}
}
bool StelFileMgr::fileFlagsCheck(const QString& path, const Flags& flags) bool StelFileMgr::fileFlagsCheck(const QString& path, const Flags& flags)
{ {
if ( ! (flags & Hidden) ) if (!(flags & Hidden))
{ {
// Files are considered Hidden on POSIX systems if the file name begins with // 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 // a "." character. Unless we have the Hidden flag set, rej ect and path
// where the basename starts with a . // where the basename starts with a .
if (baseName(path)[0] == '.') if (baseName(path).startsWith('.'))
{ {
return(false); return false;
} }
} }
QFileInfo thePath(path); QFileInfo thePath(path);
QDir parentDir = thePath.dir();
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 (thePath.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(parentDir.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 (thePath.exists())
{ {
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(void) QString StelFileMgr::getDesktopDir()
{ {
QString result; QString result;
#if defined(WIN32) #ifdef Q_OS_WIN
result = getWin32SpecialDirPath(CSIDL_DESKTOPDIRECTORY); result = getWin32SpecialDirPath(CSIDL_DESKTOPDIRECTORY);
#else #else
// TODO: this is not going to work for machines which are non-Englis h... // TODO: this is not going to work for machines which are non-Englis h...
// For Linux and perhaps some BSDs, we can call the external program // For Linux and perhaps some BSDs, we can call the external program
// "xdg-user-dir DESKTOP" if it exists, but I'm not sure about OSX. // "xdg-user-dir DESKTOP" if it exists, but I'm not sure about OSX.
result = QFile::decodeName(getenv("HOME")); result = QFile::decodeName(getenv("HOME"));
result += "/Desktop"; result += "/Desktop";
#endif #endif
if (!QFileInfo(result).isDir()) if (!QFileInfo(result).isDir())
{ {
throw(std::runtime_error("NOT FOUND")); throw std::runtime_error("Can't find Desktop directory");
} }
return result; return result;
} }
QString StelFileMgr::getUserDir(void) QString StelFileMgr::getUserDir()
{ {
return userDir; return userDir;
} }
void StelFileMgr::setUserDir(const QString& newDir) void StelFileMgr::setUserDir(const QString& newDir)
{ {
makeSureDirExistsAndIsWritable(newDir);
QFileInfo userDirFI(newDir); QFileInfo userDirFI(newDir);
if (!userDirFI.exists() || !userDirFI.isDir())
{
qWarning() << "WARNING StelFileMgr::setUserDir user dir does
not exist: "
<< userDirFI.filePath();
throw (std::runtime_error("NOT_VALID"));
}
else if (!userDirFI.isWritable())
{
qWarning() << "WARNING StelFileMgr::setUserDir user dir is n
ot writable: "
<< userDirFI.filePath();
throw (std::runtime_error("NOT_VALID"));
}
userDir = userDirFI.filePath(); userDir = userDirFI.filePath();
fileLocations.replace(0, userDir); fileLocations.replace(0, userDir);
} }
QString StelFileMgr::getInstallationDir(void) QString StelFileMgr::getInstallationDir()
{ {
// If we are running from the build tree, we use the files from ther e... // If we are running from the build tree, we use the files from ther e...
if (QFileInfo(CHECK_FILE).exists()) if (QFileInfo(CHECK_FILE).exists()){
return "."; return ".";
}
#if defined(MACOSX) #ifdef Q_OS_MAC
QFileInfo MacOSdir(QCoreApplication::applicationDirPath()); QFileInfo MacOSdir(QCoreApplication::applicationDirPath() + "/../Res
ources");
QDir ResourcesDir = MacOSdir.dir(); QDir ResourcesDir = MacOSdir.dir();
ResourcesDir.cd(QString("Resources")); ResourcesDir.cd(QString("Resources"));
QFileInfo installLocation(ResourcesDir.absolutePath()); QFileInfo installLocation(ResourcesDir.absolutePath());
QFileInfo checkFile(installLocation.filePath() + QString("/") + QStr ing(CHECK_FILE)); QFileInfo checkFile(installLocation.filePath() + QString("/") + QStr ing(CHECK_FILE));
#else #else
// Linux, BSD, Solaris etc. // Linux, BSD, Solaris etc.
// We use the value from the config.h filesystem // We use the value from the config.h filesystem
QFileInfo installLocation(QFile::decodeName(INSTALL_DATADIR)); QFileInfo installLocation(QFile::decodeName(INSTALL_DATADIR));
QFileInfo checkFile(QFile::decodeName(INSTALL_DATADIR "/" CHECK_FILE )); QFileInfo checkFile(QFile::decodeName(INSTALL_DATADIR "/" CHECK_FILE ));
#endif #endif
skipping to change at line 382 skipping to change at line 360
return installLocation.filePath(); return installLocation.filePath();
} }
else else
{ {
qWarning() << "WARNING StelFileMgr::StelFileMgr: could not f ind install location:" qWarning() << "WARNING StelFileMgr::StelFileMgr: could not f ind install location:"
<< installLocation.filePath() << " (we checked for " << checkFile.filePath() << ")."; << installLocation.filePath() << " (we checked for " << checkFile.filePath() << ").";
throw (std::runtime_error("NOT FOUND")); throw (std::runtime_error("NOT FOUND"));
} }
} }
QString StelFileMgr::getScreenshotDir(void) 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);
if (!userDirFI.exists() || !userDirFI.isDir()) if (!userDirFI.exists() || !userDirFI.isDir())
{ {
qWarning() << "WARNING StelFileMgr::setScreenshotDir dir doe qWarning() << "WARNING StelFileMgr::setScreenshotDir dir doe
s not exist: " s not exist: " << userDirFI.filePath();
<< userDirFI.filePath(); throw std::runtime_error("NOT_VALID");
throw (std::runtime_error("NOT_VALID"));
} }
else if (!userDirFI.isWritable()) else if (!userDirFI.isWritable())
{ {
qWarning() << "WARNING StelFileMgr::setScreenshotDir dir is qWarning() << "WARNING StelFileMgr::setScreenshotDir dir is
not writable: " not writable: " << userDirFI.filePath();
<< userDirFI.filePath(); throw std::runtime_error("NOT_VALID");
throw (std::runtime_error("NOT_VALID"));
} }
screenshotDir = userDirFI.filePath(); screenshotDir = userDirFI.filePath();
} }
QString StelFileMgr::getLocaleDir(void) QString StelFileMgr::getLocaleDir()
{ {
QFileInfo localePath; QFileInfo localePath;
#if defined(WIN32) || defined(CYGWIN) || defined(__MINGW32__) || defined(MI NGW32) || defined(MACOSX) #if defined(Q_OS_WIN) || defined(Q_OS_MAC)
// Windows and MacOS X have the locale dir in the installation folde r // Windows and MacOS X have the locale dir in the installation folde r
// TODO: check if this works with OSX
localePath = QFileInfo(getInstallationDir() + "/locale"); localePath = QFileInfo(getInstallationDir() + "/locale");
// or MacosxDirs::getApplicationResourcesDirectory().append( "/local e" );
#else #else
// Linux, BSD etc, the locale dir is set in the config.h // 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 // but first, if we are in the development tree, don't rely on an
// install having been done. // install having been done.
if (getInstallationDir() == ".") if (getInstallationDir() == ".")
{ {
localePath = QFileInfo("./locale"); localePath = QFileInfo("./locale");
if (!localePath.exists()) if (!localePath.exists())
localePath = QFileInfo(QFile::decodeName(INSTALL_LOC ALEDIR)); localePath = QFileInfo(QFile::decodeName(INSTALL_LOC ALEDIR));
} }
else else
localePath = QFileInfo(QFile::decodeName(INSTALL_LOCALEDIR)) ; localePath = QFileInfo(QFile::decodeName(INSTALL_LOCALEDIR)) ;
#endif #endif
if (localePath.exists()) if (localePath.exists())
{ {
return localePath.filePath(); return localePath.filePath();
} }
else else
{ {
qWarning() << "WARNING in StelFileMgr::getLocaleDir() - coul d not determine locale directory, returning \"\""; qWarning() << "WARNING in StelFileMgr::getLocaleDir() - coul d not determine locale directory, returning \"\"";
return ""; return "";
} }
} }
#if defined(WIN32) // Returns the path to the cache directory. Note that subdirectories may ne
ed to be created for specific caches.
QString StelFileMgr::getCacheDir()
{
const QString& cachePath = QDesktopServices::storageLocation(QDeskto
pServices::CacheLocation);
if (cachePath.isEmpty())
{
return getUserDir()+"/cache";
}
return cachePath;
}
QString StelFileMgr::getWin32SpecialDirPath(const int csidlId) void StelFileMgr::makeSureDirExistsAndIsWritable(const QString& dirFullPath
)
{
// Check that the dirFullPath directory exists
QFileInfo uDir(dirFullPath);
if (!uDir.exists())
{
// The modules directory doesn't exist, lets create it.
qDebug() << "Creates directory " << uDir.filePath();
if (!QDir("/").mkpath(uDir.filePath()))
{
throw std::runtime_error(QString("Could not create d
irectory: " +uDir.filePath()).toStdString());
}
}
if (!uDir.isWritable())
{
throw std::runtime_error(QString("Directory is not writable:
" +uDir.filePath()).toStdString());
}
}
#ifdef Q_OS_WIN
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).
QLibrary library(QLatin1String("shell32")); QLibrary library(QLatin1String("shell32"));
QT_WA( { QT_WA( {
typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int , BOOL); typedef BOOL (WINAPI*GetSpecialFolderPath)(HWND, LPTSTR, int , BOOL);
GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFol derPath)library.resolve("SHGetSpecialFolderPathW"); GetSpecialFolderPath SHGetSpecialFolderPath = (GetSpecialFol derPath)library.resolve("SHGetSpecialFolderPathW");
if (SHGetSpecialFolderPath) if (SHGetSpecialFolderPath)
{ {
TCHAR tpath[MAX_PATH]; TCHAR tpath[MAX_PATH];
skipping to change at line 466 skipping to change at line 470
if (SHGetSpecialFolderPath) if (SHGetSpecialFolderPath)
{ {
char cpath[MAX_PATH]; char cpath[MAX_PATH];
SHGetSpecialFolderPath(0, cpath, csidlId, FALSE); SHGetSpecialFolderPath(0, cpath, csidlId, FALSE);
return QString::fromLocal8Bit(cpath); return QString::fromLocal8Bit(cpath);
} }
} ); } );
return QString(); return QString();
} }
#endif #endif
 End of changes. 66 change blocks. 
135 lines changed or deleted 138 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/