diff --git a/plugins/patchreview/patchreviewtoolview.h b/plugins/patchreview/patchreviewtoolview.h --- a/plugins/patchreview/patchreviewtoolview.h +++ b/plugins/patchreview/patchreviewtoolview.h @@ -31,6 +31,7 @@ class PatchReviewPlugin; class LocalPatchSource; class QModelIndex; +class QSortFilterProxyModel; class PatchReviewToolView : public QWidget { @@ -98,6 +99,8 @@ Purpose::Menu* m_exportMenu; class PatchFilesModel* m_fileModel; + QSortFilterProxyModel* m_fileSortProxyModel; + public slots: void documentActivated( KDevelop::IDocument* ); void customContextMenuRequested(const QPoint& p); diff --git a/plugins/patchreview/patchreviewtoolview.cpp b/plugins/patchreview/patchreviewtoolview.cpp --- a/plugins/patchreview/patchreviewtoolview.cpp +++ b/plugins/patchreview/patchreviewtoolview.cpp @@ -204,7 +204,11 @@ bool allowSelection = m_plugin->patch() && m_plugin->patch()->canSelectFiles(); m_fileModel = new PatchFilesModel( this, allowSelection ); - m_editPatch.filesList->setModel( m_fileModel ); + m_fileSortProxyModel = new VcsFileChangesSortProxyModel(this); + m_fileSortProxyModel->setSourceModel(m_fileModel); + m_fileSortProxyModel->sort(1); + m_fileSortProxyModel->setDynamicSortFilter(true); + m_editPatch.filesList->setModel( m_fileSortProxyModel ); m_editPatch.filesList->header()->hide(); m_editPatch.filesList->setRootIsDecorated( false ); m_editPatch.filesList->setContextMenuPolicy(Qt::CustomContextMenu); diff --git a/vcs/models/vcsfilechangesmodel.h b/vcs/models/vcsfilechangesmodel.h --- a/vcs/models/vcsfilechangesmodel.h +++ b/vcs/models/vcsfilechangesmodel.h @@ -23,6 +23,7 @@ #ifndef KDEVPLATFORM_VCSFILECHANGESMODEL_H #define KDEVPLATFORM_VCSFILECHANGESMODEL_H +#include #include #include @@ -35,6 +36,16 @@ { class VcsStatusInfo; +class KDEVPLATFORMVCS_EXPORT VcsFileChangesSortProxyModel : public QSortFilterProxyModel +{ + Q_OBJECT + +public: + VcsFileChangesSortProxyModel(QObject* parent = nullptr); + + bool lessThan(const QModelIndex& rLeft, const QModelIndex& rRight) const override; +}; + /** * This class holds and represents information about changes in files. * Also it is possible to provide tree like models by inheriting this class, see protected members. @@ -48,7 +59,8 @@ Q_OBJECT public: - enum ItemRoles { VcsStatusInfoRole = Qt::UserRole+1, UrlRole, LastItemRole }; + enum ItemRoles { VcsStatusInfoRole = Qt::UserRole+1, UrlRole, StateRole, LastItemRole }; + enum Column { PathColumn = 0, StatusColumn = 1 }; /** * Constructor for class. @@ -143,4 +155,6 @@ }; } +Q_DECLARE_METATYPE(KDevelop::VcsStatusInfo::State) + #endif // KDEVPLATFORM_VCSFILECHANGESMODEL_H diff --git a/vcs/models/vcsfilechangesmodel.cpp b/vcs/models/vcsfilechangesmodel.cpp --- a/vcs/models/vcsfilechangesmodel.cpp +++ b/vcs/models/vcsfilechangesmodel.cpp @@ -32,7 +32,6 @@ #include - namespace KDevelop { @@ -78,6 +77,24 @@ return QIcon::fromTheme(QStringLiteral("dialog-error")); } +VcsFileChangesSortProxyModel::VcsFileChangesSortProxyModel(QObject* parent) + : QSortFilterProxyModel(parent) +{ +} + +bool VcsFileChangesSortProxyModel::lessThan(const QModelIndex& source_left, const QModelIndex& source_right) const +{ + const auto leftStatus = source_left.data(VcsFileChangesModel::StateRole).value(); + const auto rightStatus = source_right.data(VcsFileChangesModel::StateRole).value(); + if (leftStatus != rightStatus) { + return leftStatus < rightStatus; + } + + const QString leftPath = source_left.data(VcsFileChangesModel::UrlRole).toString(); + const QString rightPath = source_right.data(VcsFileChangesModel::UrlRole).toString(); + return QString::localeAwareCompare(leftPath, rightPath) < 0; +} + class VcsStatusInfoItem : public QStandardItem { public: @@ -101,6 +118,8 @@ return QVariant::fromValue(m_info); case VcsFileChangesModel::UrlRole: return m_info.url(); + case VcsFileChangesModel::StateRole: + return QVariant::fromValue(m_info.state()); } return {}; }