blob: fbbd57ded88c7daed04009fd5cd84acf41029eda (
plain)
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
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
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
|
// Copyright (C) 2022 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0+ OR GPL-3.0 WITH Qt-GPL-exception-1.0
#pragma once
#include "../filepath.h"
#include <QtCore/private/qabstractfileengine_p.h>
namespace Utils {
namespace Internal {
// Based on http://bloglitb.blogspot.com/2011/12/access-to-private-members-safer.htm
template<typename Tag, typename Tag::type M>
struct PrivateAccess
{
friend typename Tag::type get(Tag) { return M; }
};
struct QAFEITag
{
using type = void (QAbstractFileEngineIterator::*)(const QString &);
friend type get(QAFEITag);
};
template struct PrivateAccess<QAFEITag, &QAbstractFileEngineIterator::setPath>;
class FileIteratorWrapper : public QAbstractFileEngineIterator
{
enum class State {
NotIteratingRoot,
IteratingRoot,
BaseIteratorEnd,
Ended,
};
public:
FileIteratorWrapper(std::unique_ptr<QAbstractFileEngineIterator> &&baseIterator,
QDir::Filters filters,
const QStringList &filterNames)
: QAbstractFileEngineIterator(filters, filterNames)
, m_baseIterator(std::move(baseIterator))
{}
public:
QString next() override
{
if (m_status == State::Ended)
return QString();
setPath();
checkStatus();
if (m_status == State::BaseIteratorEnd) {
m_status = State::Ended;
return "__qtc__devices__";
}
return m_baseIterator->next();
}
bool hasNext() const override
{
if (m_status == State::Ended)
return false;
setPath();
checkStatus();
if (m_status == State::BaseIteratorEnd)
return true;
return m_baseIterator->hasNext();
}
QString currentFileName() const override
{
if (m_status == State::Ended)
return FilePath::specialPath(FilePath::SpecialPathComponent::RootPath);
setPath();
checkStatus();
return m_baseIterator->currentFileName();
}
QFileInfo currentFileInfo() const override
{
if (m_status == State::Ended)
return QFileInfo(FilePath::specialPath(FilePath::SpecialPathComponent::RootPath));
setPath();
checkStatus();
return m_baseIterator->currentFileInfo();
}
private:
void setPath() const
{
if (!m_hasSetPath) {
const QString p = path();
if (p.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0)
m_status = State::IteratingRoot;
((*m_baseIterator).*get(QAFEITag()))(p);
m_hasSetPath = true;
}
}
void checkStatus() const
{
if (m_status == State::NotIteratingRoot) {
return;
}
if (m_status == State::IteratingRoot) {
if (m_baseIterator->hasNext() == false) {
m_status = State::BaseIteratorEnd;
}
}
}
private:
std::unique_ptr<QAbstractFileEngineIterator> m_baseIterator;
mutable bool m_hasSetPath{false};
mutable State m_status{State::NotIteratingRoot};
};
} // namespace Internal
} // namespace Utils
|