mirror of
git://projects.qi-hardware.com/gmenu2x.git
synced 2024-11-25 15:56:15 +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();
|
to.shrink_to_fit();
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileLister::browse(const string& path, bool clean)
|
bool FileLister::browse(const string& path, bool clean)
|
||||||
{
|
{
|
||||||
if (clean) {
|
if (clean) {
|
||||||
directories.clear();
|
directories.clear();
|
||||||
@ -79,7 +79,7 @@ void FileLister::browse(const string& path, bool clean)
|
|||||||
if (errno != ENOENT) {
|
if (errno != ENOENT) {
|
||||||
ERROR("Unable to open directory: %s\n", slashedPath.c_str());
|
ERROR("Unable to open directory: %s\n", slashedPath.c_str());
|
||||||
}
|
}
|
||||||
return;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
set<string, case_less> directorySet;
|
set<string, case_less> directorySet;
|
||||||
@ -157,6 +157,8 @@ void FileLister::browse(const string& path, bool clean)
|
|||||||
files.clear();
|
files.clear();
|
||||||
moveNames(move(fileSet), files);
|
moveNames(move(fileSet), files);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
string FileLister::operator[](uint x)
|
string FileLister::operator[](uint x)
|
||||||
|
@ -33,7 +33,14 @@ private:
|
|||||||
|
|
||||||
public:
|
public:
|
||||||
FileLister();
|
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 size() { return files.size() + directories.size(); }
|
||||||
unsigned int dirCount() { return directories.size(); }
|
unsigned int dirCount() { return directories.size(); }
|
||||||
|
@ -53,7 +53,10 @@ int Selector::exec(int startSelection) {
|
|||||||
FileLister fl;
|
FileLister fl;
|
||||||
fl.setShowDirectories(showDirectories);
|
fl.setShowDirectories(showDirectories);
|
||||||
fl.setFilter(link.getSelectorFilter());
|
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);
|
OffscreenSurface bg(*gmenu2x->bg);
|
||||||
drawTitleIcon(bg, link.getIconPath(), true);
|
drawTitleIcon(bg, link.getIconPath(), true);
|
||||||
@ -185,15 +188,15 @@ int Selector::exec(int startSelection) {
|
|||||||
result = false;
|
result = false;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
// ...fall through...
|
||||||
case InputManager::LEFT:
|
case InputManager::LEFT:
|
||||||
if (showDirectories) {
|
if (showDirectories) {
|
||||||
string::size_type p = dir.rfind("/", dir.size()-2);
|
string oldDir = dir;
|
||||||
if (p==string::npos || dir.length() < 2 || dir[0] != '/') {
|
dir = parentDir(dir);
|
||||||
|
if (dir == "/" && oldDir == "/") {
|
||||||
close = true;
|
close = true;
|
||||||
result = false;
|
result = false;
|
||||||
} else {
|
} else {
|
||||||
dir = dir.substr(0,p+1);
|
|
||||||
selected = 0;
|
selected = 0;
|
||||||
firstElement = 0;
|
firstElement = 0;
|
||||||
prepare(fl);
|
prepare(fl);
|
||||||
@ -227,12 +230,14 @@ int Selector::exec(int startSelection) {
|
|||||||
return result ? (int)selected : -1;
|
return result ? (int)selected : -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Selector::prepare(FileLister& fl) {
|
bool Selector::prepare(FileLister& fl) {
|
||||||
fl.browse(dir);
|
bool opened = fl.browse(dir);
|
||||||
|
|
||||||
screendir = dir;
|
screendir = dir;
|
||||||
if (!screendir.empty() && screendir[screendir.length() - 1] != '/') {
|
if (!screendir.empty() && screendir[screendir.length() - 1] != '/') {
|
||||||
screendir += "/";
|
screendir += "/";
|
||||||
}
|
}
|
||||||
screendir += "previews/";
|
screendir += "previews/";
|
||||||
|
|
||||||
|
return opened;
|
||||||
}
|
}
|
||||||
|
@ -35,7 +35,7 @@ private:
|
|||||||
LinkApp& link;
|
LinkApp& link;
|
||||||
std::string file, dir, screendir;
|
std::string file, dir, screendir;
|
||||||
|
|
||||||
void prepare(FileLister& fl);
|
bool prepare(FileLister& fl);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
Selector(GMenu2X *gmenu2x, LinkApp& link,
|
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) {
|
bool fileExists(const string &file) {
|
||||||
fstream fin;
|
fstream fin;
|
||||||
fin.open(file.c_str() ,ios::in);
|
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 strreplace(std::string orig, const std::string &search, const std::string &replace);
|
||||||
std::string cmdclean(std::string cmdline);
|
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) {
|
inline std::string trimExtension(std::string const& filename) {
|
||||||
return filename.substr(0, filename.rfind('.'));
|
return filename.substr(0, filename.rfind('.'));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user