From 4062c4cf2d9c3a6716ced8686fa2e2324261c0ec Mon Sep 17 00:00:00 2001 From: Peter Penz Date: Fri, 22 Jun 2007 10:18:46 +0000 Subject: [PATCH] =?utf8?q?Allow=20to=20sort=20by=20rating,=20which=20can?= =?utf8?q?=20be=20quite=20useful=20in=20combination=20with=20the=20"Show?= =?utf8?q?=20in=20Groups"=20feature.=20Although=20still=20slow,=20it=20bas?= =?utf8?q?ically=20works.=20All=20the=20code=20is=20based=20on=20Rafael=20?= =?utf8?q?Fern=C3=A1ndez=20L=C3=B3pez=20patch=20available=20at=20http://me?= =?utf8?q?dia.ereslibre.es/2007/06/dolphin-21062007.diff.?= MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit svn path=/trunk/KDE/kdebase/apps/; revision=678801 --- src/CMakeLists.txt | 9 ++ src/dolphinitemcategorizer.cpp | 90 ++++++++++---------- src/dolphinmainwindow.cpp | 41 +++++++++ src/dolphinmainwindow.h | 8 ++ src/dolphinsortfilterproxymodel.cpp | 127 +++++++++++++++++----------- src/dolphinsortfilterproxymodel.h | 27 ++++-- src/dolphinui.rc | 2 + src/dolphinview.h | 6 +- src/viewpropertiesdialog.cpp | 9 ++ 9 files changed, 214 insertions(+), 105 deletions(-) diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 6ca332212..c305f3015 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -34,7 +34,16 @@ kde4_automoc(${dolphinprivate_LIB_SRCS}) kde4_add_library(dolphinprivate SHARED ${dolphinprivate_LIB_SRCS}) +find_package(Nepomuk) +macro_bool_to_01(Nepomuk_FOUND HAVE_NEPOMUK) + +configure_file(config-nepomuk.h.cmake ${CMAKE_CURRENT_BINARY_DIR}/config-nepomuk.h ) + target_link_libraries(dolphinprivate ${KDE4_KDEUI_LIBS} ${KDE4_KFILE_LIBS} konq) +if (Nepomuk_FOUND) + target_link_libraries(dolphinprivate ${NEPOMUK_LIBRARIES}) +endif (Nepomuk_FOUND) + set_target_properties(dolphinprivate PROPERTIES VERSION 1.0.0 SOVERSION 1 ) install(TARGETS dolphinprivate DESTINATION ${LIB_INSTALL_DIR} ) diff --git a/src/dolphinitemcategorizer.cpp b/src/dolphinitemcategorizer.cpp index 38d0e2c16..7dc19ab92 100644 --- a/src/dolphinitemcategorizer.cpp +++ b/src/dolphinitemcategorizer.cpp @@ -22,9 +22,17 @@ #include "dolphinview.h" -#include -#include +#ifdef HAVE_NEPOMUK +#include +#include +#include +#endif + #include +#include +#include +#include +#include #include @@ -47,55 +55,24 @@ QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index, return retString; } - int column; - - switch (sortRole) - { - case DolphinView::SortByName: // KDirModel::Name - column = KDirModel::Name; - break; - case DolphinView::SortBySize: // KDirModel::Size - column = KDirModel::Size; - break; - case DolphinView::SortByDate: // KDirModel::ModifiedTime - column = KDirModel::ModifiedTime; - break; - case DolphinView::SortByPermissions: // KDirModel::Permissions - column = KDirModel::Permissions; - break; - case DolphinView::SortByOwner: // KDirModel::Owner - column = KDirModel::Owner; - break; - case DolphinView::SortByGroup: // KDirModel::Group - column = KDirModel::Group; - break; - case DolphinView::SortByType: // KDirModel::Type - column = KDirModel::Type; - break; - default: - column = KDirModel::Name; - } - - // KDirModel checks columns to know to which role are - // we talking about - QModelIndex theIndex = index.model()->index(index.row(), - column, - index.parent()); - - if (!theIndex.isValid()) { - return retString; - } - - QVariant data = theIndex.model()->data(theIndex, Qt::DisplayRole); - const KDirModel *dirModel = qobject_cast(index.model()); KFileItem *item = dirModel->itemForIndex(index); - int fileSize; - KDateTime modifiedTime; switch (sortRole) { case DolphinView::SortByName: + { + // KDirModel checks columns to know to which role are + // we talking about + QModelIndex theIndex = index.model()->index(index.row(), + KDirModel::Name, + index.parent()); + + if (!theIndex.isValid()) { + return retString; + } + + QVariant data = theIndex.model()->data(theIndex, Qt::DisplayRole); if (data.toString().size()) { if (!item->isHidden() && data.toString().at(0).isLetter()) @@ -132,8 +109,11 @@ QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index, } } break; + } case DolphinView::SortByDate: + { + KDateTime modifiedTime; modifiedTime.setTime_t(item->time(KIO::UDS_MODIFICATION_TIME)); modifiedTime = modifiedTime.toLocalZone(); @@ -150,6 +130,7 @@ QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index, else retString = i18n("More than a year"); break; + } case DolphinView::SortByPermissions: retString = item->permissionsString(); @@ -163,8 +144,8 @@ QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index, retString = item->group(); break; - case DolphinView::SortBySize: - fileSize = (item) ? item->size() : -1; + case DolphinView::SortBySize: { + const int fileSize = item ? item->size() : -1; if (item && item->isDir()) { retString = i18n("Folders"); } else if (fileSize < 5242880) { @@ -175,10 +156,25 @@ QString DolphinItemCategorizer::categoryForItem(const QModelIndex& index, retString = i18nc("Size", "Big"); } break; + } case DolphinView::SortByType: retString = item->mimeComment(); break; + +#ifdef HAVE_NEPOMUK + case DolphinView::SortByRating: { + KFileItem* item = dirModel->itemForIndex(index); + if (item != 0) { + const Nepomuk::Resource resource(item->url().url(), Nepomuk::NFO::File()); + const quint32 rating = resource.rating(); + retString = i18np("1 star", "%1 stars", rating); + } + break; + } + case DolphinView::SortByTags: + break; +#endif } return retString; diff --git a/src/dolphinmainwindow.cpp b/src/dolphinmainwindow.cpp index 7d7a9f89b..7fec6908d 100644 --- a/src/dolphinmainwindow.cpp +++ b/src/dolphinmainwindow.cpp @@ -292,6 +292,15 @@ void DolphinMainWindow::slotSortingChanged(DolphinView::Sorting sorting) break; case DolphinView::SortByType: action = actionCollection()->action("by_type"); + break; +#ifdef HAVE_NEPOMUK + case DolphinView::SortByRating: + action = actionCollection()->action("by_rating"); + break; + case DolphinView::SortByTags: + action = actionCollection()->action("by_tags"); + break; +#endif default: break; } @@ -722,6 +731,16 @@ void DolphinMainWindow::sortByType() m_activeViewContainer->view()->setSorting(DolphinView::SortByType); } +void DolphinMainWindow::sortByRating() +{ + m_activeViewContainer->view()->setSorting(DolphinView::SortByRating); +} + +void DolphinMainWindow::sortByTags() +{ + m_activeViewContainer->view()->setSorting(DolphinView::SortByTags); +} + void DolphinMainWindow::toggleSortOrder() { DolphinView* view = m_activeViewContainer->view(); @@ -1157,6 +1176,26 @@ void DolphinMainWindow::setupActions() sortByType->setText(i18n("By Type")); connect(sortByType, SIGNAL(triggered()), this, SLOT(sortByType())); + KToggleAction* sortByRating = actionCollection()->add("by_rating"); + sortByRating->setText(i18n("By Rating")); + + KToggleAction* sortByTags = actionCollection()->add("by_tags"); + sortByTags->setText(i18n("By Tags")); + +#ifdef HAVE_NEPOMUK + if (MetaDataWidget::metaDataAvailable()) { + connect(sortByRating, SIGNAL(triggered()), this, SLOT(sortByRating())); + connect(sortByTags, SIGNAL(triggered()), this, SLOT(sortByTags())); + } + else { + sortByRating->setEnabled(false); + sortByTags->setEnabled(false); + } +#else + sortByRating->setEnabled(false); + sortByTags->setEnabled(false); +#endif + QActionGroup* sortGroup = new QActionGroup(this); sortGroup->addAction(sortByName); sortGroup->addAction(sortBySize); @@ -1165,6 +1204,8 @@ void DolphinMainWindow::setupActions() sortGroup->addAction(sortByOwner); sortGroup->addAction(sortByGroup); sortGroup->addAction(sortByType); + sortGroup->addAction(sortByRating); + sortGroup->addAction(sortByTags); KToggleAction* sortDescending = actionCollection()->add("descending"); sortDescending->setText(i18n("Descending")); diff --git a/src/dolphinmainwindow.h b/src/dolphinmainwindow.h index 5bbba5f21..93ab2762a 100644 --- a/src/dolphinmainwindow.h +++ b/src/dolphinmainwindow.h @@ -25,6 +25,8 @@ #include "dolphinview.h" #include "sidebarpage.h" +#include + #include #include #include @@ -278,6 +280,12 @@ private slots: /** The sorting of the current view should be done by the type. */ void sortByType(); + /** The sorting of the current view should be done by the rating. */ + void sortByRating(); + + /** The sorting of the current view should be done by tags. */ + void sortByTags(); + /** Switches between an ascending and descending sorting order. */ void toggleSortOrder(); diff --git a/src/dolphinsortfilterproxymodel.cpp b/src/dolphinsortfilterproxymodel.cpp index 5148af8ce..21194f66e 100644 --- a/src/dolphinsortfilterproxymodel.cpp +++ b/src/dolphinsortfilterproxymodel.cpp @@ -22,23 +22,17 @@ #include "dolphinsortfilterproxymodel.h" +#ifdef HAVE_NEPOMUK +#include +#include +#include +#endif + #include #include #include -static const int dolphinMapSize = 7; -static int dolphinViewToDirModelColumn[] = -{ - KDirModel::Name, // DolphinView::SortByName - KDirModel::Size, // DolphinView::SortBySize - KDirModel::ModifiedTime, // DolphinView::SortByDate - KDirModel::Permissions, // DolphinView::SortByPermissions - KDirModel::Owner, // DolphinView::SortByOwner - KDirModel::Group, // DolphinView::SortByGroup - KDirModel::Type // DolphinView::SortByType -}; - -static DolphinView::Sorting dirModelColumnToDolphinView[] = +static DolphinView::Sorting sortingTypeTable[] = { DolphinView::SortByName, // KDirModel::Name DolphinView::SortBySize, // KDirModel::Size @@ -47,12 +41,14 @@ static DolphinView::Sorting dirModelColumnToDolphinView[] = DolphinView::SortByOwner, // KDirModel::Owner DolphinView::SortByGroup, // KDirModel::Group DolphinView::SortByType // KDirModel::Type +#ifdef HAVE_NEPOMUK + , DolphinView::SortByRating + , DolphinView::SortByTags +#endif }; - DolphinSortFilterProxyModel::DolphinSortFilterProxyModel(QObject* parent) : KSortFilterProxyModel(parent), - m_sortColumn(0), m_sorting(DolphinView::SortByName), m_sortOrder(Qt::AscendingOrder) { @@ -70,27 +66,21 @@ DolphinSortFilterProxyModel::~DolphinSortFilterProxyModel() void DolphinSortFilterProxyModel::setSorting(DolphinView::Sorting sorting) { - // Update the sort column by mapping DolpginView::Sorting to - // KDirModel::ModelColumns. We will keep the sortOrder. - Q_ASSERT(static_cast(sorting) >= 0 && static_cast(sorting) < dolphinMapSize); - sort(dolphinViewToDirModelColumn[static_cast(sorting)], - m_sortOrder); + // change the sorting column by keeping the current sort order + sort(sorting, m_sortOrder); } void DolphinSortFilterProxyModel::setSortOrder(Qt::SortOrder sortOrder) { // change the sort order by keeping the current column - sort(dolphinViewToDirModelColumn[m_sorting], sortOrder); + sort(m_sorting, sortOrder); } void DolphinSortFilterProxyModel::sort(int column, Qt::SortOrder sortOrder) { - m_sortColumn = column; + m_sorting = sortingForColumn(column); m_sortOrder = sortOrder; - m_sorting = (column >= 0) && (column < dolphinMapSize) ? - dirModelColumnToDolphinView[column] : - DolphinView::SortByName; - setSortRole(dirModelColumnToDolphinView[column]); + setSortRole(m_sorting); KSortFilterProxyModel::sort(column, sortOrder); } @@ -108,10 +98,9 @@ bool DolphinSortFilterProxyModel::canFetchMore(const QModelIndex& parent) const DolphinView::Sorting DolphinSortFilterProxyModel::sortingForColumn(int column) { - if ((column >= 0) && (column < dolphinMapSize)) { - return dirModelColumnToDolphinView[column]; - } - return DolphinView::SortByName; + Q_ASSERT(column >= 0); + Q_ASSERT(column < static_cast(sizeof(sortingTypeTable) / sizeof(DolphinView::Sorting))); + return sortingTypeTable[column]; } bool DolphinSortFilterProxyModel::lessThanGeneralPurpose(const QModelIndex &left, @@ -168,7 +157,7 @@ bool DolphinSortFilterProxyModel::lessThanGeneralPurpose(const QModelIndex &left case DolphinView::SortByType: { // If we are sorting by size, show folders first. We will sort them - // correctly later + // correctly later. if (leftFileItem->isDir() && !rightFileItem->isDir()) { return true; } else if (!leftFileItem->isDir() && rightFileItem->isDir()) { @@ -178,6 +167,15 @@ bool DolphinSortFilterProxyModel::lessThanGeneralPurpose(const QModelIndex &left return naturalCompare(leftFileItem->mimeComment().toLower(), rightFileItem->mimeComment().toLower()) < 0; } +#ifdef HAVE_NEPOMUK + case DolphinView::SortByRating: { + const quint32 leftRating = ratingForIndex(left); + const quint32 rightRating = ratingForIndex(right); + return leftRating > rightRating; + } +#endif + default: + break; } return false; } @@ -187,13 +185,10 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, { KDirModel* dirModel = static_cast(sourceModel()); - QVariant leftData = dirModel->data(left, dolphinViewToDirModelColumn[sortRole()]); - QVariant rightData = dirModel->data(right, dolphinViewToDirModelColumn[sortRole()]); - - const KFileItem *leftFileItem = dirModel->itemForIndex(left); - const KFileItem *rightFileItem = dirModel->itemForIndex(right); + const KFileItem* leftFileItem = dirModel->itemForIndex(left); + const KFileItem* rightFileItem = dirModel->itemForIndex(right); - // On our priority, folders go above regular files + // On our priority, folders go above regular files. if (leftFileItem->isDir() && !rightFileItem->isDir()) { return true; } else if (!leftFileItem->isDir() && rightFileItem->isDir()) { @@ -201,7 +196,7 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, } // Hidden elements go before visible ones, if they both are - // folders or files + // folders or files. if (leftFileItem->isHidden() && !rightFileItem->isHidden()) { return true; } else if (!leftFileItem->isHidden() && rightFileItem->isHidden()) { @@ -210,12 +205,15 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, switch (sortRole()) { case DolphinView::SortByName: { - // So we are in the same priority, what counts now is their names - QString leftValueString = leftData.toString(); - QString rightValueString = rightData.toString(); - - return sortCaseSensitivity() ? (naturalCompare(leftValueString, rightValueString) < 0) : - (naturalCompare(leftValueString.toLower(), rightValueString.toLower()) < 0); + // So we are in the same priority, what counts now is their names. + const QVariant leftData = dirModel->data(left, KDirModel::Name); + const QVariant rightData = dirModel->data(right, KDirModel::Name); + const QString leftValueString(leftData.toString()); + const QString rightValueString(rightData.toString()); + + return sortCaseSensitivity() ? + (naturalCompare(leftValueString, rightValueString) < 0) : + (naturalCompare(leftValueString.toLower(), rightValueString.toLower()) < 0); } case DolphinView::SortBySize: { @@ -230,25 +228,25 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, // In the case they two have the same child items, we sort them by // their names. So we have always everything ordered. We also check - // if we are taking in count their cases + // if we are taking in count their cases. if (leftCount == rightCount) { return sortCaseSensitivity() ? (naturalCompare(leftFileItem->name(), rightFileItem->name()) < 0) : (naturalCompare(leftFileItem->name().toLower(), rightFileItem->name().toLower()) < 0); } // If they had different number of items, we sort them depending - // on how many items had each other + // on how many items had each other. return leftCount < rightCount; } // If what we are measuring is two files and they have the same size, - // sort them by their file names + // sort them by their file names. if (leftFileItem->size() == rightFileItem->size()) { return sortCaseSensitivity() ? (naturalCompare(leftFileItem->name(), rightFileItem->name()) < 0) : (naturalCompare(leftFileItem->name().toLower(), rightFileItem->name().toLower()) < 0); } - // If their sizes are different, sort them by their sizes, as expected + // If their sizes are different, sort them by their sizes, as expected. return leftFileItem->size() < rightFileItem->size(); } @@ -307,6 +305,21 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, return naturalCompare(leftFileItem->mimeComment(), rightFileItem->mimeComment()) < 0; } + +#ifdef HAVE_NEPOMUK + case DolphinView::SortByRating: { + const quint32 leftRating = ratingForIndex(left); + const quint32 rightRating = ratingForIndex(right); + + if (leftRating == rightRating) { + return sortCaseSensitivity() ? + (naturalCompare(leftFileItem->name(), rightFileItem->name()) < 0) : + (naturalCompare(leftFileItem->name().toLower(), rightFileItem->name().toLower()) < 0); + } + + return leftRating > rightRating; + } +#endif } // We have set a SortRole and trust the ProxyModel to do @@ -314,6 +327,24 @@ bool DolphinSortFilterProxyModel::lessThan(const QModelIndex& left, return QSortFilterProxyModel::lessThan(left, right); } +quint32 DolphinSortFilterProxyModel::ratingForIndex(const QModelIndex& index) const +{ +#ifdef HAVE_NEPOMUK + quint32 rating = 0; + + const KDirModel* dirModel = static_cast(sourceModel()); + KFileItem* item = dirModel->itemForIndex(index); + if (item != 0) { + const Nepomuk::Resource resource(item->url().url(), Nepomuk::NFO::File()); + rating = resource.rating(); + } + return rating; +#else + Q_UNUSED(index); + return 0; +#endif +} + int DolphinSortFilterProxyModel::naturalCompare(const QString& a, const QString& b) { diff --git a/src/dolphinsortfilterproxymodel.h b/src/dolphinsortfilterproxymodel.h index c00032f3f..5bf4bc146 100644 --- a/src/dolphinsortfilterproxymodel.h +++ b/src/dolphinsortfilterproxymodel.h @@ -48,16 +48,10 @@ public: virtual ~DolphinSortFilterProxyModel(); void setSorting(DolphinView::Sorting sorting); - DolphinView::Sorting sorting() const - { - return m_sorting; - } + inline DolphinView::Sorting sorting() const; void setSortOrder(Qt::SortOrder sortOrder); - Qt::SortOrder sortOrder() const - { - return m_sortOrder; - } + inline Qt::SortOrder sortOrder() const; /** * @reimplemented, @internal @@ -89,12 +83,27 @@ protected: const QModelIndex& right) const; private: + /** + * Returns the rating for the item with the index \a index. 0 is + * returned if no item could be found. + */ + quint32 ratingForIndex(const QModelIndex& index) const; + static int naturalCompare(const QString& a, const QString& b); private: - int m_sortColumn; DolphinView::Sorting m_sorting; Qt::SortOrder m_sortOrder; }; +DolphinView::Sorting DolphinSortFilterProxyModel::sorting() const +{ + return m_sorting; +} + +Qt::SortOrder DolphinSortFilterProxyModel::sortOrder() const +{ + return m_sortOrder; +} + #endif diff --git a/src/dolphinui.rc b/src/dolphinui.rc index c2459a5c7..a7ecc78ed 100644 --- a/src/dolphinui.rc +++ b/src/dolphinui.rc @@ -31,6 +31,8 @@ + + diff --git a/src/dolphinview.h b/src/dolphinview.h index 1a240be7a..223c52dbf 100644 --- a/src/dolphinview.h +++ b/src/dolphinview.h @@ -22,6 +22,8 @@ #ifndef DOLPHINVIEW_H #define DOLPHINVIEW_H +#include + #include #include #include @@ -102,7 +104,9 @@ public: SortByOwner, SortByGroup, SortByType, - MaxSortEnum = SortByType + SortByRating, + SortByTags, + MaxSortEnum = SortByTags }; /** diff --git a/src/viewpropertiesdialog.cpp b/src/viewpropertiesdialog.cpp index 5d7fbc59f..a333d87b0 100644 --- a/src/viewpropertiesdialog.cpp +++ b/src/viewpropertiesdialog.cpp @@ -26,6 +26,9 @@ #include "dolphin_generalsettings.h" #include "viewproperties.h" +#include +#include + #include #include #include @@ -107,6 +110,12 @@ ViewPropertiesDialog::ViewPropertiesDialog(DolphinView* dolphinView) : m_sorting->addItem(i18n("By Owner")); m_sorting->addItem(i18n("By Group")); m_sorting->addItem(i18n("By Type")); +#ifdef HAVE_NEPOMUK + if (!Nepomuk::ResourceManager::instance()->init()) { + m_sorting->addItem(i18n("By Rating")); + m_sorting->addItem(i18n("By Tags")); + } +#endif m_sorting->setCurrentIndex(m_viewProps->sorting()); QHBoxLayout* sortingLayout = new QHBoxLayout(); -- 2.47.3