aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorMarcus Tillmanns <marcus.tillmanns@qt.io>2022-05-31 11:16:44 +0200
committerMarcus Tillmanns <marcus.tillmanns@qt.io>2022-07-21 13:14:01 +0000
commit3462bc67be64d8caf59ed2f9a0ba6f5edddba3b9 (patch)
tree3c1b78f5a1709e754b1567be5bf5edd73f5288b0 /src
parenta5d44fb32b7d66448d3b1a4f871957eff02107f5 (diff)
filesystem: Add QFSEngine for filepaths
Change-Id: Ibd0c88c69863c0877138d8cc45541530c359bd9c Reviewed-by: hjk <hjk@qt.io>
Diffstat (limited to 'src')
-rw-r--r--src/app/main.cpp3
-rw-r--r--src/libs/utils/CMakeLists.txt17
-rw-r--r--src/libs/utils/filepath.cpp141
-rw-r--r--src/libs/utils/filepath.h11
-rw-r--r--src/libs/utils/fileutils.cpp54
-rw-r--r--src/libs/utils/fileutils.h10
-rw-r--r--src/libs/utils/fsengine/diriterator.h73
-rw-r--r--src/libs/utils/fsengine/fileiconprovider.cpp (renamed from src/plugins/coreplugin/fileiconprovider.cpp)68
-rw-r--r--src/libs/utils/fsengine/fileiconprovider.h (renamed from src/plugins/coreplugin/fileiconprovider.h)40
-rw-r--r--src/libs/utils/fsengine/fileiteratordevicesappender.h146
-rw-r--r--src/libs/utils/fsengine/fixedlistfsengine.h93
-rw-r--r--src/libs/utils/fsengine/fsengine.cpp96
-rw-r--r--src/libs/utils/fsengine/fsengine.h66
-rw-r--r--src/libs/utils/fsengine/fsengine_impl.cpp352
-rw-r--r--src/libs/utils/fsengine/fsengine_impl.h98
-rw-r--r--src/libs/utils/fsengine/fsenginehandler.cpp96
-rw-r--r--src/libs/utils/fsengine/fsenginehandler.h42
-rw-r--r--src/libs/utils/fsengine/rootinjectfsengine.h50
-rw-r--r--src/libs/utils/mimetypes/mimedatabase.cpp16
-rw-r--r--src/libs/utils/mimetypes2/mimedatabase.cpp12
-rw-r--r--src/libs/utils/pathchooser.cpp56
-rw-r--r--src/libs/utils/pathchooser.h3
-rw-r--r--src/libs/utils/stringutils.cpp14
-rw-r--r--src/libs/utils/stringutils.h2
-rw-r--r--src/libs/utils/utils.qbs7
-rw-r--r--src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp5
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp1
-rw-r--r--src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp2
-rw-r--r--src/plugins/cmakeprojectmanager/projecttreehelper.cpp2
-rw-r--r--src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp6
-rw-r--r--src/plugins/coreplugin/CMakeLists.txt1
-rw-r--r--src/plugins/coreplugin/coreconstants.h1
-rw-r--r--src/plugins/coreplugin/coreplugin.qbs2
-rw-r--r--src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp2
-rw-r--r--src/plugins/coreplugin/dialogs/saveitemsdialog.cpp4
-rw-r--r--src/plugins/coreplugin/editortoolbar.cpp4
-rw-r--r--src/plugins/coreplugin/foldernavigationwidget.cpp34
-rw-r--r--src/plugins/coreplugin/foldernavigationwidget.h3
-rw-r--r--src/plugins/coreplugin/inavigationwidgetfactory.cpp13
-rw-r--r--src/plugins/coreplugin/inavigationwidgetfactory.h4
-rw-r--r--src/plugins/coreplugin/locator/locatorwidget.cpp2
-rw-r--r--src/plugins/coreplugin/mainwindow.cpp68
-rw-r--r--src/plugins/coreplugin/mainwindow.h3
-rw-r--r--src/plugins/cppcheck/cppcheckdiagnosticsmodel.cpp5
-rw-r--r--src/plugins/cppeditor/cppeditorplugin.cpp2
-rw-r--r--src/plugins/cppeditor/cppincludehierarchy.cpp2
-rw-r--r--src/plugins/debugger/debuggeritemmanager.cpp1
-rw-r--r--src/plugins/designer/formeditorfactory.cpp3
-rw-r--r--src/plugins/docker/dockerconstants.h1
-rw-r--r--src/plugins/docker/dockerdevice.cpp9
-rw-r--r--src/plugins/docker/dockerdevice.h2
-rw-r--r--src/plugins/docker/dockerplugin.cpp4
-rw-r--r--src/plugins/glsleditor/glsleditorplugin.cpp3
-rw-r--r--src/plugins/mesonprojectmanager/mesonprojectplugin.cpp3
-rw-r--r--src/plugins/mesonprojectmanager/project/projecttree/mesonprojectnodes.h3
-rw-r--r--src/plugins/nim/nimplugin.cpp16
-rw-r--r--src/plugins/projectexplorer/dependenciespanel.cpp6
-rw-r--r--src/plugins/projectexplorer/devicesupport/devicemanager.cpp9
-rw-r--r--src/plugins/projectexplorer/devicesupport/idevice.h2
-rw-r--r--src/plugins/projectexplorer/gcctoolchain.cpp1
-rw-r--r--src/plugins/projectexplorer/projectmodels.cpp2
-rw-r--r--src/plugins/projectexplorer/projectnodes.cpp8
-rw-r--r--src/plugins/projectexplorer/runcontrol.cpp22
-rw-r--r--src/plugins/projectexplorer/selectablefilesmodel.cpp4
-rw-r--r--src/plugins/python/pythonplugin.cpp5
-rw-r--r--src/plugins/qbsprojectmanager/qbsnodes.cpp3
-rw-r--r--src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp4
-rw-r--r--src/plugins/qmakeprojectmanager/profileeditor.cpp8
-rw-r--r--src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp10
-rw-r--r--src/plugins/qmljseditor/qmljseditorplugin.cpp2
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectnodes.cpp2
-rw-r--r--src/plugins/qmlprojectmanager/qmlprojectplugin.cpp4
-rw-r--r--src/plugins/qtsupport/qtoptionspage.cpp17
-rw-r--r--src/plugins/remotelinux/linuxdevice.cpp9
-rw-r--r--src/plugins/remotelinux/linuxdevice.h2
-rw-r--r--src/plugins/remotelinux/remotelinuxplugin.cpp5
-rw-r--r--src/plugins/resourceeditor/qrceditor/resourcefile.cpp6
-rw-r--r--src/plugins/resourceeditor/resourceeditorfactory.cpp4
-rw-r--r--src/plugins/resourceeditor/resourcenode.cpp2
-rw-r--r--src/plugins/scxmleditor/scxmleditorfactory.cpp4
-rw-r--r--src/plugins/vcsbase/submitfilemodel.cpp6
81 files changed, 1735 insertions, 189 deletions
diff --git a/src/app/main.cpp b/src/app/main.cpp
index ca18cfcfc7e..0ba1ea6a05a 100644
--- a/src/app/main.cpp
+++ b/src/app/main.cpp
@@ -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
diff --git a/src/libs/utils/CMakeLists.txt b/src/libs/utils/CMakeLists.txt
index ae1c91364a8..9ad21c03bbf 100644
--- a/src/libs/utils/CMakeLists.txt
+++ b/src/libs/utils/CMakeLists.txt
@@ -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()
+
diff --git a/src/libs/utils/filepath.cpp b/src/libs/utils/filepath.cpp
index cb7981b9f29..d1171c371ef 100644
--- a/src/libs/utils/filepath.cpp
+++ b/src/libs/utils/filepath.cpp
@@ -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 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 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;
}
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
diff --git a/src/libs/utils/filepath.h b/src/libs/utils/filepath.h
index ad8ff1811d9..f6479685af2 100644
--- a/src/libs/utils/filepath.h
+++ b/src/libs/utils/filepath.h
@@ -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);
diff --git a/src/libs/utils/fileutils.cpp b/src/libs/utils/fileutils.cpp
index bdd67a6609e..4f2f49445e6 100644
--- a/src/libs/utils/fileutils.cpp
+++ b/src/libs/utils/fileutils.cpp
@@ -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,
diff --git a/src/libs/utils/fileutils.h b/src/libs/utils/fileutils.h
index 995ebfb78b0..dd6a01bac80 100644
--- a/src/libs/utils/fileutils.h
+++ b/src/libs/utils/fileutils.h
@@ -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
};
diff --git a/src/libs/utils/fsengine/diriterator.h b/src/libs/utils/fsengine/diriterator.h
new file mode 100644
index 00000000000..9439e820db7
--- /dev/null
+++ b/src/libs/utils/fsengine/diriterator.h
@@ -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
diff --git a/src/plugins/coreplugin/fileiconprovider.cpp b/src/libs/utils/fsengine/fileiconprovider.cpp
index 217e2df8b90..0addee53861 100644
--- a/src/plugins/coreplugin/fileiconprovider.cpp
+++ b/src/libs/utils/fsengine/fileiconprovider.cpp
@@ -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;
}
diff --git a/src/plugins/coreplugin/fileiconprovider.h b/src/libs/utils/fsengine/fileiconprovider.h
index 8089f36a1e5..44f54df4cf7 100644
--- a/src/plugins/coreplugin/fileiconprovider.h
+++ b/src/libs/utils/fsengine/fileiconprovider.h
@@ -25,33 +25,41 @@
#pragma once
-#include <coreplugin/core_global.h>
+#include "../utils_global.h"
-#include <QStyle>
-#include <QFileIconProvider>
+#ifdef QT_GUI_LIB
-namespace Utils { class FilePath; }
+#include <QFileIconProvider>
+#include <QStyle>
-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
diff --git a/src/libs/utils/fsengine/fileiteratordevicesappender.h b/src/libs/utils/fsengine/fileiteratordevicesappender.h
new file mode 100644
index 00000000000..713ae247297
--- /dev/null
+++ b/src/libs/utils/fsengine/fileiteratordevicesappender.h
@@ -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
diff --git a/src/libs/utils/fsengine/fixedlistfsengine.h b/src/libs/utils/fsengine/fixedlistfsengine.h
new file mode 100644
index 00000000000..69460a649c0
--- /dev/null
+++ b/src/libs/utils/fsengine/fixedlistfsengine.h
@@ -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
diff --git a/src/libs/utils/fsengine/fsengine.cpp b/src/libs/utils/fsengine/fsengine.cpp
new file mode 100644
index 00000000000..cbfc2821793
--- /dev/null
+++ b/src/libs/utils/fsengine/fsengine.cpp
@@ -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
diff --git a/src/libs/utils/fsengine/fsengine.h b/src/libs/utils/fsengine/fsengine.h
new file mode 100644
index 00000000000..4c6326038e3
--- /dev/null
+++ b/src/libs/utils/fsengine/fsengine.h
@@ -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
diff --git a/src/libs/utils/fsengine/fsengine_impl.cpp b/src/libs/utils/fsengine/fsengine_impl.cpp
new file mode 100644
index 00000000000..f7129ad8886
--- /dev/null
+++ b/src/libs/utils/fsengine/fsengine_impl.cpp
@@ -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
diff --git a/src/libs/utils/fsengine/fsengine_impl.h b/src/libs/utils/fsengine/fsengine_impl.h
new file mode 100644
index 00000000000..cf84edd72b1
--- /dev/null
+++ b/src/libs/utils/fsengine/fsengine_impl.h
@@ -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
diff --git a/src/libs/utils/fsengine/fsenginehandler.cpp b/src/libs/utils/fsengine/fsenginehandler.cpp
new file mode 100644
index 00000000000..b66314bd3cd
--- /dev/null
+++ b/src/libs/utils/fsengine/fsenginehandler.cpp
@@ -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
diff --git a/src/libs/utils/fsengine/fsenginehandler.h b/src/libs/utils/fsengine/fsenginehandler.h
new file mode 100644
index 00000000000..d65e1de2fed
--- /dev/null
+++ b/src/libs/utils/fsengine/fsenginehandler.h
@@ -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
diff --git a/src/libs/utils/fsengine/rootinjectfsengine.h b/src/libs/utils/fsengine/rootinjectfsengine.h
new file mode 100644
index 00000000000..4a5d48fc6aa
--- /dev/null
+++ b/src/libs/utils/fsengine/rootinjectfsengine.h
@@ -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
diff --git a/src/libs/utils/mimetypes/mimedatabase.cpp b/src/libs/utils/mimetypes/mimedatabase.cpp
index 7bf0a4c8fc3..54f8030c48e 100644
--- a/src/libs/utils/mimetypes/mimedatabase.cpp
+++ b/src/libs/utils/mimetypes/mimedatabase.cpp
@@ -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>
diff --git a/src/libs/utils/mimetypes2/mimedatabase.cpp b/src/libs/utils/mimetypes2/mimedatabase.cpp
index 5a0ced57d96..4e1cf979e93 100644
--- a/src/libs/utils/mimetypes2/mimedatabase.cpp
+++ b/src/libs/utils/mimetypes2/mimedatabase.cpp
@@ -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>
diff --git a/src/libs/utils/pathchooser.cpp b/src/libs/utils/pathchooser.cpp
index 7a31cf8318d..3e304496c34 100644
--- a/src/libs/utils/pathchooser.cpp
+++ b/src/libs/utils/pathchooser.cpp
@@ -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
diff --git a/src/libs/utils/pathchooser.h b/src/libs/utils/pathchooser.h
index 855a594ff94..0bf9d1316ad 100644
--- a/src/libs/utils/pathchooser.h
+++ b/src/libs/utils/pathchooser.h
@@ -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;
diff --git a/src/libs/utils/stringutils.cpp b/src/libs/utils/stringutils.cpp
index 30f5c805aa8..fac6c6b16ce 100644
--- a/src/libs/utils/stringutils.cpp
+++ b/src/libs/utils/stringutils.cpp
@@ -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
diff --git a/src/libs/utils/stringutils.h b/src/libs/utils/stringutils.h
index fd29223967b..e88a6adbd2c 100644
--- a/src/libs/utils/stringutils.h
+++ b/src/libs/utils/stringutils.h
@@ -130,4 +130,6 @@ QTCREATOR_UTILS_EXPORT void setClipboardAndSelection(const QString &text);
#endif
+QTCREATOR_UTILS_EXPORT QString chopIfEndsWith(QString str, QChar c);
+
} // namespace Utils
diff --git a/src/libs/utils/utils.qbs b/src/libs/utils/utils.qbs
index 71fadc6bcf3..d878c6f7d3b 100644
--- a/src/libs/utils/utils.qbs
+++ b/src/libs/utils/utils.qbs
@@ -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",
diff --git a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
index f56a60cdb69..f8d305d752c 100644
--- a/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
+++ b/src/plugins/clangtools/clangtoolsdiagnosticmodel.cpp
@@ -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:
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
index 23d1f9703b8..9f8dc48902e 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectnodes.cpp
@@ -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>
diff --git a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
index 0e4f7b4c1b5..aaeabd24f85 100644
--- a/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
+++ b/src/plugins/cmakeprojectmanager/cmakeprojectplugin.cpp
@@ -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;
diff --git a/src/plugins/cmakeprojectmanager/projecttreehelper.cpp b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
index 0f070095f24..9a7aa784ef3 100644
--- a/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
+++ b/src/plugins/cmakeprojectmanager/projecttreehelper.cpp
@@ -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;
diff --git a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
index fa7f425432a..db04ea89dcd 100644
--- a/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
+++ b/src/plugins/compilationdatabaseprojectmanager/compilationdatabaseprojectmanagerplugin.cpp
@@ -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);
diff --git a/src/plugins/coreplugin/CMakeLists.txt b/src/plugins/coreplugin/CMakeLists.txt
index 28469c43807..d97b40493b8 100644
--- a/src/plugins/coreplugin/CMakeLists.txt
+++ b/src/plugins/coreplugin/CMakeLists.txt
@@ -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
diff --git a/src/plugins/coreplugin/coreconstants.h b/src/plugins/coreplugin/coreconstants.h
index fd5e21963a7..372fc3b3c52 100644
--- a/src/plugins/coreplugin/coreconstants.h
+++ b/src/plugins/coreplugin/coreconstants.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";
diff --git a/src/plugins/coreplugin/coreplugin.qbs b/src/plugins/coreplugin/coreplugin.qbs
index ad8e49b64c0..7bbe3010501 100644
--- a/src/plugins/coreplugin/coreplugin.qbs
+++ b/src/plugins/coreplugin/coreplugin.qbs
@@ -67,8 +67,6 @@ Project {
"fancytabwidget.h",
"featureprovider.cpp",
"featureprovider.h",
- "fileiconprovider.cpp",
- "fileiconprovider.h",
"fileutils.cpp",
"fileutils.h",
"findplaceholder.cpp",
diff --git a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp
index 5f8475f35a0..d54541d3b65 100644
--- a/src/plugins/coreplugin/dialogs/readonlyfilesdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/readonlyfilesdialog.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>
diff --git a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp
index d110beac0a4..7e20a9ac8c9 100644
--- a/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp
+++ b/src/plugins/coreplugin/dialogs/saveitemsdialog.cpp
@@ -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));
}
diff --git a/src/plugins/coreplugin/editortoolbar.cpp b/src/plugins/coreplugin/editortoolbar.cpp
index ee027e11c1a..68459bc9f2d 100644
--- a/src/plugins/coreplugin/editortoolbar.cpp
+++ b/src/plugins/coreplugin/editortoolbar.cpp
@@ -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()
diff --git a/src/plugins/coreplugin/foldernavigationwidget.cpp b/src/plugins/coreplugin/foldernavigationwidget.cpp
index 4c927e0e457..0ffa8e2e347 100644
--- a/src/plugins/coreplugin/foldernavigationwidget.cpp
+++ b/src/plugins/coreplugin/foldernavigationwidget.cpp
@@ -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);
diff --git a/src/plugins/coreplugin/foldernavigationwidget.h b/src/plugins/coreplugin/foldernavigationwidget.h
index 4cee261369a..e5b2242c912 100644
--- a/src/plugins/coreplugin/foldernavigationwidget.h
+++ b/src/plugins/coreplugin/foldernavigationwidget.h
@@ -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);
diff --git a/src/plugins/coreplugin/inavigationwidgetfactory.cpp b/src/plugins/coreplugin/inavigationwidgetfactory.cpp
index 63ed236e11f..c9ccfa5f7c2 100644
--- a/src/plugins/coreplugin/inavigationwidgetfactory.cpp
+++ b/src/plugins/coreplugin/inavigationwidgetfactory.cpp
@@ -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*/)
+{
+
+}
diff --git a/src/plugins/coreplugin/inavigationwidgetfactory.h b/src/plugins/coreplugin/inavigationwidgetfactory.h
index 5b3b38455e6..2573bd6961c 100644
--- a/src/plugins/coreplugin/inavigationwidgetfactory.h
+++ b/src/plugins/coreplugin/inavigationwidgetfactory.h
@@ -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;
diff --git a/src/plugins/coreplugin/locator/locatorwidget.cpp b/src/plugins/coreplugin/locator/locatorwidget.cpp
index 73821c5d7a2..2b05025bc39 100644
--- a/src/plugins/coreplugin/locator/locatorwidget.cpp
+++ b/src/plugins/coreplugin/locator/locatorwidget.cpp
@@ -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>
diff --git a/src/plugins/coreplugin/mainwindow.cpp b/src/plugins/coreplugin/mainwindow.cpp
index 7c1641ee789..44b7233d5fe 100644
--- a/src/plugins/coreplugin/mainwindow.cpp
+++ b/src/plugins/coreplugin/mainwindow.cpp
@@ -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();
diff --git a/src/plugins/coreplugin/mainwindow.h b/src/plugins/coreplugin/mainwindow.h
index 9765373ab37..674bebf5719 100644
--- a/src/plugins/coreplugin/mainwindow.h
+++ b/src/plugins/coreplugin/mainwindow.h
@@ -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;
diff --git a/src/plugins/cppcheck/cppcheckdiagnosticsmodel.cpp b/src/plugins/cppcheck/cppcheckdiagnosticsmodel.cpp
index 0f3b8a94654..79aff12ed56 100644
--- a/src/plugins/cppcheck/cppcheckdiagnosticsmodel.cpp
+++ b/src/plugins/cppcheck/cppcheckdiagnosticsmodel.cpp
@@ -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:
diff --git a/src/plugins/cppeditor/cppeditorplugin.cpp b/src/plugins/cppeditor/cppeditorplugin.cpp
index e2999002e35..4b1b3eae771 100644
--- a/src/plugins/cppeditor/cppeditorplugin.cpp
+++ b/src/plugins/cppeditor/cppeditorplugin.cpp
@@ -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>
diff --git a/src/plugins/cppeditor/cppincludehierarchy.cpp b/src/plugins/cppeditor/cppincludehierarchy.cpp
index b11c4f28028..9ec564ac571 100644
--- a/src/plugins/cppeditor/cppincludehierarchy.cpp
+++ b/src/plugins/cppeditor/cppincludehierarchy.cpp
@@ -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>
diff --git a/src/plugins/debugger/debuggeritemmanager.cpp b/src/plugins/debugger/debuggeritemmanager.cpp
index 8e12a8b30ec..02afba73f48 100644
--- a/src/plugins/debugger/debuggeritemmanager.cpp
+++ b/src/plugins/debugger/debuggeritemmanager.cpp
@@ -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);
diff --git a/src/plugins/designer/formeditorfactory.cpp b/src/plugins/designer/formeditorfactory.cpp
index 5d0cc0438b5..58749250d94 100644
--- a/src/plugins/designer/formeditorfactory.cpp
+++ b/src/plugins/designer/formeditorfactory.cpp
@@ -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 {
diff --git a/src/plugins/docker/dockerconstants.h b/src/plugins/docker/dockerconstants.h
index 8dc823a65ba..b1ed087b228 100644
--- a/src/plugins/docker/dockerconstants.h
+++ b/src/plugins/docker/dockerconstants.h
@@ -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";
diff --git a/src/plugins/docker/dockerdevice.cpp b/src/plugins/docker/dockerdevice.cpp
index a3e157ad68a..08eaf00c490 100644
--- a/src/plugins/docker/dockerdevice.cpp
+++ b/src/plugins/docker/dockerdevice.cpp
@@ -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())
diff --git a/src/plugins/docker/dockerdevice.h b/src/plugins/docker/dockerdevice.h
index aead51456a6..33845477f2e 100644
--- a/src/plugins/docker/dockerdevice.h
+++ b/src/plugins/docker/dockerdevice.h
@@ -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;
diff --git a/src/plugins/docker/dockerplugin.cpp b/src/plugins/docker/dockerplugin.cpp
index 9e6a33789ba..8bb9a8e051a 100644
--- a/src/plugins/docker/dockerplugin.cpp
+++ b/src/plugins/docker/dockerplugin.cpp
@@ -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;
}
diff --git a/src/plugins/glsleditor/glsleditorplugin.cpp b/src/plugins/glsleditor/glsleditorplugin.cpp
index 44785ba36ec..7b614e5df97 100644
--- a/src/plugins/glsleditor/glsleditorplugin.cpp
+++ b/src/plugins/glsleditor/glsleditorplugin.cpp
@@ -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;
diff --git a/src/plugins/mesonprojectmanager/mesonprojectplugin.cpp b/src/plugins/mesonprojectmanager/mesonprojectplugin.cpp
index ddfa6e4df04..de74b780217 100644
--- a/src/plugins/mesonprojectmanager/mesonprojectplugin.cpp
+++ b/src/plugins/mesonprojectmanager/mesonprojectplugin.cpp
@@ -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;
diff --git a/src/plugins/mesonprojectmanager/project/projecttree/mesonprojectnodes.h b/src/plugins/mesonprojectmanager/project/projecttree/mesonprojectnodes.h
index 2419ac0d6eb..819b461090d 100644
--- a/src/plugins/mesonprojectmanager/project/projecttree/mesonprojectnodes.h
+++ b/src/plugins/mesonprojectmanager/project/projecttree/mesonprojectnodes.h
@@ -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 {
diff --git a/src/plugins/nim/nimplugin.cpp b/src/plugins/nim/nimplugin.cpp
index 418032f6e90..bdad9176c69 100644
--- a/src/plugins/nim/nimplugin.cpp
+++ b/src/plugins/nim/nimplugin.cpp
@@ -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");
}
diff --git a/src/plugins/projectexplorer/dependenciespanel.cpp b/src/plugins/projectexplorer/dependenciespanel.cpp
index b5ec18b984c..ca945d910b9 100644
--- a/src/plugins/projectexplorer/dependenciespanel.cpp
+++ b/src/plugins/projectexplorer/dependenciespanel.cpp
@@ -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();
}
diff --git a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
index deb96f14291..65d7ce56056 100644
--- a/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
+++ b/src/plugins/projectexplorer/devicesupport/devicemanager.cpp
@@ -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) {
diff --git a/src/plugins/projectexplorer/devicesupport/idevice.h b/src/plugins/projectexplorer/devicesupport/idevice.h
index 22e125ddd9d..a21cbdae616 100644
--- a/src/plugins/projectexplorer/devicesupport/idevice.h
+++ b/src/plugins/projectexplorer/devicesupport/idevice.h
@@ -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;
diff --git a/src/plugins/projectexplorer/gcctoolchain.cpp b/src/plugins/projectexplorer/gcctoolchain.cpp
index ee0a0e3e363..a03bad61795 100644
--- a/src/plugins/projectexplorer/gcctoolchain.cpp
+++ b/src/plugins/projectexplorer/gcctoolchain.cpp
@@ -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()));
diff --git a/src/plugins/projectexplorer/projectmodels.cpp b/src/plugins/projectexplorer/projectmodels.cpp
index 68152d940ca..39010e6a53f 100644
--- a/src/plugins/projectexplorer/projectmodels.cpp
+++ b/src/plugins/projectexplorer/projectmodels.cpp
@@ -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>
diff --git a/src/plugins/projectexplorer/projectnodes.cpp b/src/plugins/projectexplorer/projectnodes.cpp
index 61dfff43d05..d10c6521b70 100644
--- a/src/plugins/projectexplorer/projectnodes.cpp
+++ b/src/plugins/projectexplorer/projectnodes.cpp
@@ -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;
}
diff --git a/src/plugins/projectexplorer/runcontrol.cpp b/src/plugins/projectexplorer/runcontrol.cpp
index f8da814b7a6..fc5bfddc4b7 100644
--- a/src/plugins/projectexplorer/runcontrol.cpp
+++ b/src/plugins/projectexplorer/runcontrol.cpp
@@ -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);
diff --git a/src/plugins/projectexplorer/selectablefilesmodel.cpp b/src/plugins/projectexplorer/selectablefilesmodel.cpp
index 80eb130b738..6ba1c7613b9 100644
--- a/src/plugins/projectexplorer/selectablefilesmodel.cpp
+++ b/src/plugins/projectexplorer/selectablefilesmodel.cpp
@@ -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();
diff --git a/src/plugins/python/pythonplugin.cpp b/src/plugins/python/pythonplugin.cpp
index c68c96fa659..2c5f954770d 100644
--- a/src/plugins/python/pythonplugin.cpp
+++ b/src/plugins/python/pythonplugin.cpp
@@ -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);
}
diff --git a/src/plugins/qbsprojectmanager/qbsnodes.cpp b/src/plugins/qbsprojectmanager/qbsnodes.cpp
index 2d6049b5702..2dd46dd93ae 100644
--- a/src/plugins/qbsprojectmanager/qbsnodes.cpp
+++ b/src/plugins/qbsprojectmanager/qbsnodes.cpp
@@ -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>
diff --git a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
index f96a86656eb..7de1ebac225 100644
--- a/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
+++ b/src/plugins/qbsprojectmanager/qbsprojectmanagerplugin.cpp
@@ -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);
diff --git a/src/plugins/qmakeprojectmanager/profileeditor.cpp b/src/plugins/qmakeprojectmanager/profileeditor.cpp
index ecb3bfbda78..0406c01e365 100644
--- a/src/plugins/qmakeprojectmanager/profileeditor.cpp
+++ b/src/plugins/qmakeprojectmanager/profileeditor.cpp
@@ -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");
}
diff --git a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
index 10fc625d562..477fd311765 100644
--- a/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
+++ b/src/plugins/qmakeprojectmanager/qmakenodetreebuilder.cpp
@@ -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);
}
diff --git a/src/plugins/qmljseditor/qmljseditorplugin.cpp b/src/plugins/qmljseditor/qmljseditorplugin.cpp
index c83dc5320a5..cf045a12c65 100644
--- a/src/plugins/qmljseditor/qmljseditorplugin.cpp
+++ b/src/plugins/qmljseditor/qmljseditorplugin.cpp
@@ -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>
diff --git a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
index b2265540836..f5c3bb6fb71 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectnodes.cpp
@@ -25,7 +25,7 @@
#include "qmlprojectnodes.h"
-#include <coreplugin/fileiconprovider.h>
+#include <utils/fsengine/fileiconprovider.h>
#include <projectexplorer/project.h>
#include <projectexplorer/projectexplorer.h>
diff --git a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
index a24beeebc4e..54aaa2afa00 100644
--- a/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
+++ b/src/plugins/qmlprojectmanager/qmlprojectplugin.cpp
@@ -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()) {
diff --git a/src/plugins/qtsupport/qtoptionspage.cpp b/src/plugins/qtsupport/qtoptionspage.cpp
index 9f9466a177a..349375d2cf8 100644
--- a/src/plugins/qtsupport/qtoptionspage.cpp
+++ b/src/plugins/qtsupport/qtoptionspage.cpp
@@ -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);
diff --git a/src/plugins/remotelinux/linuxdevice.cpp b/src/plugins/remotelinux/linuxdevice.cpp
index 39f7ba65e62..fa83b6d7dab 100644
--- a/src/plugins/remotelinux/linuxdevice.cpp
+++ b/src/plugins/remotelinux/linuxdevice.cpp
@@ -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())
diff --git a/src/plugins/remotelinux/linuxdevice.h b/src/plugins/remotelinux/linuxdevice.h
index 2e7000a09dd..32e42ee9081 100644
--- a/src/plugins/remotelinux/linuxdevice.h
+++ b/src/plugins/remotelinux/linuxdevice.h
@@ -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;
diff --git a/src/plugins/remotelinux/remotelinuxplugin.cpp b/src/plugins/remotelinux/remotelinuxplugin.cpp
index 29aabd18d19..ef93ad8f3fe 100644
--- a/src/plugins/remotelinux/remotelinuxplugin.cpp
+++ b/src/plugins/remotelinux/remotelinuxplugin.cpp
@@ -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;
}
diff --git a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
index b89ddffb88a..fd8e7469a9e 100644
--- a/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
+++ b/src/plugins/resourceeditor/qrceditor/resourcefile.cpp
@@ -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;
diff --git a/src/plugins/resourceeditor/resourceeditorfactory.cpp b/src/plugins/resourceeditor/resourceeditorfactory.cpp
index 70077bf6fc0..10a6f582717 100644
--- a/src/plugins/resourceeditor/resourceeditorfactory.cpp
+++ b/src/plugins/resourceeditor/resourceeditorfactory.cpp
@@ -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] {
diff --git a/src/plugins/resourceeditor/resourcenode.cpp b/src/plugins/resourceeditor/resourcenode.cpp
index bc9274fa895..2de68d2a3f4 100644
--- a/src/plugins/resourceeditor/resourcenode.cpp
+++ b/src/plugins/resourceeditor/resourcenode.cpp
@@ -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>
diff --git a/src/plugins/scxmleditor/scxmleditorfactory.cpp b/src/plugins/scxmleditor/scxmleditorfactory.cpp
index 56d707173e8..2018543abe5 100644
--- a/src/plugins/scxmleditor/scxmleditorfactory.cpp
+++ b/src/plugins/scxmleditor/scxmleditorfactory.cpp
@@ -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) {
diff --git a/src/plugins/vcsbase/submitfilemodel.cpp b/src/plugins/vcsbase/submitfilemodel.cpp
index 7366e8649e8..55d2f1ad2bc 100644
--- a/src/plugins/vcsbase/submitfilemodel.cpp
+++ b/src/plugins/vcsbase/submitfilemodel.cpp
@@ -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) {