00001 #include "FileBrowserControl.h"
00002 #include <sys/types.h>
00003 #include <sys/stat.h>
00004 #include <unistd.h>
00005 #include <dirent.h>
00006
00007 ControlBase * FileBrowserControl::activate(MotionManager::MC_ID display, Socket * gui) {
00008 rebuildmenu();
00009 return ControlBase::activate(display,gui);
00010 }
00011
00012 ControlBase* FileBrowserControl::doSelect() {
00013 for(unsigned int i=0; i<hilights.size(); i++) {
00014 unsigned int cur=hilights[i];
00015 if(cur>=options.size() || options[cur]==NULL)
00016 continue;
00017 ControlBase::doSelect();
00018 std::string nm(options[cur]->getName());
00019 if(nm[nm.size()-1]=='/' || nm=="..") {
00020 if(hilights.size()>1)
00021 continue;
00022 if(nm=="..")
00023 paths.pop_back();
00024 else
00025 paths.push_back(nm.substr(0,nm.size()-1));
00026 rebuildmenu();
00027 refresh();
00028 return this;
00029 } else {
00030 ControlBase * ret=selectedFile(makePath(nm));
00031 if(ret!=this)
00032 return ret;
00033 }
00034 }
00035 refresh();
00036 return this;
00037 }
00038
00039 void FileBrowserControl::setRoot(const std::string& path) {
00040 root=path;
00041 if(root[root.size()-1]=='/')
00042 root.erase(root.size()-1);
00043 paths.clear();
00044 }
00045
00046
00047 void FileBrowserControl::setPath(const std::string& path) {
00048 for(unsigned int i=0; i<path.size(); i++)
00049 if(path[i]!='/')
00050 paths.back().append(1,path[i]);
00051 else if(paths.back().size()!=0)
00052 paths.push_back(std::string());
00053 }
00054
00055
00056 std::string FileBrowserControl::makePath() {
00057 std::string path=root;
00058 for(unsigned int i=0; i<paths.size(); i++) {
00059 path+="/";
00060 path+=paths[i];
00061 }
00062 return path;
00063 }
00064
00065
00066 std::string FileBrowserControl::makePath(const std::string& filename) {
00067 std::string path=makePath();
00068 path.append("/");
00069 path.append(filename);
00070 return path;
00071 }
00072
00073 bool FileBrowserControl::match(const std::string& file, const std::string& filt) {
00074 unsigned int i=0;
00075 if(i==filt.size() && i==file.size())
00076 return true;
00077 if(i==filt.size() || i==file.size())
00078 return false;
00079 while(filt[i]!='*') {
00080 if(toupper(filt[i])!=toupper(file[i]))
00081 return false;
00082 i++;
00083 if(i==filt.size() && i==file.size())
00084 return true;
00085 if(i==filt.size() || i==file.size())
00086 return false;
00087 }
00088 i=filt.size()-1;
00089 unsigned int j=file.size()-1;
00090 while(filt[i]!='*') {
00091 if(toupper(filt[i])!=toupper(file[j]))
00092 return false;
00093 i--; j--;
00094 }
00095 return true;
00096 }
00097
00098 void FileBrowserControl::rebuildmenu() {
00099 clearSlots();
00100 DIR* dir=opendir(makePath().c_str());
00101 if(dir==NULL) {
00102 pushSlot(new ControlBase("Bad Path"));
00103 cout << "bad path: " << makePath() << endl;
00104 return;
00105 }
00106 if(paths.size()!=0 && recurse) {
00107 struct stat s;
00108 std::string path=makePath("..");
00109 int err=stat(path.c_str(),&s);
00110 if(err==0 && s.st_mode&S_IFDIR)
00111 pushSlot(new ControlBase(".."));
00112 }
00113 struct dirent * ent=readdir(dir);
00114 while(ent!=NULL) {
00115 if(strcmp(ent->d_name,".")!=0 && strcmp(ent->d_name,"..")!=0) {
00116 struct stat s;
00117 std::string path=(makePath(ent->d_name));
00118 int err=stat(path.c_str(),&s);
00119 if(err!=0) {
00120 cout << "File disappeared: " << path << endl;
00121 return;
00122 }
00123 if(s.st_mode&S_IFDIR) {
00124 if(recurse)
00125 pushSlot(new ControlBase(std::string(ent->d_name).append(1,'/')));
00126 } else {
00127 std::string nm=(makePath(ent->d_name));
00128 if(match(nm,filter))
00129 pushSlot(new ControlBase(ent->d_name));
00130 }
00131 }
00132 ent=readdir(dir);
00133 }
00134 closedir(dir);
00135 if(options.size()==0)
00136 pushSlot(new ControlBase("[empty directory]"));
00137 else {
00138 hilights.push_back(0);
00139
00140
00141
00142
00143
00144
00145
00146 }
00147 }
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160