Tekkotsu Homepage
Demos
Overview
Downloads
Dev. Resources
Reference
Credits

FileBrowserControl.cc

Go to the documentation of this file.
00001 #include "FileBrowserControl.h"
00002 #include "NullControl.h"
00003 #include "Shared/Config.h"
00004 #include <sys/types.h>
00005 #include <sys/stat.h>
00006 #include <unistd.h>
00007 #include <dirent.h>
00008 
00009 using namespace std;
00010 
00011 ControlBase * FileBrowserControl::activate(MC_ID display, Socket * gui) {
00012   rebuildmenu();
00013   return ControlBase::activate(display,gui);
00014 }
00015 
00016 ControlBase* FileBrowserControl::doSelect() {
00017   for(unsigned int i=0; i<hilights.size(); i++) {
00018     unsigned int cur=hilights[i];
00019     if(cur>=options.size() || options[cur]==NULL)
00020       continue;
00021     ControlBase::doSelect();
00022     std::string nm(options[cur]->getName());
00023     if(nm[nm.size()-1]=='/' || nm=="..") {
00024       if(hilights.size()>1)
00025         continue;
00026       if(nm=="..")
00027         paths.pop_back();
00028       else
00029         paths.push_back(nm.substr(0,nm.size()-1));
00030       rebuildmenu();
00031       refresh();
00032       return this;
00033     } else {
00034       ControlBase * ret=selectedFile(makePath(nm));
00035       if(ret!=this)
00036         return ret;
00037     }
00038   }
00039   refresh();
00040   return this;
00041 }
00042 
00043 ControlBase * FileBrowserControl::takeInput(const std::string& msg) {
00044   if(msg.size()==0)
00045     return this;
00046   if(msg.find('/')==string::npos) {
00047     if(options.size()==1 && options.front()==NULL)
00048       rebuildmenu();
00049     return ControlBase::takeInput(msg);
00050   } else {
00051     string::size_type pos=msg.rfind('/');
00052     if(msg[0]=='/') {
00053       if(msg.substr(0,root.size())!=root)
00054         return this;
00055       if(msg.size()>root.size() && msg[root.size()]!='/')
00056         return this;
00057       paths.clear();
00058       if(pos<=root.size())
00059         return this;
00060       appendPath(msg.substr(root.size(),pos-root.size()));
00061     } else {
00062       appendPath(msg.substr(0,pos));
00063     }
00064     rebuildmenu();
00065     if(msg.size()>pos+1)
00066       return ControlBase::takeInput(msg.substr(pos+1));
00067     return this;
00068   }
00069 }
00070 
00071 void FileBrowserControl::setRoot(const std::string& path) {
00072   root=config->portPath(path);
00073   if(root[root.size()-1]=='/')
00074     root.erase(root.size()-1);
00075   paths.clear();
00076 }
00077 
00078 
00079 void FileBrowserControl::appendPath(const std::string& path) {
00080   paths.push_back(std::string());
00081   for(unsigned int i=0; i<path.size(); i++) {
00082     if(path[i]!='/')
00083       paths.back().append(1,path[i]);
00084     else if(paths.back().size()!=0)
00085       paths.push_back(std::string());
00086   }
00087 }
00088 
00089 
00090 std::string FileBrowserControl::makePath() {
00091   std::string path=root;
00092   for(unsigned int i=0; i<paths.size(); i++) {
00093     path+="/";
00094     path+=paths[i];
00095   }
00096   return path;
00097 }
00098 
00099 //! returns the path from root as a string, appends filename
00100 std::string FileBrowserControl::makePath(const std::string& filename) {
00101   std::string path=makePath();
00102   path.append("/");
00103   path.append(filename);
00104   return path;
00105 }
00106   
00107 bool FileBrowserControl::match(const std::string& file, const std::string& filt) {
00108   unsigned int i=0;
00109   if(i==filt.size() && i==file.size())
00110     return true;
00111   if(i==filt.size() || i==file.size())
00112     return false;
00113   while(filt[i]!='*') {
00114     if(toupper(filt[i])!=toupper(file[i]))
00115       return false;
00116     i++;
00117     if(i==filt.size() && i==file.size())
00118       return true;
00119     if(i==filt.size() || i==file.size())
00120       return false;
00121   }
00122   i=filt.size()-1;
00123   unsigned int j=file.size()-1;
00124   while(filt[i]!='*') {
00125     if(toupper(filt[i])!=toupper(file[j]))
00126       return false;
00127     i--; j--;
00128   }
00129   return true;
00130 }
00131 
00132 void FileBrowserControl::rebuildmenu() {
00133   clearSlots();
00134   DIR* dir=opendir(makePath().c_str());
00135   if(dir==NULL) {
00136     pushSlot(new NullControl("Bad Path: "+makePath(),makePath(),this));
00137     return;
00138   }
00139   if(paths.size()!=0 && recurse) {
00140     struct stat s;
00141     std::string path=makePath("..");
00142     int err=stat(path.c_str(),&s);
00143     if(err==0 && s.st_mode&S_IFDIR)
00144       pushSlot(new NullControl("..","go up a directory level",this));
00145   }
00146   std::map<std::string,std::string> files;
00147   struct dirent * ent=readdir(dir);
00148   while(ent!=NULL) {
00149     if(strcmp(ent->d_name,".")!=0 && strcmp(ent->d_name,"..")!=0) {
00150       struct stat s;
00151       std::string path=(makePath(ent->d_name));
00152       int err=stat(path.c_str(),&s);
00153       if(err!=0) {
00154         cout << "File disappeared: " << path << endl;
00155         return;
00156       }
00157       if(s.st_mode&S_IFDIR) {
00158         if(recurse)
00159           files[std::string(ent->d_name).append(1,'/')] = makePath(ent->d_name);
00160       } else {
00161         std::string nm=(makePath(ent->d_name));
00162         if(match(nm,filter))
00163           files[ent->d_name] = makePath(ent->d_name);
00164       }
00165     }
00166     ent=readdir(dir);
00167   }
00168   closedir(dir);
00169   for(std::map<std::string,std::string>::const_iterator fit=files.begin(); fit!=files.end(); ++fit)
00170     pushSlot(new NullControl(fit->first,fit->second,this));
00171   if(options.size()==0)
00172     pushSlot(new NullControl("[empty directory]",makePath(),this));
00173   else {
00174     hilights.push_back(0);
00175     /*  for(unsigned int i=0; i<hilights.size(); i++) {
00176         if(hilights[i]>=options.size()) {
00177         hilights.resize(i);
00178         cout << "hilights resized at " << i << endl;
00179         break;
00180         }
00181         }*/
00182   }
00183 }
00184 
00185 
00186 /*! @file
00187  * @brief Implements FileBrowserControl, which displays the contents of a directory
00188  * @author ejt (Creator)
00189  */
00190 

Tekkotsu v5.1CVS
Generated Mon May 9 04:58:38 2016 by Doxygen 1.6.3