summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filesystemfileproxy.cpp7
-rw-r--r--filesystemwidget.cpp2
-rw-r--r--helper.cpp10
-rw-r--r--smdirmodel.cpp51
-rw-r--r--smdirmodel.h16
-rw-r--r--smdirwatcher.cpp107
-rw-r--r--smdirwatcher.h30
-rw-r--r--smtreemodel.cpp6
8 files changed, 127 insertions, 102 deletions
diff --git a/filesystemfileproxy.cpp b/filesystemfileproxy.cpp
index b45b740..249eeb4 100644
--- a/filesystemfileproxy.cpp
+++ b/filesystemfileproxy.cpp
@@ -11,8 +11,7 @@
#include <QFileInfo>
#include <QDateTime>
#include <QFont>
-
-#include <QDebug>
+#include <QLocale>
#include "filesystemfileproxy.h"
#include "smdirmodel.h"
@@ -21,9 +20,9 @@
FilesystemFileProxy::FilesystemFileProxy(QObject *parent) : QSortFilterProxyModel(parent) {}
QVariant FilesystemFileProxy::data(const QModelIndex &index, int role) const{
- if(!index.isValid()){
+ if(!index.isValid()){
return QVariant();
- }
+ }
SmDirModel *source = qobject_cast<SmDirModel*>(sourceModel());
if(role == Qt::DisplayRole){
QModelIndex real = mapToSource(index);
diff --git a/filesystemwidget.cpp b/filesystemwidget.cpp
index b842541..5f462e8 100644
--- a/filesystemwidget.cpp
+++ b/filesystemwidget.cpp
@@ -65,7 +65,7 @@ FilesystemWidget::FilesystemWidget(QWidget *parent) : QWidget(parent), mClipboar
mFileProxy = new FilesystemFileProxy;
mFileProxy->setSourceModel(mFileModel);
- mFileView->setModel(mFileProxy);
+ mFileView->setModel(mFileProxy);
mFileView->setSortingEnabled(true);
mFileView->sortByColumn(0, Qt::AscendingOrder);
mFileView->setItemsExpandable(false);
diff --git a/helper.cpp b/helper.cpp
index cfb1711..270feb1 100644
--- a/helper.cpp
+++ b/helper.cpp
@@ -68,7 +68,9 @@ namespace Helper {
QByteArray data(4096, '\0');
do {
read = file.read(data.data(), 4096);
- h.addData(data.data(), read);
+ if(read > 0){
+ h.addData(data.data(), read);
+ }
} while (read == 4096);
QByteArray res = h.result();
retval = res.toHex().toLower();
@@ -214,7 +216,7 @@ namespace Helper {
QSettings s;
QString ffProbe = s.value("paths/ffprobe").toString();
QStringList args;
- QList<QVariant> retval;
+ QList<QVariant> retval = QList<QVariant>() << QVariant() << QVariant();
args << "-show_streams" << path;
QProcess ffproc;
ffproc.start(ffProbe, args);
@@ -229,9 +231,9 @@ namespace Helper {
QString llc = l.toLower();
if(llc.contains("duration")){
int idx = llc.indexOf("duration:");
- retval << llc.mid(idx + 10, 8);
+ retval[0] = llc.mid(idx + 10, 8);
idx = llc.indexOf("bitrate:");
- retval << llc.mid(idx + 9);
+ retval[1] = llc.mid(idx + 9);
break;
}
}
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 <QDir>
#include <QDateTime>
-#include <QFile>
#include <QTimer>
#include <QSettings>
-#include <QHash>
-
-#include <sys/stat.h>
#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<QVariant>,int)), this, SLOT(dirEvent(QList<QVariant>,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<QVariant> fData = fileData(fi);
+void SmDirModel::dirEvent(const QList<QVariant> &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<QVariant> &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<QVariant> SmDirModel::fileData(const QFileInfo &fi) const{
QList<QVariant> data;
data << fi.fileName() << fi.size();
diff --git a/smdirmodel.h b/smdirmodel.h
index c8cc69c..2db790b 100644
--- a/smdirmodel.h
+++ b/smdirmodel.h
@@ -8,13 +8,6 @@
#ifndef SMDIRMODEL_H
#define SMDIRMODEL_H
-#include <QStringList>
-#include <QVariant>
-#include <QModelIndex>
-#include <QList>
-#include <QFileInfo>
-#include <QMap>
-#include <QIcon>
#include <QDir>
#include <smtreemodel.h>
@@ -24,7 +17,7 @@ class SmDirWatcher;
class QTimer;
class SmTreeItem;
class QMutex;
-class SmDataGatherer;
+class SmDataColletor;
class SmDirModel : public SmTreeModel {
Q_OBJECT
@@ -38,16 +31,19 @@ class SmDirModel : public SmTreeModel {
virtual QVariant data(const QModelIndex &index, int role) const;
virtual bool setData(const QModelIndex &index, const QVariant &value, int role);
bool isDir(const QModelIndex &idx) const;
+ QDir dir() const;
QFileInfo fileInfo(const QModelIndex &idx) const;
+
public slots:
void setDir(const QString &dir);
- void dirEvent(const QString &file, int e);
+ void dirEvent(const QList<QVariant> &data, int e);
void readSettings();
void refresh();
private slots:
void populate(SmTreeItem *root);
+ void addFile(const QList<QVariant> &data);
signals:
void needResize();
@@ -61,7 +57,7 @@ class SmDirModel : public SmTreeModel {
QTimer *mRunTimer;
QMap<QString, QIcon> mIcons;
QMutex *mCollectorMx;
- SmDataGatherer *mCollector;
+ SmDataColletor *mCollector;
};
#endif // SMDIRMODEL_H
diff --git a/smdirwatcher.cpp b/smdirwatcher.cpp
index 8650d3b..8b72aab 100644
--- a/smdirwatcher.cpp
+++ b/smdirwatcher.cpp
@@ -9,6 +9,7 @@
#include <QMutexLocker>
#include <QDateTime>
#include <QDir>
+#include <QSemaphore>
#include <sys/inotify.h>
#include <stropts.h>
@@ -23,17 +24,26 @@
extern int errno;
SmDirWatcher::SmDirWatcher(QObject *parent) : QThread(parent), mFd(0), mDescr(0) {
- mFd = inotify_init1(IN_NONBLOCK);
+ mBufLen = 1024 * (sizeof(struct inotify_event) + 16);
+ mINdata = new char[mBufLen];
+ mFd = inotify_init();
+
+ mCollector = new SmDataColletor(8, this);
+ mSemFree = new QSemaphore(1024);
+ mSemUsed = new QSemaphore;
+ mDataQueue = new QQueue<QPair<QString, DWEvent> >();
+ mCollector->init(mSemFree, mSemUsed, mDataQueue);
+ mCollector->start();
}
SmDirWatcher::~SmDirWatcher(){
if(mFd && mDescr){
inotify_rm_watch(mFd, mDescr);
}
+ delete mINdata;
}
void SmDirWatcher::setDir(const QString &dir){
- QMutexLocker lock(&mWatchMx);
if(mDescr){
inotify_rm_watch(mFd, mDescr); //generates IN_IGNORE ???
}
@@ -44,78 +54,73 @@ void SmDirWatcher::setDir(const QString &dir){
*/
mDescr = inotify_add_watch(mFd, qPrintable(dir), IN_CLOSE_WRITE | IN_CREATE | IN_DELETE | IN_MODIFY | IN_MOVED_FROM | IN_MOVED_TO);
mCurrent = dir;
+ mSemFree->acquire();
+ QPair<QString, DWEvent> c = qMakePair(dir, Populate);
+ mDataQueue->enqueue(c);
+ mSemUsed->release();
}
void SmDirWatcher::run(){
- QMutexLocker lock(&mWatchMx);
- QVarLengthArray<char, 4096> data(4096);
- int r = read(mFd, data.data(), data.size());
- 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){
+ int r = read(mFd, mINdata, mBufLen);
+ if(r <= 0){
return;
}
- char *end = at + data.size();
- while(at < end){
- if(e->mask & IN_IGNORED){
- at += sizeof(inotify_event) + e->len;
+ int i = 0;
+ while(i < r){
+ inotify_event *e = reinterpret_cast<inotify_event*>(&mINdata[i]);
+ if((!e->len) || (e->mask & IN_IGNORED)){
+ i += sizeof(inotify_event) + e->len;
continue;
}
+ mSemFree->acquire();
quint32 mask = e->mask;
QString name = QString("%1/%2").arg(mCurrent).arg(e->name);
- at += sizeof(inotify_event) + e->len;
- if(mask & IN_CREATE){
- emit dwEvent(name, Added);
- return;
+ DWEvent curEvent = None;
+ if(mask & IN_CREATE || mask & IN_MOVED_TO){
+ curEvent = Added;
}
- if(mask & IN_DELETE){
- emit dwEvent(name, Deleted);
- return;
+ if(mask & IN_DELETE || mask & IN_MOVED_FROM){
+ curEvent = Deleted;
}
if(mask & IN_CLOSE_WRITE || e->mask & IN_MODIFY){
- emit dwEvent(name, Modified);
- return;
- }
- if(mask & IN_MOVED_FROM || e->mask & IN_MOVED_TO){
- emit needRefresh();
- return;
+ curEvent = Modified;
}
+ QPair<QString, DWEvent> c = qMakePair(name, curEvent);
+ mDataQueue->enqueue(c);
+ mSemUsed->release();
+ i += sizeof(inotify_event) + e->len;
}
}
-SmDataGatherer::SmDataGatherer(const int numFields, QObject *parent) : QThread(parent), mNumFields(numFields) {}
+SmDataColletor::SmDataColletor(const int numFields, QObject *parent) : QThread(parent), mSemFree(0), mSemUsed(0), mDataQueue(0), mNumFields(numFields) {}
-void SmDataGatherer::setCurrent(const QString &current, int mode){
- QMutexLocker lock(&mSetMx);
- mCurrent = current;
- mMode = mode;
+void SmDataColletor::init(QSemaphore *set, QSemaphore *get, QQueue<QPair<QString, SmDirWatcher::DWEvent> > *data){
+ mSemFree = set;
+ mSemUsed = get;
+ mDataQueue = data;
}
-void SmDataGatherer::run(){
- QMutexLocker lock(&mRunMx);
- QFileInfo fi(mCurrent);
- if(fi.isDir()){
- SmTreeItem *rv = populate();
- emit population(rv);
- return;
- }
- if(fi.isFile()){
+void SmDataColletor::run(){
+ forever {
+ mSemUsed->acquire();
+ QPair<QString, SmDirWatcher::DWEvent> cur = mDataQueue->dequeue();
+ if(cur.second == SmDirWatcher::Populate){
+ SmTreeItem *i = populate(cur.first);
+ emit population(i);
+ mSemFree->release();
+ continue;
+
+ }
+ QFileInfo fi(cur.first);
QList<QVariant> fd = fileData(fi);
- emit newData(fd, mMode);
+ emit newData(fd, cur.second);
+ mSemFree->release();
}
}
-SmTreeItem * SmDataGatherer::populate(){
+SmTreeItem * SmDataColletor::populate(const QString &dir){
SmTreeItem *retval = new SmTreeItem(mNumFields);
- QDir d = QDir(mCurrent);
+ QDir d = QDir(dir);
foreach(QFileInfo fi, d.entryInfoList()){
if(fi.fileName() == "."){
continue;
@@ -127,7 +132,7 @@ SmTreeItem * SmDataGatherer::populate(){
return retval;
}
-const QList<QVariant> SmDataGatherer::fileData(const QFileInfo &fi) const{
+const QList<QVariant> SmDataColletor::fileData(const QFileInfo &fi) const{
QList<QVariant> data;
data << fi.fileName() << fi.size();
QString mime = Helper::mimeType(fi.absoluteFilePath());
diff --git a/smdirwatcher.h b/smdirwatcher.h
index 3167aeb..19cd746 100644
--- a/smdirwatcher.h
+++ b/smdirwatcher.h
@@ -9,18 +9,21 @@
#define SMDIRWATCHER_H
#include <QThread>
-#include <QMutex>
#include <QList>
#include <QVariant>
#include <QFileInfo>
+#include <QQueue>
class SmTreeItem;
+class QSemaphore;
+class SmDataColletor;
class SmDirWatcher : public QThread {
Q_OBJECT
public:
- enum DWEvent { Added, Deleted, Modified };
+ enum DWEvent { None, Added, Deleted, Modified, Populate };
explicit SmDirWatcher(QObject *parent = 0);
+ SmDataColletor *collector() { return mCollector; }
~SmDirWatcher();
signals:
@@ -34,20 +37,23 @@ class SmDirWatcher : public QThread {
private:
int mFd;
int mDescr;
- QMutex mWatchMx;
QString mCurrent;
+ SmDataColletor *mCollector;
+ QSemaphore *mSemFree;
+ QSemaphore *mSemUsed;
+ QQueue<QPair<QString, DWEvent> > *mDataQueue;
+ char *mINdata;
+ int mBufLen;
};
-class SmDataGatherer : public QThread {
+class SmDataColletor : public QThread {
Q_OBJECT
public:
- explicit SmDataGatherer(const int numFields, QObject *parent = 0);
- void setCurrent(const QString &current, int mode = -1);
+ explicit SmDataColletor(const int numFields, QObject *parent = 0);
+ void init(QSemaphore *set, QSemaphore *get, QQueue<QPair<QString, SmDirWatcher::DWEvent> > *data);
public slots:
void run();
- //void setFile(const QString &fullPath, int event);
- //void populate(const QString &dir);
signals:
void newData(const QList<QVariant>,int);
@@ -55,12 +61,12 @@ class SmDataGatherer : public QThread {
void needRefresh();
private:
- //QList<QList<QVariant> > populate();
- SmTreeItem *populate();
+ SmTreeItem *populate(const QString &dir);
const QList<QVariant> fileData(const QFileInfo &fi) const;
QString mCurrent;
- QMutex mRunMx;
- QMutex mSetMx;
+ QSemaphore *mSemFree;
+ QSemaphore *mSemUsed;
+ QQueue<QPair<QString, SmDirWatcher::DWEvent> > *mDataQueue;
int mMode;
const int mNumFields;
};
diff --git a/smtreemodel.cpp b/smtreemodel.cpp
index c8a0452..4f8ffdc 100644
--- a/smtreemodel.cpp
+++ b/smtreemodel.cpp
@@ -266,10 +266,10 @@ bool SmTreeModel::addRow(const QList<QVariant> &data, const QModelIndex &parent,
}
QModelIndex start = index(parentItem->childCount() - 1, 0, parent);
QModelIndex end = index(parentItem->childCount() - 1, parentItem->columnCount() - 1, parent);
- emit dataChanged(start, end);
+ emit dataChanged(start, end);
return true;
- }
- return false;
+ }
+ return false;
}
SmTreeItem *SmTreeModel::itemAt(const QModelIndex &index) const{