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:
parent
9e22b0328f
commit
0b0e278459
@ -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)
|
||||
|
@ -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(); }
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -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('.'));
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user