1 /**************************************************************************
2 ** This file is part of LiteIDE
3 **
4 ** Copyright (c) 2011-2017 LiteIDE. All rights reserved.
5 **
6 ** This library is free software; you can redistribute it and/or
7 ** modify it under the terms of the GNU Lesser General Public
8 ** License as published by the Free Software Foundation; either
9 ** version 2.1 of the License, or (at your option) any later version.
10 **
11 ** This library is distributed in the hope that it will be useful,
12 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
13 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 ** Lesser General Public License for more details.
15 **
16 ** In addition, as a special exception, that plugins developed for LiteIDE,
17 ** are allowed to remain closed sourced and can be distributed under any license .
18 ** These rights are included in the file LGPL_EXCEPTION.txt in this package.
19 **
20 **************************************************************************/
21 // Module: dirsortfilterproxymodel.cpp
22 // Creator: visualfc <visualfc@gmail.com>
23
24 #include "dirsortfilterproxymodel.h"
25 #include <QFileSystemModel>
26 #include <QFileInfo>
27 #include <QDirModel>
28 #include <QDateTime>
29 //lite_memory_check_begin
30 #if defined(WIN32) && defined(_MSC_VER) && defined(_DEBUG)
31 #define _CRTDBG_MAP_ALLOC
32 #include <stdlib.h>
33 #include <crtdbg.h>
34 #define DEBUG_NEW new( _NORMAL_BLOCK, __FILE__, __LINE__ )
35 #define new DEBUG_NEW
36 #endif
37 //lite_memory_check_end
38
39
40 /* For sorting */
41 struct QDirSortItem
42 {
43 mutable QString filename_cache;
44 mutable QString suffix_cache;
45 QFileInfo item;
46 };
47
48
49 class QDirSortItemComparator
50 {
51 int qt_cmp_si_sort_flags;
52 public:
QDirSortItemComparator(int flags)53 QDirSortItemComparator(int flags) : qt_cmp_si_sort_flags(flags) {}
54 bool sort(const QDirSortItem &, const QDirSortItem &);
55 };
56
sort(const QDirSortItem & n1,const QDirSortItem & n2)57 bool QDirSortItemComparator::sort(const QDirSortItem &n1, const QDirSortItem &n2)
58 {
59 const QDirSortItem* f1 = &n1;
60 const QDirSortItem* f2 = &n2;
61
62 if ((qt_cmp_si_sort_flags & QDir::DirsFirst) && (f1->item.isDir() != f2->item.isDir()))
63 return f1->item.isDir();
64 if ((qt_cmp_si_sort_flags & QDir::DirsLast) && (f1->item.isDir() != f2->item.isDir()))
65 return !f1->item.isDir();
66
67 int r = 0;
68 int sortBy = (qt_cmp_si_sort_flags & QDir::SortByMask)
69 | (qt_cmp_si_sort_flags & QDir::Type);
70
71 switch (sortBy) {
72 case QDir::Time:
73 r = f1->item.lastModified().secsTo(f2->item.lastModified());
74 break;
75 case QDir::Size:
76 r = int(qBound<qint64>(-1, f2->item.size() - f1->item.size(), 1));
77 break;
78 case QDir::Type:
79 {
80 bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
81
82 if (f1->suffix_cache.isNull())
83 f1->suffix_cache = ic ? f1->item.suffix().toLower()
84 : f1->item.suffix();
85 if (f2->suffix_cache.isNull())
86 f2->suffix_cache = ic ? f2->item.suffix().toLower()
87 : f2->item.suffix();
88
89 r = qt_cmp_si_sort_flags & QDir::LocaleAware
90 ? f1->suffix_cache.localeAwareCompare(f2->suffix_cache)
91 : f1->suffix_cache.compare(f2->suffix_cache);
92 }
93 break;
94 default:
95 ;
96 }
97
98 if (r == 0 && sortBy != QDir::Unsorted) {
99 // Still not sorted - sort by name
100 bool ic = qt_cmp_si_sort_flags & QDir::IgnoreCase;
101
102 if (f1->filename_cache.isNull())
103 f1->filename_cache = ic ? f1->item.fileName().toLower()
104 : f1->item.fileName();
105 if (f2->filename_cache.isNull())
106 f2->filename_cache = ic ? f2->item.fileName().toLower()
107 : f2->item.fileName();
108
109 r = qt_cmp_si_sort_flags & QDir::LocaleAware
110 ? f1->filename_cache.localeAwareCompare(f2->filename_cache)
111 : f1->filename_cache.compare(f2->filename_cache);
112 }
113 if (r == 0) // Enforce an order - the order the items appear in the array
114 r = (&n1) - (&n2);
115 if (qt_cmp_si_sort_flags & QDir::Reversed)
116 return r > 0;
117 return r < 0;
118 }
119
120
DirSortFilterProxyModel(QObject * parent)121 DirSortFilterProxyModel::DirSortFilterProxyModel(QObject *parent)
122 : QSortFilterProxyModel(parent), m_sorts(QDir::NoSort)
123 {
124
125 }
126
setSorting(QDir::SortFlags sort)127 void DirSortFilterProxyModel::setSorting(QDir::SortFlags sort)
128 {
129 m_sorts = sort;
130 }
131
sorting() const132 QDir::SortFlags DirSortFilterProxyModel::sorting() const
133 {
134 return m_sorts;
135 }
136
lessThan(const QModelIndex & left,const QModelIndex & right) const137 bool DirSortFilterProxyModel::lessThan(const QModelIndex &left, const QModelIndex &right) const
138 {
139 QFileSystemModel *model = dynamic_cast<QFileSystemModel*>(this->sourceModel());
140 if (!model) {
141 return QSortFilterProxyModel::lessThan(left,right);
142 }
143 QDirSortItemComparator comp(m_sorts);
144 QDirSortItem n1;
145 QDirSortItem n2;
146 n1.item = model->fileInfo(left);
147 n2.item = model->fileInfo(right);
148 return comp.sort(n1,n2);
149 }
150
151