From: Peter Penz Date: Fri, 12 Jan 2007 20:24:23 +0000 (+0000) Subject: Natural sorting fix: assure that directories are sorted always before files as Ellen... X-Git-Url: https://cloud.milkyroute.net/gitweb/dolphin.git/commitdiff_plain/71c0a434906c94c6978acb1b148397a7fb2e8f4c Natural sorting fix: assure that directories are sorted always before files as Ellen has recommended. One minor issue is left: when the sort order is descending, the natural sorting result is: item 10.jpg item 11.jpg item 2.jpg item 1.jpg instead of item 11.jpg item 10.jpg item 2.jpg item 1.jpg svn path=/trunk/playground/utils/dolphin/; revision=622751 --- diff --git a/src/dolphinsortfilterproxymodel.cpp b/src/dolphinsortfilterproxymodel.cpp index e983007c1..34f7edc21 100644 --- a/src/dolphinsortfilterproxymodel.cpp +++ b/src/dolphinsortfilterproxymodel.cpp @@ -62,6 +62,12 @@ void DolphinSortFilterProxyModel::setSorting(DolphinView::Sorting sorting) m_sortOrder ); } +void DolphinSortFilterProxyModel::setSortOrder(Qt::SortOrder sortOrder) +{ + // change the sort order by keeping the current column + sort(dolphinViewToDirModelColumn[m_sorting], sortOrder); +} + void DolphinSortFilterProxyModel::sort(int column, Qt::SortOrder sortOrder) { m_sortOrder = sortOrder; @@ -71,13 +77,41 @@ void DolphinSortFilterProxyModel::sort(int column, Qt::SortOrder sortOrder) QSortFilterProxyModel::sort(column,sortOrder); } -void DolphinSortFilterProxyModel::setSortOrder(Qt::SortOrder sortOrder) +bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, + const QModelIndex& right) const { - // change the sort order by keeping the current column - sort(dolphinViewToDirModelColumn[m_sorting], sortOrder); + KDirModel* dirModel = static_cast(sourceModel()); + + QVariant leftData = dirModel->data(left, sortRole()); + QVariant rightData = dirModel->data(right, sortRole()); + + if ((leftData.type() == QVariant::String) && (rightData.type() == QVariant::String)) { + const QString leftStr = leftData.toString(); + const QString rightStr = rightData.toString(); + + const bool leftIsDir = dirModel->itemForIndex(left)->isDir(); + const bool rightIsDir = dirModel->itemForIndex(right)->isDir(); + + // assure that directories are always sorted before files + if (leftIsDir && !rightIsDir) { + return true; + } + + if (!leftIsDir && rightIsDir) { + return false; + } + + return sortCaseSensitivity() ? (naturalCompare(leftStr, rightStr) < 0) : + (naturalCompare(leftStr.toLower(), rightStr.toLower()) < 0); + } + + // We have set a SortRole and trust the ProxyModel to do + // the right thing for now. + return QSortFilterProxyModel::lessThan(left, right); } -static int naturalCompare(const QString& a, const QString& b) +int DolphinSortFilterProxyModel::naturalCompare(const QString& a, + const QString& b) const { // This method chops the input a and b into pieces of // digits and non-digits (a1.05 becomes a | 1 | . | 05) @@ -124,7 +158,7 @@ static int naturalCompare(const QString& a, const QString& b) if ((*currA == '0') || (*currB == '0')) { // one digit-sequence starts with 0 -> assume we are in a fraction part // do left aligned comparison (numbers are considered left aligend) - while ( 1 ) { + while (1) { if (!currA->isDigit() && !currB->isDigit()) { break; } @@ -190,25 +224,4 @@ static int naturalCompare(const QString& a, const QString& b) return currA->isNull() ? -1 : +1; } - -bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, - const QModelIndex& right) const -{ - - QVariant leftData = sourceModel()->data(left, sortRole()); - QVariant rightData = sourceModel()->data(right, sortRole()); - - if (leftData.type() == QVariant::String && rightData.type() == QVariant::String) { - const QString left = leftData.toString(); - const QString right = rightData.toString(); - - return sortCaseSensitivity() ? (naturalCompare(left, right) < 0) : - (naturalCompare(left.toLower(), right.toLower()) < 0); - } - - // We have set a SortRole and trust the ProxyModel to do - // the right thing for now. - return QSortFilterProxyModel::lessThan(left,right); -} - #include "dolphinsortfilterproxymodel.moc" diff --git a/src/dolphinsortfilterproxymodel.h b/src/dolphinsortfilterproxymodel.h index 0ca1db535..23cd45134 100644 --- a/src/dolphinsortfilterproxymodel.h +++ b/src/dolphinsortfilterproxymodel.h @@ -35,6 +35,8 @@ * - item_1.png * - item_2.png * - item_10.png + * + * It is assured that directories are always sorted before files. */ class DolphinSortFilterProxyModel : public QSortFilterProxyModel { @@ -47,21 +49,25 @@ public: void setSorting(DolphinView::Sorting sorting); DolphinView::Sorting sorting() const { return m_sorting; } + void setSortOrder(Qt::SortOrder sortOrder); + Qt::SortOrder sortOrder() const { return m_sortOrder; } + /** * @reimplemented, @internal * * If the view 'forces' sorting order to change we will * notice now. */ - virtual void sort (int column, - Qt::SortOrder order = Qt::AscendingOrder); - void setSortOrder(Qt::SortOrder sortOrder); - Qt::SortOrder sortOrder() const { return m_sortOrder; } + virtual void sort(int column, + Qt::SortOrder order = Qt::AscendingOrder); protected: virtual bool lessThan(const QModelIndex& left, const QModelIndex& right) const; +private: + int naturalCompare(const QString& a, const QString& b) const; + private: DolphinView::Sorting m_sorting; Qt::SortOrder m_sortOrder;