Python: check for pyside in qt installation

Fixes: PYSIDE-2153
Change-Id: I91ec24eb6a71d4f29edaf7a707b3c49a4deb725a
Reviewed-by: Christian Stenger <christian.stenger@qt.io>
This commit is contained in:
David Schulz
2023-08-15 15:37:51 +02:00
parent a137f2b23d
commit be54b3db2f
9 changed files with 97 additions and 22 deletions

View File

@@ -1788,6 +1788,13 @@ FilePath FilePath::stringAppended(const QString &str) const
return FilePath::fromString(toString() + str);
}
std::optional<FilePath> FilePath::tailRemoved(const QString &str) const
{
if (pathView().endsWith(str))
return withNewPath(pathView().chopped(str.size()).toString());
return {};
}
QDateTime FilePath::lastModified() const
{
return fileAccess()->lastModified(*this);

View File

@@ -97,6 +97,7 @@ public:
[[nodiscard]] FilePath pathAppended(const QString &str) const;
[[nodiscard]] FilePath stringAppended(const QString &str) const;
[[nodiscard]] std::optional<FilePath> tailRemoved(const QString &str) const;
bool startsWith(const QString &s) const;
bool endsWith(const QString &s) const;
bool contains(const QString &s) const;

View File

@@ -1,6 +1,6 @@
add_qtc_plugin(Python
DEPENDS QmlJS
PLUGIN_DEPENDS Core LanguageClient ProjectExplorer TextEditor
PLUGIN_DEPENDS Core LanguageClient ProjectExplorer TextEditor QtSupport
SOURCES
pipsupport.cpp pipsupport.h
pyside.cpp pyside.h

View File

@@ -13,6 +13,8 @@
#include <projectexplorer/runconfigurationaspects.h>
#include <projectexplorer/target.h>
#include <qtsupport/qtoptionspage.h>
#include <texteditor/textdocument.h>
#include <utils/algorithm.h>
@@ -21,6 +23,9 @@
#include <utils/process.h>
#include <utils/qtcassert.h>
#include <QBoxLayout>
#include <QComboBox>
#include <QDialogButtonBox>
#include <QRegularExpression>
#include <QTextCursor>
@@ -79,7 +84,19 @@ void PySideInstaller::installPyside(const FilePath &python,
const QString &pySide,
TextEditor::TextDocument *document)
{
document->infoBar()->removeInfo(installPySideInfoBarId);
QMap<QVersionNumber, Utils::FilePath> availablePySides;
const std::optional<FilePath> qtInstallDir
= QtSupport::LinkWithQtSupport::linkedQt().tailRemoved("Tools/sdktool/share/qtcreator");
if (qtInstallDir) {
const FilePath qtForPythonDir = qtInstallDir->pathAppended("QtForPython");
for (const FilePath &versionDir : qtForPythonDir.dirEntries(QDir::Dirs | QDir::NoDotAndDotDot)) {
FilePath requirements = versionDir.pathAppended("requirements.txt");
if (requirements.exists())
availablePySides[QVersionNumber::fromString(versionDir.fileName())] = requirements;
}
}
auto install = new PipInstallTask(python);
connect(install, &PipInstallTask::finished, install, &QObject::deleteLater);
@@ -87,7 +104,40 @@ void PySideInstaller::installPyside(const FilePath &python,
if (success)
emit pySideInstalled(python, pySide);
});
if (qtInstallDir->isEmpty()) {
install->setPackages({PipPackage(pySide)});
} else {
QDialog dialog;
dialog.setWindowTitle(Tr::tr("Select PySide version"));
dialog.setLayout(new QVBoxLayout());
dialog.layout()->addWidget(new QLabel(Tr::tr("Select which PySide version to install:")));
QComboBox *pySideSelector = new QComboBox();
pySideSelector->addItem(Tr::tr("Latest PySide from the Python Package Index"));
for (const Utils::FilePath &version : availablePySides) {
const FilePath dir = version.parentDir();
const QString text
= Tr::tr("PySide %1 wheel (%2)").arg(dir.fileName(), dir.toUserOutput());
pySideSelector->addItem(text, version.toVariant());
}
dialog.layout()->addWidget(pySideSelector);
QDialogButtonBox box;
box.setStandardButtons(QDialogButtonBox::Ok | QDialogButtonBox::Cancel);
dialog.layout()->addWidget(&box);
connect(&box, &QDialogButtonBox::accepted, &dialog, &QDialog::accept);
connect(&box, &QDialogButtonBox::rejected, &dialog, &QDialog::reject);
if (dialog.exec() == QDialog::Rejected)
return;
const FilePath requirementsFile = FilePath::fromVariant(pySideSelector->currentData());
if (requirementsFile.isEmpty()) {
install->setPackages({PipPackage(pySide)});
} else {
install->setWorkingDirectory(requirementsFile.parentDir());
install->setRequirements(requirementsFile);
}
}
document->infoBar()->removeInfo(installPySideInfoBarId);
install->run();
}

View File

@@ -9,10 +9,11 @@ QtcPlugin {
Depends { name: "Utils" }
Depends { name: "Core" }
Depends { name: "TextEditor" }
Depends { name: "ProjectExplorer" }
Depends { name: "LanguageClient" }
Depends { name: "LanguageServerProtocol" }
Depends { name: "ProjectExplorer" }
Depends { name: "QtSupport" }
Depends { name: "TextEditor" }
Group {
name: "General"

View File

@@ -15,8 +15,7 @@ Q_DECLARE_METATYPE(QmlPreview::TestFpsHandler)
namespace QmlPreview {
QmlPreviewPluginTest::QmlPreviewPluginTest(QObject *parent) : QObject(parent)
{
}
{ }
static ExtensionSystem::IPlugin *getPlugin()
{

View File

@@ -52,7 +52,8 @@ using namespace Utils;
const char kInstallSettingsKey[] = "Settings/InstallSettings";
namespace QtSupport::Internal {
namespace QtSupport {
namespace Internal {
class QtVersionItem : public TreeItem
{
@@ -869,7 +870,7 @@ void QtOptionsPageWidget::setupLinkWithQtButton()
const bool canLink = canLinkWithQt(&tip);
m_linkWithQtButton->setEnabled(canLink);
m_linkWithQtButton->setToolTip(tip);
connect(m_linkWithQtButton, &QPushButton::clicked, this, &QtOptionsPage::linkWithQt);
connect(m_linkWithQtButton, &QPushButton::clicked, this, &LinkWithQtSupport::linkWithQt);
}
void QtOptionsPageWidget::updateCurrentQtName()
@@ -1080,19 +1081,26 @@ QStringList QtOptionsPage::keywords() const
};
}
bool QtOptionsPage::canLinkWithQt()
} // Internal
bool LinkWithQtSupport::canLinkWithQt()
{
return Internal::canLinkWithQt(nullptr);
}
bool QtOptionsPage::isLinkedWithQt()
bool LinkWithQtSupport::isLinkedWithQt()
{
return currentlyLinkedQtDir(nullptr).has_value();
return Internal::currentlyLinkedQtDir(nullptr).has_value();
}
void QtOptionsPage::linkWithQt()
Utils::FilePath LinkWithQtSupport::linkedQt()
{
QtOptionsPageWidget::linkWithQt();
return Internal::currentlyLinkedQtDir(nullptr).value_or(Utils::FilePath());
}
} // QtSupport::Internal
void LinkWithQtSupport::linkWithQt()
{
Internal::QtOptionsPageWidget::linkWithQt();
}
} // QtSupport

View File

@@ -3,9 +3,12 @@
#pragma once
#include "qtsupport_global.h"
#include <coreplugin/dialogs/ioptionspage.h>
namespace QtSupport::Internal {
namespace QtSupport {
namespace Internal {
class QtOptionsPage final : public Core::IOptionsPage
{
@@ -14,9 +17,15 @@ public:
QStringList keywords() const final;
static bool canLinkWithQt();
static bool isLinkedWithQt();
static void linkWithQt();
};
} // QtSupport::Internal
} // QtSupport
namespace LinkWithQtSupport {
QTSUPPORT_EXPORT bool canLinkWithQt();
QTSUPPORT_EXPORT bool isLinkedWithQt();
QTSUPPORT_EXPORT Utils::FilePath linkedQt();
QTSUPPORT_EXPORT void linkWithQt();
}
} // Internal

View File

@@ -143,7 +143,7 @@ static void askAboutQtInstallation()
{
// if the install settings exist, the Qt Creator installation is (probably) already linked to
// a Qt installation, so don't ask
if (!QtOptionsPage::canLinkWithQt() || QtOptionsPage::isLinkedWithQt()
if (!LinkWithQtSupport::canLinkWithQt() || LinkWithQtSupport::isLinkedWithQt()
|| !ICore::infoBar()->canInfoBeAdded(kLinkWithQtInstallationSetting))
return;
@@ -155,7 +155,7 @@ static void askAboutQtInstallation()
Utils::InfoBarEntry::GlobalSuppression::Enabled);
info.addCustomButton(Tr::tr("Link with Qt"), [] {
ICore::infoBar()->removeInfo(kLinkWithQtInstallationSetting);
QTimer::singleShot(0, ICore::dialogParent(), &QtOptionsPage::linkWithQt);
QTimer::singleShot(0, ICore::dialogParent(), &LinkWithQtSupport::linkWithQt);
});
ICore::infoBar()->addInfo(info);
}