#define KFILEITEMMODEL_DEBUG
KFileItemModel::KFileItemModel(KDirLister* dirLister, QObject* parent) :
- KItemModelBase(QByteArray(), "name", parent),
+ KItemModelBase("name", parent),
m_dirLister(dirLister),
m_naturalSorting(true),
m_sortFoldersFirst(true),
- m_groupRole(NoRole),
m_sortRole(NameRole),
m_caseSensitivity(Qt::CaseInsensitive),
m_sortedItems(),
return false;
}
-bool KFileItemModel::supportsGrouping() const
+void KFileItemModel::setSortFoldersFirst(bool foldersFirst)
{
- return true;
+ if (foldersFirst != m_sortFoldersFirst) {
+ m_sortFoldersFirst = foldersFirst;
+ resortAllItems();
+ }
}
-bool KFileItemModel::supportsSorting() const
+bool KFileItemModel::sortFoldersFirst() const
{
- return true;
+ return m_sortFoldersFirst;
}
QMimeData* KFileItemModel::createMimeData(const QSet<int>& indexes) const
int KFileItemModel::indexForKeyboardSearch(const QString& text, int startFromIndex) const
{
startFromIndex = qMax(0, startFromIndex);
- for (int i = startFromIndex; i < count(); i++) {
+ for (int i = startFromIndex; i < count(); ++i) {
if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
- kDebug() << data(i)["name"].toString();
return i;
}
}
- for (int i = 0; i < startFromIndex; i++) {
+ for (int i = 0; i < startFromIndex; ++i) {
if (data(i)["name"].toString().startsWith(text, Qt::CaseInsensitive)) {
- kDebug() << data(i)["name"].toString();
return i;
}
}
return item.isNull() ? false : item.isDir();
}
+QString KFileItemModel::roleDescription(const QByteArray& role) const
+{
+ QString descr;
+
+ switch (roleIndex(role)) {
+ case NameRole: descr = i18nc("@item:intable", "Name"); break;
+ case SizeRole: descr = i18nc("@item:intable", "Size"); break;
+ case DateRole: descr = i18nc("@item:intable", "Date"); break;
+ case PermissionsRole: descr = i18nc("@item:intable", "Permissions"); break;
+ case OwnerRole: descr = i18nc("@item:intable", "Owner"); break;
+ case GroupRole: descr = i18nc("@item:intable", "Group"); break;
+ case TypeRole: descr = i18nc("@item:intable", "Type"); break;
+ case DestinationRole: descr = i18nc("@item:intable", "Destination"); break;
+ case PathRole: descr = i18nc("@item:intable", "Path"); break;
+ case NoRole: break;
+ case IsDirRole: break;
+ case IsExpandedRole: break;
+ case ExpansionLevelRole: break;
+ default: Q_ASSERT(false); break;
+ }
+
+ return descr;
+}
+
+QList<QPair<int, QVariant> > KFileItemModel::groups() const
+{
+ // TODO:
+ QPair<int, QVariant> group1(0, "Group 1");
+ QPair<int, QVariant> group2(5, "Group 2");
+ QPair<int, QVariant> group3(10, "Group 3");
+
+ QList<QPair<int, QVariant> > groups;
+ groups.append(group1);
+ groups.append(group2);
+ groups.append(group3);
+ return groups;
+}
+
KFileItem KFileItemModel::fileItem(int index) const
{
if (index >= 0 && index < count()) {
return m_items.value(item.url(), -1);
}
+int KFileItemModel::index(const KUrl& url) const
+{
+ KUrl urlToFind = url;
+ urlToFind.adjustPath(KUrl::RemoveTrailingSlash);
+ return m_items.value(urlToFind, -1);
+}
+
KFileItem KFileItemModel::rootItem() const
{
const KDirLister* dirLister = m_dirLister.data();
m_restoredExpandedUrls = urls;
}
-void KFileItemModel::onGroupRoleChanged(const QByteArray& current, const QByteArray& previous)
+void KFileItemModel::onGroupedSortingChanged(bool current)
{
- Q_UNUSED(previous);
- m_groupRole = roleIndex(current);
+ Q_UNUSED(current);
}
void KFileItemModel::onSortRoleChanged(const QByteArray& current, const QByteArray& previous)
{
Q_UNUSED(previous);
- const int itemCount = count();
- if (itemCount <= 0) {
- return;
- }
-
m_sortRole = roleIndex(current);
+ resortAllItems();
+}
- KFileItemList sortedItems = m_sortedItems;
- m_sortedItems.clear();
- m_items.clear();
- m_data.clear();
- emit itemsRemoved(KItemRangeList() << KItemRange(0, itemCount));
-
- sort(sortedItems.begin(), sortedItems.end());
- int index = 0;
- foreach (const KFileItem& item, sortedItems) {
- m_sortedItems.append(item);
- m_items.insert(item.url(), index);
- m_data.append(retrieveData(item));
-
- ++index;
- }
-
- emit itemsInserted(KItemRangeList() << KItemRange(0, itemCount));
+void KFileItemModel::onSortOrderChanged(Qt::SortOrder current, Qt::SortOrder previous)
+{
+ Q_UNUSED(current);
+ Q_UNUSED(previous);
+ resortAllItems();
}
void KFileItemModel::slotCompleted()
emit itemsRemoved(itemRanges);
}
-void KFileItemModel::removeExpandedItems()
+void KFileItemModel::resortAllItems()
{
+ const int itemCount = count();
+ if (itemCount <= 0) {
+ return;
+ }
+
+ const KFileItemList oldSortedItems = m_sortedItems;
+ const QHash<KUrl, int> oldItems = m_items;
+ const QList<QHash<QByteArray, QVariant> > oldData = m_data;
+
+ m_items.clear();
+ m_data.clear();
+
+ sort(m_sortedItems.begin(), m_sortedItems.end());
+ int index = 0;
+ foreach (const KFileItem& item, m_sortedItems) {
+ m_items.insert(item.url(), index);
+
+ const int oldItemIndex = oldItems.value(item.url());
+ m_data.append(oldData.at(oldItemIndex));
+
+ ++index;
+ }
+ bool emitItemsMoved = false;
+ QList<int> movedToIndexes;
+ movedToIndexes.reserve(m_sortedItems.count());
+ for (int i = 0; i < itemCount; i++) {
+ const int newIndex = m_items.value(oldSortedItems.at(i).url());
+ movedToIndexes.append(newIndex);
+ if (!emitItemsMoved && newIndex != i) {
+ emitItemsMoved = true;
+ }
+ }
+
+ if (emitItemsMoved) {
+ emit itemsMoved(KItemRange(0, itemCount), movedToIndexes);
+ }
+}
+
+void KFileItemModel::removeExpandedItems()
+{
KFileItemList expandedItems;
const int maxIndex = m_data.count() - 1;
result = expansionLevelsCompare(a, b);
if (result != 0) {
// The items have parents with different expansion levels
- return result < 0;
+ return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
}
}
- if (m_sortFoldersFirst) {
+ if (m_sortFoldersFirst || m_sortRole == SizeRole) {
const bool isDirA = a.isDir();
const bool isDirB = b.isDir();
if (isDirA && !isDirB) {
break;
}
+ case SizeRole: {
+ // TODO: Implement sorting folders by the number of items inside.
+ // This is more tricky to get right because this number is retrieved
+ // asynchronously by KFileItemModelRolesUpdater.
+ const KIO::filesize_t sizeA = a.size();
+ const KIO::filesize_t sizeB = b.size();
+ if (sizeA < sizeB) {
+ result = -1;
+ } else if (sizeA > sizeB) {
+ result = +1;
+ }
+ break;
+ }
+
default:
break;
}
result = QString::compare(a.url().url(), b.url().url(), Qt::CaseSensitive);
}
- return result < 0;
+ return (sortOrder() == Qt::AscendingOrder) ? result < 0 : result > 0;
}
void KFileItemModel::sort(const KFileItemList::iterator& startIterator, const KFileItemList::iterator& endIterator)