From 03831d3669ea49a99a15aaf5d17724be8c533b85 Mon Sep 17 00:00:00 2001 From: Arno Date: Wed, 20 Mar 2013 21:27:35 +0100 Subject: Use a Thread for collecting file data blocking the GUI isn't nice, so use a separate Thread to gather all the data for SmDirModel. Populating and changing directory works, but modifying a file is most likely broken. --- smdirwatcher.cpp | 96 +++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 77 insertions(+), 19 deletions(-) (limited to 'smdirwatcher.cpp') diff --git a/smdirwatcher.cpp b/smdirwatcher.cpp index 78dae2a..8650d3b 100644 --- a/smdirwatcher.cpp +++ b/smdirwatcher.cpp @@ -7,6 +7,8 @@ #include #include +#include +#include #include #include @@ -15,6 +17,8 @@ #include #include "smdirwatcher.h" +#include "smtreeitem.h" +#include "helper.h" extern int errno; @@ -34,11 +38,11 @@ void SmDirWatcher::setDir(const QString &dir){ inotify_rm_watch(mFd, mDescr); //generates IN_IGNORE ??? } /* mask rationale: - * IN_DELETE_SELF, IN_MOVE_TO and IN_MOVE_FROM cannot happen, - * since we're only watching one directory at all times - * don't care about the other events + * IN_DELETE_SELF cannot happen since we're only + * watching one directory at all time. + * We don't care about the other events */ - mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM); + mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO); mCurrent = dir; } @@ -46,40 +50,94 @@ void SmDirWatcher::run(){ QMutexLocker lock(&mWatchMx); QVarLengthArray data(4096); int r = read(mFd, data.data(), data.size()); - while(r < 0){ - int err = errno; - // buffer too small - if(err == EINVAL){ - data.resize(data.size() * 2); - r = read(mFd, data.data(), data.size()); - continue; - // dunno - }else{ + int err = errno; + if(r < 0){ + if(err != EAGAIN){ return; } + r = read(mFd, data.data(), data.size()); } // inspect data char *at = data.data(); + inotify_event *e = reinterpret_cast(at); + if(!e->len){ + return; + } char *end = at + data.size(); while(at < end){ - inotify_event *e = reinterpret_cast(at); if(e->mask & IN_IGNORED){ at += sizeof(inotify_event) + e->len; continue; } + quint32 mask = e->mask; QString name = QString("%1/%2").arg(mCurrent).arg(e->name); - if(e->mask & IN_CREATE){ + at += sizeof(inotify_event) + e->len; + if(mask & IN_CREATE){ emit dwEvent(name, Added); + return; } - if(e->mask & IN_DELETE){ + if(mask & IN_DELETE){ emit dwEvent(name, Deleted); + return; } - if(e->mask & IN_CLOSE_WRITE || e->mask & IN_MODIFY){ + if(mask & IN_CLOSE_WRITE || e->mask & IN_MODIFY){ emit dwEvent(name, Modified); + return; } - if(e->mask & IN_MOVED_FROM){ + if(mask & IN_MOVED_FROM || e->mask & IN_MOVED_TO){ emit needRefresh(); + return; } - at += sizeof(inotify_event) + e->len; } } + +SmDataGatherer::SmDataGatherer(const int numFields, QObject *parent) : QThread(parent), mNumFields(numFields) {} + +void SmDataGatherer::setCurrent(const QString ¤t, int mode){ + QMutexLocker lock(&mSetMx); + mCurrent = current; + mMode = mode; +} + +void SmDataGatherer::run(){ + QMutexLocker lock(&mRunMx); + QFileInfo fi(mCurrent); + if(fi.isDir()){ + SmTreeItem *rv = populate(); + emit population(rv); + return; + } + if(fi.isFile()){ + QList fd = fileData(fi); + emit newData(fd, mMode); + } +} + +SmTreeItem * SmDataGatherer::populate(){ + SmTreeItem *retval = new SmTreeItem(mNumFields); + QDir d = QDir(mCurrent); + foreach(QFileInfo fi, d.entryInfoList()){ + if(fi.fileName() == "."){ + continue; + } + QList data = fileData(fi); + SmTreeItem *newItem = new SmTreeItem(data, retval); + retval->appendChild(newItem); + } + return retval; +} + +const QList SmDataGatherer::fileData(const QFileInfo &fi) const{ + QList data; + data << fi.fileName() << fi.size(); + QString mime = Helper::mimeType(fi.absoluteFilePath()); + data << mime; + data << fi.lastModified(); + QList si = QList() << QVariant() << QVariant(); + if(mime.startsWith("video")){ + si = Helper::duration(fi.absoluteFilePath()); + } + data << Helper::md5Sum(fi.absoluteFilePath()); + data << si << fi.absoluteFilePath(); + return data; +} -- cgit v1.2.3-70-g09d2