summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--filesystemwidget.cpp16
-rw-r--r--shemov.cpp2
-rw-r--r--smdirmodel.cpp32
-rw-r--r--smdirmodel.h9
-rw-r--r--smdirwatcher.cpp96
-rw-r--r--smdirwatcher.h32
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);
}
diff --git a/shemov.cpp b/shemov.cpp
index b81de7a..bcd31cf 100644
--- a/shemov.cpp
+++ b/shemov.cpp
@@ -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 &current, 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 &current, 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