mirror of
https://github.com/crystalidea/qt6windows7.git
synced 2025-07-03 07:45:30 +08:00
qt 6.5.1 original
This commit is contained in:
92
tests/shared/fakedirmodel.h
Normal file
92
tests/shared/fakedirmodel.h
Normal file
@ -0,0 +1,92 @@
|
||||
// Copyright (C) 2016 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef FAKEDIRMODEL_H
|
||||
#define FAKEDIRMODEL_H
|
||||
|
||||
#include <QtGui/QStandardItemModel>
|
||||
#include <QtGui/QStandardItem>
|
||||
#include <QtGui/QIcon>
|
||||
#include <QtGui/QPixmap>
|
||||
#include <QtGui/QImage>
|
||||
#include <QtCore/QStringList>
|
||||
|
||||
typedef QList<QStandardItem *> StandardItemList;
|
||||
|
||||
static inline QIcon coloredIcon(Qt::GlobalColor color)
|
||||
{
|
||||
QImage image(22, 22, QImage::Format_ARGB32);
|
||||
image.fill(color);
|
||||
return QPixmap::fromImage(image);
|
||||
}
|
||||
|
||||
static void addFileEntry(const StandardItemList &directory, const QString &name, const QString &size)
|
||||
{
|
||||
static const QIcon fileIcon = coloredIcon(Qt::blue);
|
||||
directory.front()->appendRow(StandardItemList() << new QStandardItem(fileIcon, name) << new QStandardItem(size));
|
||||
}
|
||||
|
||||
static StandardItemList createDirEntry(const QString &name)
|
||||
{
|
||||
static const QIcon dirIcon = coloredIcon(Qt::red);
|
||||
StandardItemList result;
|
||||
result << new QStandardItem(dirIcon, name) << new QStandardItem;
|
||||
return result;
|
||||
}
|
||||
|
||||
static inline StandardItemList addDirEntry(const StandardItemList &directory, const QString &name)
|
||||
{
|
||||
const StandardItemList entry = createDirEntry(name);
|
||||
directory.front()->appendRow(entry);
|
||||
return entry;
|
||||
}
|
||||
|
||||
static QStandardItem *populateFakeDirModel(QStandardItemModel *model)
|
||||
{
|
||||
enum Columns { NameColumn, SizeColumn, ColumnCount };
|
||||
|
||||
model->setColumnCount(ColumnCount);
|
||||
model->setHorizontalHeaderLabels(QStringList() << QStringLiteral("Name") << QStringLiteral("Size"));
|
||||
|
||||
const StandardItemList root = createDirEntry(QStringLiteral("/"));
|
||||
model->appendRow(root);
|
||||
|
||||
const StandardItemList binDir = addDirEntry(root, QStringLiteral("bin"));
|
||||
addFileEntry(binDir, QStringLiteral("ls"), QStringLiteral("100 KB"));
|
||||
addFileEntry(binDir, QStringLiteral("bash"), QStringLiteral("200 KB"));
|
||||
|
||||
const StandardItemList devDir = addDirEntry(root, QStringLiteral("dev"));
|
||||
addFileEntry(devDir, QStringLiteral("tty1"), QStringLiteral("0 B"));
|
||||
addDirEntry(devDir, QStringLiteral("proc"));
|
||||
|
||||
const StandardItemList etcDir = addDirEntry(root, QStringLiteral("etc"));
|
||||
addFileEntry(etcDir, QStringLiteral("foo1.config"), QStringLiteral("1 KB"));
|
||||
addFileEntry(etcDir, QStringLiteral("foo2.conf"), QStringLiteral("654 B"));
|
||||
|
||||
const StandardItemList homeDir = addDirEntry(root, QStringLiteral("home"));
|
||||
addFileEntry(homeDir, QStringLiteral("file1"), QStringLiteral("1 KB"));
|
||||
|
||||
const StandardItemList documentsDir = addDirEntry(homeDir, QStringLiteral("Documents"));
|
||||
addFileEntry(documentsDir, QStringLiteral("txt1.odt"), QStringLiteral("2 MB"));
|
||||
addFileEntry(documentsDir, QStringLiteral("sheet1.xls"), QStringLiteral("32 KB"));
|
||||
addFileEntry(documentsDir, QStringLiteral("foo.doc"), QStringLiteral("214 KB"));
|
||||
|
||||
const StandardItemList downloadsDir = addDirEntry(homeDir, QStringLiteral("Downloads"));
|
||||
addFileEntry(downloadsDir, QStringLiteral("package1.zip"), QStringLiteral("34 MB"));
|
||||
addFileEntry(downloadsDir, QStringLiteral("package2.zip"), QStringLiteral("623 KB"));
|
||||
|
||||
const StandardItemList picturesDir = addDirEntry(homeDir, QStringLiteral("Pictures"));
|
||||
addFileEntry(picturesDir, QStringLiteral("img0001.jpg"), QStringLiteral("4 MB"));
|
||||
addFileEntry(picturesDir, QStringLiteral("img0002.png"), QStringLiteral("10 MB"));
|
||||
|
||||
// qcolumnview::moveCursor() requires an empty directory followed by another one.
|
||||
addDirEntry(root, QStringLiteral("lost+found"));
|
||||
|
||||
const StandardItemList tmpDir = addDirEntry(root, QStringLiteral("tmp"));
|
||||
addFileEntry(tmpDir, "asdujhsdjys", "435 B");
|
||||
addFileEntry(tmpDir, "krtbldfhd", "5557 B");
|
||||
|
||||
return homeDir.front();
|
||||
}
|
||||
|
||||
#endif // FAKEDIRMODEL_H
|
197
tests/shared/filesystem.h
Normal file
197
tests/shared/filesystem.h
Normal file
@ -0,0 +1,197 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
|
||||
#define QT_TESTS_SHARED_FILESYSTEM_H_INCLUDED
|
||||
|
||||
#include <QDir>
|
||||
#include <QFile>
|
||||
#include <QOperatingSystemVersion>
|
||||
#include <QScopedPointer>
|
||||
#include <QString>
|
||||
#include <QStringList>
|
||||
#include <QTemporaryDir>
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
#include <qt_windows.h>
|
||||
#include <winioctl.h>
|
||||
#ifndef IO_REPARSE_TAG_MOUNT_POINT
|
||||
#define IO_REPARSE_TAG_MOUNT_POINT (0xA0000003L)
|
||||
#endif
|
||||
#define REPARSE_MOUNTPOINT_HEADER_SIZE 8
|
||||
#ifndef FSCTL_SET_REPARSE_POINT
|
||||
#define FSCTL_SET_REPARSE_POINT CTL_CODE(FILE_DEVICE_FILE_SYSTEM, 41, METHOD_BUFFERED, FILE_SPECIAL_ACCESS)
|
||||
#endif
|
||||
#ifndef SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE // MinGW
|
||||
#define SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE (0x2)
|
||||
#endif
|
||||
QT_BEGIN_NAMESPACE
|
||||
namespace QTest {
|
||||
static QString uncServerName() { return qgetenv("COMPUTERNAME"); }
|
||||
}
|
||||
QT_END_NAMESPACE
|
||||
#endif
|
||||
|
||||
// QTemporaryDir-based helper class for creating file-system hierarchies and cleaning up.
|
||||
class FileSystem
|
||||
{
|
||||
Q_DISABLE_COPY(FileSystem)
|
||||
public:
|
||||
FileSystem() : m_temporaryDir(FileSystem::tempFilePattern()) {}
|
||||
|
||||
QString path() const { return m_temporaryDir.path(); }
|
||||
QString absoluteFilePath(const QString &fileName) const { return path() + QLatin1Char('/') + fileName; }
|
||||
|
||||
bool createDirectory(const QString &relativeDirName)
|
||||
{
|
||||
if (m_temporaryDir.isValid()) {
|
||||
QDir dir(m_temporaryDir.path());
|
||||
return dir.mkpath(relativeDirName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
bool createFile(const QString &relativeFileName)
|
||||
{
|
||||
QScopedPointer<QFile> file(openFileForWrite(relativeFileName));
|
||||
return !file.isNull();
|
||||
}
|
||||
|
||||
qint64 createFileWithContent(const QString &relativeFileName)
|
||||
{
|
||||
QScopedPointer<QFile> file(openFileForWrite(relativeFileName));
|
||||
return file.isNull() ? qint64(-1) : file->write(relativeFileName.toUtf8());
|
||||
}
|
||||
|
||||
#if defined(Q_OS_WIN)
|
||||
struct Result {
|
||||
DWORD dwErr = ERROR_SUCCESS;
|
||||
QString link;
|
||||
QString target;
|
||||
QString errorMessage;
|
||||
};
|
||||
|
||||
static Result createSymbolicLink(const QString &symLinkName, const QString &target)
|
||||
{
|
||||
Result result;
|
||||
const QString nativeSymLinkName = QDir::toNativeSeparators(symLinkName);
|
||||
const QString nativeTarget = QDir::toNativeSeparators(target);
|
||||
DWORD flags = 0;
|
||||
if (QOperatingSystemVersion::current() >= QOperatingSystemVersion(QOperatingSystemVersion::Windows, 10, 0, 14972))
|
||||
flags |= SYMBOLIC_LINK_FLAG_ALLOW_UNPRIVILEGED_CREATE;
|
||||
if (QFileInfo(target).isDir())
|
||||
flags |= SYMBOLIC_LINK_FLAG_DIRECTORY;
|
||||
if (CreateSymbolicLink(reinterpret_cast<const wchar_t*>(nativeSymLinkName.utf16()),
|
||||
reinterpret_cast<const wchar_t*>(nativeTarget.utf16()), flags) == FALSE) {
|
||||
result.dwErr = GetLastError();
|
||||
QTextStream(&result.errorMessage) << "CreateSymbolicLink(" << nativeSymLinkName << ", "
|
||||
<< nativeTarget << ", 0x" << Qt::hex << flags << Qt::dec << ") failed with error "
|
||||
<< result.dwErr << ": " << qt_error_string(int(result.dwErr));
|
||||
} else {
|
||||
result.link = nativeSymLinkName;
|
||||
result.target = nativeTarget;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
static Result createNtfsJunction(QString target, QString linkName)
|
||||
{
|
||||
typedef struct {
|
||||
DWORD ReparseTag;
|
||||
DWORD ReparseDataLength;
|
||||
WORD Reserved;
|
||||
WORD ReparseTargetLength;
|
||||
WORD ReparseTargetMaximumLength;
|
||||
WORD Reserved1;
|
||||
WCHAR ReparseTarget[1];
|
||||
} REPARSE_MOUNTPOINT_DATA_BUFFER, *PREPARSE_MOUNTPOINT_DATA_BUFFER;
|
||||
|
||||
char reparseBuffer[MAX_PATH*3];
|
||||
HANDLE hFile;
|
||||
DWORD returnedLength;
|
||||
wchar_t fileSystem[MAX_PATH] = L"";
|
||||
PREPARSE_MOUNTPOINT_DATA_BUFFER reparseInfo = (PREPARSE_MOUNTPOINT_DATA_BUFFER) reparseBuffer;
|
||||
Result result;
|
||||
|
||||
QFileInfo junctionInfo(linkName);
|
||||
linkName = QDir::toNativeSeparators(junctionInfo.absoluteFilePath());
|
||||
const QString drive = linkName.left(3);
|
||||
if (GetVolumeInformationW(reinterpret_cast<const wchar_t *>(drive.utf16()),
|
||||
NULL, 0, NULL, NULL, NULL,
|
||||
fileSystem, sizeof(fileSystem)/sizeof(WCHAR)) == FALSE) {
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "GetVolumeInformationW() failed: " + qt_error_string(int(result.dwErr));
|
||||
return result;
|
||||
}
|
||||
if (QString::fromWCharArray(fileSystem) != "NTFS") {
|
||||
result.errorMessage = "This seems not to be an NTFS volume. Junctions are not allowed.";
|
||||
result.dwErr = ERROR_NOT_SUPPORTED;
|
||||
return result;
|
||||
}
|
||||
|
||||
if (!target.startsWith("\\??\\") && !target.startsWith("\\\\?\\")) {
|
||||
QFileInfo targetInfo(target);
|
||||
target = QDir::toNativeSeparators(targetInfo.absoluteFilePath());
|
||||
target.prepend("\\??\\");
|
||||
if(target.endsWith('\\') && target.at(target.length()-2) != ':')
|
||||
target.chop(1);
|
||||
}
|
||||
QDir().mkdir(linkName);
|
||||
hFile = CreateFileW( (wchar_t*)linkName.utf16(), GENERIC_WRITE, 0, NULL, OPEN_EXISTING,
|
||||
FILE_FLAG_OPEN_REPARSE_POINT|FILE_FLAG_BACKUP_SEMANTICS, NULL );
|
||||
if (hFile == INVALID_HANDLE_VALUE) {
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "CreateFileW(" + linkName + ") failed: " + qt_error_string(int(result.dwErr));
|
||||
return result;
|
||||
}
|
||||
|
||||
memset( reparseInfo, 0, sizeof( *reparseInfo ));
|
||||
reparseInfo->ReparseTag = IO_REPARSE_TAG_MOUNT_POINT;
|
||||
reparseInfo->ReparseTargetLength = WORD(target.size()) * WORD(sizeof(wchar_t));
|
||||
reparseInfo->ReparseTargetMaximumLength = reparseInfo->ReparseTargetLength + sizeof(wchar_t);
|
||||
target.toWCharArray(reparseInfo->ReparseTarget);
|
||||
reparseInfo->ReparseDataLength = reparseInfo->ReparseTargetLength + 12;
|
||||
|
||||
bool ioc = DeviceIoControl(hFile, FSCTL_SET_REPARSE_POINT, reparseInfo,
|
||||
reparseInfo->ReparseDataLength + REPARSE_MOUNTPOINT_HEADER_SIZE,
|
||||
NULL, 0, &returnedLength, NULL);
|
||||
if (!ioc) {
|
||||
result.dwErr = GetLastError();
|
||||
result.errorMessage = "DeviceIoControl() failed: " + qt_error_string(int(result.dwErr));
|
||||
} else {
|
||||
result.link = linkName;
|
||||
result.target = target;
|
||||
}
|
||||
CloseHandle( hFile );
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
private:
|
||||
static QString tempFilePattern()
|
||||
{
|
||||
QString result = QDir::tempPath();
|
||||
if (!result.endsWith(QLatin1Char('/')))
|
||||
result.append(QLatin1Char('/'));
|
||||
result += QStringLiteral("qt-test-filesystem-");
|
||||
result += QCoreApplication::applicationName();
|
||||
result += QStringLiteral("-XXXXXX");
|
||||
return result;
|
||||
}
|
||||
|
||||
QFile *openFileForWrite(const QString &fileName) const
|
||||
{
|
||||
if (m_temporaryDir.isValid()) {
|
||||
const QString absName = absoluteFilePath(fileName);
|
||||
std::unique_ptr<QFile> file(new QFile(absName));
|
||||
if (file->open(QIODevice::WriteOnly))
|
||||
return file.release();
|
||||
qWarning("Cannot open '%s' for writing: %s", qPrintable(absName), qPrintable(file->errorString()));
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
QTemporaryDir m_temporaryDir;
|
||||
};
|
||||
|
||||
#endif // include guard
|
89
tests/shared/localechange.h
Normal file
89
tests/shared/localechange.h
Normal file
@ -0,0 +1,89 @@
|
||||
// Copyright (C) 2021 The Qt Company Ltd.
|
||||
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
|
||||
|
||||
#ifndef QT_TESTS_SHARED_LOCALE_CHANGE_H
|
||||
#define QT_TESTS_SHARED_LOCALE_CHANGE_H
|
||||
#include <qglobal.h>
|
||||
#include <QtCore/QByteArray>
|
||||
#include <QtCore/QLocale>
|
||||
#include <private/qlocale_p.h>
|
||||
|
||||
#include <locale.h>
|
||||
|
||||
namespace QTestLocaleChange {
|
||||
|
||||
QLocale resetSystemLocale()
|
||||
{
|
||||
#ifndef QT_NO_SYSTEMLOCALE
|
||||
{ // Transient instance marks system locale data as stale:
|
||||
QSystemLocale dummy;
|
||||
} // Now we can reinitialize:
|
||||
#endif
|
||||
return QLocale::system();
|
||||
}
|
||||
|
||||
class TransientLocale
|
||||
{
|
||||
const int m_category;
|
||||
const QByteArray m_prior;
|
||||
const bool m_didSet;
|
||||
#if !defined(QT_NO_SYSTEMLOCALE) && defined(Q_OS_UNIX) \
|
||||
&& (!defined(Q_OS_DARWIN) || defined(Q_OS_NACL))
|
||||
#define TRANSIENT_ENV
|
||||
// Unix system locale consults environment variables, so we need to set
|
||||
// the appropriate one, too.
|
||||
const QByteArray m_envVar, m_envPrior;
|
||||
const bool m_envSet;
|
||||
static QByteArray categoryToEnv(int category)
|
||||
{
|
||||
switch (category) {
|
||||
#define CASE(cat) case cat: return #cat
|
||||
CASE(LC_ALL); CASE(LC_NUMERIC); CASE(LC_TIME); CASE(LC_MONETARY);
|
||||
CASE(LC_MESSAGES); CASE(LC_COLLATE);
|
||||
#ifdef LC_MEASUREMENT
|
||||
CASE(LC_MEASUREMENT);
|
||||
#endif
|
||||
#undef CASE
|
||||
// Nothing in our code pays attention to any other LC_*
|
||||
default:
|
||||
Q_UNREACHABLE();
|
||||
qFatal("You need to add a case for this category");
|
||||
}
|
||||
}
|
||||
#endif // TRANSIENT_ENV
|
||||
public:
|
||||
TransientLocale(int category, const char *locale)
|
||||
: m_category(category),
|
||||
m_prior(setlocale(category, nullptr)),
|
||||
// That return value may be stomped by this later call, so we copy
|
||||
// it to a QByteArray for safe keeping.
|
||||
m_didSet(setlocale(category, locale) != nullptr)
|
||||
#ifdef TRANSIENT_ENV
|
||||
, m_envVar(categoryToEnv(category)),
|
||||
m_envPrior(qgetenv(m_envVar.constData())),
|
||||
m_envSet(qputenv(m_envVar.constData(), locale))
|
||||
#endif
|
||||
{
|
||||
resetSystemLocale();
|
||||
}
|
||||
~TransientLocale()
|
||||
{
|
||||
#ifdef TRANSIENT_ENV
|
||||
if (m_envSet) {
|
||||
if (m_envPrior.isEmpty())
|
||||
qunsetenv(m_envVar.constData());
|
||||
else
|
||||
qputenv(m_envVar.constData(), m_envPrior);
|
||||
}
|
||||
#endif
|
||||
if (m_prior.size())
|
||||
setlocale(m_category, m_prior.constData());
|
||||
resetSystemLocale();
|
||||
}
|
||||
#undef TRANSIENT_ENV
|
||||
|
||||
bool isValid() const { return m_didSet; }
|
||||
};
|
||||
}
|
||||
|
||||
#endif // QT_TESTS_SHARED_LOCALE_CHANGE_H
|
Reference in New Issue
Block a user