7#include <QtCore/qdir.h>
8#include <QtCore/private/qdir_p.h>
9#include <QtCore/qfile.h>
10#include <QtCore/private/qfsfileengine_p.h>
12#include <QtCore/qstringbuilder.h>
17using namespace Qt::StringLiterals;
24static bool isUncRoot(
const QString &server)
26 QString localPath = QDir::toNativeSeparators(server);
27 if (!localPath.startsWith(
"\\\\"_L1))
30 int idx = localPath.indexOf(u'\\', 2);
31 if (idx == -1 || idx + 1 == localPath.length())
34 return QStringView{localPath}.right(localPath.length() - idx - 1).trimmed().isEmpty();
37static inline QString fixIfRelativeUncPath(
const QString &path)
39 QString currentPath = QDir::currentPath();
40 if (currentPath.startsWith(
"//"_L1))
41 return currentPath % QChar(u'/') % path;
46QFileSystemEntry::QFileSystemEntry()
47 : m_lastSeparator(-1),
48 m_firstDotInFileName(-1),
49 m_lastDotInFileName(-1)
54
55
56
57
58QFileSystemEntry::QFileSystemEntry(
const QString &filePath)
59 : m_filePath(QDir::fromNativeSeparators(filePath)),
60 m_lastSeparator(Uninitialized),
61 m_firstDotInFileName(Uninitialized),
62 m_lastDotInFileName(0)
67
68
69
70
71QFileSystemEntry::QFileSystemEntry(
const QString &filePath, FromInternalPath )
72 : m_filePath(filePath),
73 m_lastSeparator(Uninitialized),
74 m_firstDotInFileName(Uninitialized),
75 m_lastDotInFileName(0)
80
81
82
83QFileSystemEntry::QFileSystemEntry(
const NativePath &nativeFilePath, FromNativePath )
84 : m_nativeFilePath(nativeFilePath),
85 m_lastSeparator(Uninitialized),
86 m_firstDotInFileName(Uninitialized),
87 m_lastDotInFileName(0)
91QFileSystemEntry::QFileSystemEntry(
const QString &filePath,
const NativePath &nativeFilePath)
92 : m_filePath(QDir::fromNativeSeparators(filePath)),
93 m_nativeFilePath(nativeFilePath),
94 m_lastSeparator(Uninitialized),
95 m_firstDotInFileName(Uninitialized),
96 m_lastDotInFileName(0)
100QString QFileSystemEntry::filePath()
const
106QFileSystemEntry::NativePath QFileSystemEntry::nativeFilePath()
const
108 resolveNativeFilePath();
109 return m_nativeFilePath;
112void QFileSystemEntry::resolveFilePath()
const
114 if (m_filePath.isEmpty() && !m_nativeFilePath.isEmpty()) {
116 m_filePath = QDir::fromNativeSeparators(m_nativeFilePath);
118 m_filePath = QDir::fromNativeSeparators(QFile::decodeName(m_nativeFilePath));
123void QFileSystemEntry::resolveNativeFilePath()
const
125 if (!m_filePath.isEmpty() && m_nativeFilePath.isEmpty()) {
127 QString filePath = m_filePath;
129 filePath = fixIfRelativeUncPath(m_filePath);
130 m_nativeFilePath = QFSFileEnginePrivate::longFileName(QDir::toNativeSeparators(filePath));
132 m_nativeFilePath = QFile::encodeName(QDir::toNativeSeparators(m_filePath));
137QString QFileSystemEntry::fileName()
const
141 if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':')
142 return m_filePath.mid(2);
144 return m_filePath.mid(m_lastSeparator + 1);
147QString QFileSystemEntry::path()
const
150 if (m_lastSeparator == -1) {
152 if (m_filePath.length() >= 2 && m_filePath.at(1) == u':')
153 return m_filePath.left(2);
155 return QString(u'.');
157 if (m_lastSeparator == 0)
158 return QString(u'/');
160 if (m_lastSeparator == 2 && m_filePath.at(1) == u':')
161 return m_filePath.left(m_lastSeparator + 1);
163 return m_filePath.left(m_lastSeparator);
166QString QFileSystemEntry::baseName()
const
168 findFileNameSeparators();
170 if (m_firstDotInFileName >= 0) {
171 length = m_firstDotInFileName;
172 if (m_lastSeparator != -1)
176 if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':')
177 return m_filePath.mid(2, length - 2);
179 return m_filePath.mid(m_lastSeparator + 1, length);
182QString QFileSystemEntry::completeBaseName()
const
184 findFileNameSeparators();
186 if (m_firstDotInFileName >= 0) {
187 length = m_firstDotInFileName + m_lastDotInFileName;
188 if (m_lastSeparator != -1)
192 if (m_lastSeparator == -1 && m_filePath.length() >= 2 && m_filePath.at(1) == u':')
193 return m_filePath.mid(2, length - 2);
195 return m_filePath.mid(m_lastSeparator + 1, length);
198QString QFileSystemEntry::suffix()
const
200 findFileNameSeparators();
202 if (m_lastDotInFileName == -1)
205 return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + m_lastDotInFileName + 1);
208QString QFileSystemEntry::completeSuffix()
const
210 findFileNameSeparators();
211 if (m_firstDotInFileName == -1)
214 return m_filePath.mid(qMax((qint16)0, m_lastSeparator) + m_firstDotInFileName + 1);
218bool QFileSystemEntry::isRelative()
const
221 return (m_filePath.isEmpty()
222 || (m_filePath.at(0).unicode() !=
'/'
223 && !(m_filePath.length() >= 2 && m_filePath.at(1).unicode() ==
':')));
226bool QFileSystemEntry::isAbsolute()
const
229 return ((m_filePath.length() >= 3
230 && m_filePath.at(0).isLetter()
231 && m_filePath.at(1).unicode() ==
':'
232 && m_filePath.at(2).unicode() ==
'/')
233 || (m_filePath.length() >= 2
234 && m_filePath.at(0) == u'/'
235 && m_filePath.at(1) == u'/'));
238bool QFileSystemEntry::isRelative()
const
240 return !isAbsolute();
243bool QFileSystemEntry::isAbsolute()
const
246 return (!m_filePath.isEmpty() && (m_filePath.at(0).unicode() ==
'/'));
251bool QFileSystemEntry::isDriveRoot()
const
254 return QFileSystemEntry::isDriveRootPath(m_filePath);
257bool QFileSystemEntry::isDriveRootPath(
const QString &path)
259 return (path.length() == 3
260 && path.at(0).isLetter() && path.at(1) == u':'
261 && path.at(2) == u'/');
264QString QFileSystemEntry::removeUncOrLongPathPrefix(QString path)
266 constexpr qsizetype minPrefixSize = 4;
267 if (path.size() < minPrefixSize)
270 auto data = path.data();
271 const auto slash = path[0];
272 if (slash != u'\\' && slash != u'/')
276 if (data[2] == u'?' && data[3] == slash && (data[1] == slash || data[1] == u'?')) {
277 path = path.sliced(minPrefixSize);
280 if (path.size() >= 4) {
282 if (data[0] == u'U' && data[1] == u'N' && data[2] == u'C' && data[3] == slash) {
284 return path.sliced(2);
293bool QFileSystemEntry::isRootPath(
const QString &path)
297 || isDriveRootPath(path)
306bool QFileSystemEntry::isRoot()
const
309 return isRootPath(m_filePath);
312bool QFileSystemEntry::isEmpty()
const
314 return m_filePath.isEmpty() && m_nativeFilePath.isEmpty();
319void QFileSystemEntry::findLastSeparator()
const
321 if (m_lastSeparator == Uninitialized) {
323 m_lastSeparator = m_filePath.lastIndexOf(u'/');
327void QFileSystemEntry::findFileNameSeparators()
const
329 if (m_firstDotInFileName == Uninitialized) {
331 int firstDotInFileName = -1;
332 int lastDotInFileName = -1;
333 int lastSeparator = m_lastSeparator;
336 if (lastSeparator < 0) {
340 stop = lastSeparator;
343 Q_ASSERT(m_filePath.size() ==
int(m_filePath.size()));
344 int i =
int(m_filePath.size() - 1);
345 for (; i >= stop; --i) {
346 if (m_filePath.at(i).unicode() ==
'.') {
347 firstDotInFileName = lastDotInFileName = i;
349 }
else if (m_filePath.at(i).unicode() ==
'/') {
355 if (lastSeparator != i) {
356 for (--i; i >= stop; --i) {
357 if (m_filePath.at(i).unicode() ==
'.')
358 firstDotInFileName = i;
359 else if (m_filePath.at(i).unicode() ==
'/') {
365 m_lastSeparator = lastSeparator;
366 m_firstDotInFileName = firstDotInFileName == -1 ? -1 : firstDotInFileName - qMax(0, lastSeparator);
367 if (lastDotInFileName == -1)
368 m_lastDotInFileName = -1;
369 else if (firstDotInFileName == lastDotInFileName)
370 m_lastDotInFileName = 0;
372 m_lastDotInFileName = lastDotInFileName - firstDotInFileName;
376bool QFileSystemEntry::isClean()
const
379 return qt_isPathNormalized(m_filePath, QDirPrivate::DefaultNormalization);
Combined button and popup list for selecting options.
constexpr int Uninitialized