File indexing completed on 2024-05-19 04:56:00

0001 /**
0002  * \file dirproxymodel.cpp
0003  * Proxy for filesystem model which filters directories.
0004  *
0005  * \b Project: Kid3
0006  * \author Urs Fleisch
0007  * \date 19-Mar-2011
0008  *
0009  * Copyright (C) 2011-2024  Urs Fleisch
0010  *
0011  * This file is part of Kid3.
0012  *
0013  * Kid3 is free software; you can redistribute it and/or modify
0014  * it under the terms of the GNU General Public License as published by
0015  * the Free Software Foundation; either version 2 of the License, or
0016  * (at your option) any later version.
0017  *
0018  * Kid3 is distributed in the hope that it will be useful,
0019  * but WITHOUT ANY WARRANTY; without even the implied warranty of
0020  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
0021  * GNU General Public License for more details.
0022  *
0023  * You should have received a copy of the GNU General Public License
0024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
0025  */
0026 
0027 #include "dirproxymodel.h"
0028 #include <QDateTime>
0029 #include "taggedfilesystemmodel.h"
0030 
0031 /**
0032  * Constructor.
0033  *
0034  * @param parent parent object
0035  */
0036 DirProxyModel::DirProxyModel(QObject* parent) : QSortFilterProxyModel(parent)
0037 {
0038   setObjectName(QLatin1String("DirProxyModel"));
0039 }
0040 
0041 /**
0042  * Get item flags.
0043  * @param index index of item
0044  * @return default flags without editable.
0045  */
0046 Qt::ItemFlags DirProxyModel::flags(const QModelIndex& index) const
0047 {
0048   // Prevent inplace editing (i.e. renaming) of directories.
0049   return QSortFilterProxyModel::flags(index) & ~Qt::ItemIsEditable;
0050 }
0051 
0052 /**
0053  * Check if row should be included in model.
0054  *
0055  * @param srcRow source row
0056  * @param srcParent source parent
0057  *
0058  * @return true to include row.
0059  */
0060 bool DirProxyModel::filterAcceptsRow(int srcRow, const QModelIndex& srcParent) const
0061 {
0062   if (auto srcModel = qobject_cast<FileSystemModel*>(sourceModel())) {
0063     return srcModel->isDir(srcModel->index(srcRow, 0, srcParent));
0064   }
0065   return false;
0066 }
0067 
0068 /**
0069  * Sort comparison function.
0070  * @param left index of left item in source model
0071  * @param right index of right item in source model
0072  * @return true if left is less than right.
0073  */
0074 bool DirProxyModel::lessThan(const QModelIndex& left,
0075                              const QModelIndex& right) const
0076 {
0077   // "." and ".." shall be in the first and second row.
0078   bool orderIsAscending = sortOrder() == Qt::AscendingOrder;
0079   QString leftName = left.sibling(left.row(), 0).data().toString();
0080   if (leftName == QLatin1String(".")) {
0081     return orderIsAscending;
0082   }
0083   QString rightName = right.sibling(right.row(), 0).data().toString();
0084   if (rightName == QLatin1String(".")) {
0085     return !orderIsAscending;
0086   }
0087   if (leftName == QLatin1String("..")) {
0088     return orderIsAscending;
0089   }
0090   if (rightName == QLatin1String("..")) {
0091     return !orderIsAscending;
0092   }
0093 
0094   // The data() in FileSystemModel are String QVariants, therefore
0095   // QSortFilterProxyModel::lessThan() is of no use here, custom sorting
0096   // has to be used.
0097   Q_ASSERT_X(sourceModel()->metaObject() == &TaggedFileSystemModel::staticMetaObject,
0098              "lessThan", "source model must be FileSystemModel");
0099   auto fsModel = static_cast<FileSystemModel*>(sourceModel());
0100   switch (sortColumn()) {
0101   case 0:
0102     return left.data().toString().compare(right.data().toString()) < 0;
0103   case 1:
0104     return fsModel->size(left) < fsModel->size(right);
0105   case 2:
0106     return fsModel->type(left) < fsModel->type(right);
0107   case 3:
0108     return fsModel->lastModified(left) < fsModel->lastModified(right);
0109   }
0110   qWarning("DirProxyModel: Invalid sort column %d",
0111            sortColumn());
0112   return QSortFilterProxyModel::lessThan(left, right);
0113 }