/* This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. */ #include #include #include #include "smdirmodel.h" #include "smdirwatcher.h" #include "smtreeitem.h" #include "smglobals.h" #include "helper.h" SmDirModel::SmDirModel(const QStringList &headers, QObject *parent) : SmTreeModel(headers, parent), mHeaders(headers){ mWatch = new SmDirWatcher(NumFields, this); connect(mWatch, SIGNAL(needRefresh()), this, SLOT(refresh())); mRunTimer = new QTimer(this); mRunTimer->setInterval(2000); connect(mRunTimer, SIGNAL(timeout()), mWatch, SLOT(start())); mRunTimer->start(); mRefreshTimer = new QTimer(this); 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(){ delete mWatch; delete mRunTimer; } QVariant SmDirModel::data(const QModelIndex &index, int role) const{ if(!index.isValid()){ return QVariant(); } SmTreeItem *i = itemAt(index); switch (role){ case NameRole: return i->data(Name); case SizeRole: return i->data(Size); case TypeRole: return i->data(Type); case CreatedRole: return i->data(Created); case Md5sumRole: return i->data(Md5sum); case DurSizeRole: return i->data(DurSize); case BitrateRole: return i->data(Bitrate); case FullPathRole: return i->data(FullPath); case PresentRole: return i->data(Present); case Qt::DecorationRole: { if(index.column() == 0){ QStringList mime = i->data(Type).toString().split('/'); if(mime.at(0) == "inode"){ return mIcons.value("folder"); } if(!mIcons.contains(mime.at(0))){ return mIcons.value("other"); } return mIcons.value(mime.at(0).toLower()); }else{ return QVariant(); } } case Qt::ForegroundRole: if(index.column() == 0 && i->data(Present).toInt() > 0){ return QVariant(QColor(Qt::darkGreen)); } return SmTreeModel::data(index, role); case Qt::DisplayRole: { if(index.column() == DurSize){ QVariant d = i->data(DurSize); if(d.canConvert()){ Helper::Duration dur = d.value(); return dur.toString(); } if(d.canConvert()){ QSize size = d.value(); QString retval = QString(tr("%1x%2 px").arg(QString::number(size.width())).arg(QString::number(size.height()))); return retval; } return QVariant(); } } default: return SmTreeModel::data(index, role); } } bool SmDirModel::setData(const QModelIndex &index, const QVariant &value, int role){ if(!index.isValid()){ return false; } if(role == Qt::EditRole && index.column() == Name){ //this is a rename QString newName = value.toString(); if(newName.contains(QDir::separator())){ return false; } SmTreeItem *i = itemAt(index); QString old = i->data(FullPath).toString(); QString dir = fileInfo(index).absolutePath(); 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); } bool SmDirModel::isDir(const QModelIndex &idx) const { if(!idx.isValid()){ return false; } SmTreeItem *i = itemAt(idx); QFileInfo fi(i->data(FullPath).toString()); return fi.isDir(); } QDir SmDirModel::dir() const{ return QDir(mCurrentDir); } QFileInfo SmDirModel::fileInfo(const QModelIndex &idx) const { if(!idx.isValid()){ return QFileInfo(); } SmTreeItem *i = itemAt(idx); return QFileInfo(i->data(FullPath).toString()); } void SmDirModel::setDir(const QString &dir){ mCurrentDir = dir; mCollector->start(); mWatch->setDir(mCurrentDir); } void SmDirModel::dirEvent(const QList &data, int e){ if(e == SmDirWatcher::Added){ /* 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(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, data.at(i), Qt::EditRole); } } emit needResize(); } void SmDirModel::readSettings(){ const QHash icons = SmGlobals::instance()->icons(); QSettings s; QString iconName = s.value("ui/foldericon").toString(); mIcons.insert("folder", QIcon(icons.value(iconName))); iconName = s.value("ui/movieicon").toString(); mIcons.insert("video", QIcon(icons.value(iconName))); iconName = s.value("ui/pictureicon").toString(); mIcons.insert("image", QIcon(icons.value(iconName))); iconName = s.value("ui/othericon").toString(); mIcons.insert("other", QIcon(icons.value(iconName))); bool autorefresh = s.value("ui/autorefresh", false).toBool(); if(autorefresh){ mRefreshTimer->stop(); mRefreshTimer->disconnect(); int interval = s.value("ui/autorefreshvalue").toInt(); interval *= 1000; mRefreshTimer->setInterval(interval); mRefreshTimer->start(); connect(mRefreshTimer, SIGNAL(timeout()), this, SLOT(refresh())); } } void SmDirModel::refresh(){ setDir(mCurrentDir); } void SmDirModel::setCheckForPresent(bool check){ mCollector->setCheckForPresent(check); } void SmDirModel::populate(SmTreeItem *root){ setRoot(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; }