16 * The find result model source file of file manager |
16 * The find result model source file of file manager |
17 */ |
17 */ |
18 |
18 |
19 #include "fmfindresultmodel.h" |
19 #include "fmfindresultmodel.h" |
20 #include "fmfindthread.h" |
20 #include "fmfindthread.h" |
|
21 #include "fmfileiconprovider.h" |
21 |
22 |
22 #include <QDateTime> |
23 #include <QDateTime> |
23 #include <QFileIconProvider> |
24 |
|
25 #include <hbglobal.h> |
|
26 |
|
27 /*! |
|
28 \fn void finished() |
|
29 This signal is emitted when find is finished. |
|
30 */ |
|
31 |
|
32 /*! |
|
33 \fn void modelCountChanged( int count ) |
|
34 This signal is emitted when data count in model is changed |
|
35 \a count is current data count in model. |
|
36 Currently only start find and get more find result will emit this signal. |
|
37 */ |
24 |
38 |
25 FmFindResultModel::FmFindResultModel( QObject *parent ) |
39 FmFindResultModel::FmFindResultModel( QObject *parent ) |
26 : QAbstractListModel( parent ) |
40 : QAbstractListModel( parent ) |
27 { |
41 { |
28 init(); |
42 init(); |
29 connect( mFindThread, SIGNAL(finished()), this, SIGNAL(finished()) ); |
43 connect( mFindThread, SIGNAL(finished()), this, SIGNAL(finished()) ); |
30 connect( mFindThread, SIGNAL(found(int)), this, SLOT(on_findThread_found( int) ), Qt::BlockingQueuedConnection ); |
44 connect( mFindThread, SIGNAL(found(QStringList)), this, SLOT(on_findThread_found( QStringList) ), Qt::BlockingQueuedConnection ); |
31 } |
45 } |
32 |
46 |
33 FmFindResultModel::~FmFindResultModel() |
47 FmFindResultModel::~FmFindResultModel() |
34 { |
48 { |
35 delete mIconProvider; |
49 delete mIconProvider; |
36 } |
50 } |
37 |
51 |
|
52 /*! |
|
53 Returns the number of rows in the model. This value corresponds to the |
|
54 number of items in the model's internal string list. |
|
55 |
|
56 The optional \a parent argument is in most models used to specify |
|
57 the parent of the rows to be counted. Because this is a list if a |
|
58 valid parent is specified, the result will always be 0. |
|
59 |
|
60 \sa insertRows(), removeRows(), QAbstractItemModel::rowCount() |
|
61 */ |
38 int FmFindResultModel::rowCount( const QModelIndex &parent ) const |
62 int FmFindResultModel::rowCount( const QModelIndex &parent ) const |
39 { |
63 { |
40 if (!parent.isValid()) |
64 if ( !parent.isValid() ) |
41 return mFindResult.size(); |
65 return mFindResult.count(); |
42 |
66 |
43 return 0; |
67 return 0; |
44 } |
68 } |
45 |
69 |
46 int FmFindResultModel::columnCount( const QModelIndex &parent ) const |
70 int FmFindResultModel::columnCount( const QModelIndex &parent ) const |
47 { |
71 { |
48 if (!parent.isValid()) |
72 if ( !parent.isValid() ) |
49 return 4; |
73 return 4; |
50 |
74 |
51 return 0; |
75 return 0; |
52 } |
76 } |
53 |
77 |
91 if (orientation == Qt::Horizontal) { |
115 if (orientation == Qt::Horizontal) { |
92 if (role != Qt::DisplayRole) |
116 if (role != Qt::DisplayRole) |
93 return QVariant(); |
117 return QVariant(); |
94 |
118 |
95 switch (section) { |
119 switch (section) { |
96 case 0: return tr("Name"); |
120 case 0: return hbTrId("Name"); |
97 case 1: return tr("Size"); |
121 case 1: return hbTrId("Size"); |
98 case 2: return tr("Type"); |
122 case 2: return hbTrId("Type"); |
99 case 3: return tr("Date Modified"); |
123 case 3: return hbTrId("Date Modified"); |
100 default: return QVariant(); |
124 default: return QVariant(); |
101 } |
125 } |
102 } |
126 } |
103 |
127 |
104 return QAbstractItemModel::headerData( section, orientation, role ); |
128 return QAbstractItemModel::headerData( section, orientation, role ); |
105 } |
129 } |
106 |
130 |
107 bool FmFindResultModel::insertRows( int row, int count, const QModelIndex &parent ) |
131 /*! |
108 { |
132 Inserts \a dataList into the model, beginning at the given \a row. |
109 Q_UNUSED( parent ); |
133 |
110 if (row < 0 || count < 1) |
134 The \a parent index of the rows is optional and is only used for |
|
135 consistency with QAbstractItemModel. By default, a null index is |
|
136 specified, indicating that the rows are inserted in the top level of |
|
137 the model. |
|
138 |
|
139 \sa QAbstractItemModel::insertRows() |
|
140 */ |
|
141 |
|
142 bool FmFindResultModel::insertRows( int row, const QStringList &dataList, const QModelIndex &parent ) |
|
143 { |
|
144 if ( row < 0 || dataList.count() < 1 || row > rowCount(parent) ) |
111 return false; |
145 return false; |
112 |
146 |
113 beginInsertRows( QModelIndex(), row, row + count - 1 ); |
147 beginInsertRows( QModelIndex(), row, row + dataList.count() - 1 ); |
114 |
148 mFindResult.append( dataList ); |
115 endInsertRows(); |
149 endInsertRows(); |
116 |
150 |
117 return true; |
151 // emit modelCountChanged could let FmFindWidget switch style between EmptyTipWidget and ResultListview |
118 } |
152 // FmFindWidget will show an empty tip widget such as "No found files or folderss" if set 0 as parameter |
119 |
153 emit modelCountChanged( rowCount() ); |
|
154 |
|
155 return true; |
|
156 } |
|
157 |
|
158 /*! |
|
159 Removes \a count rows from the model, beginning at the given \a row. |
|
160 |
|
161 The \a parent index of the rows is optional and is only used for |
|
162 consistency with QAbstractItemModel. By default, a null index is |
|
163 specified, indicating that the rows are removed in the top level of |
|
164 the model. |
|
165 |
|
166 \sa QAbstractItemModel::removeRows() |
|
167 */ |
120 bool FmFindResultModel::removeRows( int row, int count, const QModelIndex &parent ) |
168 bool FmFindResultModel::removeRows( int row, int count, const QModelIndex &parent ) |
121 { |
169 { |
122 Q_UNUSED( parent ); |
170 if (row < 0 || count < 1 || (row + count) > rowCount(parent) ) |
123 |
|
124 if (row < 0 || count < 1 || row + count > mFindResult.size()) |
|
125 return false; |
171 return false; |
126 |
172 |
127 beginRemoveRows( QModelIndex(), row, row + count - 1 ); |
173 beginRemoveRows( QModelIndex(), row, row + count - 1 ); |
128 |
174 |
129 for (int i = 0; i < count; ++i) |
175 for (int i = 0; i < count; ++i) |
130 mFindResult.removeAt(row); |
176 mFindResult.removeAt(row); |
131 |
177 |
132 endRemoveRows(); |
178 endRemoveRows(); |
133 |
179 |
|
180 // emit modelCountChanged could let FmFindWidget switch style between EmptyTipWidget and ResultListview |
|
181 // FmFindWidget will show an empty tip widget such as "No found files or folderss" if set 0 as parameter |
|
182 emit modelCountChanged( rowCount() ); |
|
183 |
134 return true; |
184 return true; |
135 } |
185 } |
136 |
186 |
137 QFileInfo FmFindResultModel::fileInfo( const QModelIndex &index ) const |
187 QFileInfo FmFindResultModel::fileInfo( const QModelIndex &index ) const |
138 { |
188 { |
184 bool FmFindResultModel::isFinding() const |
233 bool FmFindResultModel::isFinding() const |
185 { |
234 { |
186 return mFindThread->isRunning(); |
235 return mFindThread->isRunning(); |
187 } |
236 } |
188 |
237 |
189 void FmFindResultModel::on_findThread_found( int count ) |
238 /* |
190 { |
239 Receive \a dataList as some found result |
191 int size = mFindResult.size(); |
240 Then insert dataList to model |
192 insertRows( mFindResult.size() - count, count ); |
241 */ |
193 emit modelCountChanged( mFindResult.size() ); |
242 void FmFindResultModel::on_findThread_found( const QStringList &dataList ) |
|
243 { |
|
244 if( dataList.isEmpty() ) { |
|
245 return; |
|
246 } |
|
247 insertRows( rowCount(), dataList ); |
194 } |
248 } |
195 |
249 |
196 bool FmFindResultModel::indexValid( const QModelIndex &index ) const |
250 bool FmFindResultModel::indexValid( const QModelIndex &index ) const |
197 { |
251 { |
198 Q_UNUSED( index ); |
252 Q_UNUSED( index ); |
199 return true; |
253 return true; |
200 } |
254 } |
201 |
255 |
202 void FmFindResultModel::init() |
256 void FmFindResultModel::init() |
203 { |
257 { |
204 mFindThread = new FmFindThread( &mFindResult, this ); |
258 mFindThread = new FmFindThread( this ); |
205 mFindThread->setObjectName( "findThread" ); |
259 mFindThread->setObjectName( "findThread" ); |
206 mIconProvider = new QFileIconProvider(); |
260 mIconProvider = new FmFileIconProvider(); |
207 } |
261 } |
208 |
262 |
209 bool FmFindResultModel::caseNameLessThan(const QString &s1, const QString &s2) |
263 bool FmFindResultModel::caseNameLessThan(const QPair<QString,int> &s1, |
210 { |
264 const QPair<QString,int> &s2) |
211 QFileInfo info1( s1 ); |
265 { |
212 QFileInfo info2( s2 ); |
266 QFileInfo info1( s1.first ); |
|
267 QFileInfo info2( s2.first ); |
213 |
268 |
214 return info1.fileName() < info2.fileName(); |
269 return info1.fileName() < info2.fileName(); |
215 } |
270 } |
216 |
271 |
217 bool FmFindResultModel::caseTimeLessThan(const QString &s1, const QString &s2) |
272 bool FmFindResultModel::caseTimeLessThan(const QPair<QString,int> &s1, |
218 { |
273 const QPair<QString,int> &s2) |
219 QFileInfo info1( s1 ); |
274 { |
220 QFileInfo info2( s2 ); |
275 QFileInfo info1( s1.first ); |
|
276 QFileInfo info2( s2.first ); |
221 |
277 |
222 return info1.lastModified() < info2.lastModified(); |
278 return info1.lastModified() < info2.lastModified(); |
223 } |
279 } |
224 |
280 |
225 bool FmFindResultModel::caseSizeLessThan(const QString &s1, const QString &s2) |
281 bool FmFindResultModel::caseSizeLessThan(const QPair<QString,int> &s1, |
226 { |
282 const QPair<QString,int> &s2) |
227 QFileInfo info1( s1 ); |
283 { |
228 QFileInfo info2( s2 ); |
284 QFileInfo info1( s1.first ); |
|
285 QFileInfo info2( s2.first ); |
229 |
286 |
230 return info1.size() < info2.size(); |
287 return info1.size() < info2.size(); |
231 } |
288 } |
232 |
289 |
233 bool FmFindResultModel::caseTypeLessThan(const QString &s1, const QString &s2) |
290 bool FmFindResultModel::caseTypeLessThan(const QPair<QString,int> &s1, |
234 { |
291 const QPair<QString,int> &s2) |
235 QFileInfo info1( s1 ); |
292 { |
236 QFileInfo info2( s2 ); |
293 QFileInfo info1( s1.first ); |
|
294 QFileInfo info2( s2.first ); |
237 |
295 |
238 if( info1.isDir() != info2.isDir() ){ |
296 if( info1.isDir() != info2.isDir() ){ |
239 return info1.isDir(); |
297 return info1.isDir(); |
240 } |
298 } |
241 else{ |
299 else{ |
242 return info1.suffix().toLower() < info2.suffix().toLower(); |
300 return info1.suffix().toLower() < info2.suffix().toLower(); |
243 } |
301 } |
244 } |
302 } |
245 |
303 |
246 |
304 /*! |
|
305 \reimp |
|
306 Sort by \a column, which is aligned to \a SortFlag |
|
307 \sa SortFlag |
|
308 */ |
247 void FmFindResultModel::sort ( int column, Qt::SortOrder order ) |
309 void FmFindResultModel::sort ( int column, Qt::SortOrder order ) |
248 { |
310 { |
|
311 // Sort algorithm comes from |
|
312 // void QListModel::sort(int column, Qt::SortOrder order) |
|
313 |
249 Q_UNUSED( order ); |
314 Q_UNUSED( order ); |
250 |
315 emit layoutAboutToBeChanged(); |
251 // emit layoutAboutToBeChanged(); |
316 |
252 |
317 // store value and row pair. |
253 switch( ( SortFlag )column ) |
318 QVector < QPair<QString,int> > sorting(mFindResult.count()); |
|
319 for (int i = 0; i < mFindResult.count(); ++i) { |
|
320 QString item = mFindResult.at(i); |
|
321 sorting[i].first = item; |
|
322 sorting[i].second = i; |
|
323 } |
|
324 |
|
325 // sort in "sorting" |
|
326 switch( ( SortFlag )column ) |
254 { |
327 { |
255 case Name: |
328 case Name: |
256 qSort( mFindResult.begin(), mFindResult.end(), caseNameLessThan ); |
329 qSort( sorting.begin(), sorting.end(), caseNameLessThan ); |
257 break; |
330 break; |
258 case Time: |
331 case Time: |
259 qSort( mFindResult.begin(), mFindResult.end(), caseTimeLessThan ); |
332 qSort( sorting.begin(), sorting.end(), caseTimeLessThan ); |
260 break; |
333 break; |
261 case Size: |
334 case Size: |
262 qSort( mFindResult.begin(), mFindResult.end(), caseSizeLessThan ); |
335 qSort( sorting.begin(), sorting.end(), caseSizeLessThan ); |
263 break; |
336 break; |
264 case Type: |
337 case Type: |
265 qSort( mFindResult.begin(), mFindResult.end(), caseTypeLessThan ); |
338 qSort( sorting.begin(), sorting.end(), caseTypeLessThan ); |
266 break; |
339 break; |
267 } |
340 } |
268 // emit layoutChanged(); |
341 |
269 emit refresh(); |
342 // create from Indexes and toIndexes, then set sorted data back to mFindResult |
270 } |
343 QModelIndexList fromIndexes; |
|
344 QModelIndexList toIndexes; |
|
345 for (int r = 0; r < sorting.count(); ++r) { |
|
346 QString item = sorting.at(r).first; |
|
347 toIndexes.append(createIndex(r, 0)); |
|
348 fromIndexes.append(createIndex(sorting.at(r).second, 0)); |
|
349 mFindResult[r] = sorting.at(r).first; |
|
350 } |
|
351 changePersistentIndexList(fromIndexes, toIndexes); |
|
352 |
|
353 emit layoutChanged(); |
|
354 } |