/* 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), mExpensiveOps(true){ 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(); connect(mWatch, SIGNAL(population(SmTreeItem*)), this, SLOT(populate(SmTreeItem*))); connect(mWatch, SIGNAL(newData(QList,int)), this, SLOT(dirEvent(QList,int))); } SmDirModel::~SmDirModel(){ if(mWatch->isRunning()){ mWatch->stop(); } mWatch->deleteLater(); } 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){ QFileInfo fi(i->data(FullPath).toString()); if(fi.isDir()){ return mIcons.value("folder"); } if(fi.isFile()){ return mIcons.value("file"); } } return QVariant(); } case Qt::ForegroundRole: if(index.column() == 0){ if((i->data(Present).toInt() == InFiles) || (i->data(Present).toInt() == InPictures)){ return QVariant(QColor(Qt::darkGreen)); } else if(i->data(Present).toInt() == InOrigin){ return QVariant(QColor(Qt::darkRed)); }else{ return SmTreeModel::data(index, role); } } return SmTreeModel::data(index, role); 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); 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; 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... gatherAsync is done by * modelReset(); */ addFile(data); emit fsFreeChanged(); return; } QModelIndex idx = find(data.at(Name), Name, rootIndex()); if(!idx.isValid()){ return; } if(e == SmDirWatcher::Deleted){ removeRow(idx.row()); } if(e == SmDirWatcher::CloseWrite){ for(int i = 0; i < mHeaders.count(); ++i){ QModelIndex c = index(idx.row(), i, QModelIndex()); setData(c, data.at(i), Qt::EditRole); } } emit fsFreeChanged(); } void SmDirModel::readSettings(){ mIcons.insert("folder", SmGlobals::instance()->iconFor("folder")); mIcons.insert("file", SmGlobals::instance()->iconFor("file")); QSettings s; 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())); } bool expensive = s.value("ui/expensiveops", true).toBool(); mWatch->setExpensiveOps(expensive); } void SmDirModel::refresh(){ setDir(mCurrentDir); emit fsFreeChanged(); } 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; } TimerHandler::TimerHandler(QTimer *timer) : mTimer(timer) { mTimer->stop(); } TimerHandler::~TimerHandler(){ QSettings s; bool autoRefresh = s.value("ui/autorefresh", false).toBool(); if(autoRefresh){ mTimer->start(); } } WatcherHandler::WatcherHandler(SmDirWatcher *watcher) : mWatcher(watcher){ mWatcher->quit(); mWatcher->wait(); mWatcher->blockSignals(true); } WatcherHandler::~WatcherHandler(){ mWatcher->blockSignals(false); mWatcher->start(); }