From ce402f298b2f9733b614fbf1bde99a052d0ab5c0 Mon Sep 17 00:00:00 2001 From: Arno Date: Thu, 21 Mar 2013 16:14:54 +0100 Subject: Final inotify! A huge commit, I know, but it was definitely worth it! It makes the homebrew FilesystemModel work! It's divided up into two threads: 1. The Watcher: it reacts on inotify events and dispatches them to: 2. The Collector: this thread gathers the data and emits the SIGNALS to the the view. Now we can actually refresh the View, not possible with QFileSystemModel, and the data reloads in almost real time without blocking the GUI. Unfortunately this uncovered some bugs I had to fix: 1. Helper::md5sum: Don't crash if read fails with -1 2. SmTreeModel::addRow is broken. Even after 5h I couldn't figure out how or why, so I brute forced it. Reset the moded when a file is added. 3. Get rid of a lot of unneeded #include's I guess that's about it... --- smdirmodel.cpp | 51 ++++++++++++++++++++++++++++++++++----------------- 1 file changed, 34 insertions(+), 17 deletions(-) (limited to 'smdirmodel.cpp') diff --git a/smdirmodel.cpp b/smdirmodel.cpp index 914acff..d24fdef 100644 --- a/smdirmodel.cpp +++ b/smdirmodel.cpp @@ -5,14 +5,9 @@ 2 of the License, or (at your option) any later version. */ -#include #include -#include #include #include -#include - -#include #include "smdirmodel.h" #include "smdirwatcher.h" @@ -21,10 +16,7 @@ #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(refresh())); mRunTimer = new QTimer(this); mRunTimer->setInterval(2000); @@ -32,7 +24,9 @@ SmDirModel::SmDirModel(const QStringList &headers, QObject *parent) : SmTreeMode mRunTimer->start(); readSettings(); + mCollector = mWatch->collector(); connect(mCollector, SIGNAL(population(SmTreeItem*)), this, SLOT(populate(SmTreeItem*))); + connect(mCollector, SIGNAL(newData(QList,int)), this, SLOT(dirEvent(QList,int)), Qt::BlockingQueuedConnection); } SmDirModel::~SmDirModel(){ @@ -84,6 +78,7 @@ bool SmDirModel::setData(const QModelIndex &index, const QVariant &value, int ro return false; } if(role == Qt::EditRole && index.column() == Name){ + //this is a rename QString newName = value.toString(); if(newName.contains(QDir::separator())){ return false; @@ -94,6 +89,8 @@ bool SmDirModel::setData(const QModelIndex &index, const QVariant &value, int ro QString newPath = QString("%1/%2").arg(dir).arg(newName); QFile::rename(old, newPath); emit needResize(); + // watcher->collector will do the rest + return true; } return SmTreeModel::setData(index, value, role); } @@ -107,6 +104,10 @@ bool SmDirModel::isDir(const QModelIndex &idx) const { return fi.isDir(); } +QDir SmDirModel::dir() const{ + return QDir(mCurrentDir); +} + QFileInfo SmDirModel::fileInfo(const QModelIndex &idx) const { if(!idx.isValid()){ return QFileInfo(); @@ -117,25 +118,26 @@ QFileInfo SmDirModel::fileInfo(const QModelIndex &idx) const { void SmDirModel::setDir(const QString &dir){ mCurrentDir = dir; - mCollector->setCurrent(mCurrentDir); mCollector->start(); mWatch->setDir(mCurrentDir); } -void SmDirModel::dirEvent(const QString &file, int e){ - QFileInfo fi(file); - const QList fData = fileData(fi); +void SmDirModel::dirEvent(const QList &data, int e){ if(e == SmDirWatcher::Added){ - addRow(fData, rootIndex(), true); + /* for some reason SmTreeModel::addRow() doesn't work, + * couldn't figure it out in 5 hours, so customize it + * and reset the model + */ + addFile(data); } - QModelIndex idx = find(fData.at(Name), Name, rootIndex()); + QModelIndex idx = find(data.at(Name), Name, rootIndex()); if(e == SmDirWatcher::Deleted){ removeRow(idx.row()); } if(e == SmDirWatcher::Modified){ for(int i = 0; i < mHeaders.count(); ++i){ QModelIndex c = index(idx.row(), i, QModelIndex()); - setData(c, fData.at(i), Qt::EditRole); + setData(c, data.at(i), Qt::EditRole); } } emit needResize(); @@ -155,8 +157,6 @@ void SmDirModel::readSettings(){ } void SmDirModel::refresh(){ - mCollector->setCurrent(mCurrentDir); - mCollector->start(); } void SmDirModel::populate(SmTreeItem *root){ @@ -164,6 +164,23 @@ void SmDirModel::populate(SmTreeItem *root){ emit needResize(); } +void SmDirModel::addFile(const QList &data){ + SmTreeItem *newItem = new SmTreeItem(data, root()); + int w = root()->childCount(); + int i = 0; + while(i < root()->childCount()){ + if(newItem->data(Name).toString().toLower() < root()->child(i)->data(Name).toString().toLower()){ + w = i; + break; + } + ++i; + } + beginResetModel(); + root()->insertChild(w, newItem); + endResetModel(); + return; +} + const QList SmDirModel::fileData(const QFileInfo &fi) const{ QList data; data << fi.fileName() << fi.size(); -- cgit v1.2.3-70-g09d2