• Skip to content
  • Skip to link menu
KDE 4.3 API Reference
  • KDE API Reference
  • kdelibs
  • Sitemap
  • Contact Us
 

KFile

kdirsortfilterproxymodel.cpp

Go to the documentation of this file.
00001 /*
00002    Copyright (C) 2006 by Peter Penz <peter.penz@gmx.at>
00003    Copyright (C) 2006 by Dominic Battre <dominic@battre.de>
00004    Copyright (C) 2006 by Martin Pool <mbp@canonical.com>
00005 
00006    Separated from Dolphin by Nick Shaforostoff <shafff@ukr.net>
00007 
00008    This library is free software; you can redistribute it and/or
00009    modify it under the terms of the GNU Library General Public
00010    License version 2 as published by the Free Software Foundation.
00011 
00012    This library is distributed in the hope that it will be useful,
00013    but WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Library General Public License for more details.
00016 
00017    You should have received a copy of the GNU Library General Public License
00018    along with this library; see the file COPYING.LIB.  If not, write to
00019    the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
00020    Boston, MA 02110-1301, USA.
00021 */
00022 
00023 #include "kdirsortfilterproxymodel.h"
00024 
00025 #include <kdirmodel.h>
00026 #include <kfileitem.h>
00027 #include <kdatetime.h>
00028 #include <klocale.h>
00029 #include <kstringhandler.h>
00030 #include <kdebug.h>
00031 
00032 // TODO KDE 4.1: bring Nepomuk stuff from Dolphin to kdelibs/nepomuk
00033 // in the form of a separate subclass
00034 
00035 class KDirSortFilterProxyModel::KDirSortFilterProxyModelPrivate
00036 {
00037 public:
00038     KDirSortFilterProxyModelPrivate() : m_sortFoldersFirst(true) {}
00039 
00040     bool m_sortFoldersFirst;
00041 };
00042 
00043 KDirSortFilterProxyModel::KDirSortFilterProxyModel(QObject* parent)
00044     : KCategorizedSortFilterProxyModel(parent), d(new KDirSortFilterProxyModelPrivate)
00045 {
00046     setDynamicSortFilter(true);
00047 
00048     // sort by the user visible string for now
00049     setSortCaseSensitivity(Qt::CaseInsensitive);
00050     sort(KDirModel::Name, Qt::AscendingOrder);
00051 
00052     setSupportedDragActions(Qt::CopyAction | Qt::MoveAction | Qt::LinkAction | Qt::IgnoreAction);
00053 }
00054 
00055 KDirSortFilterProxyModel::~KDirSortFilterProxyModel()
00056 {
00057     delete d;
00058 }
00059 
00060 bool KDirSortFilterProxyModel::hasChildren(const QModelIndex& parent) const
00061 {
00062     const QModelIndex sourceParent = mapToSource(parent);
00063     return sourceModel()->hasChildren(sourceParent);
00064 }
00065 
00066 bool KDirSortFilterProxyModel::canFetchMore(const QModelIndex& parent) const
00067 {
00068     const QModelIndex sourceParent = mapToSource(parent);
00069     return sourceModel()->canFetchMore(sourceParent);
00070 }
00071 
00072 int KDirSortFilterProxyModel::pointsForPermissions(const QFileInfo &info)
00073 {
00074     int points = 0;
00075 
00076     QFile::Permission permissionsCheck[] = { QFile::ReadUser,
00077                                              QFile::WriteUser,
00078                                              QFile::ExeUser,
00079                                              QFile::ReadGroup,
00080                                              QFile::WriteGroup,
00081                                              QFile::ExeGroup,
00082                                              QFile::ReadOther,
00083                                              QFile::WriteOther,
00084                                              QFile::ExeOther };
00085 
00086     for (int i = 0; i < 9; i++) {
00087         points += info.permission(permissionsCheck[i]) ? 1 : 0;
00088     }
00089 
00090     return points;
00091 }
00092 
00093 void KDirSortFilterProxyModel::setSortFoldersFirst(bool foldersFirst)
00094 {
00095     d->m_sortFoldersFirst = foldersFirst;
00096 }
00097 
00098 bool KDirSortFilterProxyModel::sortFoldersFirst() const
00099 {
00100     return d->m_sortFoldersFirst;
00101 }
00102 
00103 bool KDirSortFilterProxyModel::subSortLessThan(const QModelIndex& left,
00104                                                const QModelIndex& right) const
00105 {
00106     KDirModel* dirModel = static_cast<KDirModel*>(sourceModel());
00107 
00108     const KFileItem leftFileItem  = dirModel->itemForIndex(left);
00109     const KFileItem rightFileItem = dirModel->itemForIndex(right);
00110 
00111     const bool isLessThan = (sortOrder() == Qt::AscendingOrder);
00112 
00113     // Folders go before files if the corresponding setting is set.
00114     if (d->m_sortFoldersFirst) {
00115         if (leftFileItem.isDir() && !rightFileItem.isDir()) {
00116             return isLessThan;
00117         } else if (!leftFileItem.isDir() && rightFileItem.isDir()) {
00118             return !isLessThan;
00119         }
00120     }
00121 
00122 
00123     // Hidden elements go before visible ones.
00124     if (leftFileItem.isHidden() && !rightFileItem.isHidden()) {
00125         return isLessThan;
00126     } else if (!leftFileItem.isHidden() && rightFileItem.isHidden()) {
00127         return !isLessThan;
00128     }
00129 
00130     switch (left.column()) {
00131     case KDirModel::Name: {
00132         return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00133     }
00134 
00135     case KDirModel::Size: {
00136         // If we have two folders, what we have to measure is the number of
00137         // items that contains each other
00138         if (leftFileItem.isDir() && rightFileItem.isDir()) {
00139             QVariant leftValue = dirModel->data(left, KDirModel::ChildCountRole);
00140             int leftCount = (leftValue.type() == QVariant::Int) ? leftValue.toInt() : KDirModel::ChildCountUnknown;
00141 
00142             QVariant rightValue = dirModel->data(right, KDirModel::ChildCountRole);
00143             int rightCount = (rightValue.type() == QVariant::Int) ? rightValue.toInt() : KDirModel::ChildCountUnknown;
00144 
00145             // In the case they two have the same child items, we sort them by
00146             // their names. So we have always everything ordered. We also check
00147             // if we are taking in count their cases.
00148             if (leftCount == rightCount) {
00149                 return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00150             }
00151 
00152             // If one of them has unknown child items, place them on the end. If we
00153             // were comparing two unknown childed items, the previous comparation
00154             // sorted them by naturalCompare between them. This case is when we
00155             // have an unknown childed item, and another known.
00156             if (leftCount == KDirModel::ChildCountUnknown) {
00157                 return false;
00158             }
00159 
00160             if (rightCount == KDirModel::ChildCountUnknown) {
00161                 return true;
00162             }
00163 
00164             // If they had different number of items, we sort them depending
00165             // on how many items had each other.
00166             return leftCount < rightCount;
00167         }
00168 
00169         // If what we are measuring is two files and they have the same size,
00170         // sort them by their file names.
00171         if (leftFileItem.size() == rightFileItem.size()) {
00172             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00173         }
00174 
00175         // If their sizes are different, sort them by their sizes, as expected.
00176         return leftFileItem.size() < rightFileItem.size();
00177     }
00178 
00179     case KDirModel::ModifiedTime: {
00180         KDateTime leftModifiedTime = leftFileItem.time(KFileItem::ModificationTime).toLocalZone();
00181         KDateTime rightModifiedTime = rightFileItem.time(KFileItem::ModificationTime).toLocalZone();
00182 
00183         if (leftModifiedTime == rightModifiedTime) {
00184             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00185         }
00186 
00187         return leftModifiedTime < rightModifiedTime;
00188     }
00189 
00190     case KDirModel::Permissions: {
00191         // ### You can't use QFileInfo on urls!! Use the KFileItem instead.
00192         QFileInfo leftFileInfo(leftFileItem.url().pathOrUrl());
00193         QFileInfo rightFileInfo(rightFileItem.url().pathOrUrl());
00194 
00195         int leftPermissionsPoints = pointsForPermissions(leftFileInfo);
00196         int rightPermissionsPoints = pointsForPermissions(rightFileInfo);
00197 
00198         if (leftPermissionsPoints == rightPermissionsPoints) {
00199             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00200         }
00201 
00202         return leftPermissionsPoints > rightPermissionsPoints;
00203     }
00204 
00205     case KDirModel::Owner: {
00206         if (leftFileItem.user() == rightFileItem.user()) {
00207             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00208         }
00209 
00210         return KStringHandler::naturalCompare(leftFileItem.user(), rightFileItem.user()) < 0;
00211     }
00212 
00213     case KDirModel::Group: {
00214         if (leftFileItem.group() == rightFileItem.group()) {
00215             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00216         }
00217 
00218         return KStringHandler::naturalCompare(leftFileItem.group(), rightFileItem.group()) < 0;
00219     }
00220 
00221     case KDirModel::Type: {
00222         if (leftFileItem.mimetype() == rightFileItem.mimetype()) {
00223             return KStringHandler::naturalCompare(leftFileItem.name(), rightFileItem.name(), sortCaseSensitivity()) < 0;
00224         }
00225 
00226         return KStringHandler::naturalCompare(leftFileItem.mimeComment(), rightFileItem.mimeComment()) < 0;
00227     }
00228 
00229     }
00230 
00231     // We have set a SortRole and trust the ProxyModel to do
00232     // the right thing for now.
00233     return KCategorizedSortFilterProxyModel::subSortLessThan(left, right);
00234 }

KFile

Skip menu "KFile"
  • Main Page
  • Class Hierarchy
  • Alphabetical List
  • Class List
  • File List
  • Class Members
  • Related Pages

kdelibs

Skip menu "kdelibs"
  • DNSSD
  • Interfaces
  •   KHexEdit
  •   KMediaPlayer
  •   KSpeech
  •   KTextEditor
  • Kate
  • kconf_update
  • KDE3Support
  •   KUnitTest
  • KDECore
  • KDED
  • KDEsu
  • KDEUI
  • KDocTools
  • KFile
  • KHTML
  • KImgIO
  • KInit
  • kio
  • KIOSlave
  • KJS
  •   KJS-API
  •   WTF
  • kjsembed
  • KNewStuff
  • KParts
  • KPty
  • Kross
  • KUtils
  • Nepomuk
  • Plasma
  • Solid
  • Sonnet
  • ThreadWeaver
Generated for kdelibs by doxygen 1.6.1
This website is maintained by Adriaan de Groot and Allen Winter.
KDE® and the K Desktop Environment® logo are registered trademarks of KDE e.V. | Legal