std::vector<std::string> Utils::getFiles(const std::string &folder, const bool all /* = true */) { std::vector<std::string> files; std::list<std::string> subfolders; subfolders.push_back(folder); #ifdef OS_WINDOWS while (!subfolders.empty()) { std::string current_folder(subfolders.back()); if (*(current_folder.end() - 1) != '/') { current_folder.append("/*"); } else { current_folder.append("*"); } subfolders.pop_back(); struct _finddata_t file_info; auto file_handler = _findfirst(current_folder.c_str(), &file_info); while (file_handler != -1) { if (all && (!strcmp(file_info.name, ".") || !strcmp(file_info.name, ".."))) { if (_findnext(file_handler, &file_info) != 0) break; continue; } if (file_info.attrib & _A_SUBDIR) { // it's a sub folder if (all) { // will search sub folder std::string folder(current_folder); folder.pop_back(); folder.append(file_info.name); subfolders.push_back(folder.c_str()); } } else { // it's a file std::string file_path; // current_folder.pop_back(); file_path.assign(current_folder.c_str()).pop_back(); file_path.append(file_info.name); files.push_back(file_path); } if (_findnext(file_handler, &file_info) != 0) break; } // while _findclose(file_handler); } #elif defined(OS_LINUX) || defined(OS_UNIX) while (!subfolders.empty()) { std::string current_folder(subfolders.back()); if (*(current_folder.end() - 1) != '/') { current_folder.push_back('/'); } DIR* pdir = opendir(current_folder.c_str()); subfolders.pop_back(); if (!pdir) { continue; } dirent* dir = NULL; while ((dir = readdir(pdir)) != NULL) { // iterates the current folder, search file & sub folder struct stat st; if (all && (!strcmp(dir->d_name, ".") || !strcmp(dir->d_name, ".."))) { // must ignore . & .. continue; } if (!strcmp(dir->d_name, ".DS_Store")) { // in OSX, 'finder' will create .DS_Store continue; } std::string file_path; file_path.append(current_folder.c_str()); file_path.append(dir->d_name); if (lstat(file_path.c_str(), &st) < 0) { // perror("lstat"); continue; } if (S_ISDIR(st.st_mode)) { // it's a sub folder if (all) { // will search sub folder std::string subfolder(current_folder); subfolder.append(dir->d_name); subfolders.push_back(subfolder.c_str()); } } else { // it's a file files.push_back(file_path); } } // while closedir(pdir); } #endif return files; }
// recursive helper for CreateFolderMenu void wxFolderMenuData::AddSubFoldersToMenu(wxString& folderName, MFolder *folder, wxMenu *menu, size_t& id) { size_t nSubfolders = folder->GetSubfolderCount(); for ( size_t n = 0; n < nSubfolders; n++ ) { MFolder_obj subfolder(folder->GetSubfolder(n)); if ( !subfolder.IsOk() ) { FAIL_MSG( _T("no subfolder?") ); continue; } // to allow moving the messages to the parent folder, create an entry // for it here (but don't do it for the root folder) if ( (n == 0) && (folder->GetType() != MF_ROOT) ) { menu->Append(WXMENU_POPUP_FOLDER_MENU + id++, folder->GetName()); m_folderNames.Add(folderName); menu->AppendSeparator(); } wxString name = subfolder->GetName(); wxString subfolderName = folderName; if ( !!subfolderName ) { // there shouldn't be slash in the beginning subfolderName += '/'; } subfolderName += name; if ( subfolder->GetSubfolderCount() == 0 ) { // it's a simple menu item menu->Append(WXMENU_POPUP_FOLDER_MENU + id++, name); } else // subfolder has more subfolders, make it a submenu { wxMenu *submenu = new wxMenu; AddSubFoldersToMenu(subfolderName, subfolder, submenu, id); menu->Append(WXMENU_POPUP_FOLDER_MENU + id++, name, submenu); } // in any case, add it to the id->name map m_folderNames.Add(subfolderName); } }
void Folder::GetAllSubfolders(std::vector<Folder>* subfolders, bool recursive, int* err) const { DIR* dir = opendir(path().ToString().c_str()); if (!dir) { if (err) { *err = errno; } return; } dirent dentBuf = {0}; dirent* dent = NULL; while (readdir_r(dir, &dentBuf, &dent) == 0 && dent) { if ((strcmp("..", dentBuf.d_name) == 0) || (strcmp(".", dentBuf.d_name)) == 0) { continue; } struct stat st; if (fstatat(dirfd(dir), dentBuf.d_name, &st, 0) == 0) { if (S_ISDIR(st.st_mode)) { Folder subfolder(Path(path().ToString() + PATH_LITERAL('/') + dentBuf.d_name)); subfolders->push_back(subfolder); if (recursive) { subfolder.GetAllSubfolders(subfolders, recursive); } } } else { if (err) { *err = errno; } continue; } } closedir(dir); }
void FileSystemScanner::addFolders(Folder* parent) { tracer->sinvoked(__func__) << "with folder: " << parent->dir()->absPath() << endl; // get all folders in the current directory const QFileInfoList* subfolderlist = parent->dir()->entryInfoList(QDir::Dirs); if (subfolderlist) { QFileInfoListIterator iterator(*subfolderlist); QFileInfo* fileInfo = 0; while ((fileInfo = iterator.current()) != 0) { // ignore ./.. and hidden folders (beginning with .) // and ignore folders called 'ThumbNails' if (!fileInfo->fileName().startsWith(".") && mustHandleFolder(fileInfo->fileName()) ) { QDir subfolder(fileInfo->absFilePath()); tracer->sdebug(__func__) << "handling subfolder: " << subfolder.absPath() << endl; bool loopDetected = false; // we have to test if this folder is part of a loop or if it is the superfolder of an already added dir QString* alreadyAddedFolder; for (alreadyAddedFolder = m_loopDetectionHelper->first(); alreadyAddedFolder; alreadyAddedFolder = m_loopDetectionHelper->next()) { if (*alreadyAddedFolder == subfolder.canonicalPath()) { loopDetected = true; tracer->swarning(__func__) << "loop detected, not adding folder again: '" << fileInfo->absFilePath() << "' is pointing to '" << *alreadyAddedFolder << "'" << endl; emit(progress_loopDetected(fileInfo->absFilePath(), *alreadyAddedFolder)); break; } if ((*alreadyAddedFolder).startsWith(subfolder.canonicalPath(), true)) { loopDetected = true; tracer->swarning(__func__) << "loop detected, not adding folder because it is a super directory (" << subfolder.canonicalPath() << ") of an already added folder: '" << *alreadyAddedFolder << "'" << endl; emit(progress_loopDetected(subfolder.canonicalPath(), *alreadyAddedFolder)); break; } } if (!loopDetected) { Folder* existingFolder = 0; // we have to test if the folder is already processed to prevent endless loops QIntDictIterator<Folder> it(*m_engine->m_sourceDirDict); while (!existingFolder && it.current()) { Folder* current = it.current(); if (current->dir()->canonicalPath() == subfolder.canonicalPath()) { existingFolder = current; tracer->sdebug(__func__) << "folder is already added: " << current->dir()->canonicalPath() << endl; emit(progress_folderAlreadyAdded(current->dir()->canonicalPath())); } ++it; } if (existingFolder) { // add the directory to the list of handled directories for detecting loops m_loopDetectionHelper->append(new QString(existingFolder->dir()->canonicalPath())); // make recursive call addFolders(existingFolder); } else { tracer->sdebug(__func__) << "found new folder to add " << fileInfo->absFilePath() << endl; // create the new folder Folder* child = new Folder(m_engine->m_nextSourceDirId++, new QDir(fileInfo->absFilePath()), false); child->setFound(true); // add the current directory to the tree child->setParent(parent); // put the folder into the folder dictionary (id to folder map) m_engine->m_sourceDirDict->insert(child->id(), child); // add the directory to the list of handled directories for detcting loops m_loopDetectionHelper->append(new QString(child->dir()->canonicalPath())); // add all files in the current folder rescanFolder(child, false); emit(newFolder(child)); if (m_cancel) { return; } // make recursive call addFolders(child); } } } ++iterator; } } }