diff --git a/ChangeLog b/ChangeLog index e47d6e3d6..d5e2298ab 100644 --- a/ChangeLog +++ b/ChangeLog @@ -36,6 +36,7 @@ 27. Fix streams export. 28. Save/restore maximised state when collpasing/expanding interface. 29. Add 'copy to device', etc, actions to folders page. +30. Incremental update of folder page items. 0.3.0 ----- diff --git a/TODO b/TODO index ac00046b2..0502cba80 100644 --- a/TODO +++ b/TODO @@ -1,10 +1,6 @@ - Library - Artist icons ? -- Folders - - Add delete file/folder option?? - - Incremental update of model? Not sure its worth the hassle - - Streams - Handle more than 1st entry?? Not sure - Icecast? diff --git a/models/dirviewitem.h b/models/dirviewitem.h index 1121be378..5856789e2 100644 --- a/models/dirviewitem.h +++ b/models/dirviewitem.h @@ -29,6 +29,7 @@ #include #include #include +#include class DirViewItem { @@ -39,25 +40,28 @@ public: Type_File }; - DirViewItem(const QString name, Type type, DirViewItem *p) + DirViewItem(const QString &name, Type type, DirViewItem *p) : m_parentItem(p) , m_name(name) , m_type(type) { } virtual ~DirViewItem() { - qDeleteAll(m_childItems); } + int row() const { - return m_parentItem ? m_parentItem->m_childItems.indexOf(const_cast(this)) : 0; + return m_parentItem ? m_parentItem->indexOf(const_cast(this)) : 0; + } + virtual int indexOf(DirViewItem *) const { + return 0; } DirViewItem * parent() const { return m_parentItem; } - int childCount() const { - return m_childItems.count();; + virtual int childCount() const { + return 0; } - DirViewItem * child(int row) const { - return m_childItems.value(row);; + virtual DirViewItem * child(int) const { + return 0; } QString fullName(); int columnCount() const { @@ -75,7 +79,6 @@ public: protected: DirViewItem * m_parentItem; - QList m_childItems; QString m_name; Type m_type; }; diff --git a/models/dirviewitemdir.cpp b/models/dirviewitemdir.cpp index 64d00da7a..2f971df7c 100644 --- a/models/dirviewitemdir.cpp +++ b/models/dirviewitemdir.cpp @@ -26,17 +26,65 @@ #include "dirviewitemdir.h" #include "dirviewitemfile.h" +#include -DirViewItem * DirViewItemDir::createDirectory(const QString dirName) +DirViewItem * DirViewItemDir::createDirectory(const QString &dirName) { DirViewItemDir *dir = new DirViewItemDir(dirName, this); + m_indexes.insert(dirName, m_childItems.count()); m_childItems.append(dir); return dir; } -DirViewItem * DirViewItemDir::insertFile(const QString fileName) +DirViewItem * DirViewItemDir::insertFile(const QString &fileName) { DirViewItemFile *file = new DirViewItemFile(fileName, this); + m_indexes.insert(fileName, m_childItems.count()); m_childItems.append(file); return file; } + +void DirViewItemDir::insertFile(const QStringList &path) +{ + if (1==path.count()) { + insertFile(path[0]); + } else { + static_cast(createDirectory(path[0]))->insertFile(path.mid(1)); + } +} + +void DirViewItemDir::remove(DirViewItem *dir) +{ + int index=m_childItems.indexOf(dir); + + if (-1==index) { + return; + } + bool updateIndexes=(m_childItems.count()-1)!=index; + DirViewItem *d=m_childItems.takeAt(index); + + if (updateIndexes) { + m_indexes.clear(); + int idx=0; + foreach (DirViewItem *i, m_childItems) { + m_indexes.insert(i->name(), idx++); + } + } else { + m_indexes.remove(d->name()); + } +} + +QSet DirViewItemDir::allFiles() const +{ + QSet files; + + foreach (DirViewItem *i, m_childItems) { + if (Type_Dir==i->type()) { + files+=static_cast(i)->allFiles(); + } else if (Type_File==i->type()) { + files.insert(i->fullName()); + } + } + + return files; +} diff --git a/models/dirviewitemdir.h b/models/dirviewitemdir.h index 051b57240..256bae887 100644 --- a/models/dirviewitemdir.h +++ b/models/dirviewitemdir.h @@ -31,17 +31,42 @@ class DirViewItemDir : public DirViewItem { public: - DirViewItemDir(const QString name, DirViewItem *parent) + DirViewItemDir(const QString &name, DirViewItem *parent) : DirViewItem(name, DirViewItem::Type_Dir, parent) { } DirViewItemDir() : DirViewItem(QString(), DirViewItem::Type_Root, 0) { } virtual ~DirViewItemDir() { + qDeleteAll(m_childItems); } - DirViewItem * createDirectory(const QString dirName); - DirViewItem * insertFile(const QString fileName); + virtual int indexOf(DirViewItem *c) const { + return m_childItems.indexOf(c); + } + int childCount() const { + return m_childItems.count(); + } + DirViewItem * child(int row) const { + return m_childItems.value(row); + } + DirViewItem * child(const QString &name) const { + return m_indexes.contains(name) ? m_childItems.value(m_indexes[name]) : 0; + } + DirViewItem * createDirectory(const QString &dirName); + DirViewItem * insertFile(const QString &fileName); + void insertFile(const QStringList &path); + void remove(DirViewItem *dir); + + bool hasChild(const QString &name) { + return m_indexes.contains(name); + } + + QSet allFiles() const; + +private: + QHash m_indexes; + QList m_childItems; }; #endif diff --git a/models/dirviewitemfile.h b/models/dirviewitemfile.h index 22fc99495..dc63a0ef1 100644 --- a/models/dirviewitemfile.h +++ b/models/dirviewitemfile.h @@ -31,7 +31,7 @@ class DirViewItemFile : public DirViewItem { public: - DirViewItemFile(const QString name, DirViewItem *parent) + DirViewItemFile(const QString &name, DirViewItem *parent) : DirViewItem(name, DirViewItem::Type_File, parent) { } virtual ~DirViewItemFile() { diff --git a/models/dirviewmodel.cpp b/models/dirviewmodel.cpp index 5e1e4c456..b86001f1a 100644 --- a/models/dirviewmodel.cpp +++ b/models/dirviewmodel.cpp @@ -174,12 +174,88 @@ void DirViewModel::clear() void DirViewModel::updateDirView(DirViewItemRoot *newroot) { TF_DEBUG - const DirViewItemRoot *oldRoot = rootItem; + bool incremental=rootItem->childCount() && newroot->childCount(); - beginResetModel(); - rootItem = newroot; - delete oldRoot; - endResetModel(); + if (incremental) { + QSet currentFiles=rootItem->allFiles(); + QSet updateFiles=newroot->allFiles(); + QSet removed=currentFiles-updateFiles; + QSet added=updateFiles-currentFiles; + + foreach (const QString &s, added) { + addFileToList(s); + } + foreach (const QString &s, removed) { + removeFileFromList(s); + } + } else { + const DirViewItemRoot *oldRoot = rootItem; + + beginResetModel(); + rootItem = newroot; + delete oldRoot; + endResetModel(); + } +} + +void DirViewModel::addFileToList(const QString &file) +{ + addFileToList(file.split('/'), QModelIndex(), rootItem); +} + +void DirViewModel::removeFileFromList(const QString &file) +{ + removeFileFromList(file.split('/'), QModelIndex(), rootItem); +} + +void DirViewModel::addFileToList(const QStringList &parts, const QModelIndex &parent, DirViewItemDir *dir) +{ + if (0==parts.count()) { + return; + } + + QString p=parts[0]; + + DirViewItem *child=dir->child(p); + if (child) { + if (DirViewItem::Type_Dir==child->type()) { + addFileToList(parts.mid(1), index(dir->indexOf(child), 0, parent), static_cast(child)); + } + } else { + beginInsertRows(parent, dir->childCount(), dir->childCount()); + dir->insertFile(parts); + endInsertRows(); + } +} + +void DirViewModel::removeFileFromList(const QStringList &parts, const QModelIndex &parent, DirViewItemDir *dir) +{ + if (0==parts.count()) { + return; + } + + QString p=parts[0]; + + DirViewItem *child=dir->child(p); + if (child) { + if (DirViewItem::Type_Dir==child->type()) { + removeFileFromList(parts.mid(1), index(dir->indexOf(child), 0, parent), static_cast(child)); + } else if (DirViewItem::Type_File==child->type()) { + int index=dir->indexOf(child); + beginRemoveRows(parent, index, index); + dir->remove(child); + endRemoveRows(); + } + } + + if (0==dir->childCount() && dir->parent()) { + DirViewItemDir *pd=static_cast(dir->parent()); + int index=pd->indexOf(dir); + beginRemoveRows(parent.parent(), index, index); + pd->remove(dir); + delete dir; + endRemoveRows(); + } } Qt::ItemFlags DirViewModel::flags(const QModelIndex &index) const diff --git a/models/dirviewmodel.h b/models/dirviewmodel.h index 62f842860..89df46036 100644 --- a/models/dirviewmodel.h +++ b/models/dirviewmodel.h @@ -48,12 +48,18 @@ public: QStringList filenames(const QModelIndexList &indexes) const; QMimeData *mimeData(const QModelIndexList &indexes) const; void clear(); + void addFileToList(const QString &file); + void removeFileFromList(const QString &file); -public slots: +public Q_SLOTS: void updateDirView(DirViewItemRoot *newroot); private: - const DirViewItemRoot *rootItem; + void addFileToList(const QStringList &parts, const QModelIndex &parent, DirViewItemDir *dir); + void removeFileFromList(const QStringList &parts, const QModelIndex &parent, DirViewItemDir *dir); + +private: + DirViewItemRoot *rootItem; void recurseDirItems(DirViewItem &parent, QStringList &filenames) const; };