forked from qt-creator/qt-creator
filesystem: Add QFSEngine for filepaths
Change-Id: Ibd0c88c69863c0877138d8cc45541530c359bd9c Reviewed-by: hjk <hjk@qt.io>
This commit is contained in:
@@ -35,6 +35,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/optional.h>
|
||||
#include <utils/qtcsettings.h>
|
||||
@@ -451,6 +452,8 @@ int main(int argc, char **argv)
|
||||
Restarter restarter(argc, argv);
|
||||
Utils::Environment::systemEnvironment(); // cache system environment before we do any changes
|
||||
|
||||
Utils::FSEngine fileSystemEngine;
|
||||
|
||||
// Manually determine various command line options
|
||||
// We can't use the regular way of the plugin manager,
|
||||
// because settings can change the way plugin manager behaves
|
||||
|
@@ -57,6 +57,8 @@ add_qtc_library(Utils
|
||||
filewizardpage.cpp filewizardpage.h
|
||||
fixedsizeclicklabel.cpp fixedsizeclicklabel.h
|
||||
flowlayout.cpp flowlayout.h
|
||||
fsengine/fsengine.cpp fsengine/fsengine.h
|
||||
fsengine/fileiconprovider.cpp fsengine/fileiconprovider.h
|
||||
functiontraits.h
|
||||
futuresynchronizer.cpp futuresynchronizer.h
|
||||
fuzzymatcher.cpp fuzzymatcher.h
|
||||
@@ -247,6 +249,20 @@ extend_qtc_library(Utils CONDITION UNIX AND NOT APPLE
|
||||
touchbar/touchbar.cpp
|
||||
)
|
||||
|
||||
extend_qtc_library(Utils
|
||||
CONDITION TARGET Qt5::CorePrivate
|
||||
DEPENDS Qt5::CorePrivate
|
||||
DEFINES QTC_UTILS_WITH_FSENGINE
|
||||
SOURCES fsengine/fsengine_impl.cpp
|
||||
fsengine/fsengine_impl.h
|
||||
fsengine/diriterator.h
|
||||
fsengine/fileiteratordevicesappender.h
|
||||
fsengine/rootinjectfsengine.h
|
||||
fsengine/fixedlistfsengine.h
|
||||
fsengine/fsenginehandler.cpp
|
||||
fsengine/fsenginehandler.h
|
||||
)
|
||||
|
||||
if (WIN32)
|
||||
add_qtc_executable(qtcreator_process_stub
|
||||
SOURCES process_stub_win.c
|
||||
@@ -263,3 +279,4 @@ if (WIN32)
|
||||
else()
|
||||
add_qtc_executable(qtcreator_process_stub SOURCES process_stub_unix.c)
|
||||
endif()
|
||||
|
||||
|
@@ -39,6 +39,7 @@
|
||||
#include <QRegularExpression>
|
||||
#include <QStorageInfo>
|
||||
#include <QUrl>
|
||||
#include <QStringView>
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
#ifdef QTCREATOR_PCH_H
|
||||
@@ -480,9 +481,20 @@ QString FilePath::toString() const
|
||||
{
|
||||
if (m_scheme.isEmpty())
|
||||
return m_data;
|
||||
|
||||
if (m_data.startsWith('/'))
|
||||
return m_scheme + "://" + hostEncoded(m_host) + m_data;
|
||||
return m_scheme + "://" + hostEncoded(m_host) + "/./" + m_data;
|
||||
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + m_data;
|
||||
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + "/./" + m_data;
|
||||
}
|
||||
|
||||
QString FilePath::toFSPathString() const
|
||||
{
|
||||
if (m_scheme.isEmpty())
|
||||
return m_data;
|
||||
|
||||
if (m_data.startsWith('/'))
|
||||
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + m_data;
|
||||
return specialPath(SpecialPathComponent::RootPath) + "/" + m_scheme + "/" + hostEncoded(m_host) + "/./" + m_data;
|
||||
}
|
||||
|
||||
QUrl FilePath::toUrl() const
|
||||
@@ -504,6 +516,12 @@ void FileUtils::setDeviceFileHooks(const DeviceFileHooks &hooks)
|
||||
/// this path belongs to.
|
||||
QString FilePath::toUserOutput() const
|
||||
{
|
||||
if (needsDevice()) {
|
||||
if (m_data.startsWith('/'))
|
||||
return m_scheme + "://" + hostEncoded(m_host) + m_data;
|
||||
return m_scheme + "://" + hostEncoded(m_host) + "/./" + m_data;
|
||||
}
|
||||
|
||||
FilePath tmp = *this;
|
||||
if (osType() == OsTypeWindows)
|
||||
tmp.m_data.replace('/', '\\');
|
||||
@@ -941,6 +959,27 @@ FilePath FilePath::absoluteFilePath() const
|
||||
return result;
|
||||
}
|
||||
|
||||
QString FilePath::specialPath(SpecialPathComponent component)
|
||||
{
|
||||
switch (component) {
|
||||
case SpecialPathComponent::RootName:
|
||||
return QLatin1String("__qtc_devices__");
|
||||
case SpecialPathComponent::RootPath:
|
||||
return (QDir::rootPath() + "__qtc_devices__");
|
||||
case SpecialPathComponent::DeviceRootName:
|
||||
return QLatin1String("device");
|
||||
case SpecialPathComponent::DeviceRootPath:
|
||||
return QDir::rootPath() + "__qtc_devices__/device";
|
||||
}
|
||||
|
||||
QTC_ASSERT(false, return {});
|
||||
}
|
||||
|
||||
FilePath FilePath::specialFilePath(SpecialPathComponent component)
|
||||
{
|
||||
return FilePath::fromString(specialPath(component));
|
||||
}
|
||||
|
||||
FilePath FilePath::normalizedPathName() const
|
||||
{
|
||||
FilePath result = *this;
|
||||
@@ -1005,28 +1044,88 @@ FilePath FilePath::fromString(const QString &filepath)
|
||||
|
||||
void FilePath::setFromString(const QString &filename)
|
||||
{
|
||||
if (filename.startsWith('/')) {
|
||||
m_data = filename; // fast track: absolute local paths
|
||||
} else {
|
||||
int pos1 = filename.indexOf("://");
|
||||
if (pos1 >= 0) {
|
||||
m_scheme = filename.left(pos1);
|
||||
pos1 += 3;
|
||||
int pos2 = filename.indexOf('/', pos1);
|
||||
if (pos2 == -1) {
|
||||
m_data = filename.mid(pos1);
|
||||
} else {
|
||||
m_host = filename.mid(pos1, pos2 - pos1);
|
||||
m_host.replace("%2f", "/");
|
||||
m_host.replace("%25", "%");
|
||||
m_data = filename.mid(pos2);
|
||||
#ifndef UTILS_FILEPATH_USE_REGEXP
|
||||
static const QLatin1String qtcDevSlash("__qtc_devices__/");
|
||||
|
||||
const QStringView fileNameView(filename);
|
||||
const QString rootPath = QDir::rootPath();
|
||||
|
||||
if (fileNameView.startsWith(rootPath, Qt::CaseInsensitive)) { // Absolute path ...
|
||||
const QStringView withoutRootPath = fileNameView.mid(rootPath.size());
|
||||
if (withoutRootPath.startsWith(qtcDevSlash)) { // Starts with "/__qtc_devices__/" ...
|
||||
const QStringView withoutQtcDeviceRoot = withoutRootPath.mid(qtcDevSlash.size());
|
||||
|
||||
const auto firstSlash = withoutQtcDeviceRoot.indexOf('/');
|
||||
|
||||
if (firstSlash != -1) {
|
||||
m_scheme = withoutQtcDeviceRoot.left(firstSlash).toString();
|
||||
const auto secondSlash = withoutQtcDeviceRoot.indexOf('/', firstSlash + 1);
|
||||
m_host = withoutQtcDeviceRoot.mid(firstSlash + 1, secondSlash - firstSlash - 1)
|
||||
.toString();
|
||||
if (secondSlash != -1) {
|
||||
const QStringView path = withoutQtcDeviceRoot.mid(secondSlash);
|
||||
m_data = path.startsWith(QLatin1String("/./")) ? path.mid(3).toString()
|
||||
: path.toString();
|
||||
return;
|
||||
}
|
||||
m_data = "/";
|
||||
|
||||
return;
|
||||
}
|
||||
if (m_data.startsWith("/./"))
|
||||
m_data = m_data.mid(3);
|
||||
} else {
|
||||
m_data = filename; // treat everything else as local, too.
|
||||
m_scheme = "";
|
||||
m_host = "";
|
||||
m_data = filename;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
const auto firstSlash = filename.indexOf('/');
|
||||
const auto schemeEnd = filename.indexOf("://");
|
||||
if (schemeEnd != -1 && schemeEnd < firstSlash) {
|
||||
// This is a pseudo Url, we can't use QUrl here sadly.
|
||||
m_scheme = filename.left(schemeEnd);
|
||||
const auto hostEnd = filename.indexOf('/', schemeEnd + 3);
|
||||
m_host = filename.mid(schemeEnd + 3, hostEnd - schemeEnd - 3);
|
||||
m_data = filename.mid(hostEnd);
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
m_data = filename;
|
||||
|
||||
return;
|
||||
#else
|
||||
// Convert the root path ( "/" or e.g. "c:/") to a regex match string ( e.g. ^[(?i)c(?-i)]:\/ )
|
||||
// (?i) will turn on case insensitivity, (?-i) will turn it off again.
|
||||
static const QString rootPart = '^'
|
||||
+ QDir::rootPath()
|
||||
.replace('/', "\\/")
|
||||
.replace(QRegularExpression("([a-zA-Z])"),
|
||||
R"((?i)[\1](?-i))");
|
||||
|
||||
static const QString pathPattern = rootPart + specialPath(SpecialPathComponent::RootName)
|
||||
+ QString(R"(\/([^\/]+)\/([^\/]+)(\/.*)?)");
|
||||
|
||||
static const QRegularExpression rePath(pathPattern);
|
||||
static const QRegularExpression reUrl(R"(^\/?([^:]+):\/{2}([^\/]*)(\/.*))");
|
||||
|
||||
const auto m = filename.startsWith(specialPath(SpecialPathComponent::RootPath),
|
||||
Qt::CaseInsensitive)
|
||||
? rePath.match(filename)
|
||||
: reUrl.match(filename);
|
||||
|
||||
if (m.hasMatch()) {
|
||||
m_scheme = m.captured(1);
|
||||
m_host = m.captured(2);
|
||||
m_host.replace("%2f", "/");
|
||||
m_host.replace("%25", "%");
|
||||
|
||||
m_data = m.captured(3).isEmpty() ? "/" : m.captured(3);
|
||||
} else {
|
||||
m_data = filename;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/// Constructs a FilePath from \a filePath. The \a defaultExtension is appended
|
||||
|
@@ -78,6 +78,7 @@ public:
|
||||
|
||||
QString toUserOutput() const;
|
||||
QString toString() const;
|
||||
QString toFSPathString() const;
|
||||
QVariant toVariant() const;
|
||||
QUrl toUrl() const;
|
||||
|
||||
@@ -210,6 +211,16 @@ public:
|
||||
[[nodiscard]] FilePath absolutePath() const; // Avoid. Use resolvePath(...)[.parent()] with proper base.
|
||||
[[nodiscard]] FilePath absoluteFilePath() const; // Avoid. Use resolvePath(...) with proper base.
|
||||
|
||||
enum class SpecialPathComponent {
|
||||
RootName,
|
||||
RootPath,
|
||||
DeviceRootName,
|
||||
DeviceRootPath,
|
||||
};
|
||||
|
||||
[[nodiscard]] static QString specialPath(SpecialPathComponent component);
|
||||
[[nodiscard]] static FilePath specialFilePath(SpecialPathComponent component);
|
||||
|
||||
private:
|
||||
friend class ::tst_fileutils;
|
||||
static QString calcRelativePath(const QString &absolutePath, const QString &absoluteAnchorPath);
|
||||
|
@@ -29,6 +29,9 @@
|
||||
#include "algorithm.h"
|
||||
#include "qtcassert.h"
|
||||
|
||||
#include "fsengine/fileiconprovider.h"
|
||||
#include "fsengine/fsengine.h"
|
||||
|
||||
#include <QDataStream>
|
||||
#include <QDebug>
|
||||
#include <QOperatingSystemVersion>
|
||||
@@ -41,6 +44,7 @@
|
||||
#ifdef QT_GUI_LIB
|
||||
#include <QMessageBox>
|
||||
#include <QRegularExpression>
|
||||
#include <QGuiApplication>
|
||||
#endif
|
||||
|
||||
#ifdef Q_OS_WIN
|
||||
@@ -438,8 +442,15 @@ FilePath FileUtils::getOpenFilePath(QWidget *parent,
|
||||
const FilePath &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options)
|
||||
QFileDialog::Options options,
|
||||
bool fromDeviceIfShiftIsPressed)
|
||||
{
|
||||
#ifdef QT_GUI_LIB
|
||||
if (fromDeviceIfShiftIsPressed && qApp->queryKeyboardModifiers() & Qt::ShiftModifier) {
|
||||
return getOpenFilePathFromDevice(parent, caption, dir, filter, selectedFilter, options);
|
||||
}
|
||||
#endif
|
||||
|
||||
const QString result = QFileDialog::getOpenFileName(dialogParent(parent),
|
||||
caption,
|
||||
dir.toString(),
|
||||
@@ -493,6 +504,47 @@ FilePaths FileUtils::getOpenFilePaths(QWidget *parent,
|
||||
return transform(result, &FilePath::fromString);
|
||||
}
|
||||
|
||||
FilePath FileUtils::getOpenFilePathFromDevice(QWidget *parent,
|
||||
const QString &caption,
|
||||
const FilePath &dir,
|
||||
const QString &filter,
|
||||
QString *selectedFilter,
|
||||
QFileDialog::Options options)
|
||||
{
|
||||
QFileDialog dialog;
|
||||
dialog.setOptions(options | QFileDialog::DontUseNativeDialog);
|
||||
dialog.setWindowTitle(caption);
|
||||
dialog.setDirectory(dir.toString());
|
||||
dialog.setNameFilter(filter);
|
||||
|
||||
QList<QUrl> sideBarUrls = Utils::transform(Utils::filtered(FSEngine::registeredDeviceRoots(),
|
||||
[](const auto &filePath) {
|
||||
return filePath.exists();
|
||||
}),
|
||||
[](const auto &filePath) {
|
||||
return QUrl::fromLocalFile(
|
||||
filePath.toFSPathString());
|
||||
});
|
||||
dialog.setSidebarUrls(sideBarUrls);
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
|
||||
dialog.setIconProvider(Utils::FileIconProvider::iconProvider());
|
||||
|
||||
if (dialog.exec()) {
|
||||
FilePaths filePaths = Utils::transform(dialog.selectedFiles(), [](const auto &path) {
|
||||
return FilePath::fromString(path);
|
||||
});
|
||||
|
||||
if (selectedFilter) {
|
||||
*selectedFilter = dialog.selectedNameFilter();
|
||||
}
|
||||
|
||||
return filePaths.first();
|
||||
}
|
||||
|
||||
return {};
|
||||
}
|
||||
|
||||
// Used on 'ls' output on unix-like systems.
|
||||
void FileUtils::iterateLsOutput(const FilePath &base,
|
||||
const QStringList &entries,
|
||||
|
@@ -152,7 +152,8 @@ public:
|
||||
const FilePath &dir = {},
|
||||
const QString &filter = {},
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = {});
|
||||
QFileDialog::Options options = {},
|
||||
bool fromDeviceIfShiftIsPressed = false);
|
||||
|
||||
static FilePath getSaveFilePath(QWidget *parent,
|
||||
const QString &caption,
|
||||
@@ -172,6 +173,13 @@ public:
|
||||
const QString &filter = {},
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = {});
|
||||
|
||||
static FilePath getOpenFilePathFromDevice(QWidget *parent,
|
||||
const QString &caption,
|
||||
const FilePath &dir = {},
|
||||
const QString &filter = {},
|
||||
QString *selectedFilter = nullptr,
|
||||
QFileDialog::Options options = {});
|
||||
#endif
|
||||
|
||||
};
|
||||
|
73
src/libs/utils/fsengine/diriterator.h
Normal file
73
src/libs/utils/fsengine/diriterator.h
Normal file
@@ -0,0 +1,73 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../filepath.h"
|
||||
#include "../stringutils.h"
|
||||
|
||||
#include <QFileInfo>
|
||||
#include <QString>
|
||||
|
||||
#include <QtCore/private/qabstractfileengine_p.h>
|
||||
|
||||
namespace Utils {
|
||||
namespace Internal {
|
||||
|
||||
class DirIterator : public QAbstractFileEngineIterator
|
||||
{
|
||||
public:
|
||||
DirIterator(FilePaths paths)
|
||||
: QAbstractFileEngineIterator({}, {})
|
||||
, m_filePaths(std::move(paths))
|
||||
, it(m_filePaths.begin())
|
||||
{}
|
||||
|
||||
// QAbstractFileEngineIterator interface
|
||||
public:
|
||||
QString next() override
|
||||
{
|
||||
if (it == m_filePaths.end())
|
||||
return QString();
|
||||
const QString r = currentFilePath();
|
||||
++it;
|
||||
return r;
|
||||
}
|
||||
bool hasNext() const override { return !m_filePaths.empty() && m_filePaths.end() != it + 1; }
|
||||
QString currentFileName() const override { return chopIfEndsWith(it->toString(), '/'); }
|
||||
|
||||
QFileInfo currentFileInfo() const override
|
||||
{
|
||||
return QFileInfo(chopIfEndsWith(it->toString(), '/'));
|
||||
}
|
||||
|
||||
private:
|
||||
const FilePaths m_filePaths;
|
||||
FilePaths::const_iterator it;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace Utils
|
@@ -41,11 +41,14 @@
|
||||
|
||||
#include <QFileIconProvider>
|
||||
#include <QIcon>
|
||||
#include <QLoggingCategory>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
Q_LOGGING_CATEGORY(fileIconProvider, "qtc.core.fileiconprovider", QtWarningMsg)
|
||||
|
||||
/*!
|
||||
\namespace Core::FileIconProvider
|
||||
\namespace Utils::FileIconProvider
|
||||
\inmodule QtCreator
|
||||
\brief Provides functions for registering custom overlay icons for system
|
||||
icons.
|
||||
@@ -64,11 +67,9 @@ using namespace Utils;
|
||||
|
||||
using Item = Utils::variant<QIcon, QString>; // icon or filename for the icon
|
||||
|
||||
namespace Core {
|
||||
namespace Utils {
|
||||
namespace FileIconProvider {
|
||||
|
||||
enum { debug = 0 };
|
||||
|
||||
static Utils::optional<QIcon> getIcon(QHash<QString, Item> &cache, const QString &key)
|
||||
{
|
||||
auto it = cache.constFind(key);
|
||||
@@ -128,8 +129,44 @@ public:
|
||||
// Mapping of file suffix to icon.
|
||||
mutable QHash<QString, Item> m_suffixCache;
|
||||
mutable QHash<QString, Item> m_filenameCache;
|
||||
|
||||
// QAbstractFileIconProvider interface
|
||||
public:
|
||||
QIcon icon(IconType) const override;
|
||||
QIcon icon(const QFileInfo &) const override;
|
||||
QString type(const QFileInfo &) const override;
|
||||
};
|
||||
|
||||
QIcon FileIconProviderImplementation::icon(IconType type) const
|
||||
{
|
||||
return QFileIconProvider::icon(type);
|
||||
}
|
||||
|
||||
QIcon FileIconProviderImplementation::icon(const QFileInfo &fi) const
|
||||
{
|
||||
return icon(FilePath::fromString(fi.filePath()));
|
||||
}
|
||||
|
||||
QString FileIconProviderImplementation::type(const QFileInfo &fi) const
|
||||
{
|
||||
const FilePath fPath = FilePath::fromString(fi.filePath());
|
||||
if (fPath.needsDevice()) {
|
||||
if (fPath.isDir()) {
|
||||
#ifdef Q_OS_WIN
|
||||
return QGuiApplication::translate("QAbstractFileIconProvider", "File Folder", "Match Windows Explorer");
|
||||
#else
|
||||
return QGuiApplication::translate("QAbstractFileIconProvider", "Folder", "All other platforms");
|
||||
#endif
|
||||
}
|
||||
if (fPath.isExecutableFile()) {
|
||||
return "Program";
|
||||
}
|
||||
|
||||
return QFileIconProvider::type(fi);
|
||||
}
|
||||
return QFileIconProvider::type(fi);
|
||||
}
|
||||
|
||||
FileIconProviderImplementation *instance()
|
||||
{
|
||||
static FileIconProviderImplementation theInstance;
|
||||
@@ -155,11 +192,20 @@ static const QIcon &dirIcon()
|
||||
|
||||
QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
|
||||
{
|
||||
if (debug)
|
||||
qDebug() << "FileIconProvider::icon" << filePath.absoluteFilePath();
|
||||
qCDebug(fileIconProvider) << "FileIconProvider::icon" << filePath.absoluteFilePath();
|
||||
|
||||
if (filePath.isEmpty())
|
||||
return unknownFileIcon();
|
||||
|
||||
// Check if its one of the virtual devices directories
|
||||
if (filePath.path().startsWith(FilePath::specialPath(FilePath::SpecialPathComponent::RootPath))) {
|
||||
// If the filepath does not need a device, it is a virtual device directory
|
||||
if (!filePath.needsDevice())
|
||||
return dirIcon();
|
||||
}
|
||||
|
||||
bool isDir = filePath.isDir();
|
||||
if (filePath.needsDevice())
|
||||
return isDir ? dirIcon() : unknownFileIcon();
|
||||
|
||||
// Check for cached overlay icons by file suffix.
|
||||
const QString filename = !isDir ? filePath.fileName() : QString();
|
||||
if (!filename.isEmpty()) {
|
||||
@@ -167,6 +213,7 @@ QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
|
||||
if (icon)
|
||||
return *icon;
|
||||
}
|
||||
|
||||
const QString suffix = !isDir ? filePath.suffix() : QString();
|
||||
if (!suffix.isEmpty()) {
|
||||
const Utils::optional<QIcon> icon = getIcon(m_suffixCache, suffix);
|
||||
@@ -174,6 +221,9 @@ QIcon FileIconProviderImplementation::icon(const FilePath &filePath) const
|
||||
return *icon;
|
||||
}
|
||||
|
||||
if (filePath.needsDevice())
|
||||
return isDir ? dirIcon() : unknownFileIcon();
|
||||
|
||||
// Get icon from OS (and cache it based on suffix!)
|
||||
QIcon icon;
|
||||
if (HostOsInfo::isWindowsHost() || HostOsInfo::isMacHost())
|
||||
@@ -263,7 +313,7 @@ QIcon directoryIcon(const QString &overlay)
|
||||
const QPixmap dirPixmap = QApplication::style()->standardIcon(QStyle::SP_DirIcon).pixmap(desiredSize);
|
||||
const QIcon overlayIcon(overlay);
|
||||
QIcon result;
|
||||
result.addPixmap(Core::FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
|
||||
result.addPixmap(FileIconProvider::overlayIcon(dirPixmap, overlayIcon));
|
||||
return result;
|
||||
}
|
||||
|
@@ -25,33 +25,41 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/core_global.h>
|
||||
#include "../utils_global.h"
|
||||
|
||||
#ifdef QT_GUI_LIB
|
||||
|
||||
#include <QStyle>
|
||||
#include <QFileIconProvider>
|
||||
#include <QStyle>
|
||||
|
||||
namespace Utils { class FilePath; }
|
||||
|
||||
namespace Core {
|
||||
namespace Utils {
|
||||
class FilePath;
|
||||
|
||||
namespace FileIconProvider {
|
||||
|
||||
// Access to the single instance
|
||||
CORE_EXPORT QFileIconProvider *iconProvider();
|
||||
QTCREATOR_UTILS_EXPORT QFileIconProvider *iconProvider();
|
||||
|
||||
// Access to individual items
|
||||
CORE_EXPORT QIcon icon(const Utils::FilePath &filePath);
|
||||
CORE_EXPORT QIcon icon(QFileIconProvider::IconType type);
|
||||
QTCREATOR_UTILS_EXPORT QIcon icon(const Utils::FilePath &filePath);
|
||||
QTCREATOR_UTILS_EXPORT QIcon icon(QFileIconProvider::IconType type);
|
||||
|
||||
// Register additional overlay icons
|
||||
CORE_EXPORT QPixmap overlayIcon(const QPixmap &baseIcon, const QIcon &overlayIcon);
|
||||
CORE_EXPORT QPixmap overlayIcon(QStyle::StandardPixmap baseIcon, const QIcon &overlayIcon, const QSize &size);
|
||||
CORE_EXPORT void registerIconOverlayForSuffix(const QString &path, const QString &suffix);
|
||||
CORE_EXPORT void registerIconOverlayForFilename(const QString &path, const QString &filename);
|
||||
CORE_EXPORT void registerIconOverlayForMimeType(const QString &path, const QString &mimeType);
|
||||
CORE_EXPORT void registerIconOverlayForMimeType(const QIcon &icon, const QString &mimeType);
|
||||
QTCREATOR_UTILS_EXPORT QPixmap overlayIcon(const QPixmap &baseIcon, const QIcon &overlayIcon);
|
||||
QTCREATOR_UTILS_EXPORT QPixmap overlayIcon(QStyle::StandardPixmap baseIcon,
|
||||
const QIcon &overlayIcon,
|
||||
const QSize &size);
|
||||
QTCREATOR_UTILS_EXPORT void registerIconOverlayForSuffix(const QString &path, const QString &suffix);
|
||||
QTCREATOR_UTILS_EXPORT void registerIconOverlayForFilename(const QString &path,
|
||||
const QString &filename);
|
||||
QTCREATOR_UTILS_EXPORT void registerIconOverlayForMimeType(const QString &path,
|
||||
const QString &mimeType);
|
||||
QTCREATOR_UTILS_EXPORT void registerIconOverlayForMimeType(const QIcon &icon,
|
||||
const QString &mimeType);
|
||||
|
||||
CORE_EXPORT QIcon directoryIcon(const QString &overlay);
|
||||
QTCREATOR_UTILS_EXPORT QIcon directoryIcon(const QString &overlay);
|
||||
|
||||
} // namespace FileIconProvider
|
||||
} // namespace Core
|
||||
} // namespace Utils
|
||||
|
||||
#endif
|
146
src/libs/utils/fsengine/fileiteratordevicesappender.h
Normal file
146
src/libs/utils/fsengine/fileiteratordevicesappender.h
Normal file
@@ -0,0 +1,146 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#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.toLower() == QDir::rootPath())
|
||||
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
|
93
src/libs/utils/fsengine/fixedlistfsengine.h
Normal file
93
src/libs/utils/fsengine/fixedlistfsengine.h
Normal file
@@ -0,0 +1,93 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "diriterator.h"
|
||||
|
||||
#include "../filepath.h"
|
||||
#include "../stringutils.h"
|
||||
|
||||
#include <QtCore/private/qabstractfileengine_p.h>
|
||||
|
||||
namespace Utils {
|
||||
namespace Internal {
|
||||
|
||||
class FixedListFSEngine : public QAbstractFileEngine
|
||||
{
|
||||
const FilePath m_filePath;
|
||||
FilePaths m_children;
|
||||
|
||||
public:
|
||||
FixedListFSEngine(FilePath path, const FilePaths children)
|
||||
: m_filePath(std::move(path))
|
||||
, m_children(std::move(children))
|
||||
{
|
||||
m_children.prepend(m_filePath.pathAppended("."));
|
||||
}
|
||||
|
||||
// QAbstractFileEngine interface
|
||||
public:
|
||||
bool isRelativePath() const override { return false; }
|
||||
FileFlags fileFlags(FileFlags /*type*/) const override
|
||||
{
|
||||
return FileFlag::DirectoryType | FileFlag::ExistsFlag | FileFlag::ReadGroupPerm
|
||||
| FileFlag::ReadUserPerm | FileFlag::ReadOwnerPerm | FileFlag::ReadOtherPerm;
|
||||
}
|
||||
QString fileName(FileName file) const override
|
||||
{
|
||||
switch (file) {
|
||||
case QAbstractFileEngine::AbsoluteName:
|
||||
case QAbstractFileEngine::DefaultName:
|
||||
case QAbstractFileEngine::CanonicalName:
|
||||
return chopIfEndsWith(m_filePath.toString(), '/');
|
||||
break;
|
||||
case QAbstractFileEngine::BaseName:
|
||||
return m_filePath.baseName();
|
||||
break;
|
||||
case QAbstractFileEngine::PathName:
|
||||
case QAbstractFileEngine::AbsolutePathName:
|
||||
case QAbstractFileEngine::CanonicalPathName:
|
||||
return chopIfEndsWith(m_filePath.parentDir().toString(), '/');
|
||||
break;
|
||||
|
||||
default:
|
||||
// case QAbstractFileEngine::LinkName:
|
||||
// case QAbstractFileEngine::BundleName:
|
||||
// case QAbstractFileEngine::JunctionName:
|
||||
return {};
|
||||
break;
|
||||
}
|
||||
|
||||
return QAbstractFileEngine::fileName(file);
|
||||
}
|
||||
Iterator *beginEntryList(QDir::Filters /*filters*/, const QStringList & /*filterNames*/) override
|
||||
{
|
||||
return new DirIterator(m_children);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Utils
|
96
src/libs/utils/fsengine/fsengine.cpp
Normal file
96
src/libs/utils/fsengine/fsengine.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "fsengine.h"
|
||||
|
||||
#ifdef QTC_UTILS_WITH_FSENGINE
|
||||
#include "fsenginehandler.h"
|
||||
#else
|
||||
class Utils::Internal::FSEngineHandler
|
||||
{};
|
||||
#endif
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
FSEngine::FSEngine()
|
||||
: m_engineHandler(std::make_unique<Internal::FSEngineHandler>())
|
||||
{}
|
||||
|
||||
FSEngine::~FSEngine() {}
|
||||
|
||||
bool FSEngine::isAvailable()
|
||||
{
|
||||
#ifdef QTC_UTILS_WITH_FSENGINE
|
||||
return true;
|
||||
#else
|
||||
return false;
|
||||
#endif
|
||||
}
|
||||
|
||||
FilePaths FSEngine::registeredDeviceRoots()
|
||||
{
|
||||
return FSEngine::deviceRoots();
|
||||
}
|
||||
|
||||
void FSEngine::addDevice(const FilePath &deviceRoot)
|
||||
{
|
||||
deviceRoots().append(deviceRoot);
|
||||
}
|
||||
|
||||
void FSEngine::removeDevice(const FilePath &deviceRoot)
|
||||
{
|
||||
deviceRoots().removeAll(deviceRoot);
|
||||
}
|
||||
|
||||
FilePaths &FSEngine::deviceRoots()
|
||||
{
|
||||
static FilePaths g_deviceRoots;
|
||||
return g_deviceRoots;
|
||||
}
|
||||
|
||||
QStringList &FSEngine::deviceSchemes()
|
||||
{
|
||||
static QStringList g_deviceSchemes {"device"};
|
||||
return g_deviceSchemes;
|
||||
}
|
||||
|
||||
void FSEngine::registerDeviceScheme(const QString &scheme)
|
||||
{
|
||||
deviceSchemes().append(scheme);
|
||||
}
|
||||
|
||||
void FSEngine::unregisterDeviceScheme(const QString &scheme)
|
||||
{
|
||||
deviceSchemes().removeAll(scheme);
|
||||
}
|
||||
|
||||
QStringList FSEngine::registeredDeviceSchemes()
|
||||
{
|
||||
return FSEngine::deviceSchemes();
|
||||
}
|
||||
|
||||
} // namespace Utils
|
66
src/libs/utils/fsengine/fsengine.h
Normal file
66
src/libs/utils/fsengine/fsengine.h
Normal file
@@ -0,0 +1,66 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../filepath.h"
|
||||
#include "../utils_global.h"
|
||||
|
||||
#include <memory>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace Internal {
|
||||
class FSEngineHandler;
|
||||
}
|
||||
|
||||
class QTCREATOR_UTILS_EXPORT FSEngine
|
||||
{
|
||||
friend class Internal::FSEngineHandler;
|
||||
|
||||
public:
|
||||
FSEngine();
|
||||
~FSEngine();
|
||||
|
||||
public:
|
||||
static bool isAvailable();
|
||||
|
||||
static Utils::FilePaths registeredDeviceRoots();
|
||||
static void addDevice(const Utils::FilePath &deviceRoot);
|
||||
static void removeDevice(const Utils::FilePath &deviceRoot);
|
||||
|
||||
static void registerDeviceScheme(const QString &scheme);
|
||||
static void unregisterDeviceScheme(const QString &scheme);
|
||||
static QStringList registeredDeviceSchemes();
|
||||
|
||||
private:
|
||||
static Utils::FilePaths &deviceRoots();
|
||||
static QStringList &deviceSchemes();
|
||||
|
||||
private:
|
||||
std::unique_ptr<Internal::FSEngineHandler> m_engineHandler;
|
||||
};
|
||||
|
||||
} // namespace Utils
|
352
src/libs/utils/fsengine/fsengine_impl.cpp
Normal file
352
src/libs/utils/fsengine/fsengine_impl.cpp
Normal file
@@ -0,0 +1,352 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "fsengine_impl.h"
|
||||
|
||||
#include "diriterator.h"
|
||||
|
||||
#include "../filepath.h"
|
||||
#include "../qtcassert.h"
|
||||
|
||||
#include <QIODevice>
|
||||
#include <QDateTime>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
FSEngineImpl::FSEngineImpl(FilePath filePath)
|
||||
: m_filePath(std::move(filePath))
|
||||
{}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
|
||||
bool FSEngineImpl::open(QIODeviceBase::OpenMode openMode, std::optional<QFile::Permissions>)
|
||||
#else
|
||||
bool FSEngineImpl::open(QIODevice::OpenMode openMode)
|
||||
#endif
|
||||
{
|
||||
QTC_ASSERT(m_tempStorage.open(), return false);
|
||||
|
||||
bool read = openMode & QIODevice::ReadOnly;
|
||||
bool write = openMode & QIODevice::WriteOnly;
|
||||
bool append = openMode & QIODevice::Append;
|
||||
|
||||
if (!write && !m_filePath.exists())
|
||||
return false;
|
||||
|
||||
if (openMode & QIODevice::NewOnly && m_filePath.exists())
|
||||
return false;
|
||||
|
||||
if (read || append) {
|
||||
QTC_ASSERT(m_tempStorage.write(m_filePath.fileContents()) >= 0, return false);
|
||||
|
||||
if (!append)
|
||||
m_tempStorage.seek(0);
|
||||
}
|
||||
|
||||
if (write && !append)
|
||||
m_hasChangedContent = true;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::close()
|
||||
{
|
||||
QTC_ASSERT(flush(), return false);
|
||||
m_tempStorage.close();
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::flush()
|
||||
{
|
||||
return syncToDisk();
|
||||
}
|
||||
|
||||
bool FSEngineImpl::syncToDisk()
|
||||
{
|
||||
if (m_hasChangedContent) {
|
||||
const qint64 oldPos = m_tempStorage.pos();
|
||||
QTC_ASSERT(m_tempStorage.seek(0), return false);
|
||||
QTC_ASSERT(m_filePath.writeFileContents(m_tempStorage.readAll()), return false);
|
||||
m_tempStorage.seek(oldPos);
|
||||
m_hasChangedContent = false;
|
||||
return true;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
qint64 FSEngineImpl::size() const
|
||||
{
|
||||
return m_filePath.fileSize();
|
||||
}
|
||||
|
||||
qint64 FSEngineImpl::pos() const
|
||||
{
|
||||
return m_tempStorage.pos();
|
||||
}
|
||||
|
||||
bool FSEngineImpl::seek(qint64 pos)
|
||||
{
|
||||
return m_tempStorage.seek(pos);
|
||||
}
|
||||
|
||||
bool FSEngineImpl::isSequential() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::remove()
|
||||
{
|
||||
return m_filePath.removeRecursively();
|
||||
}
|
||||
|
||||
bool FSEngineImpl::copy(const QString &newName)
|
||||
{
|
||||
return m_filePath.copyFile(FilePath::fromString(newName));
|
||||
}
|
||||
|
||||
bool FSEngineImpl::rename(const QString &newName)
|
||||
{
|
||||
return m_filePath.renameFile(FilePath::fromString(newName));
|
||||
}
|
||||
|
||||
bool FSEngineImpl::renameOverwrite(const QString &newName)
|
||||
{
|
||||
Q_UNUSED(newName)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::link(const QString &newName)
|
||||
{
|
||||
Q_UNUSED(newName)
|
||||
return false;
|
||||
}
|
||||
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
|
||||
bool FSEngineImpl::mkdir(const QString &dirName, bool createParentDirectories,
|
||||
std::optional<QFile::Permissions>) const
|
||||
#else
|
||||
bool FSEngineImpl::mkdir(const QString &dirName, bool createParentDirectories) const
|
||||
#endif
|
||||
{
|
||||
Q_UNUSED(createParentDirectories)
|
||||
return FilePath::fromString(dirName).createDir();
|
||||
}
|
||||
|
||||
bool FSEngineImpl::rmdir(const QString &dirName, bool recurseParentDirectories) const
|
||||
{
|
||||
if (recurseParentDirectories)
|
||||
return false;
|
||||
|
||||
return m_filePath.pathAppended(dirName).removeRecursively();
|
||||
}
|
||||
|
||||
bool FSEngineImpl::setSize(qint64 size)
|
||||
{
|
||||
return m_tempStorage.resize(size);
|
||||
}
|
||||
|
||||
bool FSEngineImpl::caseSensitive() const
|
||||
{
|
||||
// TODO?
|
||||
return true;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::isRelativePath() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QStringList FSEngineImpl::entryList(QDir::Filters filters, const QStringList &filterNames) const
|
||||
{
|
||||
QStringList result;
|
||||
m_filePath.iterateDirectory(
|
||||
[&result](const FilePath &p) {
|
||||
result.append(p.toFSPathString());
|
||||
return true;
|
||||
},
|
||||
{filterNames, filters});
|
||||
return result;
|
||||
}
|
||||
|
||||
QAbstractFileEngine::FileFlags FSEngineImpl::fileFlags(FileFlags type) const
|
||||
{
|
||||
FileFlags result{0};
|
||||
|
||||
if (type & FileInfoAll && m_filePath.exists()) {
|
||||
result |= QAbstractFileEngine::ExistsFlag;
|
||||
|
||||
if (type & DirectoryType && m_filePath.isDir())
|
||||
result |= QAbstractFileEngine::DirectoryType;
|
||||
if (type & FileType && m_filePath.isFile())
|
||||
result |= QAbstractFileEngine::FileType;
|
||||
|
||||
if (type & PermsMask) {
|
||||
result |= FileFlags::fromInt(m_filePath.permissions().toInt());
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::setPermissions(uint /*perms*/)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
QByteArray FSEngineImpl::id() const
|
||||
{
|
||||
return QAbstractFileEngine::id();
|
||||
}
|
||||
|
||||
QString FSEngineImpl::fileName(FileName file) const
|
||||
{
|
||||
switch (file) {
|
||||
case QAbstractFileEngine::AbsoluteName:
|
||||
case QAbstractFileEngine::DefaultName:
|
||||
return m_filePath.toFSPathString();
|
||||
break;
|
||||
case QAbstractFileEngine::BaseName:
|
||||
return m_filePath.baseName();
|
||||
break;
|
||||
case QAbstractFileEngine::PathName:
|
||||
case QAbstractFileEngine::AbsolutePathName:
|
||||
return m_filePath.parentDir().toFSPathString();
|
||||
break;
|
||||
case QAbstractFileEngine::CanonicalName:
|
||||
return m_filePath.canonicalPath().toFSPathString();
|
||||
break;
|
||||
case QAbstractFileEngine::CanonicalPathName:
|
||||
return m_filePath.canonicalPath().parentDir().toFSPathString();
|
||||
break;
|
||||
default:
|
||||
// case QAbstractFileEngine::LinkName:
|
||||
// case QAbstractFileEngine::BundleName:
|
||||
// case QAbstractFileEngine::JunctionName:
|
||||
return {};
|
||||
break;
|
||||
|
||||
}
|
||||
|
||||
return QAbstractFileEngine::fileName(file);
|
||||
}
|
||||
|
||||
uint FSEngineImpl::ownerId(FileOwner) const
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString FSEngineImpl::owner(FileOwner) const
|
||||
{
|
||||
return "<unknown>";
|
||||
}
|
||||
|
||||
bool FSEngineImpl::setFileTime(const QDateTime &newDate, FileTime time)
|
||||
{
|
||||
Q_UNUSED(newDate)
|
||||
Q_UNUSED(time)
|
||||
return false;
|
||||
}
|
||||
|
||||
QDateTime FSEngineImpl::fileTime(FileTime time) const
|
||||
{
|
||||
Q_UNUSED(time)
|
||||
return m_filePath.lastModified();
|
||||
}
|
||||
|
||||
void FSEngineImpl::setFileName(const QString &file)
|
||||
{
|
||||
close();
|
||||
m_filePath = FilePath::fromString(file);
|
||||
}
|
||||
|
||||
int FSEngineImpl::handle() const
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::cloneTo(QAbstractFileEngine *target)
|
||||
{
|
||||
return QAbstractFileEngine::cloneTo(target);
|
||||
}
|
||||
|
||||
QAbstractFileEngine::Iterator *FSEngineImpl::beginEntryList(QDir::Filters filters,
|
||||
const QStringList &filterNames)
|
||||
{
|
||||
FilePaths paths{m_filePath.pathAppended(".")};
|
||||
m_filePath.iterateDirectory(
|
||||
[&paths](const FilePath &p) {
|
||||
paths.append(p);
|
||||
return true;
|
||||
},
|
||||
{filterNames, filters});
|
||||
|
||||
return new DirIterator(paths);
|
||||
}
|
||||
|
||||
QAbstractFileEngine::Iterator *FSEngineImpl::endEntryList()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
qint64 FSEngineImpl::read(char *data, qint64 maxlen)
|
||||
{
|
||||
return m_tempStorage.read(data, maxlen);
|
||||
}
|
||||
|
||||
qint64 FSEngineImpl::readLine(char *data, qint64 maxlen)
|
||||
{
|
||||
return m_tempStorage.readLine(data, maxlen);
|
||||
}
|
||||
|
||||
qint64 FSEngineImpl::write(const char *data, qint64 len)
|
||||
{
|
||||
qint64 bytesWritten = m_tempStorage.write(data, len);
|
||||
|
||||
if (bytesWritten > 0)
|
||||
m_hasChangedContent = true;
|
||||
|
||||
return bytesWritten;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::extension(Extension extension,
|
||||
const ExtensionOption *option,
|
||||
ExtensionReturn *output)
|
||||
{
|
||||
Q_UNUSED(extension)
|
||||
Q_UNUSED(option)
|
||||
Q_UNUSED(output)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool FSEngineImpl::supportsExtension(Extension extension) const
|
||||
{
|
||||
Q_UNUSED(extension)
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Utils
|
98
src/libs/utils/fsengine/fsengine_impl.h
Normal file
98
src/libs/utils/fsengine/fsengine_impl.h
Normal file
@@ -0,0 +1,98 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "../filepath.h"
|
||||
|
||||
#include <QtCore/private/qabstractfileengine_p.h>
|
||||
|
||||
#include <QTemporaryFile>
|
||||
|
||||
namespace Utils {
|
||||
namespace Internal {
|
||||
|
||||
class FSEngineImpl : public QAbstractFileEngine
|
||||
{
|
||||
public:
|
||||
FSEngineImpl(FilePath filePath);
|
||||
|
||||
public:
|
||||
#if QT_VERSION >= QT_VERSION_CHECK(6, 3, 0)
|
||||
bool open(QIODeviceBase::OpenMode openMode,
|
||||
std::optional<QFile::Permissions> permissions = std::nullopt) override;
|
||||
bool mkdir(const QString &dirName, bool createParentDirectories,
|
||||
std::optional<QFile::Permissions> permissions = std::nullopt) const override;
|
||||
#else
|
||||
bool open(QIODevice::OpenMode openMode) override;
|
||||
bool mkdir(const QString &dirName, bool createParentDirectories) const override;
|
||||
#endif
|
||||
bool close() override;
|
||||
bool flush() override;
|
||||
bool syncToDisk() override;
|
||||
qint64 size() const override;
|
||||
qint64 pos() const override;
|
||||
bool seek(qint64 pos) override;
|
||||
bool isSequential() const override;
|
||||
bool remove() override;
|
||||
bool copy(const QString &newName) override;
|
||||
bool rename(const QString &newName) override;
|
||||
bool renameOverwrite(const QString &newName) override;
|
||||
bool link(const QString &newName) override;
|
||||
bool rmdir(const QString &dirName, bool recurseParentDirectories) const override;
|
||||
bool setSize(qint64 size) override;
|
||||
bool caseSensitive() const override;
|
||||
bool isRelativePath() const override;
|
||||
QStringList entryList(QDir::Filters filters, const QStringList &filterNames) const override;
|
||||
FileFlags fileFlags(FileFlags type) const override;
|
||||
bool setPermissions(uint perms) override;
|
||||
QByteArray id() const override;
|
||||
QString fileName(FileName file) const override;
|
||||
uint ownerId(FileOwner) const override;
|
||||
QString owner(FileOwner) const override;
|
||||
bool setFileTime(const QDateTime &newDate, FileTime time) override;
|
||||
QDateTime fileTime(FileTime time) const override;
|
||||
void setFileName(const QString &file) override;
|
||||
int handle() const override;
|
||||
bool cloneTo(QAbstractFileEngine *target) override;
|
||||
Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override;
|
||||
Iterator *endEntryList() override;
|
||||
qint64 read(char *data, qint64 maxlen) override;
|
||||
qint64 readLine(char *data, qint64 maxlen) override;
|
||||
qint64 write(const char *data, qint64 len) override;
|
||||
bool extension(Extension extension,
|
||||
const ExtensionOption *option,
|
||||
ExtensionReturn *output) override;
|
||||
bool supportsExtension(Extension extension) const override;
|
||||
|
||||
private:
|
||||
FilePath m_filePath;
|
||||
QTemporaryFile m_tempStorage;
|
||||
|
||||
bool m_hasChangedContent{false};
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Utils
|
96
src/libs/utils/fsengine/fsenginehandler.cpp
Normal file
96
src/libs/utils/fsengine/fsenginehandler.cpp
Normal file
@@ -0,0 +1,96 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "fsenginehandler.h"
|
||||
|
||||
#include "fixedlistfsengine.h"
|
||||
#include "fsengine_impl.h"
|
||||
#include "rootinjectfsengine.h"
|
||||
|
||||
#include "fsengine.h"
|
||||
|
||||
#include "../algorithm.h"
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
QAbstractFileEngine *FSEngineHandler::create(const QString &fileName) const
|
||||
{
|
||||
if (fileName.startsWith(':'))
|
||||
return nullptr;
|
||||
|
||||
QString fixedFileName = fileName;
|
||||
|
||||
if (fileName.startsWith("//")) {
|
||||
fixedFileName = fixedFileName.mid(1);
|
||||
}
|
||||
if (fixedFileName == FilePath::specialPath(FilePath::SpecialPathComponent::RootPath)) {
|
||||
const FilePaths paths
|
||||
= Utils::transform(FSEngine::registeredDeviceSchemes(), [](const QString &scheme) {
|
||||
return FilePath::specialFilePath(FilePath::SpecialPathComponent::RootPath)
|
||||
.pathAppended(scheme);
|
||||
});
|
||||
|
||||
return new FixedListFSEngine(FilePath::specialFilePath(
|
||||
FilePath::SpecialPathComponent::RootPath),
|
||||
paths);
|
||||
}
|
||||
|
||||
if (fixedFileName.startsWith(FilePath::specialPath(FilePath::SpecialPathComponent::RootPath))) {
|
||||
const QStringList deviceSchemes = FSEngine::registeredDeviceSchemes();
|
||||
for (const QString &scheme : deviceSchemes) {
|
||||
if (fixedFileName
|
||||
== FilePath::specialFilePath(FilePath::SpecialPathComponent::RootPath)
|
||||
.pathAppended(scheme)
|
||||
.toString()) {
|
||||
const FilePaths filteredRoots = Utils::filtered(FSEngine::deviceRoots(),
|
||||
[scheme](const FilePath &root) {
|
||||
return root.scheme() == scheme;
|
||||
});
|
||||
|
||||
return new FixedListFSEngine(FilePath::specialFilePath(
|
||||
FilePath::SpecialPathComponent::RootPath)
|
||||
.pathAppended(scheme),
|
||||
filteredRoots);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FilePath filePath = FilePath::fromString(fixedFileName);
|
||||
if (filePath.needsDevice()) {
|
||||
return new FSEngineImpl(filePath);
|
||||
}
|
||||
|
||||
if (fixedFileName.compare(QDir::rootPath(), Qt::CaseInsensitive) == 0) {
|
||||
return new RootInjectFSEngine(fixedFileName);
|
||||
}
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace Utils
|
42
src/libs/utils/fsengine/fsenginehandler.h
Normal file
42
src/libs/utils/fsengine/fsenginehandler.h
Normal file
@@ -0,0 +1,42 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <QtCore/private/qabstractfileengine_p.h>
|
||||
|
||||
namespace Utils {
|
||||
|
||||
namespace Internal {
|
||||
|
||||
class FSEngineHandler : public QAbstractFileEngineHandler
|
||||
{
|
||||
public:
|
||||
QAbstractFileEngine *create(const QString &fileName) const override;
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
|
||||
} // namespace Utils
|
50
src/libs/utils/fsengine/rootinjectfsengine.h
Normal file
50
src/libs/utils/fsengine/rootinjectfsengine.h
Normal file
@@ -0,0 +1,50 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2022 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "fileiteratordevicesappender.h"
|
||||
|
||||
#include <QtCore/private/qfsfileengine_p.h>
|
||||
|
||||
namespace Utils {
|
||||
namespace Internal {
|
||||
|
||||
class RootInjectFSEngine : public QFSFileEngine
|
||||
{
|
||||
public:
|
||||
using QFSFileEngine::QFSFileEngine;
|
||||
|
||||
public:
|
||||
Iterator *beginEntryList(QDir::Filters filters, const QStringList &filterNames) override
|
||||
{
|
||||
std::unique_ptr<QAbstractFileEngineIterator> baseIterator(
|
||||
QFSFileEngine::beginEntryList(filters, filterNames));
|
||||
return new FileIteratorWrapper(std::move(baseIterator), filters, filterNames);
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace Internal
|
||||
} // namespace Utils
|
@@ -49,14 +49,14 @@
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
|
||||
#include <QtCore/QCoreApplication>
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QSet>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QStack>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QCoreApplication>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QSet>
|
||||
#include <QBuffer>
|
||||
#include <QUrl>
|
||||
#include <QStack>
|
||||
#include <QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
@@ -49,12 +49,12 @@
|
||||
|
||||
#include "algorithm.h"
|
||||
|
||||
#include <QtCore/QFile>
|
||||
#include <QtCore/QFileInfo>
|
||||
#include <QtCore/QStandardPaths>
|
||||
#include <QtCore/QBuffer>
|
||||
#include <QtCore/QUrl>
|
||||
#include <QtCore/QDebug>
|
||||
#include <QFile>
|
||||
#include <QFileInfo>
|
||||
#include <QStandardPaths>
|
||||
#include <QBuffer>
|
||||
#include <QUrl>
|
||||
#include <QDebug>
|
||||
|
||||
#include <algorithm>
|
||||
#include <functional>
|
||||
|
@@ -33,6 +33,7 @@
|
||||
#include "qtcassert.h"
|
||||
#include "qtcprocess.h"
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QFileDialog>
|
||||
#include <QHBoxLayout>
|
||||
#include <QMenu>
|
||||
@@ -194,6 +195,7 @@ public:
|
||||
QList<QAbstractButton *> m_buttons;
|
||||
const MacroExpander *m_macroExpander = globalMacroExpander();
|
||||
std::function<void()> m_openTerminal;
|
||||
bool m_allowPathFromDevice = false;
|
||||
};
|
||||
|
||||
PathChooserPrivate::PathChooserPrivate()
|
||||
@@ -420,40 +422,46 @@ void PathChooser::slotBrowse()
|
||||
case PathChooser::Directory:
|
||||
case PathChooser::ExistingDirectory:
|
||||
newPath = FileUtils::getExistingDirectory(this,
|
||||
makeDialogTitle(tr("Choose Directory")), predefined);
|
||||
makeDialogTitle(tr("Choose Directory")),
|
||||
predefined);
|
||||
break;
|
||||
case PathChooser::ExistingCommand:
|
||||
case PathChooser::Command:
|
||||
newPath = FileUtils::getOpenFilePath(this,
|
||||
makeDialogTitle(tr("Choose Executable")), predefined, d->m_dialogFilter);
|
||||
makeDialogTitle(tr("Choose Executable")),
|
||||
predefined,
|
||||
d->m_dialogFilter,
|
||||
nullptr,
|
||||
{},
|
||||
d->m_allowPathFromDevice);
|
||||
newPath = appBundleExpandedPath(newPath);
|
||||
break;
|
||||
case PathChooser::File: // fall through
|
||||
newPath = FileUtils::getOpenFilePath(this,
|
||||
makeDialogTitle(tr("Choose File")), predefined, d->m_dialogFilter);
|
||||
makeDialogTitle(tr("Choose File")),
|
||||
predefined,
|
||||
d->m_dialogFilter,
|
||||
nullptr,
|
||||
{},
|
||||
d->m_allowPathFromDevice);
|
||||
newPath = appBundleExpandedPath(newPath);
|
||||
break;
|
||||
case PathChooser::SaveFile:
|
||||
newPath = FileUtils::getSaveFilePath(this,
|
||||
makeDialogTitle(tr("Choose File")), predefined, d->m_dialogFilter);
|
||||
makeDialogTitle(tr("Choose File")),
|
||||
predefined,
|
||||
d->m_dialogFilter);
|
||||
break;
|
||||
case PathChooser::Any: {
|
||||
QFileDialog dialog(this);
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
dialog.setWindowTitle(makeDialogTitle(tr("Choose File")));
|
||||
if (predefined.exists())
|
||||
dialog.setDirectory(predefined.absolutePath().toDir());
|
||||
// FIXME: fix QFileDialog so that it filters properly: lib*.a
|
||||
dialog.setNameFilter(d->m_dialogFilter);
|
||||
if (dialog.exec() == QDialog::Accepted) {
|
||||
// probably loop here until the *.framework dir match
|
||||
QStringList paths = dialog.selectedFiles();
|
||||
if (!paths.isEmpty())
|
||||
newPath = FilePath::fromString(paths.at(0));
|
||||
}
|
||||
newPath = FileUtils::getOpenFilePath(this,
|
||||
makeDialogTitle(tr("Choose File")),
|
||||
predefined,
|
||||
d->m_dialogFilter,
|
||||
nullptr,
|
||||
{},
|
||||
d->m_allowPathFromDevice);
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -758,4 +766,14 @@ void PathChooser::setCommandVersionArguments(const QStringList &arguments)
|
||||
}
|
||||
}
|
||||
|
||||
void PathChooser::setAllowPathFromDevice(bool allow)
|
||||
{
|
||||
d->m_allowPathFromDevice = allow;
|
||||
}
|
||||
|
||||
bool PathChooser::allowPathFromDevice() const
|
||||
{
|
||||
return d->m_allowPathFromDevice;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -158,6 +158,9 @@ public:
|
||||
// setting an empty QString will disable this and clear the placeHolderText
|
||||
void setDefaultValue(const QString &defaultValue);
|
||||
|
||||
void setAllowPathFromDevice(bool allow);
|
||||
bool allowPathFromDevice() const;
|
||||
|
||||
private:
|
||||
QString rawPath() const; // The raw unexpanded input.
|
||||
bool validatePath(FancyLineEdit *edit, QString *errorMessage) const;
|
||||
|
@@ -28,6 +28,7 @@
|
||||
#include "algorithm.h"
|
||||
#include "hostosinfo.h"
|
||||
#include "qtcassert.h"
|
||||
#include "filepath.h"
|
||||
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
#include <QApplication>
|
||||
@@ -119,6 +120,9 @@ QTCREATOR_UTILS_EXPORT QString withTildeHomePath(const QString &path)
|
||||
if (HostOsInfo::isWindowsHost())
|
||||
return path;
|
||||
|
||||
if (FilePath::fromString(path).needsDevice())
|
||||
return path;
|
||||
|
||||
static const QString homePath = QDir::homePath();
|
||||
|
||||
QFileInfo fi(QDir::cleanPath(path));
|
||||
@@ -475,7 +479,6 @@ QTCREATOR_UTILS_EXPORT QString languageNameFromLanguageCode(const QString &langu
|
||||
}
|
||||
|
||||
#ifdef QT_WIDGETS_LIB
|
||||
|
||||
QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text)
|
||||
{
|
||||
QClipboard *clipboard = QApplication::clipboard();
|
||||
@@ -483,7 +486,14 @@ QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text)
|
||||
if (clipboard->supportsSelection())
|
||||
clipboard->setText(text, QClipboard::Selection);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
QTCREATOR_UTILS_EXPORT QString chopIfEndsWith(QString str, QChar c)
|
||||
{
|
||||
if (str.endsWith(c))
|
||||
str.chop(1);
|
||||
|
||||
return str;
|
||||
}
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -130,4 +130,6 @@ QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text);
|
||||
|
||||
#endif
|
||||
|
||||
QTCREATOR_UTILS_EXPORT QString chopIfEndsWith(QString str, QChar c);
|
||||
|
||||
} // namespace Utils
|
||||
|
@@ -33,7 +33,7 @@ Project {
|
||||
cpp.frameworks: ["Foundation", "AppKit"]
|
||||
}
|
||||
|
||||
Depends { name: "Qt"; submodules: ["concurrent", "network", "qml", "widgets", "xml"] }
|
||||
Depends { name: "Qt"; submodules: ["concurrent", "core-private", "network", "qml", "widgets", "xml"] }
|
||||
Depends { name: "Qt.macextras"; condition: Qt.core.versionMajor < 6 && qbs.targetOS.contains("macos") }
|
||||
Depends { name: "app_version_header" }
|
||||
|
||||
@@ -133,6 +133,11 @@ Project {
|
||||
"fixedsizeclicklabel.h",
|
||||
"flowlayout.cpp",
|
||||
"flowlayout.h",
|
||||
"fsengine/fileiconprovider.cpp",
|
||||
"fsengine/fileiconprovider.h",
|
||||
"fsengine/qtcfsengine.cpp",
|
||||
"fsengine/qtcfsengine.h",
|
||||
"fsengine/qtcfsengine_p.h",
|
||||
"functiontraits.h",
|
||||
"futuresynchronizer.cpp",
|
||||
"futuresynchronizer.h",
|
||||
|
@@ -30,10 +30,11 @@
|
||||
#include "clangtoolsutils.h"
|
||||
#include "diagnosticmark.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/session.h>
|
||||
#include <texteditor/textmark.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
@@ -58,7 +59,7 @@ QVariant FilePathItem::data(int column, int role) const
|
||||
case Qt::DisplayRole:
|
||||
return m_filePath.toUserOutput();
|
||||
case Qt::DecorationRole:
|
||||
return Core::FileIconProvider::icon(m_filePath);
|
||||
return Utils::FileIconProvider::icon(m_filePath);
|
||||
case Debugger::DetailedErrorView::FullTextRole:
|
||||
return m_filePath.toUserOutput();
|
||||
default:
|
||||
|
@@ -29,7 +29,6 @@
|
||||
#include "cmakeprojectconstants.h"
|
||||
|
||||
#include <android/androidconstants.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <ios/iosconstants.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
@@ -41,13 +41,13 @@
|
||||
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <texteditor/snippets/snippetprovider.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/parameteraction.h>
|
||||
|
||||
using namespace Core;
|
||||
|
@@ -25,10 +25,10 @@
|
||||
|
||||
#include "projecttreehelper.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
|
@@ -32,13 +32,13 @@
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/projecttree.h>
|
||||
#include <projectexplorer/session.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/parameteraction.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
@@ -71,9 +71,9 @@ bool CompilationDatabaseProjectManagerPlugin::initialize(const QStringList &argu
|
||||
|
||||
d = new CompilationDatabaseProjectManagerPluginPrivate;
|
||||
|
||||
FileIconProvider::registerIconOverlayForFilename(Utils::Icons::PROJECT.imageFilePath().toString(),
|
||||
Utils::FileIconProvider::registerIconOverlayForFilename(Utils::Icons::PROJECT.imageFilePath().toString(),
|
||||
COMPILE_COMMANDS_JSON);
|
||||
FileIconProvider::registerIconOverlayForFilename(
|
||||
Utils::FileIconProvider::registerIconOverlayForFilename(
|
||||
Utils::Icons::PROJECT.imageFilePath().toString(),
|
||||
QString(COMPILE_COMMANDS_JSON) + Constants::COMPILATIONDATABASEPROJECT_FILES_SUFFIX);
|
||||
|
||||
|
@@ -59,7 +59,6 @@ add_qtc_plugin(Core
|
||||
fancyactionbar.qrc
|
||||
fancytabwidget.cpp fancytabwidget.h
|
||||
featureprovider.cpp featureprovider.h
|
||||
fileiconprovider.cpp fileiconprovider.h
|
||||
fileutils.cpp fileutils.h
|
||||
find/basetextfind.cpp find/basetextfind.h
|
||||
find/currentdocumentfind.cpp find/currentdocumentfind.h
|
||||
|
@@ -91,6 +91,7 @@ const char NEW[] = "QtCreator.New";
|
||||
const char NEW_FILE[] = "QtCreator.NewFile";
|
||||
const char OPEN[] = "QtCreator.Open";
|
||||
const char OPEN_WITH[] = "QtCreator.OpenWith";
|
||||
const char OPEN_FROM_DEVICE[] = "QtCreator.OpenFromDevice";
|
||||
const char REVERTTOSAVED[] = "QtCreator.RevertToSaved";
|
||||
const char SAVE[] = "QtCreator.Save";
|
||||
const char SAVEAS[] = "QtCreator.SaveAs";
|
||||
|
@@ -67,8 +67,6 @@ Project {
|
||||
"fancytabwidget.h",
|
||||
"featureprovider.cpp",
|
||||
"featureprovider.h",
|
||||
"fileiconprovider.cpp",
|
||||
"fileiconprovider.h",
|
||||
"fileutils.cpp",
|
||||
"fileutils.h",
|
||||
"findplaceholder.cpp",
|
||||
|
@@ -27,7 +27,6 @@
|
||||
#include "ui_readonlyfilesdialog.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager_p.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
@@ -35,6 +34,7 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/stringutils.h>
|
||||
|
||||
|
@@ -26,10 +26,10 @@
|
||||
#include "saveitemsdialog.h"
|
||||
|
||||
#include <coreplugin/diffservice.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
@@ -78,7 +78,7 @@ SaveItemsDialog::SaveItemsDialog(QWidget *parent,
|
||||
QTreeWidgetItem *item = new QTreeWidgetItem(m_ui.treeWidget, QStringList()
|
||||
<< visibleName << QDir::toNativeSeparators(directory));
|
||||
if (!filePath.isEmpty())
|
||||
item->setIcon(0, FileIconProvider::icon(filePath));
|
||||
item->setIcon(0, Utils::FileIconProvider::icon(filePath));
|
||||
item->setData(0, Qt::UserRole, QVariant::fromValue(document));
|
||||
}
|
||||
|
||||
|
@@ -31,10 +31,10 @@
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/editormanager_p.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
@@ -415,7 +415,7 @@ void EditorToolBar::updateDocumentStatus(IDocument *document)
|
||||
if (document->filePath().isEmpty())
|
||||
d->m_dragHandle->setIcon(QIcon());
|
||||
else
|
||||
d->m_dragHandle->setIcon(FileIconProvider::icon(document->filePath()));
|
||||
d->m_dragHandle->setIcon(Utils::FileIconProvider::icon(document->filePath()));
|
||||
|
||||
d->m_editorList->setToolTip(document->filePath().isEmpty()
|
||||
? document->displayName()
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditor.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/fileutils.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/icore.h>
|
||||
@@ -46,6 +45,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/filecrumblabel.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/navigationtreeview.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -158,8 +158,26 @@ public:
|
||||
|
||||
protected:
|
||||
bool lessThan(const QModelIndex &source_left, const QModelIndex &source_right) const override;
|
||||
bool filterAcceptsRow(int source_row, const QModelIndex &source_parent) const override;
|
||||
};
|
||||
|
||||
bool FolderSortProxyModel::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
||||
{
|
||||
if (static_cast<QFileSystemModel *>(sourceModel())->rootPath().isEmpty()) {
|
||||
QModelIndex sourceIndex = sourceModel()->index(source_row, 0, source_parent);
|
||||
while (sourceIndex.isValid()) {
|
||||
if (sourceIndex.data().toString()
|
||||
== FilePath::specialPath(FilePath::SpecialPathComponent::RootName)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
sourceIndex = sourceIndex.parent();
|
||||
}
|
||||
}
|
||||
|
||||
return QSortFilterProxyModel::filterAcceptsRow(source_row, source_parent);
|
||||
}
|
||||
|
||||
FolderSortProxyModel::FolderSortProxyModel(QObject *parent)
|
||||
: QSortFilterProxyModel(parent)
|
||||
{
|
||||
@@ -281,8 +299,9 @@ FolderNavigationWidget::FolderNavigationWidget(QWidget *parent) : QWidget(parent
|
||||
m_sortProxyModel->setSourceModel(m_fileSystemModel);
|
||||
m_sortProxyModel->setSortRole(FolderNavigationModel::IsFolderRole);
|
||||
m_sortProxyModel->sort(0);
|
||||
|
||||
m_fileSystemModel->setResolveSymlinks(false);
|
||||
m_fileSystemModel->setIconProvider(Core::FileIconProvider::iconProvider());
|
||||
m_fileSystemModel->setIconProvider(Utils::FileIconProvider::iconProvider());
|
||||
QDir::Filters filters = QDir::AllEntries | QDir::NoDotAndDotDot;
|
||||
if (Utils::HostOsInfo::isWindowsHost()) // Symlinked directories can cause file watcher warnings on Win32.
|
||||
filters |= QDir::NoSymLinks;
|
||||
@@ -924,6 +943,17 @@ static FolderNavigationWidget *currentFolderNavigationWidget()
|
||||
return qobject_cast<FolderNavigationWidget *>(Core::ICore::currentContextWidget());
|
||||
}
|
||||
|
||||
void FolderNavigationWidgetFactory::addRootPath(Utils::Id id, const QString &displayName, const QIcon &icon, const Utils::FilePath &path)
|
||||
{
|
||||
if (path.isDir())
|
||||
insertRootDirectory({id.toString(), 0, displayName, path, icon});
|
||||
}
|
||||
|
||||
void FolderNavigationWidgetFactory::removeRootPath(Utils::Id id)
|
||||
{
|
||||
removeRootDirectory(id.toString());
|
||||
}
|
||||
|
||||
void FolderNavigationWidgetFactory::registerActions()
|
||||
{
|
||||
Core::Context context(C_FOLDERNAVIGATIONWIDGET);
|
||||
|
@@ -80,6 +80,9 @@ public:
|
||||
void saveSettings(Utils::QtcSettings *settings, int position, QWidget *widget) override;
|
||||
void restoreSettings(QSettings *settings, int position, QWidget *widget) override;
|
||||
|
||||
void addRootPath(Utils::Id id, const QString &displayName, const QIcon &icon, const Utils::FilePath &path) override;
|
||||
void removeRootPath(Utils::Id path) override;
|
||||
|
||||
static void insertRootDirectory(const RootDirectory &directory);
|
||||
static void removeRootDirectory(const QString &id);
|
||||
|
||||
|
@@ -28,6 +28,7 @@
|
||||
|
||||
#include "inavigationwidgetfactory.h"
|
||||
|
||||
#include <QIcon>
|
||||
#include <QKeySequence>
|
||||
|
||||
/*!
|
||||
@@ -171,3 +172,15 @@ void INavigationWidgetFactory::saveSettings(Utils::QtcSettings * /* settings */,
|
||||
void INavigationWidgetFactory::restoreSettings(QSettings * /* settings */, int /* position */, QWidget * /* widget */)
|
||||
{
|
||||
}
|
||||
|
||||
// Registers a new root path in the factory
|
||||
void INavigationWidgetFactory::addRootPath(Utils::Id /*id*/, const QString & /*displayName*/, const QIcon & /*icon*/, const Utils::FilePath & /*path*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
// Removes a root path from the factory
|
||||
void INavigationWidgetFactory::removeRootPath(Utils::Id /*path*/)
|
||||
{
|
||||
|
||||
}
|
||||
|
@@ -27,6 +27,7 @@
|
||||
|
||||
#include "core_global.h"
|
||||
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/id.h>
|
||||
|
||||
#include <QObject>
|
||||
@@ -80,6 +81,9 @@ public:
|
||||
virtual void saveSettings(Utils::QtcSettings *settings, int position, QWidget *widget);
|
||||
virtual void restoreSettings(QSettings *settings, int position, QWidget *widget);
|
||||
|
||||
virtual void addRootPath(Utils::Id id, const QString &displayName, const QIcon &icon, const Utils::FilePath &path);
|
||||
virtual void removeRootPath(Utils::Id id);
|
||||
|
||||
private:
|
||||
QString m_displayName;
|
||||
int m_priority = 0;
|
||||
|
@@ -33,12 +33,12 @@
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icontext.h>
|
||||
#include <coreplugin/mainwindow.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/appmainwindow.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/highlightingitemdelegate.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/itemviews.h>
|
||||
|
@@ -72,6 +72,8 @@
|
||||
#include <coreplugin/settingsdatabase.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
#include <utils/historycompleter.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/mimeutils.h>
|
||||
@@ -83,6 +85,7 @@
|
||||
#include <utils/touchbar/touchbar.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
#include <QAbstractProxyModel>
|
||||
#include <QActionGroup>
|
||||
#include <QApplication>
|
||||
#include <QBrush>
|
||||
@@ -93,11 +96,13 @@
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFileInfo>
|
||||
#include <QFileSystemModel>
|
||||
#include <QMenu>
|
||||
#include <QMenuBar>
|
||||
#include <QMessageBox>
|
||||
#include <QPrinter>
|
||||
#include <QSettings>
|
||||
#include <QSortFilterProxyModel>
|
||||
#include <QStatusBar>
|
||||
#include <QStyleFactory>
|
||||
#include <QSyntaxHighlighter>
|
||||
@@ -114,6 +119,17 @@ using namespace Utils;
|
||||
namespace Core {
|
||||
namespace Internal {
|
||||
|
||||
static const char settingsGroup[] = "MainWindow";
|
||||
static const char colorKey[] = "Color";
|
||||
static const char askBeforeExitKey[] = "AskBeforeExit";
|
||||
static const char windowGeometryKey[] = "WindowGeometry";
|
||||
static const char windowStateKey[] = "WindowState";
|
||||
static const char modeSelectorLayoutKey[] = "ModeSelectorLayout";
|
||||
static const char openFromDeviceDialogKey[] = "OpenFromDeviceDialog";
|
||||
|
||||
static const bool askBeforeExitDefault = false;
|
||||
|
||||
|
||||
enum { debugMainWindow = 0 };
|
||||
|
||||
MainWindow::MainWindow()
|
||||
@@ -583,6 +599,14 @@ void MainWindow::registerDefaultActions()
|
||||
mfile->addAction(cmd, Constants::G_FILE_OPEN);
|
||||
connect(m_openWithAction, &QAction::triggered, this, &MainWindow::openFileWith);
|
||||
|
||||
if (FSEngine::isAvailable()) {
|
||||
// Open From Device Action
|
||||
m_openFromDeviceAction = new QAction(Tr::tr("Open From Device..."), this);
|
||||
cmd = ActionManager::registerAction(m_openFromDeviceAction, Constants::OPEN_FROM_DEVICE);
|
||||
mfile->addAction(cmd, Constants::G_FILE_OPEN);
|
||||
connect(m_openFromDeviceAction, &QAction::triggered, this, &MainWindow::openFileFromDevice);
|
||||
}
|
||||
|
||||
// File->Recent Files Menu
|
||||
ActionContainer *ac = ActionManager::createMenu(Constants::M_FILE_RECENTFILES);
|
||||
mfile->addMenu(ac, Constants::G_FILE_OPEN);
|
||||
@@ -1043,6 +1067,41 @@ void MainWindow::openFileWith()
|
||||
}
|
||||
}
|
||||
|
||||
void MainWindow::openFileFromDevice()
|
||||
{
|
||||
QSettings *settings = PluginManager::settings();
|
||||
settings->beginGroup(QLatin1String(settingsGroup));
|
||||
QVariant dialogSettings = settings->value(QLatin1String(openFromDeviceDialogKey));
|
||||
|
||||
QFileDialog dialog;
|
||||
dialog.setOption(QFileDialog::DontUseNativeDialog);
|
||||
if (!dialogSettings.isNull()) {
|
||||
dialog.restoreState(dialogSettings.toByteArray());
|
||||
}
|
||||
QList<QUrl> sideBarUrls = Utils::transform(Utils::filtered(FSEngine::registeredDeviceRoots(),
|
||||
[](const auto &filePath) {
|
||||
return filePath.exists();
|
||||
}),
|
||||
[](const auto &filePath) {
|
||||
return QUrl::fromLocalFile(filePath.toFSPathString());
|
||||
});
|
||||
dialog.setSidebarUrls(sideBarUrls);
|
||||
dialog.setFileMode(QFileDialog::AnyFile);
|
||||
|
||||
dialog.setIconProvider(FileIconProvider::iconProvider());
|
||||
|
||||
if (dialog.exec()) {
|
||||
FilePaths filePaths = Utils::transform(dialog.selectedFiles(), [](const auto &path) {
|
||||
return FilePath::fromString(path);
|
||||
});
|
||||
|
||||
openFiles(filePaths, ICore::SwitchMode);
|
||||
}
|
||||
|
||||
settings->setValue(QLatin1String(openFromDeviceDialogKey), dialog.saveState());
|
||||
settings->endGroup();
|
||||
}
|
||||
|
||||
IContext *MainWindow::contextObject(QWidget *widget) const
|
||||
{
|
||||
const auto it = m_contextWidgets.find(widget);
|
||||
@@ -1126,15 +1185,6 @@ void MainWindow::aboutToShutdown()
|
||||
hide();
|
||||
}
|
||||
|
||||
static const char settingsGroup[] = "MainWindow";
|
||||
static const char colorKey[] = "Color";
|
||||
static const char askBeforeExitKey[] = "AskBeforeExit";
|
||||
static const char windowGeometryKey[] = "WindowGeometry";
|
||||
static const char windowStateKey[] = "WindowState";
|
||||
static const char modeSelectorLayoutKey[] = "ModeSelectorLayout";
|
||||
|
||||
static const bool askBeforeExitDefault = false;
|
||||
|
||||
void MainWindow::readSettings()
|
||||
{
|
||||
QSettings *settings = PluginManager::settings();
|
||||
|
@@ -116,6 +116,8 @@ public:
|
||||
|
||||
void restart();
|
||||
|
||||
void openFileFromDevice();
|
||||
|
||||
public slots:
|
||||
static void openFileWith();
|
||||
void exit();
|
||||
@@ -186,6 +188,7 @@ private:
|
||||
QAction *m_newAction = nullptr;
|
||||
QAction *m_openAction = nullptr;
|
||||
QAction *m_openWithAction = nullptr;
|
||||
QAction *m_openFromDeviceAction = nullptr;
|
||||
QAction *m_saveAllAction = nullptr;
|
||||
QAction *m_exitAction = nullptr;
|
||||
QAction *m_optionsAction = nullptr;
|
||||
|
@@ -25,10 +25,9 @@
|
||||
|
||||
#include "cppcheckdiagnosticsmodel.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <debugger/analyzer/diagnosticlocation.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
namespace Cppcheck {
|
||||
@@ -47,7 +46,7 @@ QVariant FilePathItem::data(int column, int role) const
|
||||
case Qt::DisplayRole:
|
||||
return m_filePath;
|
||||
case Qt::DecorationRole:
|
||||
return Core::FileIconProvider::icon(Utils::FilePath::fromString(m_filePath));
|
||||
return Utils::FileIconProvider::icon(Utils::FilePath::fromString(m_filePath));
|
||||
case Debugger::DetailedErrorView::FullTextRole:
|
||||
return m_filePath;
|
||||
default:
|
||||
|
@@ -83,7 +83,6 @@
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/editormanager/ieditorfactory.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/navigationwidget.h>
|
||||
@@ -105,6 +104,7 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/macroexpander.h>
|
||||
#include <utils/mimeutils.h>
|
||||
|
@@ -35,7 +35,6 @@
|
||||
#include "cppmodelmanager.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/find/itemviewfind.h>
|
||||
|
||||
#include <cplusplus/CppDocument.h>
|
||||
@@ -45,6 +44,7 @@
|
||||
#include <utils/delegates.h>
|
||||
#include <utils/dropsupport.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/navigationtreeview.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/qtcsettings.h>
|
||||
|
@@ -318,6 +318,7 @@ DebuggerItemConfigWidget::DebuggerItemConfigWidget()
|
||||
item.reinitializeFromFile({}, errorMessage);
|
||||
return errorMessage->isEmpty();
|
||||
});
|
||||
m_binaryChooser->setAllowPathFromDevice(true);
|
||||
|
||||
m_workingDirectoryChooser = new PathChooser(this);
|
||||
m_workingDirectoryChooser->setExpectedKind(PathChooser::Directory);
|
||||
|
@@ -28,14 +28,15 @@
|
||||
#include "formwindoweditor.h"
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
|
||||
using namespace Core;
|
||||
using namespace Designer::Constants;
|
||||
using namespace Utils;
|
||||
|
||||
namespace Designer {
|
||||
namespace Internal {
|
||||
|
@@ -28,6 +28,7 @@
|
||||
namespace Docker::Constants {
|
||||
|
||||
const char DOCKER[] = "docker";
|
||||
const char DOCKER_DEVICE_SCHEME[] = "docker";
|
||||
|
||||
const char DOCKER_SETTINGS_ID[] = "Docker.Settings";
|
||||
const char DOCKER_DEVICE_TYPE[] = "DockerDeviceType";
|
||||
|
@@ -641,6 +641,15 @@ QString DockerDevice::mapToDevicePath(const Utils::FilePath &globalPath) const
|
||||
return path;
|
||||
}
|
||||
|
||||
Utils::FilePath DockerDevice::rootPath() const
|
||||
{
|
||||
FilePath root;
|
||||
root.setScheme(Constants::DOCKER_DEVICE_SCHEME);
|
||||
root.setHost(d->m_data.repoAndTag());
|
||||
root.setPath("/");
|
||||
return root;
|
||||
}
|
||||
|
||||
bool DockerDevice::handlesFile(const FilePath &filePath) const
|
||||
{
|
||||
if (filePath.scheme() == "device" && filePath.host() == id().toString())
|
||||
|
@@ -81,6 +81,8 @@ public:
|
||||
Utils::FilePath mapToGlobalPath(const Utils::FilePath &pathOnDevice) const override;
|
||||
QString mapToDevicePath(const Utils::FilePath &globalPath) const override;
|
||||
|
||||
Utils::FilePath rootPath() const override;
|
||||
|
||||
bool handlesFile(const Utils::FilePath &filePath) const override;
|
||||
bool isExecutableFile(const Utils::FilePath &filePath) const override;
|
||||
bool isReadableFile(const Utils::FilePath &filePath) const override;
|
||||
|
@@ -26,11 +26,13 @@
|
||||
#include "dockerplugin.h"
|
||||
|
||||
#include "dockerapi.h"
|
||||
#include "dockerconstants.h"
|
||||
#include "dockerdevice.h"
|
||||
#include "dockersettings.h"
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
using namespace Core;
|
||||
@@ -57,6 +59,7 @@ static DockerPlugin *s_instance = nullptr;
|
||||
DockerPlugin::DockerPlugin()
|
||||
{
|
||||
s_instance = this;
|
||||
FSEngine::registerDeviceScheme(Constants::DOCKER_DEVICE_SCHEME);
|
||||
}
|
||||
|
||||
DockerApi *DockerPlugin::dockerApi()
|
||||
@@ -67,6 +70,7 @@ DockerApi *DockerPlugin::dockerApi()
|
||||
|
||||
DockerPlugin::~DockerPlugin()
|
||||
{
|
||||
FSEngine::unregisterDeviceScheme(Constants::DOCKER_DEVICE_SCHEME);
|
||||
s_instance = nullptr;
|
||||
delete d;
|
||||
}
|
||||
|
@@ -38,9 +38,10 @@
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <QMenu>
|
||||
|
||||
using namespace Core;
|
||||
|
@@ -37,13 +37,14 @@
|
||||
#include "settings/tools/toolssettingsaccessor.h"
|
||||
#include "settings/tools/toolssettingspage.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
using namespace Core;
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
@@ -25,11 +25,10 @@
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/projectnodes.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
namespace MesonProjectManager {
|
||||
namespace Internal {
|
||||
|
@@ -43,8 +43,6 @@
|
||||
#include "settings/nimsettings.h"
|
||||
#include "suggest/nimsuggestcache.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/projectmanager.h>
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
@@ -53,6 +51,8 @@
|
||||
|
||||
#include <texteditor/snippets/snippetprovider.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
using namespace Utils;
|
||||
using namespace ProjectExplorer;
|
||||
|
||||
@@ -128,13 +128,13 @@ bool NimPlugin::initialize(const QStringList &arguments, QString *errorMessage)
|
||||
void NimPlugin::extensionsInitialized()
|
||||
{
|
||||
// Add MIME overlay icons (these icons displayed at Project dock panel)
|
||||
const QIcon icon = Utils::Icon({{":/nim/images/settingscategory_nim.png",
|
||||
Utils::Theme::PanelTextColorDark
|
||||
}}, Utils::Icon::Tint).icon();
|
||||
const QIcon icon = Icon({{":/nim/images/settingscategory_nim.png",
|
||||
Theme::PanelTextColorDark
|
||||
}}, Icon::Tint).icon();
|
||||
if (!icon.isNull()) {
|
||||
Core::FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIM_MIMETYPE);
|
||||
Core::FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIM_SCRIPT_MIMETYPE);
|
||||
Core::FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIMBLE_MIMETYPE);
|
||||
FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIM_MIMETYPE);
|
||||
FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIM_SCRIPT_MIMETYPE);
|
||||
FileIconProvider::registerIconOverlayForMimeType(icon, Constants::C_NIMBLE_MIMETYPE);
|
||||
}
|
||||
TaskHub::addCategory(Constants::C_NIMPARSE_ID, "Nim");
|
||||
}
|
||||
|
@@ -27,11 +27,11 @@
|
||||
#include "project.h"
|
||||
#include "session.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/detailswidget.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QSize>
|
||||
@@ -99,7 +99,7 @@ QVariant DependenciesModel::data(const QModelIndex &index, int role) const
|
||||
case Qt::CheckStateRole:
|
||||
return SessionManager::hasDependency(m_project, p) ? Qt::Checked : Qt::Unchecked;
|
||||
case Qt::DecorationRole:
|
||||
return Core::FileIconProvider::icon(p->projectFilePath());
|
||||
return Utils::FileIconProvider::icon(p->projectFilePath());
|
||||
default:
|
||||
return QVariant();
|
||||
}
|
||||
|
@@ -34,6 +34,7 @@
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/environment.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
#include <utils/persistentsettings.h>
|
||||
#include <utils/portlist.h>
|
||||
#include <utils/qtcassert.h>
|
||||
@@ -304,6 +305,10 @@ void DeviceManager::addDevice(const IDevice::ConstPtr &_device)
|
||||
d->devices << device;
|
||||
}
|
||||
emit deviceAdded(device->id());
|
||||
|
||||
if (FSEngine::isAvailable()) {
|
||||
Utils::FSEngine::addDevice(device->rootPath());
|
||||
}
|
||||
}
|
||||
|
||||
emit updated();
|
||||
@@ -323,6 +328,10 @@ void DeviceManager::removeDevice(Utils::Id id)
|
||||
}
|
||||
emit deviceRemoved(device->id());
|
||||
|
||||
if (FSEngine::isAvailable()) {
|
||||
Utils::FSEngine::removeDevice(device->rootPath());
|
||||
}
|
||||
|
||||
if (wasDefault) {
|
||||
for (int i = 0; i < d->devices.count(); ++i) {
|
||||
if (deviceAt(i)->type() == deviceType) {
|
||||
|
@@ -205,7 +205,7 @@ public:
|
||||
MachineType machineType() const;
|
||||
void setMachineType(MachineType machineType);
|
||||
|
||||
Utils::FilePath rootPath() const;
|
||||
virtual Utils::FilePath rootPath() const;
|
||||
Utils::FilePath filePath(const QString &pathOnDevice) const;
|
||||
|
||||
Utils::FilePath debugServerPath() const;
|
||||
|
@@ -1341,6 +1341,7 @@ GccToolChainConfigWidget::GccToolChainConfigWidget(GccToolChain *tc) :
|
||||
m_compilerCommand->setExpectedKind(PathChooser::ExistingCommand);
|
||||
m_compilerCommand->setCommandVersionArguments(gnuVersionArgs);
|
||||
m_compilerCommand->setHistoryCompleter("PE.Gcc.Command.History");
|
||||
m_compilerCommand->setAllowPathFromDevice(true);
|
||||
m_mainLayout->addRow(tr("&Compiler path:"), m_compilerCommand);
|
||||
m_platformCodeGenFlagsLineEdit = new QLineEdit(this);
|
||||
m_platformCodeGenFlagsLineEdit->setText(ProcessArgs::joinArgs(tc->platformCodeGenFlags()));
|
||||
|
@@ -35,13 +35,13 @@
|
||||
|
||||
#include <app/app_version.h>
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
#include <utils/utilsicons.h>
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/dropsupport.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/stringutils.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
@@ -32,12 +32,12 @@
|
||||
#include "projecttree.h"
|
||||
#include "target.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/iversioncontrol.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/mimeutils.h>
|
||||
#include <utils/pointeralgorithm.h>
|
||||
@@ -257,7 +257,7 @@ QIcon FileNode::icon() const
|
||||
if (hasError())
|
||||
return Utils::Icons::WARNING.icon();
|
||||
if (m_icon.isNull())
|
||||
m_icon = Core::FileIconProvider::icon(filePath());
|
||||
m_icon = Utils::FileIconProvider::icon(filePath());
|
||||
return m_icon;
|
||||
}
|
||||
|
||||
@@ -479,7 +479,7 @@ QIcon FolderNode::icon() const
|
||||
} else {
|
||||
auto iconPtr = Utils::get_if<QIcon>(&m_icon);
|
||||
if (!iconPtr || iconPtr->isNull())
|
||||
m_icon = Core::FileIconProvider::icon(QFileIconProvider::Folder);
|
||||
m_icon = Utils::FileIconProvider::icon(QFileIconProvider::Folder);
|
||||
}
|
||||
return Utils::get<QIcon>(m_icon);
|
||||
}
|
||||
@@ -1089,7 +1089,7 @@ QIcon DirectoryIcon::icon() const
|
||||
const auto it = m_cache.find(m_overlay);
|
||||
if (it != m_cache.end())
|
||||
return it.value();
|
||||
const QIcon icon = Core::FileIconProvider::directoryIcon(m_overlay);
|
||||
const QIcon icon = Utils::FileIconProvider::directoryIcon(m_overlay);
|
||||
m_cache.insert(m_overlay, icon);
|
||||
return icon;
|
||||
}
|
||||
|
@@ -514,24 +514,22 @@ void RunControl::initiateFinish()
|
||||
|
||||
RunWorker *RunControl::createWorker(Utils::Id workerId)
|
||||
{
|
||||
const auto check = std::bind(&RunWorkerFactory::canRun,
|
||||
std::placeholders::_1,
|
||||
workerId,
|
||||
DeviceTypeKitAspect::deviceTypeId(d->kit),
|
||||
QString{});
|
||||
RunWorkerFactory *factory = Utils::findOrDefault(g_runWorkerFactories, check);
|
||||
RunWorkerFactory *factory
|
||||
= Utils::findOrDefault(g_runWorkerFactories, [this, workerId](RunWorkerFactory *factory) {
|
||||
return factory->canRun(workerId, DeviceTypeKitAspect::deviceTypeId(d->kit), QString{});
|
||||
});
|
||||
return factory ? factory->producer()(this) : nullptr;
|
||||
}
|
||||
|
||||
bool RunControl::createMainWorker()
|
||||
{
|
||||
const auto canRun = std::bind(&RunWorkerFactory::canRun,
|
||||
std::placeholders::_1,
|
||||
d->runMode,
|
||||
DeviceTypeKitAspect::deviceTypeId(d->kit),
|
||||
d->runConfigId.toString());
|
||||
const QList<RunWorkerFactory *> candidates
|
||||
= Utils::filtered(g_runWorkerFactories, [this](RunWorkerFactory *factory) {
|
||||
return factory->canRun(d->runMode,
|
||||
DeviceTypeKitAspect::deviceTypeId(d->kit),
|
||||
d->runConfigId.toString());
|
||||
});
|
||||
|
||||
const QList<RunWorkerFactory *> candidates = Utils::filtered(g_runWorkerFactories, canRun);
|
||||
// There might be combinations that cannot run. But that should have been checked
|
||||
// with canRun below.
|
||||
QTC_ASSERT(!candidates.empty(), return false);
|
||||
|
@@ -26,11 +26,11 @@
|
||||
#include "selectablefilesmodel.h"
|
||||
#include "projectexplorerconstants.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fancylineedit.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/pathchooser.h>
|
||||
#include <utils/runextensions.h>
|
||||
#include <utils/stringutils.h>
|
||||
@@ -231,7 +231,7 @@ QVariant SelectableFilesModel::data(const QModelIndex &index, int role) const
|
||||
return t->checked;
|
||||
if (role == Qt::DecorationRole) {
|
||||
if (t->icon.isNull())
|
||||
t->icon = Core::FileIconProvider::icon(t->fullPath);
|
||||
t->icon = Utils::FileIconProvider::icon(t->fullPath);
|
||||
return t->icon;
|
||||
}
|
||||
return QVariant();
|
||||
|
@@ -31,8 +31,6 @@
|
||||
#include "pythonsettings.h"
|
||||
#include "pythonrunconfiguration.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/buildtargetinfo.h>
|
||||
#include <projectexplorer/localenvironmentaspect.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
@@ -40,6 +38,7 @@
|
||||
#include <projectexplorer/runcontrol.h>
|
||||
#include <projectexplorer/taskhub.h>
|
||||
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
@@ -100,7 +99,7 @@ void PythonPlugin::extensionsInitialized()
|
||||
// Add MIME overlay icons (these icons displayed at Project dock panel)
|
||||
QString imageFile = Utils::creatorTheme()->imageFile(Utils::Theme::IconOverlayPro,
|
||||
::Constants::FILEOVERLAY_PY);
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(imageFile, "py");
|
||||
|
||||
TaskHub::addCategory(PythonErrorTaskCategory, "Python", true);
|
||||
}
|
||||
|
@@ -32,13 +32,14 @@
|
||||
#include "qbssession.h"
|
||||
|
||||
#include <android/androidconstants.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <qtsupport/qtsupportconstants.h>
|
||||
#include <resourceeditor/resourcenode.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
|
@@ -46,7 +46,6 @@
|
||||
#include <coreplugin/helpmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/idocument.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/buildmanager.h>
|
||||
#include <projectexplorer/project.h>
|
||||
@@ -63,6 +62,7 @@
|
||||
#include <qmljstools/qmljstoolsconstants.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/utilsicons.h>
|
||||
|
||||
@@ -112,7 +112,7 @@ bool QbsProjectManagerPlugin::initialize(const QStringList &arguments, QString *
|
||||
|
||||
const Core::Context projectContext(::QbsProjectManager::Constants::PROJECT_ID);
|
||||
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(ProjectExplorer::Constants::FILEOVERLAY_QT, "qbs");
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(ProjectExplorer::Constants::FILEOVERLAY_QT, "qbs");
|
||||
Core::HelpManager::registerDocumentation({Core::HelpManager::documentationPath() + "/qbs.qch"});
|
||||
|
||||
ProjectManager::registerProjectType<QbsProject>(QmlJSTools::Constants::QBS_MIMETYPE);
|
||||
|
@@ -32,7 +32,6 @@
|
||||
#include "qmakeproject.h"
|
||||
#include "qmakeprojectmanagerconstants.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <qtsupport/qtsupportconstants.h>
|
||||
#include <projectexplorer/buildconfiguration.h>
|
||||
@@ -41,6 +40,7 @@
|
||||
#include <projectexplorer/session.h>
|
||||
#include <texteditor/texteditoractionhandler.h>
|
||||
#include <texteditor/textdocument.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
@@ -298,11 +298,11 @@ ProFileEditorFactory::ProFileEditorFactory()
|
||||
setSyntaxHighlighterCreator([]() { return new ProFileHighlighter; });
|
||||
|
||||
const QString defaultOverlay = QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QT);
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(
|
||||
creatorTheme()->imageFile(Theme::IconOverlayPro, defaultOverlay), "pro");
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(
|
||||
creatorTheme()->imageFile(Theme::IconOverlayPri, defaultOverlay), "pri");
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(
|
||||
creatorTheme()->imageFile(Theme::IconOverlayPrf, defaultOverlay), "prf");
|
||||
}
|
||||
|
||||
|
@@ -27,7 +27,6 @@
|
||||
|
||||
#include "qmakeproject.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
#include <qtsupport/baseqtversion.h>
|
||||
@@ -35,6 +34,7 @@
|
||||
#include <resourceeditor/resourcenode.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
|
||||
using namespace Core;
|
||||
@@ -112,12 +112,12 @@ QmakeStaticData::QmakeStaticData()
|
||||
const QString filter = QString::fromUtf8(fileType.addFileFilter);
|
||||
fileTypeData.push_back(QmakeStaticData::FileTypeData(fileType.type,
|
||||
desc, filter,
|
||||
Core::FileIconProvider::directoryIcon(QLatin1String(fileType.icon))));
|
||||
Utils::FileIconProvider::directoryIcon(QLatin1String(fileType.icon))));
|
||||
}
|
||||
// Project icon
|
||||
projectIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
|
||||
productIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_PRODUCT);
|
||||
groupIcon = Core::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_GROUP);
|
||||
projectIcon = Utils::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_QT);
|
||||
productIcon = Utils::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_PRODUCT);
|
||||
groupIcon = Utils::FileIconProvider::directoryIcon(ProjectExplorer::Constants::FILEOVERLAY_GROUP);
|
||||
|
||||
qAddPostRoutine(clearQmakeStaticData);
|
||||
}
|
||||
|
@@ -43,7 +43,6 @@
|
||||
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/actionmanager/actionmanager.h>
|
||||
#include <coreplugin/actionmanager/actioncontainer.h>
|
||||
#include <coreplugin/actionmanager/command.h>
|
||||
@@ -55,6 +54,7 @@
|
||||
#include <texteditor/snippets/snippetprovider.h>
|
||||
#include <texteditor/texteditorconstants.h>
|
||||
#include <texteditor/tabsettings.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/json.h>
|
||||
|
||||
|
@@ -25,7 +25,7 @@
|
||||
|
||||
#include "qmlprojectnodes.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <projectexplorer/project.h>
|
||||
#include <projectexplorer/projectexplorer.h>
|
||||
|
@@ -38,7 +38,6 @@
|
||||
#include <coreplugin/coreconstants.h>
|
||||
#include <coreplugin/designmode.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/messagebox.h>
|
||||
#include <coreplugin/modemanager.h>
|
||||
@@ -62,6 +61,7 @@
|
||||
#include <extensionsystem/pluginspec.h>
|
||||
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcprocess.h>
|
||||
|
||||
#include <QAction>
|
||||
@@ -286,7 +286,7 @@ bool QmlProjectPlugin::initialize(const QStringList &, QString *errorMessage)
|
||||
}
|
||||
|
||||
ProjectManager::registerProjectType<QmlProject>(QmlJSTools::Constants::QMLPROJECT_MIMETYPE);
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(":/qmlproject/images/qmlproject.png",
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(":/qmlproject/images/qmlproject.png",
|
||||
"qmlproject");
|
||||
|
||||
if (QmlProject::isQtDesignStudio()) {
|
||||
|
@@ -60,6 +60,7 @@
|
||||
#include <QDialogButtonBox>
|
||||
#include <QDir>
|
||||
#include <QFormLayout>
|
||||
#include <QGuiApplication>
|
||||
#include <QHeaderView>
|
||||
#include <QLabel>
|
||||
#include <QMessageBox>
|
||||
@@ -644,12 +645,15 @@ QtOptionsPageWidget::~QtOptionsPageWidget()
|
||||
|
||||
void QtOptionsPageWidget::addQtDir()
|
||||
{
|
||||
FilePath qtVersion = FileUtils::getOpenFilePath(this,
|
||||
tr("Select a qmake Executable"),
|
||||
{},
|
||||
BuildableHelperLibrary::filterForQmakeFileDialog(),
|
||||
0,
|
||||
QFileDialog::DontResolveSymlinks);
|
||||
FilePath qtVersion
|
||||
= FileUtils::getOpenFilePath(this,
|
||||
tr("Select a qmake Executable"),
|
||||
{},
|
||||
BuildableHelperLibrary::filterForQmakeFileDialog(),
|
||||
nullptr,
|
||||
QFileDialog::DontResolveSymlinks,
|
||||
true);
|
||||
|
||||
if (qtVersion.isEmpty())
|
||||
return;
|
||||
|
||||
@@ -1025,6 +1029,7 @@ void QtOptionsPageWidget::linkWithQt()
|
||||
});
|
||||
const Utils::optional<FilePath> currentLink = currentlyLinkedQtDir(nullptr);
|
||||
pathInput->setFilePath(currentLink ? *currentLink : defaultQtInstallationPath());
|
||||
pathInput->setAllowPathFromDevice(true);
|
||||
auto buttons = new QDialogButtonBox;
|
||||
layout->addStretch(10);
|
||||
layout->addWidget(buttons);
|
||||
|
@@ -1046,6 +1046,15 @@ QString LinuxDevice::userAtHost() const
|
||||
return sshParameters().userAtHost();
|
||||
}
|
||||
|
||||
Utils::FilePath LinuxDevice::rootPath() const
|
||||
{
|
||||
Utils::FilePath root;
|
||||
root.setScheme("ssh");
|
||||
root.setHost(userAtHost());
|
||||
root.setPath("/");
|
||||
return root;
|
||||
}
|
||||
|
||||
bool LinuxDevice::handlesFile(const FilePath &filePath) const
|
||||
{
|
||||
if (filePath.scheme() == "device" && filePath.host() == id().toString())
|
||||
|
@@ -57,6 +57,8 @@ public:
|
||||
|
||||
QString userAtHost() const;
|
||||
|
||||
Utils::FilePath rootPath() const override;
|
||||
|
||||
bool handlesFile(const Utils::FilePath &filePath) const override;
|
||||
bool isExecutableFile(const Utils::FilePath &filePath) const override;
|
||||
bool isReadableFile(const Utils::FilePath &filePath) const override;
|
||||
|
@@ -49,7 +49,10 @@
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <projectexplorer/target.h>
|
||||
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
|
||||
using namespace ProjectExplorer;
|
||||
using namespace Utils;
|
||||
|
||||
namespace RemoteLinux {
|
||||
namespace Internal {
|
||||
@@ -114,10 +117,12 @@ static RemoteLinuxPluginPrivate *dd = nullptr;
|
||||
RemoteLinuxPlugin::RemoteLinuxPlugin()
|
||||
{
|
||||
setObjectName(QLatin1String("RemoteLinuxPlugin"));
|
||||
FSEngine::registerDeviceScheme("ssh");
|
||||
}
|
||||
|
||||
RemoteLinuxPlugin::~RemoteLinuxPlugin()
|
||||
{
|
||||
FSEngine::unregisterDeviceScheme("ssh");
|
||||
delete dd;
|
||||
}
|
||||
|
||||
|
@@ -25,7 +25,6 @@
|
||||
|
||||
#include "resourcefile_p.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/fileutils.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include <coreplugin/vcsmanager.h>
|
||||
@@ -33,6 +32,7 @@
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/removefiledialog.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
@@ -580,7 +580,7 @@ void ResourceFile::clearPrefixList()
|
||||
ResourceModel::ResourceModel(QObject *parent)
|
||||
: QAbstractItemModel(parent), m_dirty(false)
|
||||
{
|
||||
static QIcon resourceFolderIcon = Core::FileIconProvider::directoryIcon(QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QRC));
|
||||
static QIcon resourceFolderIcon = Utils::FileIconProvider::directoryIcon(QLatin1String(ProjectExplorer::Constants::FILEOVERLAY_QRC));
|
||||
m_prefixIcon = resourceFolderIcon;
|
||||
}
|
||||
|
||||
@@ -797,7 +797,7 @@ QVariant ResourceModel::data(const QModelIndex &index, int role) const
|
||||
if (iconFileExtension(path))
|
||||
file->icon = QIcon(path);
|
||||
else
|
||||
file->icon = Core::FileIconProvider::icon(Utils::FilePath::fromString(path));
|
||||
file->icon = Utils::FileIconProvider::icon(Utils::FilePath::fromString(path));
|
||||
}
|
||||
if (!file->icon.isNull())
|
||||
result = file->icon;
|
||||
|
@@ -28,9 +28,9 @@
|
||||
#include "resourceeditorplugin.h"
|
||||
#include "resourceeditorconstants.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QFileInfo>
|
||||
@@ -45,7 +45,7 @@ ResourceEditorFactory::ResourceEditorFactory(ResourceEditorPlugin *plugin)
|
||||
setMimeTypes(QStringList(QLatin1String(C_RESOURCE_MIMETYPE)));
|
||||
setDisplayName(QCoreApplication::translate("OpenWith::Editors", C_RESOURCEEDITOR_DISPLAY_NAME));
|
||||
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(
|
||||
ProjectExplorer::Constants::FILEOVERLAY_QRC, "qrc");
|
||||
|
||||
setEditorCreator([plugin] {
|
||||
|
@@ -28,12 +28,12 @@
|
||||
#include "qrceditor/resourcefile_p.h"
|
||||
|
||||
#include <coreplugin/documentmanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
|
||||
#include <qmljstools/qmljstoolsconstants.h>
|
||||
|
||||
#include <utils/algorithm.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/mimeutils.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/threadutils.h>
|
||||
|
@@ -29,8 +29,8 @@
|
||||
#include "scxmleditordata.h"
|
||||
|
||||
#include <coreplugin/editormanager/editormanager.h>
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <projectexplorer/projectexplorerconstants.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
|
||||
#include <QGuiApplication>
|
||||
#include <QFileInfo>
|
||||
@@ -44,7 +44,7 @@ ScxmlEditorFactory::ScxmlEditorFactory()
|
||||
setDisplayName(QCoreApplication::translate("ScxmlEditor", C_SCXMLEDITOR_DISPLAY_NAME));
|
||||
addMimeType(ProjectExplorer::Constants::SCXML_MIMETYPE);
|
||||
|
||||
Core::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml");
|
||||
Utils::FileIconProvider::registerIconOverlayForSuffix(":/projectexplorer/images/fileoverlay_scxml.png", "scxml");
|
||||
|
||||
setEditorCreator([this] {
|
||||
if (!m_editorData) {
|
||||
|
@@ -25,8 +25,8 @@
|
||||
|
||||
#include "submitfilemodel.h"
|
||||
|
||||
#include <coreplugin/fileiconprovider.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fileiconprovider.h>
|
||||
#include <utils/qtcassert.h>
|
||||
#include <utils/theme/theme.h>
|
||||
|
||||
@@ -88,8 +88,8 @@ static QList<QStandardItem *> createFileRow(const QString &repositoryRoot,
|
||||
fileItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled);
|
||||
// For some reason, Windows (at least) requires a valid (existing) file path to the icon, so
|
||||
// the repository root is needed here.
|
||||
// Note: for "overlaid" icons in Core::FileIconProvider a valid file path is not required
|
||||
fileItem->setIcon(Core::FileIconProvider::icon(
|
||||
// Note: for "overlaid" icons in Utils::FileIconProvider a valid file path is not required
|
||||
fileItem->setIcon(Utils::FileIconProvider::icon(
|
||||
Utils::FilePath::fromString(repositoryRoot).pathAppended(fileName)));
|
||||
const QList<QStandardItem *> row{statusItem, fileItem};
|
||||
if (statusHint != SubmitFileModel::FileStatusUnknown) {
|
||||
|
4
tests/auto/filesystemmodel/CMakeLists.txt
Normal file
4
tests/auto/filesystemmodel/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
add_qtc_test(tst_filesystemmodel
|
||||
DEPENDS Utils
|
||||
SOURCES tst_filesystemmodel.cpp ../../../src/shared/modeltest/modeltest.cpp
|
||||
)
|
75
tests/auto/filesystemmodel/tst_filesystemmodel.cpp
Normal file
75
tests/auto/filesystemmodel/tst_filesystemmodel.cpp
Normal file
@@ -0,0 +1,75 @@
|
||||
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include "../../../src/shared/modeltest/modeltest.h"
|
||||
|
||||
#include <utils/filesystemmodel/filesystemmodel.h>
|
||||
|
||||
#include <QCoreApplication>
|
||||
#include <QDebug>
|
||||
#include <QLocalSocket>
|
||||
#include <QNetworkAccessManager>
|
||||
#include <QProcess>
|
||||
#include <QtTest>
|
||||
|
||||
#ifndef WITH_TESTS
|
||||
#define WITH_TESTS
|
||||
#endif
|
||||
|
||||
class FileSystemModelTest : public ModelTest
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
FileSystemModelTest()
|
||||
: ModelTest(new Utils::FileSystemModel())
|
||||
{
|
||||
static_cast<Utils::FileSystemModel*>(this->model())->setRootPath("/");
|
||||
}
|
||||
|
||||
private slots:
|
||||
void qTestWithTestClass() {
|
||||
Utils::FileSystemModel modelToBeTested;
|
||||
modelToBeTested.setRootPath("/");
|
||||
auto tester = new QAbstractItemModelTester(&modelToBeTested);
|
||||
}
|
||||
|
||||
void testWithSortFilterProxyModel() {
|
||||
Utils::FileSystemModel modelToBeTested;
|
||||
QSortFilterProxyModel proxyModel;
|
||||
|
||||
proxyModel.setSourceModel(&modelToBeTested);
|
||||
proxyModel.setSortRole(Qt::UserRole + 50);
|
||||
proxyModel.sort(0);
|
||||
|
||||
modelToBeTested.setRootPath("/");
|
||||
auto tester = new QAbstractItemModelTester(&proxyModel);
|
||||
}
|
||||
};
|
||||
|
||||
QTEST_MAIN(FileSystemModelTest)
|
||||
|
||||
#include "tst_filesystemmodel.moc"
|
@@ -10,3 +10,4 @@ add_subdirectory(templateengine)
|
||||
add_subdirectory(treemodel)
|
||||
add_subdirectory(multicursor)
|
||||
add_subdirectory(deviceshell)
|
||||
add_subdirectory(fsengine)
|
||||
|
@@ -56,6 +56,10 @@ private slots:
|
||||
void relativePath();
|
||||
void fromToString_data();
|
||||
void fromToString();
|
||||
void fromString_data();
|
||||
void fromString();
|
||||
void toString_data();
|
||||
void toString();
|
||||
void comparison_data();
|
||||
void comparison();
|
||||
void linkFromString_data();
|
||||
@@ -281,6 +285,83 @@ void tst_fileutils::relativePath()
|
||||
QCOMPARE(actualPath.toString(), result);
|
||||
}
|
||||
|
||||
void tst_fileutils::toString_data()
|
||||
{
|
||||
QTest::addColumn<QString>("scheme");
|
||||
QTest::addColumn<QString>("host");
|
||||
QTest::addColumn<QString>("path");
|
||||
QTest::addColumn<QString>("result");
|
||||
QTest::addColumn<QString>("userResult");
|
||||
|
||||
QTest::newRow("empty") << "" << "" << "" << "" << "";
|
||||
QTest::newRow("scheme") << "http" << "" << "" << QDir::rootPath() + "__qtc_devices__/http//./" << "http:///./";
|
||||
QTest::newRow("scheme-and-host") << "http" << "127.0.0.1" << "" << QDir::rootPath() + "__qtc_devices__/http/127.0.0.1/./" << "http://127.0.0.1/./";
|
||||
QTest::newRow("root") << "http" << "127.0.0.1" << "/" << QDir::rootPath() + "__qtc_devices__/http/127.0.0.1/" << "http://127.0.0.1/";
|
||||
|
||||
QTest::newRow("root-folder") << "" << "" << "/" << "/" << "/";
|
||||
QTest::newRow("qtc-dev-root-folder") << "" << "" << QDir::rootPath() + "__qtc_devices__" << QDir::rootPath() + "__qtc_devices__" << QDir::rootPath() + "__qtc_devices__";
|
||||
QTest::newRow("qtc-dev-type-root-folder") << "" << "" << QDir::rootPath() + "__qtc_devices__/docker" << QDir::rootPath() + "__qtc_devices__/docker" << QDir::rootPath() + "__qtc_devices__/docker";
|
||||
QTest::newRow("qtc-root-folder") << "docker" << "alpine:latest" << "/" << QDir::rootPath() + "__qtc_devices__/docker/alpine:latest/" << "docker://alpine:latest/";
|
||||
QTest::newRow("qtc-root-folder-rel") << "docker" << "alpine:latest" << "" << QDir::rootPath() + "__qtc_devices__/docker/alpine:latest/./" << "docker://alpine:latest/./";
|
||||
}
|
||||
|
||||
void tst_fileutils::toString()
|
||||
{
|
||||
QFETCH(QString, scheme);
|
||||
QFETCH(QString, host);
|
||||
QFETCH(QString, path);
|
||||
QFETCH(QString, result);
|
||||
QFETCH(QString, userResult);
|
||||
|
||||
FilePath filePath;
|
||||
filePath.setScheme(scheme);
|
||||
filePath.setHost(host);
|
||||
filePath.setPath(path);
|
||||
|
||||
QCOMPARE(filePath.toString(), result);
|
||||
QCOMPARE(filePath.toUserOutput(), userResult);
|
||||
}
|
||||
|
||||
void tst_fileutils::fromString_data()
|
||||
{
|
||||
QTest::addColumn<QString>("input");
|
||||
|
||||
QTest::addColumn<QString>("scheme");
|
||||
QTest::addColumn<QString>("host");
|
||||
QTest::addColumn<QString>("path");
|
||||
|
||||
QTest::newRow("empty") << "" << "" << "" << "";
|
||||
|
||||
QTest::newRow("unix-root") << "/" << "" << "" << "/";
|
||||
QTest::newRow("unix-folder") << "/tmp" << "" << "" << "/tmp";
|
||||
QTest::newRow("unix-folder-with-trailing-slash") << "/tmp/" << "" << "" << "/tmp/";
|
||||
|
||||
QTest::newRow("windows-root") << "c:" << "" << "" << "c:";
|
||||
QTest::newRow("windows-folder") << "c:\\Windows" << "" << "" << "c:\\Windows";
|
||||
QTest::newRow("windows-folder-with-trailing-slash") << "c:\\Windows\\" << "" << "" << "c:\\Windows\\";
|
||||
QTest::newRow("windows-folder-slash") << "C:/Windows" << "" << "" << "C:/Windows";
|
||||
|
||||
QTest::newRow("docker-root-url") << "docker://1234/" << "docker" << "1234" << "/";
|
||||
QTest::newRow("docker-root-url-special") << QDir::rootPath() + "__qtc_devices__/docker/1234/" << "docker" << "1234" << "/";
|
||||
|
||||
QTest::newRow("qtc-dev") << QDir::rootPath() + "__qtc_devices__" << "" << "" << QDir::rootPath() + "__qtc_devices__";
|
||||
QTest::newRow("qtc-dev-type") << QDir::rootPath() + "__qtc_devices__/docker" << "" << "" << QDir::rootPath() + "__qtc_devices__/docker";
|
||||
QTest::newRow("qtc-dev-type-dev") << QDir::rootPath() + "__qtc_devices__/docker/1234" << "docker" << "1234" << "/";
|
||||
|
||||
}
|
||||
|
||||
void tst_fileutils::fromString()
|
||||
{
|
||||
QFETCH(QString, input);
|
||||
QFETCH(QString, scheme);
|
||||
QFETCH(QString, host);
|
||||
QFETCH(QString, path);
|
||||
FilePath filePath = FilePath::fromString(input);
|
||||
QCOMPARE(filePath.scheme(), scheme);
|
||||
QCOMPARE(filePath.host(), host);
|
||||
QCOMPARE(filePath.path(), path);
|
||||
}
|
||||
|
||||
void tst_fileutils::fromToString_data()
|
||||
{
|
||||
QTest::addColumn<QString>("scheme");
|
||||
@@ -294,14 +375,14 @@ void tst_fileutils::fromToString_data()
|
||||
QTest::newRow("s3") << "" << "" << "/a/b" << "/a/b";
|
||||
|
||||
QTest::newRow("s4")
|
||||
<< "docker" << "1234abcdef" << "/bin/ls" << "docker://1234abcdef/bin/ls";
|
||||
<< "docker" << "1234abcdef" << "/bin/ls" << QDir::rootPath() + "__qtc_devices__/docker/1234abcdef/bin/ls";
|
||||
|
||||
QTest::newRow("s5")
|
||||
<< "docker" << "1234" << "/bin/ls" << "docker://1234/bin/ls";
|
||||
<< "docker" << "1234" << "/bin/ls" << QDir::rootPath() + "__qtc_devices__/docker/1234/bin/ls";
|
||||
|
||||
// This is not a proper URL.
|
||||
QTest::newRow("s6")
|
||||
<< "docker" << "1234" << "somefile" << "docker://1234/./somefile";
|
||||
<< "docker" << "1234" << "somefile" << QDir::rootPath() + "__qtc_devices__/docker/1234/./somefile";
|
||||
|
||||
// Local Windows paths:
|
||||
QTest::newRow("w1") << "" << "" << "C:/data" << "C:/data";
|
||||
|
4
tests/auto/utils/fsengine/CMakeLists.txt
Normal file
4
tests/auto/utils/fsengine/CMakeLists.txt
Normal file
@@ -0,0 +1,4 @@
|
||||
add_qtc_test(tst_utils_fsengine
|
||||
DEPENDS Utils
|
||||
SOURCES tst_fsengine.cpp
|
||||
)
|
291
tests/auto/utils/fsengine/tst_fsengine.cpp
Normal file
291
tests/auto/utils/fsengine/tst_fsengine.cpp
Normal file
@@ -0,0 +1,291 @@
|
||||
/****************************************************************************
|
||||
**
|
||||
** Copyright (C) 2016 The Qt Company Ltd.
|
||||
** Contact: https://www.qt.io/licensing/
|
||||
**
|
||||
** This file is part of Qt Creator.
|
||||
**
|
||||
** Commercial License Usage
|
||||
** Licensees holding valid commercial Qt licenses may use this file in
|
||||
** accordance with the commercial license agreement provided with the
|
||||
** Software or, alternatively, in accordance with the terms contained in
|
||||
** a written agreement between you and The Qt Company. For licensing terms
|
||||
** and conditions see https://www.qt.io/terms-conditions. For further
|
||||
** information use the contact form at https://www.qt.io/contact-us.
|
||||
**
|
||||
** GNU General Public License Usage
|
||||
** Alternatively, this file may be used under the terms of the GNU
|
||||
** General Public License version 3 as published by the Free Software
|
||||
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
|
||||
** included in the packaging of this file. Please review the following
|
||||
** information to ensure the GNU General Public License requirements will
|
||||
** be met: https://www.gnu.org/licenses/gpl-3.0.html.
|
||||
**
|
||||
****************************************************************************/
|
||||
|
||||
#include <utils/filepath.h>
|
||||
#include <utils/fileutils.h>
|
||||
#include <utils/fsengine/fsengine.h>
|
||||
#include <utils/hostosinfo.h>
|
||||
|
||||
#include <QDebug>
|
||||
#include <QFileSystemModel>
|
||||
#include <QtTest>
|
||||
|
||||
using namespace Utils;
|
||||
|
||||
class tst_fsengine : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
private slots:
|
||||
void initTestCase();
|
||||
|
||||
void testFilePathFromToString();
|
||||
|
||||
void testRootPathContainsFakeDir();
|
||||
void testNotExistingFile();
|
||||
void testCreateFile();
|
||||
void testListDir();
|
||||
void testCreateDir();
|
||||
void testWindowsPaths();
|
||||
void testUrl();
|
||||
|
||||
private:
|
||||
QString makeTestPath(QString path, bool asUrl = false);
|
||||
|
||||
private:
|
||||
FSEngine engine;
|
||||
QString tempFolder;
|
||||
};
|
||||
|
||||
template<class... Args>
|
||||
using Continuation = std::function<void(Args...)>;
|
||||
|
||||
void tst_fsengine::initTestCase()
|
||||
{
|
||||
if (!FSEngine::isAvailable())
|
||||
QSKIP("Utils was built without Filesystem Engine");
|
||||
|
||||
DeviceFileHooks deviceHooks;
|
||||
|
||||
deviceHooks.fileContents =
|
||||
[](const FilePath &path, qint64 maxSize, qint64 offset) -> QByteArray {
|
||||
return FilePath::fromString(path.path()).fileContents(maxSize, offset);
|
||||
};
|
||||
|
||||
deviceHooks.isExecutableFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isExecutableFile();
|
||||
};
|
||||
deviceHooks.isReadableFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isReadableFile();
|
||||
};
|
||||
deviceHooks.isReadableDir = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isReadableDir();
|
||||
};
|
||||
deviceHooks.isWritableDir = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isWritableDir();
|
||||
};
|
||||
deviceHooks.isWritableFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isWritableFile();
|
||||
};
|
||||
deviceHooks.isFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isFile();
|
||||
};
|
||||
deviceHooks.isDir = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).isDir();
|
||||
};
|
||||
deviceHooks.ensureWritableDir = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).ensureWritableDir();
|
||||
};
|
||||
deviceHooks.ensureExistingFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).ensureExistingFile();
|
||||
};
|
||||
deviceHooks.createDir = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).createDir();
|
||||
};
|
||||
deviceHooks.exists = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).exists();
|
||||
};
|
||||
deviceHooks.removeFile = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).removeFile();
|
||||
};
|
||||
deviceHooks.removeRecursively = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).removeRecursively();
|
||||
};
|
||||
deviceHooks.copyFile = [](const FilePath &filePath, const FilePath &target) {
|
||||
return FilePath::fromString(filePath.path()).copyFile(target);
|
||||
};
|
||||
deviceHooks.renameFile = [](const FilePath &filePath, const FilePath &target) {
|
||||
return FilePath::fromString(filePath.path()).renameFile(target);
|
||||
};
|
||||
deviceHooks.searchInPath = [](const FilePath &filePath, const FilePaths &dirs) {
|
||||
return FilePath::fromString(filePath.path()).searchInPath(dirs);
|
||||
};
|
||||
deviceHooks.symLinkTarget = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).symLinkTarget();
|
||||
};
|
||||
deviceHooks.iterateDirectory = [](const FilePath &filePath,
|
||||
const std::function<bool(const FilePath &)> &callBack,
|
||||
const FileFilter &filter) {
|
||||
return FilePath::fromString(filePath.path())
|
||||
.iterateDirectory(
|
||||
[&filePath, &callBack](const FilePath &path) -> bool {
|
||||
const FilePath devicePath = path.onDevice(filePath);
|
||||
|
||||
return callBack(devicePath);
|
||||
},
|
||||
filter);
|
||||
};
|
||||
deviceHooks.asyncFileContents = [](const Continuation<QByteArray> &cont,
|
||||
const FilePath &filePath,
|
||||
qint64 maxSize,
|
||||
qint64 offset) {
|
||||
return FilePath::fromString(filePath.path()).asyncFileContents(cont, maxSize, offset);
|
||||
};
|
||||
deviceHooks.writeFileContents = [](const FilePath &filePath, const QByteArray &data) {
|
||||
return FilePath::fromString(filePath.path()).writeFileContents(data);
|
||||
};
|
||||
deviceHooks.lastModified = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).lastModified();
|
||||
};
|
||||
deviceHooks.permissions = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).permissions();
|
||||
};
|
||||
deviceHooks.setPermissions = [](const FilePath &filePath, QFile::Permissions permissions) {
|
||||
return FilePath::fromString(filePath.path()).setPermissions(permissions);
|
||||
};
|
||||
deviceHooks.osType = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).osType();
|
||||
};
|
||||
// deviceHooks.environment = [](const FilePath &filePath) -> Environment {return {};};
|
||||
deviceHooks.fileSize = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).fileSize();
|
||||
};
|
||||
deviceHooks.bytesAvailable = [](const FilePath &filePath) {
|
||||
return FilePath::fromString(filePath.path()).bytesAvailable();
|
||||
};
|
||||
|
||||
deviceHooks.mapToDevicePath = [](const FilePath &filePath) { return filePath.path(); };
|
||||
|
||||
FileUtils::setDeviceFileHooks(deviceHooks);
|
||||
|
||||
FSEngine::addDevice(FilePath::fromString("device://test"));
|
||||
|
||||
tempFolder = QDir::tempPath();
|
||||
QDir testFolder(QString("%1/tst_fsengine").arg(tempFolder));
|
||||
if (testFolder.exists())
|
||||
QVERIFY(testFolder.removeRecursively());
|
||||
|
||||
QDir(tempFolder).mkdir("tst_fsengine");
|
||||
}
|
||||
|
||||
void tst_fsengine::testFilePathFromToString()
|
||||
{
|
||||
FilePath p = FilePath::fromString("device://test/test.txt");
|
||||
QCOMPARE(p.scheme(), "device");
|
||||
QCOMPARE(p.host(), "test");
|
||||
QCOMPARE(p.path(), "/test.txt");
|
||||
|
||||
QString asString = p.toString();
|
||||
QCOMPARE(asString,
|
||||
FilePath::specialPath(FilePath::SpecialPathComponent::DeviceRootPath)
|
||||
+ "/test/test.txt");
|
||||
|
||||
FilePath p2 = FilePath::fromString(asString);
|
||||
QCOMPARE(p.scheme(), "device");
|
||||
QCOMPARE(p.host(), "test");
|
||||
QCOMPARE(p.path(), "/test.txt");
|
||||
}
|
||||
|
||||
void tst_fsengine::testRootPathContainsFakeDir()
|
||||
{
|
||||
QDir root(HostOsInfo::isWindowsHost() ? "c:/" : "/");
|
||||
|
||||
const auto rootList = root.entryList();
|
||||
QVERIFY(rootList.contains(FilePath::specialPath(FilePath::SpecialPathComponent::RootName)));
|
||||
|
||||
QDir schemes(FilePath::specialPath(FilePath::SpecialPathComponent::RootPath));
|
||||
const auto schemeList = schemes.entryList();
|
||||
QVERIFY(schemeList.contains("device"));
|
||||
|
||||
QDir deviceRoot(FilePath::specialPath(FilePath::SpecialPathComponent::DeviceRootPath) + "/test");
|
||||
const auto deviceRootList = deviceRoot.entryList();
|
||||
QVERIFY(!deviceRootList.isEmpty());
|
||||
}
|
||||
|
||||
void tst_fsengine::testNotExistingFile()
|
||||
{
|
||||
QFile f(makeTestPath("test-does-not-exist.txt"));
|
||||
|
||||
QCOMPARE(f.open(QIODevice::ReadOnly), false);
|
||||
}
|
||||
|
||||
void tst_fsengine::testCreateFile()
|
||||
{
|
||||
{
|
||||
QFile f(makeTestPath("test-create-file.txt"));
|
||||
QCOMPARE(f.exists(), false);
|
||||
QVERIFY(f.open(QIODevice::WriteOnly));
|
||||
}
|
||||
|
||||
QFile f(makeTestPath("test-create-file.txt"));
|
||||
QCOMPARE(f.exists(), true);
|
||||
}
|
||||
|
||||
void tst_fsengine::testCreateDir()
|
||||
{
|
||||
QDir d(makeTestPath({}));
|
||||
QCOMPARE(d.mkdir("test-create-dir"), true);
|
||||
}
|
||||
|
||||
QString tst_fsengine::makeTestPath(QString path, bool asUrl)
|
||||
{
|
||||
if (asUrl) {
|
||||
return QString("device://test%1/tst_fsengine/%2").arg(tempFolder, path);
|
||||
}
|
||||
|
||||
return QString(FilePath::specialPath(FilePath::SpecialPathComponent::DeviceRootPath)
|
||||
+ "/test%1/tst_fsengine/%2")
|
||||
.arg(tempFolder, path);
|
||||
}
|
||||
|
||||
void tst_fsengine::testListDir()
|
||||
{
|
||||
QDir dd(makeTestPath({}));
|
||||
QCOMPARE(dd.mkdir("test-list-dir"), true);
|
||||
|
||||
QDir d(makeTestPath("test-list-dir"));
|
||||
|
||||
{
|
||||
QFile f(makeTestPath("test-list-dir/f1.txt"));
|
||||
QVERIFY(f.open(QIODevice::WriteOnly));
|
||||
}
|
||||
|
||||
const auto list = d.entryList();
|
||||
QVERIFY(list.contains("f1.txt"));
|
||||
}
|
||||
|
||||
void tst_fsengine::testWindowsPaths()
|
||||
{
|
||||
if (!HostOsInfo::isWindowsHost())
|
||||
QSKIP("This test is only valid on windows");
|
||||
|
||||
// Test upper-case "C:"
|
||||
QVERIFY(FilePath::fromString("C:/__qtc_devices__/device/{cd6c7e4b-12fd-43ca-9bb2-053a38e6b7c5}")
|
||||
.needsDevice());
|
||||
|
||||
// Test lower-case "C:"
|
||||
QVERIFY(FilePath::fromString("c:/__qtc_devices__/device/{cd6c7e4b-12fd-43ca-9bb2-053a38e6b7c5}")
|
||||
.needsDevice());
|
||||
}
|
||||
|
||||
void tst_fsengine::testUrl()
|
||||
{
|
||||
FilePath p = FilePath::fromString(makeTestPath("", true));
|
||||
|
||||
QVERIFY(p.needsDevice());
|
||||
}
|
||||
|
||||
QTEST_GUILESS_MAIN(tst_fsengine)
|
||||
#include "tst_fsengine.moc"
|
Reference in New Issue
Block a user