bool FileExplorerUpdater::ParseSVNstate(const wxString &path, VCSstatearray &sa) { if(!wxFileName::DirExists(wxFileName(path,_T(".svn")).GetFullPath())) return false; wxArrayString output; int hresult=Exec(_T("svn stat -N ")+path,output); if(hresult!=0) return false; for(size_t i=0;i<output.GetCount();i++) { if(output[i].Len()<=7) break; VCSstate s; wxChar a=output[i][0]; switch(a) { case ' ': s.state=fvsVcUpToDate; break; case '?': s.state=fvsVcNonControlled; break; case 'A': s.state=fvsVcAdded; break; case 'M': s.state=fvsVcModified; break; case 'C': s.state=fvsVcConflict; break; case 'D': s.state=fvsVcMissing; break; case 'I': s.state=fvsVcNonControlled; break; case 'X': s.state=fvsVcExternal; break; case '!': s.state=fvsVcMissing; break; case '~': s.state=fvsVcLockStolen; break; default: break; } #ifdef __WXMSW__ wxFileName f(output[i].Mid(1).Strip(wxString::both)); f.MakeAbsolute(path); s.path=f.GetFullPath(); #else s.path=wxFileName(output[i].Mid(1).Strip(wxString::both)).GetFullPath(); #endif sa.Add(s); } return true; }
bool FileExplorerUpdater::ParseHGstate(const wxString &path, VCSstatearray &sa) { wxString parent=path; while(true) { if(wxFileName::DirExists(wxFileName(parent,_T(".hg")).GetFullPath())) break; wxString oldparent=parent; parent=wxFileName(parent).GetPath(); if(oldparent==parent||parent.IsEmpty()) return false; } if(parent.IsEmpty()) return false; wxArrayString output; wxString wdir=wxGetCwd(); wxSetWorkingDirectory(path); //TODO: Check if thread safe! int hresult=Exec(_T("hg -y stat ."),output); wxSetWorkingDirectory(wdir); if(hresult!=0) return false; for(size_t i=0;i<output.GetCount();i++) { if(output[i].Len()<=2) break; VCSstate s; wxChar a=output[i][0]; switch(a) { case 'C': //clean s.state=fvsVcUpToDate; break; case '?': //not tracked s.state=fvsVcNonControlled; break; case '!': // local copy removed -- will not see this file s.state=fvsVcMissing; break; case 'A': // added s.state=fvsVcAdded; break; case 'R': //removed from branch, but exists in local copy s.state=fvsVcMissing; break; case 'M': //modified s.state=fvsVcModified; break; default: break; } wxFileName f(output[i].Mid(2)); f.MakeAbsolute(path); s.path=f.GetFullPath(); sa.Add(s); } return true; }
bool FileExplorerUpdater::ParseCVSstate(const wxString &path, VCSstatearray &sa) { wxArrayString output; wxString wdir=wxGetCwd(); wxSetWorkingDirectory(path); Exec(_T("cvs stat -q -l ."),output); wxSetWorkingDirectory(wdir); // if(hresult!=0) // return false; for(size_t i=0;i<output.GetCount();i++) { int ind1=output[i].Find(_T("File: ")); int ind2=output[i].Find(_T("Status: ")); if(ind1<0||ind2<0) return false; wxString state=output[i].Mid(ind2+8).Strip(); VCSstate s; while(1) { if(state==_T("Up-to-date")) { s.state=fvsVcUpToDate; break; } if(state==_T("Locally Modified")) { s.state=fvsVcModified; break; } if(state==_T("Locally Added")) { s.state=fvsVcAdded; break; } break; } wxFileName f(output[i].Mid(ind1+6,ind2+6-ind1).Strip()); f.MakeAbsolute(path); s.path=f.GetFullPath(); sa.Add(s); } if(output.GetCount()>0) return true; else return false; }
// called from Thread::Entry bool FileExplorerUpdater::GetCurrentState(const wxString &path) { //wxString wildcard=m_fe->m_WildCards->GetValue(); // m_Tree->DeleteChildren(ti); //Don't delete everything, we will add new files/dirs, remove deleted files/dirs and update state of all other files. m_currentstate.clear(); wxDir dir(path); if (!dir.IsOpened()) { // deal with the error here - wxDir would already log an error message // explaining the exact reason for the failure return false; } wxString filename; int flags=wxDIR_FILES|wxDIR_DIRS; if(m_fe->m_show_hidden) flags|=wxDIR_HIDDEN; VCSstatearray sa; bool is_vcs=false; bool is_cvs=false; // TODO: THIS NEEDS TO BE CALLED FROM MAIN THREAD BUT CAN'T BE UI-BLOCKING (CAN'T CALL wxExecute FROM THREADS) // TODO: IDEALLY THE VCS COMMAND LINE PROGRAM SHOULD BE CALLED ONCE ON THE BASE DIRECTORY (SINCE THEY ARE USUALLY RECURSIVE) TO AVOID REPEATED CALLS FOR SUB-DIRS if(m_fe->m_parse_svn) if(ParseSVNstate(path,sa)) is_vcs=true; if(m_fe->m_parse_bzr && !is_vcs) if(ParseBZRstate(path,sa)) is_vcs=true; if(m_fe->m_parse_hg && !is_vcs) if(ParseHGstate(path,sa)) is_vcs=true; /* if(m_fe->m_parse_cvs && !is_vcs) if(ParseCVSstate(path,sa)) { is_vcs=true; is_cvs=true; }*/ bool cont = dir.GetFirst(&filename,wxEmptyString,flags); while ( cont && !TestDestroy() && !m_kill) { int itemstate; bool match=true; wxString fullpath=wxFileName(path,filename).GetFullPath(); if(wxFileName::DirExists(fullpath)) itemstate=fvsFolderOpen; if(wxFileName::FileExists(fullpath)) { if(is_vcs&&!is_cvs) itemstate=fvsVcUpToDate; else itemstate=fvsNormal; wxFileName fn(path,filename); #if wxCHECK_VERSION(2,8,0) if(!fn.IsFileWritable()) itemstate=fvsReadOnly; #endif int deli=-1; for(size_t i=0;i<sa.GetCount();i++) { if(fn.SameAs(sa[i].path)) { itemstate=sa[i].state; deli=i; break; } } if(deli>=0) sa.RemoveAt(deli); if(!WildCardListMatch(m_wildcard,filename,true)) match=false; } if(match) { FileData fd; fd.name=filename; fd.state=itemstate; m_currentstate.push_back(fd); } cont = dir.GetNext(&filename); } return !TestDestroy(); }
bool FileExplorerUpdater::ParseBZRstate(const wxString &path, VCSstatearray &sa) { wxString parent=path; while(true) { if(wxFileName::DirExists(wxFileName(parent,_T(".bzr")).GetFullPath())) break; wxString oldparent=parent; parent=wxFileName(parent).GetPath(); if(oldparent==parent||parent.IsEmpty()) return false; } if(parent.IsEmpty()) return false; wxArrayString output; wxString rpath=parent; #ifdef __WXMSW__ int hresult=Exec(_T("cmd /c bzr stat --short ")+path,output); #else int hresult=Exec(_T("bzr stat --short ")+path,output); #endif if(hresult!=0) { return false; } for(size_t i=0;i<output.GetCount();i++) { if(output[i].Len()<=4) break; VCSstate s; wxChar a=output[i][0]; switch(a) { case '+': s.state=fvsVcUpToDate; break; case '-': s.state=fvsVcNonControlled; break; // case 'C': // s.state=fvsVcConflict; // break; case '?': s.state=fvsVcNonControlled; break; case 'R': s.state=fvsVcModified; break; case 'P': //pending merge s.state=fvsVcOutOfDate; break; } a=output[i][1]; switch(a) { case 'N': // created s.state=fvsVcAdded; break; case 'D': //deleted s.state=fvsVcMissing; break; case 'K': //kind changed case 'M': //modified s.state=fvsVcModified; break; } if(output[i][0]=='C') s.state=fvsVcConflict; wxFileName f(output[i].Mid(4)); f.MakeAbsolute(rpath); s.path=f.GetFullPath(); sa.Add(s); } return true; }