diff options
| author | Arno <am@disconnect.de> | 2013-03-20 21:27:35 +0100 | 
|---|---|---|
| committer | Arno <am@disconnect.de> | 2013-03-20 21:27:35 +0100 | 
| commit | 03831d3669ea49a99a15aaf5d17724be8c533b85 (patch) | |
| tree | 618e3fe63b0430a4dbe604153ab588eb811fd183 | |
| parent | 457e5328c8fbbf236fb163e90d732a35a583fd2d (diff) | |
| download | SheMov-03831d3669ea49a99a15aaf5d17724be8c533b85.tar.gz SheMov-03831d3669ea49a99a15aaf5d17724be8c533b85.tar.bz2 SheMov-03831d3669ea49a99a15aaf5d17724be8c533b85.zip  | |
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.
| -rw-r--r-- | filesystemwidget.cpp | 16 | ||||
| -rw-r--r-- | shemov.cpp | 2 | ||||
| -rw-r--r-- | smdirmodel.cpp | 32 | ||||
| -rw-r--r-- | smdirmodel.h | 9 | ||||
| -rw-r--r-- | smdirwatcher.cpp | 96 | ||||
| -rw-r--r-- | smdirwatcher.h | 32 | 
6 files changed, 135 insertions, 52 deletions
diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp index 4b7a9c7..b842541 100644 --- a/filesystemwidget.cpp +++ b/filesystemwidget.cpp @@ -8,7 +8,6 @@  #include <QtWidgets/QFileSystemModel>  #include <QtWidgets/QTreeView>  #include <QSettings> -#include <QDir>  #include <QtWidgets/QSplitter>  #include <QtWidgets/QVBoxLayout>  #include <QtWidgets/QHBoxLayout> @@ -18,16 +17,12 @@  #include <QProcess>  #include <QtWidgets/QApplication>  #include <QtWidgets/QMessageBox> -#include <QFile>  #include <QtWidgets/QAction> -#include <QRegExp> -#include <QFile>  #include <QTextStream>  #include <QSqlQuery>  #include <QClipboard>  #include <QMimeData>  #include <QUrl> -#include <QList>  #include "filesystemwidget.h"  #include "filesystemdirproxy.h" @@ -40,13 +35,17 @@  #include "smdirmodel.h"  FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboardMode(None) { -	mModel = new FileSystemModel(this); +    mModel = new FileSystemModel(this);      mModel->setRootPath("/");  	mModel->setFilter(QDir::AllEntries | QDir::NoDot);  	mModel->setReadOnly(false);  	mIconProvider = new SheMovIconProvider;  	mModel->setIconProvider(mIconProvider); +    QStringList fHeaders = QStringList() << tr("Name") << tr("Size") << tr("Type") << tr("Created") << tr("Md5Sum") << tr("Duration") << tr("Bitrate") << tr("Full Path"); +    mFileModel = new SmDirModel(fHeaders, this); +    connect(mFileModel, SIGNAL(needResize()), this, SLOT(resizeFileView())); +  	mDirProxy = new FilesystemDirProxy;  	mDirProxy->setSourceModel(mModel);  	mDirView = new QTreeView; @@ -64,9 +63,7 @@ FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboar  	mFileView = new FileView;  	mFileProxy = new FilesystemFileProxy; -    QStringList fHeaders = QStringList() << tr("Name") << tr("Size") << tr("Type") << tr("Created") << tr("Md5Sum") << tr("Duration") << tr("Bitrate") << tr("Full Path"); -    mFileModel = new SmDirModel(fHeaders, this); -    connect(mFileModel, SIGNAL(needResize()), this, SLOT(resizeFileView())); +      mFileProxy->setSourceModel(mFileModel);  	mFileView->setModel(mFileProxy);  	mFileView->setSortingEnabled(true); @@ -114,7 +111,6 @@ FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboar  	splitter->setStretchFactor(0, 1);  	splitter->setStretchFactor(1, 2);  	mainLayout->addWidget(splitter); -  	setLayout(mainLayout);  } @@ -147,7 +147,7 @@ SheMov::SheMov(QWidget *parent, Qt::WindowFlags flags) : QMainWindow(parent, fla      splash.finish(this);  	mATree->seriesWidget()->readSettings();  	mATree->filesWidget()->filesTree()->readSettings(); -	mFSWidget->readSettings(); +    mFSWidget->readSettings();  	readSettings();  	mFSWidget->fileView()->setFocus(Qt::ActiveWindowFocusReason);  	mATree->filesWidget()->filesTree()->header()->resizeSections(QHeaderView::ResizeToContents); diff --git a/smdirmodel.cpp b/smdirmodel.cpp index cf2197a..914acff 100644 --- a/smdirmodel.cpp +++ b/smdirmodel.cpp @@ -21,14 +21,18 @@  #include "helper.h"  SmDirModel::SmDirModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mHeaders(headers){ +    mCollector = new SmDataGatherer(NumFields, this); +      mWatch = new SmDirWatcher(this);      connect(mWatch, SIGNAL(dwEvent(QString,int)), this, SLOT(dirEvent(QString,int))); -    connect(mWatch, SIGNAL(needRefresh()), this, SLOT(populate())); +    connect(mWatch, SIGNAL(needRefresh()), this, SLOT(refresh()));      mRunTimer = new QTimer(this);      mRunTimer->setInterval(2000);      connect(mRunTimer, SIGNAL(timeout()), mWatch, SLOT(start()));      mRunTimer->start();      readSettings(); + +    connect(mCollector, SIGNAL(population(SmTreeItem*)), this, SLOT(populate(SmTreeItem*)));  }  SmDirModel::~SmDirModel(){ @@ -112,13 +116,10 @@ QFileInfo SmDirModel::fileInfo(const QModelIndex &idx) const {  }  void SmDirModel::setDir(const QString &dir){ -    QFileInfo fi(dir); -    if(!fi.isDir()){ -        return; -    } -    mCur = dir; -    populate(); -    mWatch->setDir(dir); +    mCurrentDir = dir; +    mCollector->setCurrent(mCurrentDir); +    mCollector->start(); +    mWatch->setDir(mCurrentDir);  }  void SmDirModel::dirEvent(const QString &file, int e){ @@ -154,20 +155,11 @@ void SmDirModel::readSettings(){  }  void SmDirModel::refresh(){ -    populate(); +    mCollector->setCurrent(mCurrentDir); +    mCollector->start();  } -void SmDirModel::populate(){ -    SmTreeItem *root = new SmTreeItem(mHeaders.size()); -    QDir d = QDir(mCur); -    foreach(QFileInfo fi, d.entryInfoList()){ -        if(fi.fileName() == "."){ -            continue; -        } -        QList<QVariant> data = fileData(fi); -        SmTreeItem *n = new SmTreeItem(data, root); -        root->appendChild(n); -    } +void SmDirModel::populate(SmTreeItem *root){      setRoot(root);      emit needResize();  } diff --git a/smdirmodel.h b/smdirmodel.h index 3712cba..c8cc69c 100644 --- a/smdirmodel.h +++ b/smdirmodel.h @@ -23,12 +23,15 @@  class SmDirWatcher;  class QTimer;  class SmTreeItem; +class QMutex; +class SmDataGatherer;  class SmDirModel : public SmTreeModel {      Q_OBJECT      public:          enum CustomRoles { NameRole = Qt::UserRole + 1, SizeRole = Qt::UserRole + 2, TypeRole = Qt::UserRole + 3, CreatedRole = Qt::UserRole + 4, Md5sumRole = Qt::UserRole + 5, DurationRole = Qt::UserRole + 6, BitrateRole = Qt::UserRole + 7, FullPathRole = Qt::UserRole + 8 };          enum Fields { Name = 0, Size = 1, Type = 2, Created = 3, Md5sum = 4, Duration = 5, Bitrate = 6, FullPath = 7 }; +        enum { NumFields = 8 };          enum FileDate { Access, Modified, Status };          explicit SmDirModel(const QStringList &headers, QObject *parent = 0);          ~SmDirModel(); @@ -36,7 +39,6 @@ class SmDirModel : public SmTreeModel {          virtual bool setData(const QModelIndex &index, const QVariant &value, int role);          bool isDir(const QModelIndex &idx) const;          QFileInfo fileInfo(const QModelIndex &idx) const; -        QDir dir() const { return QDir(mCur); };      public slots:          void setDir(const QString &dir); @@ -45,7 +47,7 @@ class SmDirModel : public SmTreeModel {          void refresh();      private slots: -        void populate(); +        void populate(SmTreeItem *root);      signals:          void needResize(); @@ -54,9 +56,12 @@ class SmDirModel : public SmTreeModel {          const QList<QVariant> fileData(const QFileInfo &fi) const;          SmDirWatcher *mWatch;          QStringList mHeaders; +        QString mCurrentDir;          QString mCur;          QTimer *mRunTimer;          QMap<QString, QIcon> mIcons; +        QMutex *mCollectorMx; +        SmDataGatherer *mCollector;  };  #endif // SMDIRMODEL_H diff --git a/smdirwatcher.cpp b/smdirwatcher.cpp index 78dae2a..8650d3b 100644 --- a/smdirwatcher.cpp +++ b/smdirwatcher.cpp @@ -7,6 +7,8 @@  #include <QVarLengthArray>  #include <QMutexLocker> +#include <QDateTime> +#include <QDir>  #include <sys/inotify.h>  #include <stropts.h> @@ -15,6 +17,8 @@  #include <errno.h>  #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<char, 4096> 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<inotify_event*>(at); +    if(!e->len){ +        return; +    }      char *end = at + data.size();      while(at < end){ -        inotify_event *e = reinterpret_cast<inotify_event*>(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<QVariant> 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<QVariant> data = fileData(fi); +        SmTreeItem *newItem = new SmTreeItem(data, retval); +        retval->appendChild(newItem); +    } +    return retval; +} + +const QList<QVariant> SmDataGatherer::fileData(const QFileInfo &fi) const{ +    QList<QVariant> data; +    data << fi.fileName() << fi.size(); +    QString mime = Helper::mimeType(fi.absoluteFilePath()); +    data << mime; +    data << fi.lastModified(); +    QList<QVariant> si = QList<QVariant>() << QVariant() << QVariant(); +    if(mime.startsWith("video")){ +        si = Helper::duration(fi.absoluteFilePath()); +    } +    data << Helper::md5Sum(fi.absoluteFilePath()); +    data << si << fi.absoluteFilePath(); +    return data; +} diff --git a/smdirwatcher.h b/smdirwatcher.h index 0da5b4b..3167aeb 100644 --- a/smdirwatcher.h +++ b/smdirwatcher.h @@ -10,6 +10,11 @@  #include <QThread>  #include <QMutex> +#include <QList> +#include <QVariant> +#include <QFileInfo> + +class SmTreeItem;  class SmDirWatcher : public QThread {      Q_OBJECT @@ -33,4 +38,31 @@ class SmDirWatcher : public QThread {          QString mCurrent;  }; +class SmDataGatherer : public QThread { +    Q_OBJECT +    public: +        explicit SmDataGatherer(const int numFields, QObject *parent = 0); +        void setCurrent(const QString ¤t, int mode = -1); + +    public slots: +        void run(); +        //void setFile(const QString &fullPath, int event); +        //void populate(const QString &dir); + +    signals: +        void newData(const QList<QVariant>,int); +        void population(SmTreeItem*); +        void needRefresh(); + +     private: +        //QList<QList<QVariant> > populate(); +        SmTreeItem *populate(); +        const QList<QVariant> fileData(const QFileInfo &fi) const; +        QString mCurrent; +        QMutex mRunMx; +        QMutex mSetMx; +        int mMode; +        const int mNumFields; +}; +  #endif // SMDIRWATCHER_H  | 
