1
0
mirror of git://projects.qi-hardware.com/gmenu2x.git synced 2024-11-22 11:46:14 +02:00

Deal gracefully with the selector being started on a non-existent dir

If directory browsing is enabled, fall back to the closest existing
parent directory. If directory browsing is disabled, show empty list.
This commit is contained in:
Maarten ter Huurne 2014-08-17 10:05:21 +02:00
parent 9e22b0328f
commit 0b0e278459
6 changed files with 40 additions and 11 deletions

View File

@ -63,7 +63,7 @@ static void moveNames(set<string, case_less>&& from, vector<string>& to)
to.shrink_to_fit();
}
void FileLister::browse(const string& path, bool clean)
bool FileLister::browse(const string& path, bool clean)
{
if (clean) {
directories.clear();
@ -79,7 +79,7 @@ void FileLister::browse(const string& path, bool clean)
if (errno != ENOENT) {
ERROR("Unable to open directory: %s\n", slashedPath.c_str());
}
return;
return false;
}
set<string, case_less> directorySet;
@ -157,6 +157,8 @@ void FileLister::browse(const string& path, bool clean)
files.clear();
moveNames(move(fileSet), files);
}
return true;
}
string FileLister::operator[](uint x)

View File

@ -33,7 +33,14 @@ private:
public:
FileLister();
void browse(const std::string& path, bool clean = true);
/**
* Scans the given directory.
* @param clean If true, start a new result set, if false add to the
* results from the previous scan.
* @return True iff the given directory could be opened.
*/
bool browse(const std::string& path, bool clean = true);
unsigned int size() { return files.size() + directories.size(); }
unsigned int dirCount() { return directories.size(); }

View File

@ -53,7 +53,10 @@ int Selector::exec(int startSelection) {
FileLister fl;
fl.setShowDirectories(showDirectories);
fl.setFilter(link.getSelectorFilter());
prepare(fl);
while (!prepare(fl) && showDirectories && dir != "/") {
// The given directory could not be opened; try parent.
dir = parentDir(dir);
}
OffscreenSurface bg(*gmenu2x->bg);
drawTitleIcon(bg, link.getIconPath(), true);
@ -185,15 +188,15 @@ int Selector::exec(int startSelection) {
result = false;
break;
}
// ...fall through...
case InputManager::LEFT:
if (showDirectories) {
string::size_type p = dir.rfind("/", dir.size()-2);
if (p==string::npos || dir.length() < 2 || dir[0] != '/') {
string oldDir = dir;
dir = parentDir(dir);
if (dir == "/" && oldDir == "/") {
close = true;
result = false;
} else {
dir = dir.substr(0,p+1);
selected = 0;
firstElement = 0;
prepare(fl);
@ -227,12 +230,14 @@ int Selector::exec(int startSelection) {
return result ? (int)selected : -1;
}
void Selector::prepare(FileLister& fl) {
fl.browse(dir);
bool Selector::prepare(FileLister& fl) {
bool opened = fl.browse(dir);
screendir = dir;
if (!screendir.empty() && screendir[screendir.length() - 1] != '/') {
screendir += "/";
}
screendir += "previews/";
return opened;
}

View File

@ -35,7 +35,7 @@ private:
LinkApp& link;
std::string file, dir, screendir;
void prepare(FileLister& fl);
bool prepare(FileLister& fl);
public:
Selector(GMenu2X *gmenu2x, LinkApp& link,

View File

@ -81,6 +81,13 @@ string readFileAsString(const char *filename) {
}
}
string parentDir(string const& dir) {
// Note that size() is unsigned, so for short strings the '- 2' wraps
// around and as a result the entire string is searched, which is fine.
auto p = dir.rfind('/', dir.size() - 2);
return p == string::npos ? "/" : dir.substr(0, p + 1);
}
bool fileExists(const string &file) {
fstream fin;
fin.open(file.c_str() ,ios::in);

View File

@ -52,6 +52,14 @@ std::string readFileAsString(const char *filename);
std::string strreplace(std::string orig, const std::string &search, const std::string &replace);
std::string cmdclean(std::string cmdline);
/**
* Returns the parent directory of the given directory path, or "/" if there is
* no parent.
* This function does not check the file system: it is only string manipulation.
* @return The parent directory path, including a trailing '/'.
*/
std::string parentDir(std::string const& dir);
inline std::string trimExtension(std::string const& filename) {
return filename.substr(0, filename.rfind('.'));
}