Motivating example:
In a previous session, the application has stored some path selected by the user. In the meantime that path may have been deleted, moved, renamed or the drive unmounted. The application would now like to let the user browse for a path via a
QFileDialog
and for the user's convenience, the previous path is passed as the starting directory of the file dialog, as presumably the new path is likely to be near the old path. Unfortunately, ifQFileDialog
is given a starting path that does not exist, it defaults to the current working directory, which is very unlikely to be helpful to the user as it is typically the installation directory of the application.So we would like to preprocess the old path to point to a directory that actually exists before passing it to
QFileDialog
. If the old path doesn't exist, we'd like to replace it with the nearest directory that does.
So how does one take a file path (which may or may not exist) and search "up" that path until one finds something that actually exists in the filesystem?
These are the two approaches I've come up with so far, but suggestions for improvement would be very much appreciated.
QString GetNearestExistingAncestorOfPath(const QString & path)
{
if(QFileInfo::exists(path)) return path;
QDir dir(path);
if(!dir.makeAbsolute()) return {};
do
{
dir.setPath(QDir::cleanPath(dir.filePath(QStringLiteral(".."))));
}
while(!dir.exists() && !dir.isRoot());
return dir.exists() ? dir.path() : QString{};
}
QString GetNearestExistingAncestorOfPath(const QString & path)
{
if(QFileInfo::exists(path)) return path;
auto segments = QDir::cleanPath(path).split('/');
QDir dir(segments.takeFirst() + '/');
if(!dir.exists()) return {};
for(const auto & segment : qAsConst(segments))
{
if(!dir.cd(segment)) break;
}
return dir.path();
}