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 ControlBase * FileBrowserControl::takeInput(const std::string& msg) {
00040 if(options.size()==1 && options.front()==NULL)
00041 rebuildmenu();
00042 return ControlBase::takeInput(msg);
00043 }
00044
00045 void FileBrowserControl::setRoot(const std::string& path) {
00046 root=path;
00047 if(root[root.size()-1]=='/')
00048 root.erase(root.size()-1);
00049 paths.clear();
00050 }
00051
00052
00053 void FileBrowserControl::setPath(const std::string& path) {
00054 for(unsigned int i=0; i<path.size(); i++)
00055 if(path[i]!='/')
00056 paths.back().append(1,path[i]);
00057 else if(paths.back().size()!=0)
00058 paths.push_back(std::string());
00059 }
00060
00061
00062 std::string FileBrowserControl::makePath() {
00063 std::string path=root;
00064 for(unsigned int i=0; i<paths.size(); i++) {
00065 path+="/";
00066 path+=paths[i];
00067 }
00068 return path;
00069 }
00070
00071
00072 std::string FileBrowserControl::makePath(const std::string& filename) {
00073 std::string path=makePath();
00074 path.append("/");
00075 path.append(filename);
00076 return path;
00077 }
00078
00079 bool FileBrowserControl::match(const std::string& file, const std::string& filt) {
00080 unsigned int i=0;
00081 if(i==filt.size() && i==file.size())
00082 return true;
00083 if(i==filt.size() || i==file.size())
00084 return false;
00085 while(filt[i]!='*') {
00086 if(toupper(filt[i])!=toupper(file[i]))
00087 return false;
00088 i++;
00089 if(i==filt.size() && i==file.size())
00090 return true;
00091 if(i==filt.size() || i==file.size())
00092 return false;
00093 }
00094 i=filt.size()-1;
00095 unsigned int j=file.size()-1;
00096 while(filt[i]!='*') {
00097 if(toupper(filt[i])!=toupper(file[j]))
00098 return false;
00099 i--; j--;
00100 }
00101 return true;
00102 }
00103
00104 void FileBrowserControl::rebuildmenu() {
00105 clearSlots();
00106 DIR* dir=opendir(makePath().c_str());
00107 if(dir==NULL) {
00108 pushSlot(new ControlBase("Bad Path"));
00109 cout << "bad path: " << makePath() << endl;
00110 return;
00111 }
00112 if(paths.size()!=0 && recurse) {
00113 struct stat s;
00114 std::string path=makePath("..");
00115 int err=stat(path.c_str(),&s);
00116 if(err==0 && s.st_mode&S_IFDIR)
00117 pushSlot(new ControlBase(".."));
00118 }
00119 struct dirent * ent=readdir(dir);
00120 while(ent!=NULL) {
00121 if(strcmp(ent->d_name,".")!=0 && strcmp(ent->d_name,"..")!=0) {
00122 struct stat s;
00123 std::string path=(makePath(ent->d_name));
00124 int err=stat(path.c_str(),&s);
00125 if(err!=0) {
00126 cout << "File disappeared: " << path << endl;
00127 return;
00128 }
00129 if(s.st_mode&S_IFDIR) {
00130 if(recurse)
00131 pushSlot(new ControlBase(std::string(ent->d_name).append(1,'/')));
00132 } else {
00133 std::string nm=(makePath(ent->d_name));
00134 if(match(nm,filter))
00135 pushSlot(new ControlBase(ent->d_name));
00136 }
00137 }
00138 ent=readdir(dir);
00139 }
00140 closedir(dir);
00141 if(options.size()==0)
00142 pushSlot(new ControlBase("[empty directory]"));
00143 else {
00144 hilights.push_back(0);
00145
00146
00147
00148
00149
00150
00151
00152 }
00153 }
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166