Line | Source | Count |
1 | | - |
2 | | - |
3 | | - |
4 | | - |
5 | | - |
6 | | - |
7 | | - |
8 | | - |
9 | | - |
10 | | - |
11 | | - |
12 | | - |
13 | | - |
14 | | - |
15 | | - |
16 | | - |
17 | | - |
18 | | - |
19 | | - |
20 | | - |
21 | | - |
22 | | - |
23 | | - |
24 | | - |
25 | | - |
26 | | - |
27 | | - |
28 | | - |
29 | | - |
30 | | - |
31 | | - |
32 | | - |
33 | | - |
34 | | - |
35 | | - |
36 | | - |
37 | | - |
38 | | - |
39 | | - |
40 | #include "qfilesystemmodel_p.h" | - |
41 | #include "qfilesystemmodel.h" | - |
42 | #include <qlocale.h> | - |
43 | #include <qmimedata.h> | - |
44 | #include <qurl.h> | - |
45 | #include <qdebug.h> | - |
46 | #include <qmessagebox.h> | - |
47 | #include <qapplication.h> | - |
48 | #include <QtCore/qcollator.h> | - |
49 | | - |
50 | #include <algorithm> | - |
51 | | - |
52 | #ifdef Q_OS_WIN | - |
53 | # include <QtCore/QVarLengthArray> | - |
54 | # include <qt_windows.h> | - |
55 | #endif | - |
56 | | - |
57 | QT_BEGIN_NAMESPACE | - |
58 | | - |
59 | #ifndef QT_NO_FILESYSTEMMODEL | - |
60 | | - |
61 | | - |
62 | | - |
63 | | - |
64 | | - |
65 | | - |
66 | | - |
67 | | - |
68 | | - |
69 | | - |
70 | | - |
71 | | - |
72 | | - |
73 | | - |
74 | | - |
75 | | - |
76 | | - |
77 | | - |
78 | | - |
79 | | - |
80 | | - |
81 | | - |
82 | | - |
83 | | - |
84 | | - |
85 | | - |
86 | | - |
87 | | - |
88 | | - |
89 | | - |
90 | | - |
91 | | - |
92 | | - |
93 | | - |
94 | | - |
95 | | - |
96 | | - |
97 | | - |
98 | | - |
99 | | - |
100 | | - |
101 | | - |
102 | | - |
103 | | - |
104 | | - |
105 | | - |
106 | | - |
107 | | - |
108 | | - |
109 | | - |
110 | | - |
111 | | - |
112 | | - |
113 | | - |
114 | | - |
115 | | - |
116 | | - |
117 | | - |
118 | | - |
119 | | - |
120 | | - |
121 | | - |
122 | | - |
123 | | - |
124 | | - |
125 | | - |
126 | | - |
127 | | - |
128 | | - |
129 | | - |
130 | | - |
131 | | - |
132 | | - |
133 | | - |
134 | | - |
135 | | - |
136 | | - |
137 | | - |
138 | | - |
139 | | - |
140 | | - |
141 | | - |
142 | | - |
143 | | - |
144 | | - |
145 | | - |
146 | | - |
147 | | - |
148 | | - |
149 | | - |
150 | | - |
151 | | - |
152 | | - |
153 | | - |
154 | | - |
155 | | - |
156 | | - |
157 | | - |
158 | | - |
159 | | - |
160 | | - |
161 | | - |
162 | | - |
163 | | - |
164 | QFileInfo QFileSystemModel::fileInfo(const QModelIndex &index) const | - |
165 | { | - |
166 | Q_D(const QFileSystemModel); | - |
167 | return d->node(index)->fileInfo(); | - |
168 | } | - |
169 | | - |
170 | | - |
171 | | - |
172 | | - |
173 | | - |
174 | | - |
175 | | - |
176 | | - |
177 | | - |
178 | | - |
179 | | - |
180 | | - |
181 | | - |
182 | | - |
183 | | - |
184 | | - |
185 | | - |
186 | | - |
187 | | - |
188 | | - |
189 | | - |
190 | | - |
191 | | - |
192 | | - |
193 | | - |
194 | | - |
195 | | - |
196 | | - |
197 | | - |
198 | | - |
199 | | - |
200 | | - |
201 | | - |
202 | | - |
203 | | - |
204 | bool QFileSystemModel::remove(const QModelIndex &aindex) | - |
205 | { | - |
206 | const QString path = filePath(aindex); | - |
207 | const bool success = QFileInfo(path).isFile() ? QFile::remove(path) : QDir(path).removeRecursively(); | - |
208 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
209 | if (success) { | - |
210 | QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func()); | - |
211 | d->fileInfoGatherer.removePath(path); | - |
212 | } | - |
213 | #endif | - |
214 | return success; | - |
215 | } | - |
216 | | - |
217 | | - |
218 | | - |
219 | | - |
220 | QFileSystemModel::QFileSystemModel(QObject *parent) | - |
221 | : QAbstractItemModel(*new QFileSystemModelPrivate, parent) | - |
222 | { | - |
223 | Q_D(QFileSystemModel); | - |
224 | d->init(); | - |
225 | } | - |
226 | | - |
227 | | - |
228 | | - |
229 | | - |
230 | QFileSystemModel::QFileSystemModel(QFileSystemModelPrivate &dd, QObject *parent) | - |
231 | : QAbstractItemModel(dd, parent) | - |
232 | { | - |
233 | Q_D(QFileSystemModel); | - |
234 | d->init(); | - |
235 | } | - |
236 | | - |
237 | | - |
238 | | - |
239 | | - |
240 | QFileSystemModel::~QFileSystemModel() | - |
241 | { | - |
242 | } | - |
243 | | - |
244 | | - |
245 | | - |
246 | | - |
247 | QModelIndex QFileSystemModel::index(int row, int column, const QModelIndex &parent) const | - |
248 | { | - |
249 | Q_D(const QFileSystemModel); | - |
250 | if (row < 0 || column < 0 || row >= rowCount(parent) || column >= columnCount(parent)) | - |
251 | return QModelIndex(); | - |
252 | | - |
253 | | - |
254 | QFileSystemModelPrivate::QFileSystemNode *parentNode = (d->indexValid(parent) ? d->node(parent) : | - |
255 | const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&d->root)); | - |
256 | Q_ASSERT(parentNode); | - |
257 | | - |
258 | | - |
259 | const QString &childName = parentNode->visibleChildren.at(d->translateVisibleLocation(parentNode, row)); | - |
260 | const QFileSystemModelPrivate::QFileSystemNode *indexNode = parentNode->children.value(childName); | - |
261 | Q_ASSERT(indexNode); | - |
262 | | - |
263 | return createIndex(row, column, const_cast<QFileSystemModelPrivate::QFileSystemNode*>(indexNode)); | - |
264 | } | - |
265 | | - |
266 | | - |
267 | | - |
268 | | - |
269 | QModelIndex QFileSystemModel::sibling(int row, int column, const QModelIndex &idx) const | - |
270 | { | - |
271 | if (row == idx.row() && column < QFileSystemModelPrivate::NumColumns) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
272 | | - |
273 | return createIndex(row, column, idx.internalPointer()); never executed: return createIndex(row, column, idx.internalPointer()); | 0 |
274 | } else { | - |
275 | | - |
276 | | - |
277 | return QAbstractItemModel::sibling(row, column, idx); never executed: return QAbstractItemModel::sibling(row, column, idx); | 0 |
278 | } | - |
279 | } | - |
280 | | - |
281 | | - |
282 | | - |
283 | | - |
284 | | - |
285 | | - |
286 | QModelIndex QFileSystemModel::index(const QString &path, int column) const | - |
287 | { | - |
288 | Q_D(const QFileSystemModel); | - |
289 | QFileSystemModelPrivate::QFileSystemNode *node = d->node(path, false); | - |
290 | return d->index(node, column); | - |
291 | } | - |
292 | | - |
293 | | - |
294 | | - |
295 | | - |
296 | | - |
297 | | - |
298 | QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QModelIndex &index) const | - |
299 | { | - |
300 | if (!index.isValid()) | - |
301 | return const_cast<QFileSystemNode*>(&root); | - |
302 | QFileSystemModelPrivate::QFileSystemNode *indexNode = static_cast<QFileSystemModelPrivate::QFileSystemNode*>(index.internalPointer()); | - |
303 | Q_ASSERT(indexNode); | - |
304 | return indexNode; | - |
305 | } | - |
306 | | - |
307 | #ifdef Q_OS_WIN32 | - |
308 | static QString qt_GetLongPathName(const QString &strShortPath) | - |
309 | { | - |
310 | if (strShortPath.isEmpty() | - |
311 | || strShortPath == QLatin1String(".") || strShortPath == QLatin1String("..")) | - |
312 | return strShortPath; | - |
313 | if (strShortPath.length() == 2 && strShortPath.endsWith(QLatin1Char(':'))) | - |
314 | return strShortPath.toUpper(); | - |
315 | const QString absPath = QDir(strShortPath).absolutePath(); | - |
316 | if (absPath.startsWith(QLatin1String("//")) | - |
317 | || absPath.startsWith(QLatin1String("\\\\"))) | - |
318 | return QDir::fromNativeSeparators(absPath); | - |
319 | if (absPath.startsWith(QLatin1Char('/'))) | - |
320 | return QString(); | - |
321 | const QString inputString = QLatin1String("\\\\?\\") + QDir::toNativeSeparators(absPath); | - |
322 | QVarLengthArray<TCHAR, MAX_PATH> buffer(MAX_PATH); | - |
323 | DWORD result = ::GetLongPathName((wchar_t*)inputString.utf16(), | - |
324 | buffer.data(), | - |
325 | buffer.size()); | - |
326 | if (result > DWORD(buffer.size())) { | - |
327 | buffer.resize(result); | - |
328 | result = ::GetLongPathName((wchar_t*)inputString.utf16(), | - |
329 | buffer.data(), | - |
330 | buffer.size()); | - |
331 | } | - |
332 | if (result > 4) { | - |
333 | QString longPath = QString::fromWCharArray(buffer.data() + 4); | - |
334 | longPath[0] = longPath.at(0).toUpper(); | - |
335 | return QDir::fromNativeSeparators(longPath); | - |
336 | } else { | - |
337 | return QDir::fromNativeSeparators(strShortPath); | - |
338 | } | - |
339 | } | - |
340 | #endif | - |
341 | | - |
342 | | - |
343 | | - |
344 | | - |
345 | | - |
346 | | - |
347 | QFileSystemModelPrivate::QFileSystemNode *QFileSystemModelPrivate::node(const QString &path, bool fetch) const | - |
348 | { | - |
349 | Q_Q(const QFileSystemModel); | - |
350 | Q_UNUSED(q); | - |
351 | if (path.isEmpty() || path == myComputer() || path.startsWith(QLatin1Char(':')))TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
352 | return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); never executed: return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); | 0 |
353 | | - |
354 | | - |
355 | QString absolutePath; | - |
356 | #ifdef Q_OS_WIN32 | - |
357 | QString longPath = qt_GetLongPathName(path); | - |
358 | #else | - |
359 | QString longPath = path; | - |
360 | #endif | - |
361 | if (longPath == rootDir.path())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
362 | absolutePath = rootDir.absolutePath(); never executed: absolutePath = rootDir.absolutePath(); | 0 |
363 | else | - |
364 | absolutePath = QDir(longPath).absolutePath(); never executed: absolutePath = QDir(longPath).absolutePath(); | 0 |
365 | | - |
366 | | - |
367 | QStringList pathElements = absolutePath.split(QLatin1Char('/'), QString::SkipEmptyParts); | - |
368 | if ((pathElements.isEmpty())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
369 | #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) | - |
370 | && QDir::fromNativeSeparators(longPath) != QLatin1String("/")TRUE | never evaluated | FALSE | never evaluated |
| 0 |
371 | #endif | - |
372 | ) | - |
373 | return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); never executed: return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); | 0 |
374 | QModelIndex index = QModelIndex(); | - |
375 | QString elementPath; | - |
376 | QChar separator = QLatin1Char('/'); | - |
377 | QString trailingSeparator; | - |
378 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) | - |
379 | if (absolutePath.startsWith(QLatin1String("//"))) { | - |
380 | QString host = QLatin1String("\\\\") + pathElements.firstconstFirst(); | - |
381 | if (absolutePath == QDir::fromNativeSeparators(host)) | - |
382 | absolutePath.append(QLatin1Char('/')); | - |
383 | if (longPath.endsWith(QLatin1Char('/')) && !absolutePath.endsWith(QLatin1Char('/'))) | - |
384 | absolutePath.append(QLatin1Char('/')); | - |
385 | if (absolutePath.endsWith(QLatin1Char('/'))) | - |
386 | trailingSeparator = QLatin1String("\\"); | - |
387 | int r = 0; | - |
388 | QFileSystemModelPrivate::QFileSystemNode *rootNode = const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); | - |
389 | if (!root.children.contains(host.toLower())) { | - |
390 | if (pathElements.count() == 1 && !absolutePath.endsWith(QLatin1Char('/'))) | - |
391 | return rootNode; | - |
392 | QFileInfo info(host); | - |
393 | if (!info.exists()) | - |
394 | return rootNode; | - |
395 | QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); | - |
396 | p->addNode(rootNode, host,info); | - |
397 | p->addVisibleFiles(rootNode, QStringList(host)); | - |
398 | } | - |
399 | r = rootNode->visibleLocation(host); | - |
400 | r = translateVisibleLocation(rootNode, r); | - |
401 | index = q->index(r, 0, QModelIndex()); | - |
402 | pathElements.pop_front(); | - |
403 | separator = QLatin1Char('\\'); | - |
404 | elementPath = host; | - |
405 | elementPath.append(separator); | - |
406 | } else { | - |
407 | if (!pathElements.at(0).contains(QLatin1Char(':'))) { | - |
408 | QString rootPath = QDir(longPath).rootPath(); | - |
409 | pathElements.prepend(rootPath); | - |
410 | } | - |
411 | if (pathElements.at(0).endsWith(QLatin1Char('/'))) | - |
412 | pathElements[0].chop(1); | - |
413 | } | - |
414 | #else | - |
415 | | - |
416 | if (absolutePath[0] == QLatin1Char('/'))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
417 | pathElements.prepend(QLatin1String("/")); never executed: pathElements.prepend(QLatin1String("/")); | 0 |
418 | #endif | - |
419 | | - |
420 | QFileSystemModelPrivate::QFileSystemNode *parent = node(index); | - |
421 | | - |
422 | for (int i = 0; i < pathElements.count(); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
423 | QString element = pathElements.at(i); | - |
424 | if (i != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
425 | elementPath.append(separator); never executed: elementPath.append(separator); | 0 |
426 | elementPath.append(element); | - |
427 | if (i == pathElements.count() - 1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
428 | elementPath.append(trailingSeparator); never executed: elementPath.append(trailingSeparator); | 0 |
429 | #ifdef Q_OS_WIN | - |
430 | | - |
431 | | - |
432 | | - |
433 | | - |
434 | | - |
435 | | - |
436 | | - |
437 | while (element.endsWith(QLatin1Char('.')) || element.endsWith(QLatin1Char(' '))) | - |
438 | element.chop(1); | - |
439 | | - |
440 | if (element.isEmpty()) | - |
441 | return parent; | - |
442 | #endif | - |
443 | bool alreadyExisted = parent->children.contains(element); | - |
444 | | - |
445 | | - |
446 | | - |
447 | if (alreadyExisted) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
448 | if ((parent->children.count() == 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
449 | || (parent->caseSensitive()TRUE | never evaluated | FALSE | never evaluated |
| 0 |
450 | && parent->children.value(element)->fileName != element)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
451 | || (!parent->caseSensitive()TRUE | never evaluated | FALSE | never evaluated |
| 0 |
452 | && parent->children.value(element)->fileName.toLower() != element.toLower()))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
453 | alreadyExisted = false; never executed: alreadyExisted = false; | 0 |
454 | } never executed: end of block | 0 |
455 | | - |
456 | QFileSystemModelPrivate::QFileSystemNode *node; | - |
457 | if (!alreadyExisted) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
458 | | - |
459 | | - |
460 | QFileInfo info(elementPath); | - |
461 | if (!info.exists())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
462 | return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); never executed: return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); | 0 |
463 | QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); | - |
464 | node = p->addNode(parent, element,info); | - |
465 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
466 | node->populate(fileInfoGatherer.getInfo(info)); | - |
467 | #endif | - |
468 | } else { never executed: end of block | 0 |
469 | node = parent->children.value(element); | - |
470 | } never executed: end of block | 0 |
471 | | - |
472 | Q_ASSERT(node); | - |
473 | if (!node->isVisible) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
474 | | - |
475 | if (alreadyExisted && node->hasInformation() && !fetch)TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
476 | return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); never executed: return const_cast<QFileSystemModelPrivate::QFileSystemNode*>(&root); | 0 |
477 | | - |
478 | QFileSystemModelPrivate *p = const_cast<QFileSystemModelPrivate*>(this); | - |
479 | p->addVisibleFiles(parent, QStringList(element)); | - |
480 | if (!p->bypassFilters.contains(node))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
481 | p->bypassFilters[node] = 1; never executed: p->bypassFilters[node] = 1; | 0 |
482 | QString dir = q->filePath(this->index(parent)); | - |
483 | if (!node->hasInformation() && fetch) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
484 | Fetching f;f .dir= { std::move(dir; | - |
| f.file =), std::move(element; | |
| f.node =), node ;}; | |
485 | p->toFetch.append(std::move(f);)); | - |
486 | p->fetchingTimer.start(0, const_cast<QFileSystemModel*>(q)); | - |
487 | } never executed: end of block | 0 |
488 | } never executed: end of block | 0 |
489 | parent = node; | - |
490 | } never executed: end of block | 0 |
491 | | - |
492 | return parent; never executed: return parent; | 0 |
493 | } | - |
494 | | - |
495 | | - |
496 | | - |
497 | | - |
498 | void QFileSystemModel::timerEvent(QTimerEvent *event) | - |
499 | { | - |
500 | Q_D(QFileSystemModel); | - |
501 | if (event->timerId() == d->fetchingTimer.timerId()) { | - |
502 | d->fetchingTimer.stop(); | - |
503 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
504 | for (int i = 0; i < d->toFetch.count(); ++i) { | - |
505 | const QFileSystemModelPrivate::QFileSystemNode *node = d->toFetch.at(i).node; | - |
506 | if (!node->hasInformation()) { | - |
507 | d->fileInfoGatherer.fetchExtendedInformation(d->toFetch.at(i).dir, | - |
508 | QStringList(d->toFetch.at(i).file)); | - |
509 | } else { | - |
510 | | - |
511 | } | - |
512 | } | - |
513 | #endif | - |
514 | d->toFetch.clear(); | - |
515 | } | - |
516 | } | - |
517 | | - |
518 | | - |
519 | | - |
520 | | - |
521 | | - |
522 | bool QFileSystemModel::isDir(const QModelIndex &index) const | - |
523 | { | - |
524 | | - |
525 | Q_D(const QFileSystemModel); | - |
526 | if (!index.isValid()) | - |
527 | return true; | - |
528 | QFileSystemModelPrivate::QFileSystemNode *n = d->node(index); | - |
529 | if (n->hasInformation()) | - |
530 | return n->isDir(); | - |
531 | return fileInfo(index).isDir(); | - |
532 | } | - |
533 | | - |
534 | | - |
535 | | - |
536 | | - |
537 | qint64 QFileSystemModel::size(const QModelIndex &index) const | - |
538 | { | - |
539 | Q_D(const QFileSystemModel); | - |
540 | if (!index.isValid()) | - |
541 | return 0; | - |
542 | return d->node(index)->size(); | - |
543 | } | - |
544 | | - |
545 | | - |
546 | | - |
547 | | - |
548 | QString QFileSystemModel::type(const QModelIndex &index) const | - |
549 | { | - |
550 | Q_D(const QFileSystemModel); | - |
551 | if (!index.isValid()) | - |
552 | return QString(); | - |
553 | return d->node(index)->type(); | - |
554 | } | - |
555 | | - |
556 | | - |
557 | | - |
558 | | - |
559 | QDateTime QFileSystemModel::lastModified(const QModelIndex &index) const | - |
560 | { | - |
561 | Q_D(const QFileSystemModel); | - |
562 | if (!index.isValid()) | - |
563 | return QDateTime(); | - |
564 | return d->node(index)->lastModified(); | - |
565 | } | - |
566 | | - |
567 | | - |
568 | | - |
569 | | - |
570 | QModelIndex QFileSystemModel::parent(const QModelIndex &index) const | - |
571 | { | - |
572 | Q_D(const QFileSystemModel); | - |
573 | if (!d->indexValid(index)) | - |
574 | return QModelIndex(); | - |
575 | | - |
576 | QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(index); | - |
577 | Q_ASSERT(indexNode != 0); | - |
578 | QFileSystemModelPrivate::QFileSystemNode *parentNode = indexNode->parent; | - |
579 | if (parentNode == 0 || parentNode == &d->root) | - |
580 | return QModelIndex(); | - |
581 | | - |
582 | | - |
583 | QFileSystemModelPrivate::QFileSystemNode *grandParentNode = parentNode->parent; | - |
584 | Q_ASSERT(grandParentNode->children.contains(parentNode->fileName)); | - |
585 | int visualRow = d->translateVisibleLocation(grandParentNode, grandParentNode->visibleLocation(grandParentNode->children.value(parentNode->fileName)->fileName)); | - |
586 | if (visualRow == -1) | - |
587 | return QModelIndex(); | - |
588 | return createIndex(visualRow, 0, parentNode); | - |
589 | } | - |
590 | | - |
591 | | - |
592 | | - |
593 | | - |
594 | | - |
595 | | - |
596 | QModelIndex QFileSystemModelPrivate::index(const QFileSystemModelPrivate::QFileSystemNode *node, int column) const | - |
597 | { | - |
598 | Q_Q(const QFileSystemModel); | - |
599 | QFileSystemModelPrivate::QFileSystemNode *parentNode = (node ? node->parent : 0); | - |
600 | if (node == &root || !parentNode) | - |
601 | return QModelIndex(); | - |
602 | | - |
603 | | - |
604 | Q_ASSERT(node); | - |
605 | if (!node->isVisible) | - |
606 | return QModelIndex(); | - |
607 | | - |
608 | int visualRow = translateVisibleLocation(parentNode, parentNode->visibleLocation(node->fileName)); | - |
609 | return q->createIndex(visualRow, column, const_cast<QFileSystemNode*>(node)); | - |
610 | } | - |
611 | | - |
612 | | - |
613 | | - |
614 | | - |
615 | bool QFileSystemModel::hasChildren(const QModelIndex &parent) const | - |
616 | { | - |
617 | Q_D(const QFileSystemModel); | - |
618 | if (parent.column() > 0) | - |
619 | return false; | - |
620 | | - |
621 | if (!parent.isValid()) | - |
622 | return true; | - |
623 | | - |
624 | const QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(parent); | - |
625 | Q_ASSERT(indexNode); | - |
626 | return (indexNode->isDir()); | - |
627 | } | - |
628 | | - |
629 | | - |
630 | | - |
631 | | - |
632 | bool QFileSystemModel::canFetchMore(const QModelIndex &parent) const | - |
633 | { | - |
634 | Q_D(const QFileSystemModel); | - |
635 | const QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(parent); | - |
636 | return (!indexNode->populatedChildren); | - |
637 | } | - |
638 | | - |
639 | | - |
640 | | - |
641 | | - |
642 | void QFileSystemModel::fetchMore(const QModelIndex &parent) | - |
643 | { | - |
644 | Q_D(QFileSystemModel); | - |
645 | if (!d->setRootPath) | - |
646 | return; | - |
647 | QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(parent); | - |
648 | if (indexNode->populatedChildren) | - |
649 | return; | - |
650 | indexNode->populatedChildren = true; | - |
651 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
652 | d->fileInfoGatherer.list(filePath(parent)); | - |
653 | #endif | - |
654 | } | - |
655 | | - |
656 | | - |
657 | | - |
658 | | - |
659 | int QFileSystemModel::rowCount(const QModelIndex &parent) const | - |
660 | { | - |
661 | Q_D(const QFileSystemModel); | - |
662 | if (parent.column() > 0) | - |
663 | return 0; | - |
664 | | - |
665 | if (!parent.isValid()) | - |
666 | return d->root.visibleChildren.count(); | - |
667 | | - |
668 | const QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(parent); | - |
669 | return parentNode->visibleChildren.count(); | - |
670 | } | - |
671 | | - |
672 | | - |
673 | | - |
674 | | - |
675 | int QFileSystemModel::columnCount(const QModelIndex &parent) const | - |
676 | { | - |
677 | return (parent.column() > 0) ? 0 : QFileSystemModelPrivate::NumColumns; | - |
678 | } | - |
679 | | - |
680 | | - |
681 | | - |
682 | | - |
683 | | - |
684 | | - |
685 | QVariant QFileSystemModel::myComputer(int role) const | - |
686 | { | - |
687 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
688 | Q_D(const QFileSystemModel); | - |
689 | #endif | - |
690 | switch (role) { | - |
691 | case Qt::DisplayRole: | - |
692 | return QFileSystemModelPrivate::myComputer(); | - |
693 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
694 | case Qt::DecorationRole: | - |
695 | return d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::Computer); | - |
696 | #endif | - |
697 | } | - |
698 | return QVariant(); | - |
699 | } | - |
700 | | - |
701 | | - |
702 | | - |
703 | | - |
704 | QVariant QFileSystemModel::data(const QModelIndex &index, int role) const | - |
705 | { | - |
706 | Q_D(const QFileSystemModel); | - |
707 | if (!index.isValid() || index.model() != this) | - |
708 | return QVariant(); | - |
709 | | - |
710 | switch (role) { | - |
711 | case Qt::EditRole: | - |
712 | case Qt::DisplayRole: | - |
713 | switch (index.column()) { | - |
714 | case 0: return d->displayName(index); | - |
715 | case 1: return d->size(index); | - |
716 | case 2: return d->type(index); | - |
717 | case 3: return d->time(index); | - |
718 | default: | - |
719 | qWarning("data: invalid display value column %d", index.column()); | - |
720 | break; | - |
721 | } | - |
722 | break; | - |
723 | case FilePathRole: | - |
724 | return filePath(index); | - |
725 | case FileNameRole: | - |
726 | return d->name(index); | - |
727 | case Qt::DecorationRole: | - |
728 | if (index.column() == 0) { | - |
729 | QIcon icon = d->icon(index); | - |
730 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
731 | if (icon.isNull()) { | - |
732 | if (d->node(index)->isDir()) | - |
733 | icon = d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::Folder); | - |
734 | else | - |
735 | icon = d->fileInfoGatherer.iconProvider()->icon(QFileIconProvider::File); | - |
736 | } | - |
737 | #endif // QT_NO_FILESYSTEMWATCHER | - |
738 | return icon; | - |
739 | } | - |
740 | break; | - |
741 | case Qt::TextAlignmentRole: | - |
742 | if (index.column() == 1) | - |
743 | return Qt::AlignRight; | - |
744 | break; | - |
745 | case FilePermissions: | - |
746 | int p = permissions(index); | - |
747 | return p; | - |
748 | } | - |
749 | | - |
750 | return QVariant(); | - |
751 | } | - |
752 | | - |
753 | | - |
754 | | - |
755 | | - |
756 | QString QFileSystemModelPrivate::size(const QModelIndex &index) const | - |
757 | { | - |
758 | if (!index.isValid()) | - |
759 | return QString(); | - |
760 | const QFileSystemNode *n = node(index); | - |
761 | if (n->isDir()) { | - |
762 | #ifdef Q_OS_MAC | - |
763 | return QLatin1String("--"); | - |
764 | #else | - |
765 | return QLatin1String(""); | - |
766 | #endif | - |
767 | | - |
768 | | - |
769 | | - |
770 | | - |
771 | } | - |
772 | return size(n->size()); | - |
773 | } | - |
774 | | - |
775 | QString QFileSystemModelPrivate::size(qint64 bytes) | - |
776 | { | - |
777 | | - |
778 | | - |
779 | const qint64 kb = 1024; | - |
780 | const qint64 mb = 1024 * kb; | - |
781 | const qint64 gb = 1024 * mb; | - |
782 | const qint64 tb = 1024 * gb; | - |
783 | if (bytes >= tb) | - |
784 | return QFileSystemModel::tr("%1 TB").arg(QLocale().toString(qreal(bytes) / tb, 'f', 3)); | - |
785 | if (bytes >= gb) | - |
786 | return QFileSystemModel::tr("%1 GB").arg(QLocale().toString(qreal(bytes) / gb, 'f', 2)); | - |
787 | if (bytes >= mb) | - |
788 | return QFileSystemModel::tr("%1 MB").arg(QLocale().toString(qreal(bytes) / mb, 'f', 1)); | - |
789 | if (bytes >= kb) | - |
790 | return QFileSystemModel::tr("%1 KB").arg(QLocale().toString(bytes / kb)); | - |
791 | return QFileSystemModel::tr("%1 bytes").arg(QLocale().toString(bytes)); | - |
792 | } | - |
793 | | - |
794 | | - |
795 | | - |
796 | | - |
797 | QString QFileSystemModelPrivate::time(const QModelIndex &index) const | - |
798 | { | - |
799 | if (!index.isValid()) | - |
800 | return QString(); | - |
801 | #ifndef QT_NO_DATESTRING | - |
802 | return node(index)->lastModified().toString(Qt::SystemLocaleDate); | - |
803 | #else | - |
804 | Q_UNUSED(index); | - |
805 | return QString(); | - |
806 | #endif | - |
807 | } | - |
808 | | - |
809 | | - |
810 | | - |
811 | | - |
812 | QString QFileSystemModelPrivate::type(const QModelIndex &index) const | - |
813 | { | - |
814 | if (!index.isValid()) | - |
815 | return QString(); | - |
816 | return node(index)->type(); | - |
817 | } | - |
818 | | - |
819 | | - |
820 | | - |
821 | | - |
822 | QString QFileSystemModelPrivate::name(const QModelIndex &index) const | - |
823 | { | - |
824 | if (!index.isValid()) | - |
825 | return QString(); | - |
826 | QFileSystemNode *dirNode = node(index); | - |
827 | if ( | - |
828 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
829 | fileInfoGatherer.resolveSymlinks() && | - |
830 | #endif | - |
831 | !resolvedSymLinks.isEmpty() && dirNode->isSymLink( true)) { | - |
832 | QString fullPath = QDir::fromNativeSeparators(filePath(index)); | - |
833 | return resolvedSymLinks.value(fullPath, dirNode->fileName); | - |
834 | } | - |
835 | return dirNode->fileName; | - |
836 | } | - |
837 | | - |
838 | | - |
839 | | - |
840 | | - |
841 | QString QFileSystemModelPrivate::displayName(const QModelIndex &index) const | - |
842 | { | - |
843 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) | - |
844 | QFileSystemNode *dirNode = node(index); | - |
845 | if (!dirNode->volumeName.isNull()) | - |
846 | return dirNode->volumeName + QLatin1String(" (") + name(index) + QLatin1Char(')'); | - |
847 | #endif | - |
848 | return name(index); | - |
849 | } | - |
850 | | - |
851 | | - |
852 | | - |
853 | | - |
854 | QIcon QFileSystemModelPrivate::icon(const QModelIndex &index) const | - |
855 | { | - |
856 | if (!index.isValid()) | - |
857 | return QIcon(); | - |
858 | return node(index)->icon(); | - |
859 | } | - |
860 | | - |
861 | | - |
862 | | - |
863 | | - |
864 | bool QFileSystemModel::setData(const QModelIndex &idx, const QVariant &value, int role) | - |
865 | { | - |
866 | Q_D(QFileSystemModel); | - |
867 | if (!idx.isValid() | - |
868 | || idx.column() != 0 | - |
869 | || role != Qt::EditRole | - |
870 | || (flags(idx) & Qt::ItemIsEditable) == 0) { | - |
871 | return false; | - |
872 | } | - |
873 | | - |
874 | QString newName = value.toString(); | - |
875 | QString oldName = idx.data().toString(); | - |
876 | if (newName == idx.data().toString()) | - |
877 | return true; | - |
878 | | - |
879 | const QString parentPath = filePath(parent(idx)); | - |
880 | | - |
881 | if (newName.isEmpty() | - |
882 | || QDir::toNativeSeparators(newName).contains(QDir::separator()) | - |
883 | || !QDir(parentPath).rename(oldName, newName)) { | - |
884 | #ifndef QT_NO_MESSAGEBOX | - |
885 | QMessageBox::information(0, QFileSystemModel::tr("Invalid filename"), | - |
886 | QFileSystemModel::tr("<b>The name \"%1\" can not be used.</b><p>Try using another name, with fewer characters or no punctuations marks.") | - |
887 | .arg(newName), | - |
888 | QMessageBox::Ok); | - |
889 | #endif // QT_NO_MESSAGEBOX | - |
890 | return false; | - |
891 | } else { | - |
892 | | - |
893 | | - |
894 | | - |
895 | | - |
896 | | - |
897 | | - |
898 | | - |
899 | | - |
900 | | - |
901 | | - |
902 | QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(idx); | - |
903 | QFileSystemModelPrivate::QFileSystemNode *parentNode = indexNode->parent; | - |
904 | int visibleLocation = parentNode->visibleLocation(parentNode->children.value(indexNode->fileName)->fileName); | - |
905 | | - |
906 | parentNode->visibleChildren.removeAt(visibleLocation); | - |
907 | QFileSystemModelPrivate::QFileSystemNode * oldValue = parentNode->children.value(oldName); | - |
908 | parentNode->children[newName] = oldValue; | - |
909 | oldValue->fileName = newName; | - |
910 | oldValue->parent = parentNode; | - |
911 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
912 | oldValue->populate(d->fileInfoGatherer.getInfo(QFileInfo(parentPath, newName))); | - |
913 | #endif | - |
914 | oldValue->isVisible = true; | - |
915 | | - |
916 | parentNode->children.remove(oldName); | - |
917 | parentNode->visibleChildren.insert(visibleLocation, newName); | - |
918 | | - |
919 | d->delayedSort(); | - |
920 | emit fileRenamed(parentPath, oldName, newName); | - |
921 | } | - |
922 | return true; | - |
923 | } | - |
924 | | - |
925 | | - |
926 | | - |
927 | | - |
928 | QVariant QFileSystemModel::headerData(int section, Qt::Orientation orientation, int role) const | - |
929 | { | - |
930 | switch (role) { | - |
931 | case Qt::DecorationRole: | - |
932 | if (section == 0) { | - |
933 | | - |
934 | | - |
935 | QImage pixmap(16, 1, QImage::Format_Mono); | - |
936 | pixmap.fill(0); | - |
937 | pixmap.setAlphaChannel(pixmap.createAlphaMask()); | - |
938 | return pixmap; | - |
939 | } | - |
940 | break; | - |
941 | case Qt::TextAlignmentRole: | - |
942 | return Qt::AlignLeft; | - |
943 | } | - |
944 | | - |
945 | if (orientation != Qt::Horizontal || role != Qt::DisplayRole) | - |
946 | return QAbstractItemModel::headerData(section, orientation, role); | - |
947 | | - |
948 | QString returnValue; | - |
949 | switch (section) { | - |
950 | case 0: returnValue = tr("Name"); | - |
951 | break; | - |
952 | case 1: returnValue = tr("Size"); | - |
953 | break; | - |
954 | case 2: returnValue = | - |
955 | #ifdef Q_OS_MAC | - |
956 | tr("Kind", "Match OS X Finder"); | - |
957 | #else | - |
958 | tr("Type", "All other platforms"); | - |
959 | #endif | - |
960 | break; | - |
961 | | - |
962 | | - |
963 | | - |
964 | | - |
965 | case 3: returnValue = tr("Date Modified"); | - |
966 | break; | - |
967 | default: return QVariant(); | - |
968 | } | - |
969 | return returnValue; | - |
970 | } | - |
971 | | - |
972 | | - |
973 | | - |
974 | | - |
975 | Qt::ItemFlags QFileSystemModel::flags(const QModelIndex &index) const | - |
976 | { | - |
977 | Q_D(const QFileSystemModel); | - |
978 | Qt::ItemFlags flags = QAbstractItemModel::flags(index); | - |
979 | if (!index.isValid()) | - |
980 | return flags; | - |
981 | | - |
982 | QFileSystemModelPrivate::QFileSystemNode *indexNode = d->node(index); | - |
983 | if (d->nameFilterDisables && !d->passNameFilters(indexNode)) { | - |
984 | flags &= ~Qt::ItemIsEnabled; | - |
985 | | - |
986 | return flags; | - |
987 | } | - |
988 | | - |
989 | flags |= Qt::ItemIsDragEnabled; | - |
990 | if (d->readOnly) | - |
991 | return flags; | - |
992 | if ((index.column() == 0) && indexNode->permissions() & QFile::WriteUser) { | - |
993 | flags |= Qt::ItemIsEditable; | - |
994 | if (indexNode->isDir()) | - |
995 | flags |= Qt::ItemIsDropEnabled; | - |
996 | else | - |
997 | flags |= Qt::ItemNeverHasChildren; | - |
998 | } | - |
999 | return flags; | - |
1000 | } | - |
1001 | | - |
1002 | | - |
1003 | | - |
1004 | | - |
1005 | void QFileSystemModelPrivate::_q_performDelayedSort() | - |
1006 | { | - |
1007 | Q_Q(QFileSystemModel); | - |
1008 | q->sort(sortColumn, sortOrder); | - |
1009 | } | - |
1010 | | - |
1011 | | - |
1012 | | - |
1013 | | - |
1014 | | - |
1015 | | - |
1016 | class QFileSystemModelSorter | - |
1017 | { | - |
1018 | public: | - |
1019 | inline QFileSystemModelSorter(int column) : sortColumn(column) | - |
1020 | { | - |
1021 | naturalCompare.setNumericMode(true); | - |
1022 | naturalCompare.setCaseSensitivity(Qt::CaseInsensitive); | - |
1023 | } | - |
1024 | | - |
1025 | bool compareNodes(const QFileSystemModelPrivate::QFileSystemNode *l, | - |
1026 | const QFileSystemModelPrivate::QFileSystemNode *r) const | - |
1027 | { | - |
1028 | switch (sortColumn) { | - |
1029 | case 0: { | - |
1030 | #ifndef Q_OS_MAC | - |
1031 | | - |
1032 | bool left = l->isDir(); | - |
1033 | bool right = r->isDir(); | - |
1034 | if (left ^ right) | - |
1035 | return left; | - |
1036 | #endif | - |
1037 | return naturalCompare.compare(l->fileName, r->fileName) < 0; | - |
1038 | } | - |
1039 | case 1: | - |
1040 | { | - |
1041 | | - |
1042 | bool left = l->isDir(); | - |
1043 | bool right = r->isDir(); | - |
1044 | if (left ^ right) | - |
1045 | return left; | - |
1046 | | - |
1047 | qint64 sizeDifference = l->size() - r->size(); | - |
1048 | if (sizeDifference == 0) | - |
1049 | return naturalCompare.compare(l->fileName, r->fileName) < 0; | - |
1050 | | - |
1051 | return sizeDifference < 0; | - |
1052 | } | - |
1053 | case 2: | - |
1054 | { | - |
1055 | int compare = naturalCompare.compare(l->type(), r->type()); | - |
1056 | if (compare == 0) | - |
1057 | return naturalCompare.compare(l->fileName, r->fileName) < 0; | - |
1058 | | - |
1059 | return compare < 0; | - |
1060 | } | - |
1061 | case 3: | - |
1062 | { | - |
1063 | if (l->lastModified() == r->lastModified()) | - |
1064 | return naturalCompare.compare(l->fileName, r->fileName) < 0; | - |
1065 | | - |
1066 | return l->lastModified() < r->lastModified(); | - |
1067 | } | - |
1068 | } | - |
1069 | Q_ASSERT(false); | - |
1070 | return false; | - |
1071 | } | - |
1072 | | - |
1073 | bool operator()(const QFileSystemModelPrivate::QFileSystemNode *l, | - |
1074 | const QFileSystemModelPrivate::QFileSystemNode *r) const | - |
1075 | { | - |
1076 | return compareNodes(l, r); | - |
1077 | } | - |
1078 | | - |
1079 | | - |
1080 | private: | - |
1081 | QCollator naturalCompare; | - |
1082 | int sortColumn; | - |
1083 | }; | - |
1084 | | - |
1085 | | - |
1086 | | - |
1087 | | - |
1088 | | - |
1089 | | - |
1090 | void QFileSystemModelPrivate::sortChildren(int column, const QModelIndex &parent) | - |
1091 | { | - |
1092 | Q_Q(QFileSystemModel); | - |
1093 | QFileSystemModelPrivate::QFileSystemNode *indexNode = node(parent); | - |
1094 | if (indexNode->children.count() == 0) | - |
1095 | return; | - |
1096 | | - |
1097 | QVector<QFileSystemModelPrivate::QFileSystemNode*> values; | - |
1098 | QHash<QString, QFileSystemNode *>::const_iterator iterator; | - |
1099 | for(iterator = indexNode->children.constBegin() ; iterator != indexNode->children.constEnd() ; ++iterator) { | - |
1100 | if (filtersAcceptsNode(iterator.value())) { | - |
1101 | values.append(iterator.value()); | - |
1102 | } else { | - |
1103 | iterator.value()->isVisible = false; | - |
1104 | } | - |
1105 | } | - |
1106 | QFileSystemModelSorter ms(column); | - |
1107 | std::sort(values.begin(), values.end(), ms); | - |
1108 | | - |
1109 | indexNode->visibleChildren.clear(); | - |
1110 | | - |
1111 | indexNode->dirtyChildrenIndex = -1; | - |
1112 | const int numValues = values.count(); | - |
1113 | indexNode->visibleChildren.reserve(numValues); | - |
1114 | for (int i = 0; i < numValues; ++i) { | - |
1115 | indexNode->visibleChildren.append(values.at(i)->fileName); | - |
1116 | values.at(i)->isVisible = true; | - |
1117 | } | - |
1118 | | - |
1119 | if (!disableRecursiveSort) { | - |
1120 | for (int i = 0; i < q->rowCount(parent); ++i) { | - |
1121 | const QModelIndex childIndex = q->index(i, 0, parent); | - |
1122 | QFileSystemModelPrivate::QFileSystemNode *indexNode = node(childIndex); | - |
1123 | | - |
1124 | if (indexNode->isVisible) | - |
1125 | sortChildren(column, childIndex); | - |
1126 | } | - |
1127 | } | - |
1128 | } | - |
1129 | | - |
1130 | | - |
1131 | | - |
1132 | | - |
1133 | void QFileSystemModel::sort(int column, Qt::SortOrder order) | - |
1134 | { | - |
1135 | Q_D(QFileSystemModel); | - |
1136 | if (d->sortOrder == order && d->sortColumn == column && !d->forceSort) | - |
1137 | return; | - |
1138 | | - |
1139 | emit layoutAboutToBeChanged(); | - |
1140 | QModelIndexList oldList = persistentIndexList(); | - |
1141 | QVector<QPair<QFileSystemModelPrivate::QFileSystemNode*, int> > oldNodes; | - |
1142 | const int nodeCount = oldList.count(); | - |
1143 | oldNodes.reserve(nodeCount); | - |
1144 | for (int i = 0; i < nodeCount; ++i) { | - |
1145 | const QModelIndex &oldNode = oldList.at(i); | - |
1146 | QPair<QFileSystemModelPrivate::QFileSystemNode*, int> pair(d->node(oldNode), oldNode.column()); | - |
1147 | oldNodes.append(pair); | - |
1148 | } | - |
1149 | | - |
1150 | if (!(d->sortColumn == column && d->sortOrder != order && !d->forceSort)) { | - |
1151 | | - |
1152 | d->sortChildren(column, index(rootPath())); | - |
1153 | d->sortColumn = column; | - |
1154 | d->forceSort = false; | - |
1155 | } | - |
1156 | d->sortOrder = order; | - |
1157 | | - |
1158 | QModelIndexList newList; | - |
1159 | const int numOldNodes = oldNodes.size(); | - |
1160 | newList.reserve(numOldNodes); | - |
1161 | for (int i = 0; i < numOldNodes; ++i) { | - |
1162 | const QPair<QFileSystemModelPrivate::QFileSystemNode*, int> &oldNode = oldNodes.at(i); | - |
1163 | newList.append(d->index(oldNode.first, oldNode.second)); | - |
1164 | } | - |
1165 | changePersistentIndexList(oldList, newList); | - |
1166 | emit layoutChanged(); | - |
1167 | } | - |
1168 | | - |
1169 | | - |
1170 | | - |
1171 | | - |
1172 | | - |
1173 | QStringList QFileSystemModel::mimeTypes() const | - |
1174 | { | - |
1175 | return QStringList(QLatin1String("text/uri-list")); | - |
1176 | } | - |
1177 | | - |
1178 | | - |
1179 | | - |
1180 | | - |
1181 | | - |
1182 | | - |
1183 | | - |
1184 | | - |
1185 | | - |
1186 | QMimeData *QFileSystemModel::mimeData(const QModelIndexList &indexes) const | - |
1187 | { | - |
1188 | QList<QUrl> urls; | - |
1189 | QList<QModelIndex>::const_iterator it = indexes.begin(); | - |
1190 | for (; it != indexes.end(); ++it) | - |
1191 | if ((*it).column() == 0) | - |
1192 | urls << QUrl::fromLocalFile(filePath(*it)); | - |
1193 | QMimeData *data = new QMimeData(); | - |
1194 | data->setUrls(urls); | - |
1195 | return data; | - |
1196 | } | - |
1197 | | - |
1198 | | - |
1199 | | - |
1200 | | - |
1201 | | - |
1202 | | - |
1203 | | - |
1204 | | - |
1205 | bool QFileSystemModel::dropMimeData(const QMimeData *data, Qt::DropAction action, | - |
1206 | int row, int column, const QModelIndex &parent) | - |
1207 | { | - |
1208 | Q_UNUSED(row); | - |
1209 | Q_UNUSED(column); | - |
1210 | if (!parent.isValid() || isReadOnly()) | - |
1211 | return false; | - |
1212 | | - |
1213 | bool success = true; | - |
1214 | QString to = filePath(parent) + QDir::separator(); | - |
1215 | | - |
1216 | QList<QUrl> urls = data->urls(); | - |
1217 | QList<QUrl>::const_iterator it = urls.constBegin(); | - |
1218 | | - |
1219 | switch (action) { | - |
1220 | case Qt::CopyAction: | - |
1221 | for (; it != urls.constEnd(); ++it) { | - |
1222 | QString path = (*it).toLocalFile(); | - |
1223 | success = QFile::copy(path, to + QFileInfo(path).fileName()) && success; | - |
1224 | } | - |
1225 | break; | - |
1226 | case Qt::LinkAction: | - |
1227 | for (; it != urls.constEnd(); ++it) { | - |
1228 | QString path = (*it).toLocalFile(); | - |
1229 | success = QFile::link(path, to + QFileInfo(path).fileName()) && success; | - |
1230 | } | - |
1231 | break; | - |
1232 | case Qt::MoveAction: | - |
1233 | for (; it != urls.constEnd(); ++it) { | - |
1234 | QString path = (*it).toLocalFile(); | - |
1235 | success = QFile::rename(path, to + QFileInfo(path).fileName()) && success; | - |
1236 | } | - |
1237 | break; | - |
1238 | default: | - |
1239 | return false; | - |
1240 | } | - |
1241 | | - |
1242 | return success; | - |
1243 | } | - |
1244 | | - |
1245 | | - |
1246 | | - |
1247 | | - |
1248 | Qt::DropActions QFileSystemModel::supportedDropActions() const | - |
1249 | { | - |
1250 | return Qt::CopyAction | Qt::MoveAction | Qt::LinkAction; | - |
1251 | } | - |
1252 | | - |
1253 | | - |
1254 | | - |
1255 | | - |
1256 | | - |
1257 | QString QFileSystemModel::filePath(const QModelIndex &index) const | - |
1258 | { | - |
1259 | Q_D(const QFileSystemModel); | - |
1260 | QString fullPath = d->filePath(index); | - |
1261 | QFileSystemModelPrivate::QFileSystemNode *dirNode = d->node(index); | - |
1262 | if (dirNode->isSymLink() | - |
1263 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1264 | && d->fileInfoGatherer.resolveSymlinks() | - |
1265 | #endif | - |
1266 | && d->resolvedSymLinks.contains(fullPath) | - |
1267 | && dirNode->isDir()) { | - |
1268 | QFileInfo resolvedInfo(fullPath); | - |
1269 | resolvedInfo = resolvedInfo.canonicalFilePath(); | - |
1270 | if (resolvedInfo.exists()) | - |
1271 | return resolvedInfo.filePath(); | - |
1272 | } | - |
1273 | return fullPath; | - |
1274 | } | - |
1275 | | - |
1276 | QString QFileSystemModelPrivate::filePath(const QModelIndex &index) const | - |
1277 | { | - |
1278 | Q_Q(const QFileSystemModel); | - |
1279 | Q_UNUSED(q); | - |
1280 | if (!index.isValid()) | - |
1281 | return QString(); | - |
1282 | Q_ASSERT(index.model() == q); | - |
1283 | | - |
1284 | QStringList path; | - |
1285 | QModelIndex idx = index; | - |
1286 | while (idx.isValid()) { | - |
1287 | QFileSystemModelPrivate::QFileSystemNode *dirNode = node(idx); | - |
1288 | if (dirNode) | - |
1289 | path.prepend(dirNode->fileName); | - |
1290 | idx = idx.parent(); | - |
1291 | } | - |
1292 | QString fullPath = QDir::fromNativeSeparators(path.join(QDir::separator())); | - |
1293 | #if !defined(Q_OS_WIN) || defined(Q_OS_WINCE) | - |
1294 | if ((fullPath.length() > 2) && fullPath[0] == QLatin1Char('/') && fullPath[1] == QLatin1Char('/')) | - |
1295 | fullPath = fullPath.mid(1); | - |
1296 | #endif | - |
1297 | #if defined(Q_OS_WIN) | - |
1298 | if (fullPath.length() == 2 && fullPath.endsWith(QLatin1Char(':'))) | - |
1299 | fullPath.append(QLatin1Char('/')); | - |
1300 | #endif | - |
1301 | return fullPath; | - |
1302 | } | - |
1303 | | - |
1304 | | - |
1305 | | - |
1306 | | - |
1307 | QModelIndex QFileSystemModel::mkdir(const QModelIndex &parent, const QString &name) | - |
1308 | { | - |
1309 | Q_D(QFileSystemModel); | - |
1310 | if (!parent.isValid()) | - |
1311 | return parent; | - |
1312 | | - |
1313 | QDir dir(filePath(parent)); | - |
1314 | if (!dir.mkdir(name)) | - |
1315 | return QModelIndex(); | - |
1316 | QFileSystemModelPrivate::QFileSystemNode *parentNode = d->node(parent); | - |
1317 | d->addNode(parentNode, name, QFileInfo()); | - |
1318 | Q_ASSERT(parentNode->children.contains(name)); | - |
1319 | QFileSystemModelPrivate::QFileSystemNode *node = parentNode->children[name]; | - |
1320 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1321 | node->populate(d->fileInfoGatherer.getInfo(QFileInfo(dir.absolutePath() + QDir::separator() + name))); | - |
1322 | #endif | - |
1323 | d->addVisibleFiles(parentNode, QStringList(name)); | - |
1324 | return d->index(node); | - |
1325 | } | - |
1326 | | - |
1327 | | - |
1328 | | - |
1329 | | - |
1330 | QFile::Permissions QFileSystemModel::permissions(const QModelIndex &index) const | - |
1331 | { | - |
1332 | Q_D(const QFileSystemModel); | - |
1333 | return d->node(index)->permissions(); | - |
1334 | } | - |
1335 | | - |
1336 | | - |
1337 | | - |
1338 | | - |
1339 | | - |
1340 | | - |
1341 | | - |
1342 | | - |
1343 | | - |
1344 | | - |
1345 | | - |
1346 | | - |
1347 | | - |
1348 | | - |
1349 | QModelIndex QFileSystemModel::setRootPath(const QString &newPath) | - |
1350 | { | - |
1351 | Q_D(QFileSystemModel); | - |
1352 | #ifdef Q_OS_WIN | - |
1353 | #ifdef Q_OS_WIN32 | - |
1354 | QString longNewPath = qt_GetLongPathName(newPath); | - |
1355 | #else | - |
1356 | QString longNewPath = QDir::fromNativeSeparators(newPath); | - |
1357 | #endif | - |
1358 | #else | - |
1359 | QString longNewPath = newPath; | - |
1360 | #endif | - |
1361 | QDir newPathDir(longNewPath); | - |
1362 | | - |
1363 | if (!newPath.isEmpty()) { | - |
1364 | longNewPath = QDir::cleanPath(longNewPath); | - |
1365 | newPathDir.setPath(longNewPath); | - |
1366 | } | - |
1367 | | - |
1368 | d->setRootPath = true; | - |
1369 | | - |
1370 | | - |
1371 | if (!newPath.isEmpty() && longNewPath.isEmpty()) | - |
1372 | return d->index(rootPath()); | - |
1373 | | - |
1374 | if (d->rootDir.path() == longNewPath) | - |
1375 | return d->index(rootPath()); | - |
1376 | | - |
1377 | bool showDrives = (longNewPath.isEmpty() || longNewPath == d->myComputer()); | - |
1378 | if (!showDrives && !newPathDir.exists()) | - |
1379 | return d->index(rootPath()); | - |
1380 | | - |
1381 | | - |
1382 | if (!rootPath().isEmpty() && rootPath() != QLatin1String(".")) { | - |
1383 | | - |
1384 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1385 | d->fileInfoGatherer.removePath(rootPath()); | - |
1386 | #endif | - |
1387 | | - |
1388 | | - |
1389 | | - |
1390 | d->node(rootPath())->populatedChildren = false; | - |
1391 | } | - |
1392 | | - |
1393 | | - |
1394 | d->rootDir = newPathDir; | - |
1395 | QModelIndex newRootIndex; | - |
1396 | if (showDrives) { | - |
1397 | | - |
1398 | d->rootDir.setPath(QLatin1String("")); | - |
1399 | } else { | - |
1400 | newRootIndex = d->index(newPathDir.path()); | - |
1401 | } | - |
1402 | fetchMore(newRootIndex); | - |
1403 | emit rootPathChanged(longNewPath); | - |
1404 | d->forceSort = true; | - |
1405 | d->delayedSort(); | - |
1406 | return newRootIndex; | - |
1407 | } | - |
1408 | | - |
1409 | | - |
1410 | | - |
1411 | | - |
1412 | | - |
1413 | | - |
1414 | QString QFileSystemModel::rootPath() const | - |
1415 | { | - |
1416 | Q_D(const QFileSystemModel); | - |
1417 | return d->rootDir.path(); | - |
1418 | } | - |
1419 | | - |
1420 | | - |
1421 | | - |
1422 | | - |
1423 | | - |
1424 | | - |
1425 | QDir QFileSystemModel::rootDirectory() const | - |
1426 | { | - |
1427 | Q_D(const QFileSystemModel); | - |
1428 | QDir dir(d->rootDir); | - |
1429 | dir.setNameFilters(nameFilters()); | - |
1430 | dir.setFilter(filter()); | - |
1431 | return dir; | - |
1432 | } | - |
1433 | | - |
1434 | | - |
1435 | | - |
1436 | | - |
1437 | void QFileSystemModel::setIconProvider(QFileIconProvider *provider) | - |
1438 | { | - |
1439 | Q_D(QFileSystemModel); | - |
1440 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1441 | d->fileInfoGatherer.setIconProvider(provider); | - |
1442 | #endif | - |
1443 | d->root.updateIcon(provider, QString()); | - |
1444 | } | - |
1445 | | - |
1446 | | - |
1447 | | - |
1448 | | - |
1449 | QFileIconProvider *QFileSystemModel::iconProvider() const | - |
1450 | { | - |
1451 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1452 | Q_D(const QFileSystemModel); | - |
1453 | return d->fileInfoGatherer.iconProvider(); | - |
1454 | #else | - |
1455 | return 0; | - |
1456 | #endif | - |
1457 | } | - |
1458 | | - |
1459 | | - |
1460 | | - |
1461 | | - |
1462 | | - |
1463 | | - |
1464 | | - |
1465 | | - |
1466 | | - |
1467 | void QFileSystemModel::setFilter(QDir::Filters filters) | - |
1468 | { | - |
1469 | Q_D(QFileSystemModel); | - |
1470 | if (d->filters == filters) | - |
1471 | return; | - |
1472 | d->filters = filters; | - |
1473 | | - |
1474 | setNameFilters(nameFilters()); | - |
1475 | d->forceSort = true; | - |
1476 | d->delayedSort(); | - |
1477 | } | - |
1478 | | - |
1479 | | - |
1480 | | - |
1481 | | - |
1482 | | - |
1483 | | - |
1484 | | - |
1485 | | - |
1486 | | - |
1487 | QDir::Filters QFileSystemModel::filter() const | - |
1488 | { | - |
1489 | Q_D(const QFileSystemModel); | - |
1490 | return d->filters; | - |
1491 | } | - |
1492 | | - |
1493 | | - |
1494 | | - |
1495 | | - |
1496 | | - |
1497 | | - |
1498 | | - |
1499 | | - |
1500 | | - |
1501 | void QFileSystemModel::setResolveSymlinks(bool enable) | - |
1502 | { | - |
1503 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1504 | Q_D(QFileSystemModel); | - |
1505 | d->fileInfoGatherer.setResolveSymlinks(enable); | - |
1506 | #else | - |
1507 | Q_UNUSED(enable) | - |
1508 | #endif | - |
1509 | } | - |
1510 | | - |
1511 | bool QFileSystemModel::resolveSymlinks() const | - |
1512 | { | - |
1513 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1514 | Q_D(const QFileSystemModel); | - |
1515 | return d->fileInfoGatherer.resolveSymlinks(); | - |
1516 | #else | - |
1517 | return false; | - |
1518 | #endif | - |
1519 | } | - |
1520 | | - |
1521 | | - |
1522 | | - |
1523 | | - |
1524 | | - |
1525 | | - |
1526 | | - |
1527 | | - |
1528 | | - |
1529 | | - |
1530 | void QFileSystemModel::setReadOnly(bool enable) | - |
1531 | { | - |
1532 | Q_D(QFileSystemModel); | - |
1533 | d->readOnly = enable; | - |
1534 | } | - |
1535 | | - |
1536 | bool QFileSystemModel::isReadOnly() const | - |
1537 | { | - |
1538 | Q_D(const QFileSystemModel); | - |
1539 | return d->readOnly; | - |
1540 | } | - |
1541 | | - |
1542 | | - |
1543 | | - |
1544 | | - |
1545 | | - |
1546 | | - |
1547 | | - |
1548 | void QFileSystemModel::setNameFilterDisables(bool enable) | - |
1549 | { | - |
1550 | Q_D(QFileSystemModel); | - |
1551 | if (d->nameFilterDisables == enable) | - |
1552 | return; | - |
1553 | d->nameFilterDisables = enable; | - |
1554 | d->forceSort = true; | - |
1555 | d->delayedSort(); | - |
1556 | } | - |
1557 | | - |
1558 | bool QFileSystemModel::nameFilterDisables() const | - |
1559 | { | - |
1560 | Q_D(const QFileSystemModel); | - |
1561 | return d->nameFilterDisables; | - |
1562 | } | - |
1563 | | - |
1564 | | - |
1565 | | - |
1566 | | - |
1567 | void QFileSystemModel::setNameFilters(const QStringList &filters) | - |
1568 | { | - |
1569 | | - |
1570 | #ifndef QT_NO_REGEXP | - |
1571 | Q_D(QFileSystemModel); | - |
1572 | | - |
1573 | if (!d->bypassFilters.isEmpty()) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1574 | | - |
1575 | d->bypassFilters.clear(); | - |
1576 | | - |
1577 | QPersistentModelIndex root(index(rootPath())); | - |
1578 | const QModelIndexList persistantListpersistentList = persistentIndexList(); | - |
1579 | for (int i = 0; i < persistantList.count(); ++iconst auto &persistentIndex : persistentList) { | - |
1580 | QFileSystemModelPrivate::QFileSystemNode *node;node = d->node(persistantList.at(i));persistentIndex); | - |
1581 | while (node) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1582 | if (d->bypassFilters.contains(node))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1583 | break; never executed: break; | 0 |
1584 | if (node->isDir())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1585 | d->bypassFilters[node] = true; never executed: d->bypassFilters[node] = true; | 0 |
1586 | node = node->parent; | - |
1587 | } never executed: end of block | 0 |
1588 | } never executed: end of block | 0 |
1589 | } never executed: end of block | 0 |
1590 | | - |
1591 | d->nameFilters.clear(); | - |
1592 | const Qt::CaseSensitivity caseSensitive = | - |
1593 | (filter() & QDir::CaseSensitive) ? Qt::CaseSensitive : Qt::CaseInsensitive;TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1594 | for (int i = 0; i <const auto &filter : filters.size(); ++i) | - |
1595 | {d->nameFilters << QRegExp(filters.at(i),filter, caseSensitive, QRegExp::Wildcard); never executed: d->nameFilters << QRegExp(filter, caseSensitive, QRegExp::Wildcard); | 0 |
1596 | }d->forceSort = true; | - |
1597 | d->delayedSort(); | - |
1598 | #endif | - |
1599 | } never executed: end of block | 0 |
1600 | | - |
1601 | | - |
1602 | | - |
1603 | | - |
1604 | QStringList QFileSystemModel::nameFilters() const | - |
1605 | { | - |
1606 | Q_D(const QFileSystemModel); | - |
1607 | QStringList filters; | - |
1608 | #ifndef QT_NO_REGEXP | - |
1609 | const int numNameFilters = d->nameFilters.size(); | - |
1610 | filters.reserve(numNameFilters); | - |
1611 | for (int i = 0; i < numNameFilters; ++i) { | - |
1612 | filters << d->nameFilters.at(i).pattern(); | - |
1613 | } | - |
1614 | #endif | - |
1615 | return filters; | - |
1616 | } | - |
1617 | | - |
1618 | | - |
1619 | | - |
1620 | | - |
1621 | bool QFileSystemModel::event(QEvent *event) | - |
1622 | { | - |
1623 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1624 | Q_D(QFileSystemModel); | - |
1625 | if (event->type() == QEvent::LanguageChange) { | - |
1626 | d->root.retranslateStrings(d->fileInfoGatherer.iconProvider(), QString()); | - |
1627 | return true; | - |
1628 | } | - |
1629 | #endif | - |
1630 | return QAbstractItemModel::event(event); | - |
1631 | } | - |
1632 | | - |
1633 | bool QFileSystemModel::rmdir(const QModelIndex &aindex) | - |
1634 | { | - |
1635 | QString path = filePath(aindex); | - |
1636 | const bool success = QDir().rmdir(path); | - |
1637 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1638 | if (success) { | - |
1639 | QFileSystemModelPrivate * d = const_cast<QFileSystemModelPrivate*>(d_func()); | - |
1640 | d->fileInfoGatherer.removePath(path); | - |
1641 | } | - |
1642 | #endif | - |
1643 | return success; | - |
1644 | } | - |
1645 | | - |
1646 | | - |
1647 | | - |
1648 | | - |
1649 | | - |
1650 | | - |
1651 | | - |
1652 | void QFileSystemModelPrivate::_q_directoryChanged(const QString &directory, const QStringList &files) | - |
1653 | { | - |
1654 | QFileSystemModelPrivate::QFileSystemNode *parentNode = node(directory, false); | - |
1655 | if (parentNode->children.count() == 0) | - |
1656 | return; | - |
1657 | QStringList toRemove; | - |
1658 | QStringList newFiles = files; | - |
1659 | std::sort(newFiles.begin(), newFiles.end()); | - |
1660 | QHash<QString, QFileSystemNode*>::const_iterator i = parentNode->children.constBegin(); | - |
1661 | while (i != parentNode->children.constEnd()) { | - |
1662 | QStringList::iterator iterator = std::lower_bound(newFiles.begin(), newFiles.end(), i.value()->fileName); | - |
1663 | if ((iterator == newFiles.end()) || (i.value()->fileName < *iterator)) | - |
1664 | toRemove.append(i.value()->fileName); | - |
1665 | | - |
1666 | ++i; | - |
1667 | } | - |
1668 | for (int i = 0 ; i < toRemove.count() ; ++i ) | - |
1669 | removeNode(parentNode, toRemove[i]); | - |
1670 | } | - |
1671 | | - |
1672 | | - |
1673 | | - |
1674 | | - |
1675 | | - |
1676 | | - |
1677 | | - |
1678 | | - |
1679 | QFileSystemModelPrivate::QFileSystemNode* QFileSystemModelPrivate::addNode(QFileSystemNode *parentNode, const QString &fileName, const QFileInfo& info) | - |
1680 | { | - |
1681 | | - |
1682 | QFileSystemModelPrivate::QFileSystemNode *node = new QFileSystemModelPrivate::QFileSystemNode(fileName, parentNode); | - |
1683 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1684 | node->populate(info); | - |
1685 | #else | - |
1686 | Q_UNUSED(info) | - |
1687 | #endif | - |
1688 | #if defined(Q_OS_WIN) && !defined(Q_OS_WINCE) && !defined(Q_OS_WINRT) | - |
1689 | | - |
1690 | if (parentNode->fileName.isEmpty()) { | - |
1691 | wchar_t name[MAX_PATH + 1]; | - |
1692 | | - |
1693 | const QString nodeName = fileName + QLatin1String("\\"); | - |
1694 | BOOL success = ::GetVolumeInformation((wchar_t *)(nodeName.utf16()), | - |
1695 | name, MAX_PATH + 1, NULL, 0, NULL, NULL, 0); | - |
1696 | if (success && name[0]) | - |
1697 | node->volumeName = QString::fromWCharArray(name); | - |
1698 | } | - |
1699 | #endif | - |
1700 | parentNode->children.insert(fileName, node); | - |
1701 | return node; | - |
1702 | } | - |
1703 | | - |
1704 | | - |
1705 | | - |
1706 | | - |
1707 | | - |
1708 | | - |
1709 | | - |
1710 | | - |
1711 | | - |
1712 | void QFileSystemModelPrivate::removeNode(QFileSystemModelPrivate::QFileSystemNode *parentNode, const QString& name) | - |
1713 | { | - |
1714 | Q_Q(QFileSystemModel); | - |
1715 | QModelIndex parent = index(parentNode); | - |
1716 | bool indexHidden = isHiddenByFilter(parentNode, parent); | - |
1717 | | - |
1718 | int vLocation = parentNode->visibleLocation(name); | - |
1719 | if (vLocation >= 0 && !indexHidden) | - |
1720 | q->beginRemoveRows(parent, translateVisibleLocation(parentNode, vLocation), | - |
1721 | translateVisibleLocation(parentNode, vLocation)); | - |
1722 | QFileSystemNode * node = parentNode->children.take(name); | - |
1723 | delete node; | - |
1724 | | - |
1725 | if (vLocation >= 0) | - |
1726 | parentNode->visibleChildren.removeAt(vLocation); | - |
1727 | if (vLocation >= 0 && !indexHidden) | - |
1728 | q->endRemoveRows(); | - |
1729 | } | - |
1730 | | - |
1731 | | - |
1732 | | - |
1733 | | - |
1734 | | - |
1735 | | - |
1736 | | - |
1737 | | - |
1738 | | - |
1739 | void QFileSystemModelPrivate::addVisibleFiles(QFileSystemNode *parentNode, const QStringList &newFiles) | - |
1740 | { | - |
1741 | Q_Q(QFileSystemModel); | - |
1742 | QModelIndex parent = index(parentNode); | - |
1743 | bool indexHidden = isHiddenByFilter(parentNode, parent); | - |
1744 | if (!indexHidden) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1745 | q->beginInsertRows(parent, parentNode->visibleChildren.count() , parentNode->visibleChildren.count() + newFiles.count() - 1); | - |
1746 | } never executed: end of block | 0 |
1747 | | - |
1748 | if (parentNode->dirtyChildrenIndex == -1)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1749 | parentNode->dirtyChildrenIndex = parentNode->visibleChildren.count(); never executed: parentNode->dirtyChildrenIndex = parentNode->visibleChildren.count(); | 0 |
1750 | | - |
1751 | for (int i =const 0;auto i&newFile <: newFiles.count(); ++i) { | - |
1752 | parentNode->visibleChildren.append(newFiles.at(i));newFile); | - |
1753 | parentNode->children.value(newFiles.at(i))->newFile)->isVisible = true; | - |
1754 | } never executed: end of block | 0 |
1755 | if (!indexHidden)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1756 | q->endInsertRows(); never executed: q->endInsertRows(); | 0 |
1757 | } never executed: end of block | 0 |
1758 | | - |
1759 | | - |
1760 | | - |
1761 | | - |
1762 | | - |
1763 | | - |
1764 | | - |
1765 | | - |
1766 | void QFileSystemModelPrivate::removeVisibleFile(QFileSystemNode *parentNode, int vLocation) | - |
1767 | { | - |
1768 | Q_Q(QFileSystemModel); | - |
1769 | if (vLocation == -1) | - |
1770 | return; | - |
1771 | QModelIndex parent = index(parentNode); | - |
1772 | bool indexHidden = isHiddenByFilter(parentNode, parent); | - |
1773 | if (!indexHidden) | - |
1774 | q->beginRemoveRows(parent, translateVisibleLocation(parentNode, vLocation), | - |
1775 | translateVisibleLocation(parentNode, vLocation)); | - |
1776 | parentNode->children.value(parentNode->visibleChildren.at(vLocation))->isVisible = false; | - |
1777 | parentNode->visibleChildren.removeAt(vLocation); | - |
1778 | if (!indexHidden) | - |
1779 | q->endRemoveRows(); | - |
1780 | } | - |
1781 | | - |
1782 | | - |
1783 | | - |
1784 | | - |
1785 | | - |
1786 | | - |
1787 | | - |
1788 | void QFileSystemModelPrivate::_q_fileSystemChanged(const QString &path, const QVector<QPair<QString, QFileInfo> > &updates) | - |
1789 | { | - |
1790 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1791 | Q_Q(QFileSystemModel); | - |
1792 | QVector<QString> rowsToUpdate; | - |
1793 | QStringList newFiles; | - |
1794 | QFileSystemModelPrivate::QFileSystemNode *parentNode = node(path, false); | - |
1795 | QModelIndex parentIndex = index(parentNode); | - |
1796 | for (int i =const 0;auto i&update <: updates.count(); ++i) { | - |
1797 | QString fileName = updatesupdate.at(i).first; | - |
1798 | Q_ASSERT(!fileName.isEmpty()); | - |
1799 | QExtendedInformation info = fileInfoGatherer.getInfo(updatesupdate.at(i).second); | - |
1800 | bool previouslyHere = parentNode->children.contains(fileName); | - |
1801 | if (!previouslyHere) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1802 | addNode(parentNode, fileName, info.fileInfo()); | - |
1803 | } never executed: end of block | 0 |
1804 | QFileSystemModelPrivate::QFileSystemNode * node = parentNode->children.value(fileName); | - |
1805 | bool isCaseSensitive = parentNode->caseSensitive(); | - |
1806 | if (isCaseSensitive) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1807 | if (node->fileName != fileName)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1808 | continue; never executed: continue; | 0 |
1809 | } else { never executed: end of block | 0 |
1810 | if (QString::compare(node->fileName,fileName,Qt::CaseInsensitive) != 0)TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1811 | continue; never executed: continue; | 0 |
1812 | } never executed: end of block | 0 |
1813 | if (isCaseSensitive) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1814 | Q_ASSERT(node->fileName == fileName); | - |
1815 | } else { never executed: end of block | 0 |
1816 | node->fileName = fileName; | - |
1817 | } never executed: end of block | 0 |
1818 | | - |
1819 | if (*node != info ) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1820 | node->populate(info); | - |
1821 | bypassFilters.remove(node); | - |
1822 | | - |
1823 | if (filtersAcceptsNode(node)) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1824 | if (!node->isVisible) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1825 | newFiles.append(fileName); | - |
1826 | } else { never executed: end of block | 0 |
1827 | rowsToUpdate.append(fileName); | - |
1828 | } never executed: end of block | 0 |
1829 | } else { | - |
1830 | if (node->isVisible) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1831 | int visibleLocation = parentNode->visibleLocation(fileName); | - |
1832 | removeVisibleFile(parentNode, visibleLocation); | - |
1833 | } else { never executed: end of block | 0 |
1834 | | - |
1835 | } never executed: end of block | 0 |
1836 | } | - |
1837 | } | - |
1838 | } never executed: end of block | 0 |
1839 | | - |
1840 | | - |
1841 | std::sort(rowsToUpdate.begin(), rowsToUpdate.end()); | - |
1842 | QString min; | - |
1843 | QString max; | - |
1844 | for (int i = 0; i < rowsToUpdate.count(); ++i) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1845 | QString value = rowsToUpdate.at(i); | - |
1846 | | - |
1847 | | - |
1848 | | - |
1849 | | - |
1850 | | - |
1851 | | - |
1852 | | - |
1853 | | - |
1854 | | - |
1855 | | - |
1856 | | - |
1857 | | - |
1858 | max = value; | - |
1859 | min = value; | - |
1860 | int visibleMin = parentNode->visibleLocation(min); | - |
1861 | int visibleMax = parentNode->visibleLocation(max); | - |
1862 | if (visibleMin >= 0TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1863 | && visibleMin < parentNode->visibleChildren.count()TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1864 | && parentNode->visibleChildren.at(visibleMin) == minTRUE | never evaluated | FALSE | never evaluated |
| 0 |
1865 | && visibleMax >= 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1866 | QModelIndex bottom = q->index(translateVisibleLocation(parentNode, visibleMin), 0, parentIndex); | - |
1867 | QModelIndex top = q->index(translateVisibleLocation(parentNode, visibleMax), 3, parentIndex); | - |
1868 | emit q->dataChanged(bottom, top); | - |
1869 | } never executed: end of block | 0 |
1870 | | - |
1871 | | - |
1872 | | - |
1873 | } never executed: end of block | 0 |
1874 | | - |
1875 | if (newFiles.count() > 0) {TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1876 | addVisibleFiles(parentNode, newFiles); | - |
1877 | } never executed: end of block | 0 |
1878 | | - |
1879 | if (newFiles.count() > 0 || (sortColumn != 0 && rowsToUpdate.count() > 0)) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1880 | forceSort = true; | - |
1881 | delayedSort(); | - |
1882 | } never executed: end of block | 0 |
1883 | #else | - |
1884 | Q_UNUSED(path) | - |
1885 | Q_UNUSED(updates) | - |
1886 | #endif // !QT_NO_FILESYSTEMWATCHER | - |
1887 | } never executed: end of block | 0 |
1888 | | - |
1889 | | - |
1890 | | - |
1891 | | - |
1892 | void QFileSystemModelPrivate::_q_resolvedName(const QString &fileName, const QString &resolvedName) | - |
1893 | { | - |
1894 | resolvedSymLinks[fileName] = resolvedName; | - |
1895 | } | - |
1896 | | - |
1897 | | - |
1898 | | - |
1899 | | - |
1900 | void QFileSystemModelPrivate::init() | - |
1901 | { | - |
1902 | Q_Q(QFileSystemModel); | - |
1903 | qRegisterMetaType<QVector<QPair<QString,QFileInfo> > >(); | - |
1904 | #ifndef QT_NO_FILESYSTEMWATCHER | - |
1905 | q->connect(&fileInfoGatherer, SIGNAL(newListOfFiles(QString,QStringList)), | - |
1906 | q, SLOT(_q_directoryChanged(QString,QStringList))); | - |
1907 | q->connect(&fileInfoGatherer, SIGNAL(updates(QString,QVector<QPair<QString,QFileInfo> >)), | - |
1908 | q, SLOT(_q_fileSystemChanged(QString,QVector<QPair<QString,QFileInfo> >))); | - |
1909 | q->connect(&fileInfoGatherer, SIGNAL(nameResolved(QString,QString)), | - |
1910 | q, SLOT(_q_resolvedName(QString,QString))); | - |
1911 | q->connect(&fileInfoGatherer, SIGNAL(directoryLoaded(QString)), | - |
1912 | q, SIGNAL(directoryLoaded(QString))); | - |
1913 | #endif // !QT_NO_FILESYSTEMWATCHER | - |
1914 | q->connect(&delayedSortTimer, SIGNAL(timeout()), q, SLOT(_q_performDelayedSort()), Qt::QueuedConnection); | - |
1915 | | - |
1916 | roleNames.insertMulti(QFileSystemModel::FileIconRole, QByteArrayLiteral("fileIcon")); | - |
1917 | roleNames.insert(QFileSystemModel::FilePathRole, QByteArrayLiteral("filePath")); | - |
1918 | roleNames.insert(QFileSystemModel::FileNameRole, QByteArrayLiteral("fileName")); | - |
1919 | roleNames.insert(QFileSystemModel::FilePermissions, QByteArrayLiteral("filePermissions")); | - |
1920 | } | - |
1921 | | - |
1922 | | - |
1923 | | - |
1924 | | - |
1925 | | - |
1926 | | - |
1927 | | - |
1928 | | - |
1929 | | - |
1930 | bool QFileSystemModelPrivate::filtersAcceptsNode(const QFileSystemNode *node) const | - |
1931 | { | - |
1932 | | - |
1933 | if (node->parent == &root || bypassFilters.contains(node)) | - |
1934 | return true; | - |
1935 | | - |
1936 | | - |
1937 | if (!node->hasInformation()) | - |
1938 | return false; | - |
1939 | | - |
1940 | const bool filterPermissions = ((filters & QDir::PermissionMask) | - |
1941 | && (filters & QDir::PermissionMask) != QDir::PermissionMask); | - |
1942 | const bool hideDirs = !(filters & (QDir::Dirs | QDir::AllDirs)); | - |
1943 | const bool hideFiles = !(filters & QDir::Files); | - |
1944 | const bool hideReadable = !(!filterPermissions || (filters & QDir::Readable)); | - |
1945 | const bool hideWritable = !(!filterPermissions || (filters & QDir::Writable)); | - |
1946 | const bool hideExecutable = !(!filterPermissions || (filters & QDir::Executable)); | - |
1947 | const bool hideHidden = !(filters & QDir::Hidden); | - |
1948 | const bool hideSystem = !(filters & QDir::System); | - |
1949 | const bool hideSymlinks = (filters & QDir::NoSymLinks); | - |
1950 | const bool hideDot = (filters & QDir::NoDot); | - |
1951 | const bool hideDotDot = (filters & QDir::NoDotDot); | - |
1952 | | - |
1953 | | - |
1954 | bool isDot = (node->fileName == QLatin1String(".")); | - |
1955 | bool isDotDot = (node->fileName == QLatin1String("..")); | - |
1956 | if ( (hideHidden && !(isDot || isDotDot) && node->isHidden()) | - |
1957 | || (hideSystem && node->isSystem()) | - |
1958 | || (hideDirs && node->isDir()) | - |
1959 | || (hideFiles && node->isFile()) | - |
1960 | || (hideSymlinks && node->isSymLink()) | - |
1961 | || (hideReadable && node->isReadable()) | - |
1962 | || (hideWritable && node->isWritable()) | - |
1963 | || (hideExecutable && node->isExecutable()) | - |
1964 | || (hideDot && isDot) | - |
1965 | || (hideDotDot && isDotDot)) | - |
1966 | return false; | - |
1967 | | - |
1968 | return nameFilterDisables || passNameFilters(node); | - |
1969 | } | - |
1970 | | - |
1971 | | - |
1972 | | - |
1973 | | - |
1974 | | - |
1975 | | - |
1976 | bool QFileSystemModelPrivate::passNameFilters(const QFileSystemNode *node) const | - |
1977 | { | - |
1978 | #ifndef QT_NO_REGEXP | - |
1979 | if (nameFilters.isEmpty())TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1980 | return true; never executed: return true; | 0 |
1981 | | - |
1982 | | - |
1983 | if (!(node->isDir() && (filters & QDir::AllDirs))) {TRUE | never evaluated | FALSE | never evaluated |
TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1984 | for (int i =const 0;auto i&nameFilter <: nameFilters.size(); ++i) { | - |
1985 | QRegExp copy = nameFilters.at(i);nameFilter; | - |
1986 | if (copy.exactMatch(node->fileName))TRUE | never evaluated | FALSE | never evaluated |
| 0 |
1987 | return true; never executed: return true; | 0 |
1988 | } never executed: end of block | 0 |
1989 | return false; never executed: return false; | 0 |
1990 | } | - |
1991 | #endif | - |
1992 | return true; never executed: return true; | 0 |
1993 | } | - |
1994 | | - |
1995 | QT_END_NAMESPACE | - |
1996 | | - |
1997 | #include "moc_qfilesystemmodel.cpp" | - |
1998 | | - |
1999 | #endif // QT_NO_FILESYSTEMMODEL | - |
| | |