📄 ndir.cpp
字号:
#include "ndir.h"//#include <qtopia/global.h>//#include <qtopia/qcopenvelope_qws.h>#include <qapplication.h>#include <qdir.h>#include <qfileinfo.h>#include <assert.h>#include <ctype.h>#include <dirent.h>#include <stdlib.h>QStringList NDir::s_known_suffixes;static QString s_tmp_dirpath;static QStringList s_tmp_suffixlist;static bool s_use_namefilter= false;static bool s_exclude_sysdirs= false;static bool s_exclude_subdirs= false;typedef int(*dir_filter)(const struct dirent *);int dirfilter(const struct dirent *entry) { // hide files starting with a dot if(!strncmp(entry->d_name, ".", 1)) return 0; // shown known, wanted types QString suffix= QString(strrchr(entry->d_name, '.')).lower(); if(!suffix.isNull()) { if(s_use_namefilter && s_tmp_suffixlist.contains(suffix)) return 1; if(NDir::s_known_suffixes.contains(suffix)) return !s_use_namefilter; } // see whether the file is a dir, hide sysdirs and subdirs according to settings bool isdir= QFileInfo(s_tmp_dirpath + QString::fromUtf8(entry->d_name)).isDir(); if(isdir) { if(s_exclude_subdirs) { return false; } else if(s_exclude_sysdirs) { return strcmp(entry->d_name, "pda") && strcmp(entry->d_name, "System") && strcmp(entry->d_name, "Mophun") && strcmp(entry->d_name, "Recycled") && strcmp(entry->d_name, "System Volume Information"); } else { return true; } } else { return !s_use_namefilter; }}typedef int(*dir_sorter)(const void *, const void *);// does a case insensitive sort and puts the subdirs firstint sort_dirsfirst_alpha(const struct dirent **a, const struct dirent **b) { struct dirent ta, tb; struct dirent *pa= &ta, *pb= &tb; for(int i= 0; i <= NAME_MAX; i++) if((ta.d_name[i]= toupper((*a)->d_name[i])) == '\0') break; for(int i= 0; i <= NAME_MAX; i++) if((tb.d_name[i]= toupper((*b)->d_name[i])) == '\0') break; if(s_exclude_subdirs) { return alphasort(&pa, &pb); } else { bool aisdir= false; char *suffixa= strrchr((*a)->d_name, '.'); if(suffixa == NULL || !NDir::s_known_suffixes.contains(suffixa)) aisdir= QFileInfo(s_tmp_dirpath + QString::fromUtf8((*a)->d_name)).isDir(); bool bisdir= false; char *suffixb= strrchr((*b)->d_name, '.'); if(suffixb == NULL || !NDir::s_known_suffixes.contains(suffixb)) bisdir= QFileInfo(s_tmp_dirpath + QString::fromUtf8((*b)->d_name)).isDir(); return (bisdir * 1024) - (aisdir * 1024) + alphasort(&pa, &pb); }}//--------------------------------------------------///*! @internal @class NDir ndirview.h @brief Provides a list of directory entries.*/NDir::NDir(QObject *parent, const char *name) : QObject(parent, name) , m_filelist(NULL) , m_filecnt(0) , m_include_subdirs(true) { if(s_known_suffixes.isEmpty()) { s_known_suffixes+= ".mp3"; s_known_suffixes+= ".jpg"; s_known_suffixes+= ".avi"; s_known_suffixes+= ".png"; s_known_suffixes+= ".gif"; s_known_suffixes+= ".bmp"; s_known_suffixes+= ".m3u"; }// QCopChannel *ch= new QCopChannel("QPE/System", this);// connect(// ch, SIGNAL(received(const QCString&, const QByteArray&)), // this, SLOT(onReceived(const QCString&, const QByteArray&))// );}NDir::~NDir() { freeData();}void NDir::freeData() { while(m_filecnt-- > 0) free(m_filelist[m_filecnt]); free(m_filelist); m_filelist= NULL;}bool NDir::includesSubdirs() const { return m_include_subdirs;}void NDir::setIncludeSubdirs(bool enable) { m_include_subdirs= enable; updateEntries();}QString NDir::nameFilter() const { return m_suffixlist.join(" ");}/* example filter: ".jpg .png"*/void NDir::setNameFilter(const QString &filter) { m_suffixlist= QStringList::split(QRegExp("[;\\s]"), filter); updateEntries();}QString NDir::path() const { return m_dirpath;}bool NDir::setPath(const QString &path, bool show_waitindicator) {// if(show_waitindicator) {// { QCopEnvelope e("QPE/System", "busy()"); }// qApp->processEvents();// } QString oldpath(m_dirpath); m_dirpath= path; bool res= updateEntries(); if(m_dirpath != oldpath) emit dirChanged(path); // if(show_waitindicator) {// QCopEnvelope e("QPE/System", "notBusy(QString)");// e << qApp->name();// } return res;}bool NDir::updateEntries() { // a bit of a hack to provide data to the static functions s_tmp_dirpath= m_dirpath + '/'; s_tmp_suffixlist= m_suffixlist; s_use_namefilter= !m_suffixlist.isEmpty(); s_exclude_sysdirs= m_dirpath == "/media"; s_exclude_subdirs= !m_include_subdirs; freeData(); int res= scandir(m_dirpath.utf8(), &m_filelist, dirfilter, (dir_sorter) sort_dirsfirst_alpha); m_filecnt= QMAX(res, 0); emit entriesChanged(); return res >= 0;}QString NDir::nameAt(uint index) const { assert(index < m_filecnt); return QString::fromUtf8(m_filelist[index]->d_name);}QString NDir::pathAt(uint index) const { assert(index < m_filecnt); return m_dirpath + "/" + nameAt(index);}bool NDir::isDir(const QString &path) const { QString suffix= path.right(path.length() - path.findRev('.')); if(s_known_suffixes.contains(suffix)) { return false; } else { return QFileInfo(path).isDir(); }}uint NDir::count() const { return m_filecnt;}void NDir::broadcastFileChange(const QString &path) {// QCopEnvelope e("QPE/System", "filesChanged(QString)");// e << path;}void NDir::onReceived(const QCString &msg, const QByteArray &data) { if(msg == "filesChanged(QString)") { // update entries when a change of contents was broadcasted QDataStream din(data, IO_ReadOnly); QString path; din >> path; if(path == m_dirpath || path == "*") updateEntries(); } else if(msg == "postDirectAccess()") { // update entries after USB connection updateEntries(); }}void NDir::renameFile(const QString &path, const QString &newname) { QFileInfo fi(path); if(fi.dir().rename(fi.fileName(), newname)) broadcastFileChange(fi.dirPath());}QString NDir::ensureUniqueName(const QString &dirname, const QString &name) { QDir dir(dirname); if(!dir.exists(name)) return name; // separate suffix from the rest of the name QString lname= name; QString suffix= ""; int pos= name.findRev('.'); if(pos >= 0) { lname= name.left(pos); suffix= name.right(name.length() - pos); } // find out whether the name already ends with a number int cnt= 1; for(uint i= 1; i <= lname.length(); i++) { bool ok= false; int tmp= lname.right(i).toInt(&ok); if(ok) { cnt= tmp; } else { lname= lname.left(lname.length() - i + 1); break; } } lname= lname.stripWhiteSpace(); // count number up until we find a unique name QString res; do { res= lname + ' ' + QString::number(++cnt) + suffix; } while(dir.exists(res)); return res;}bool NDir::deleteFile(const QString &path) { QFileInfo fi(path);// Global::statusMessage(tr("Deleting %1").arg(fi.fileName())); qApp->processEvents(); bool res; if(fi.isDir()) { res= deleteDir(path); } else { res= QFile(path).remove(); } if(res) { broadcastFileChange(fi.dirPath()); return true; } else { return false; }}// deletes a directory recursivelybool NDir::deleteDir(const QString &path) { if(path.isNull() || path.isEmpty()) return false; QDir dir(path); const QFileInfoList *files= dir.entryInfoList(); if(files != NULL) { for(QFileInfoListIterator it(*files); (*it) != NULL; ++it) { if((*it)->isDir()) { if((*it)->fileName()!= "." && (*it)->fileName()!= "..") deleteDir((*it)->filePath()); } else dir.remove((*it)->filePath()); } } dir.rmdir(path); broadcastFileChange(path); return true;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -