aboutsummaryrefslogtreecommitdiffstats
path: root/src/plugins/python/pythonwizardpage.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/plugins/python/pythonwizardpage.cpp')
-rw-r--r--src/plugins/python/pythonwizardpage.cpp219
1 files changed, 219 insertions, 0 deletions
diff --git a/src/plugins/python/pythonwizardpage.cpp b/src/plugins/python/pythonwizardpage.cpp
new file mode 100644
index 00000000000..bcbca5a7072
--- /dev/null
+++ b/src/plugins/python/pythonwizardpage.cpp
@@ -0,0 +1,219 @@
+// Copyright (C) 2022 The Qt Company Ltd.
+// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only WITH Qt-GPL-exception-1.0
+
+#include "pythonwizardpage.h"
+
+#include "pythonconstants.h"
+#include "pythonsettings.h"
+#include "pythontr.h"
+
+#include <coreplugin/generatedfile.h>
+
+#include <utils/algorithm.h>
+#include <utils/layoutbuilder.h>
+#include <utils/mimeutils.h>
+#include <utils/qtcassert.h>
+
+#include <projectexplorer/project.h>
+#include <projectexplorer/projectmanager.h>
+#include <projectexplorer/target.h>
+
+using namespace ProjectExplorer;
+using namespace Utils;
+
+namespace Python::Internal {
+
+PythonWizardPageFactory::PythonWizardPageFactory()
+{
+ setTypeIdsSuffix("PythonConfiguration");
+}
+
+WizardPage *PythonWizardPageFactory::create(JsonWizard *wizard, Id typeId, const QVariant &data)
+{
+ Q_UNUSED(wizard)
+
+ QTC_ASSERT(canCreate(typeId), return nullptr);
+
+ QList<QPair<QString, QVariant>> pySideAndData;
+ for (const QVariant &item : data.toMap().value("items").toList()) {
+ const QMap<QString, QVariant> map = item.toMap();
+ const QVariant name = map.value("trKey");
+ if (name.isValid())
+ pySideAndData.emplaceBack(QPair<QString, QVariant>{name.toString(), map.value("value")});
+ }
+ bool validIndex = false;
+ int defaultPySide = data.toMap().value("index").toInt(&validIndex);
+ if (!validIndex)
+ defaultPySide = -1;
+ return new PythonWizardPage(pySideAndData, defaultPySide);
+}
+
+static bool validItem(const QVariant &item)
+{
+ QMap<QString, QVariant> map = item.toMap();
+ if (!map.value("trKey").canConvert<QString>())
+ return false;
+ map = map.value("value").toMap();
+ return map.value("PySideVersion").canConvert<QString>();
+}
+
+bool PythonWizardPageFactory::validateData(Id typeId, const QVariant &data, QString *errorMessage)
+{
+ QTC_ASSERT(canCreate(typeId), return false);
+ const QList<QVariant> items = data.toMap().value("items").toList();
+
+ if (items.isEmpty()) {
+ if (errorMessage) {
+ *errorMessage = Tr::tr("'data' of a Python wizard page expects a map with 'items' "
+ "containing a list of objects");
+ }
+ return false;
+ }
+
+ if (!Utils::allOf(items, &validItem)) {
+ if (errorMessage) {
+ *errorMessage = Tr::tr(
+ "An item of Python wizard page data expects a 'trKey' field containing the ui "
+ "visible string for that python version and an field 'value' containing an object "
+ "with a 'PySideVersion' field used for import statements in the python files.");
+ }
+ return false;
+ }
+ return true;
+}
+
+PythonWizardPage::PythonWizardPage(const QList<QPair<QString, QVariant>> &pySideAndData,
+ const int defaultPyside)
+{
+ using namespace Layouting;
+ m_interpreter.setSettingsDialogId(Constants::C_PYTHONOPTIONS_PAGE_ID);
+ connect(PythonSettings::instance(),
+ &PythonSettings::interpretersChanged,
+ this,
+ &PythonWizardPage::updateInterpreters);
+
+ m_pySideVersion.setLabelText(Tr::tr("PySide version"));
+ m_pySideVersion.setDisplayStyle(SelectionAspect::DisplayStyle::ComboBox);
+ for (auto [name, data] : pySideAndData)
+ m_pySideVersion.addOption(SelectionAspect::Option(name, {}, data));
+ if (defaultPyside >= 0)
+ m_pySideVersion.setDefaultValue(defaultPyside);
+
+ m_createVenv.setLabelText(Tr::tr("Create new Virtual Environment"));
+
+ m_venvPath.setLabelText(Tr::tr("Path to virtual environment"));
+ m_venvPath.setEnabler(&m_createVenv);
+ m_venvPath.setExpectedKind(PathChooser::Directory);
+
+ m_stateLabel = new InfoLabel();
+ m_stateLabel->setWordWrap(true);
+ m_stateLabel->setFilled(true);
+ m_stateLabel->setType(InfoLabel::Error);
+ connect(&m_venvPath, &StringAspect::valueChanged, this, &PythonWizardPage::updateStateLabel);
+ connect(&m_createVenv, &BoolAspect::valueChanged, this, &PythonWizardPage::updateStateLabel);
+
+ Grid {
+ m_pySideVersion, br,
+ m_interpreter, br,
+ m_createVenv, br,
+ m_venvPath, br,
+ m_stateLabel, br,
+ noMargin
+ }.attachTo(this);
+}
+
+void PythonWizardPage::initializePage()
+{
+ auto wiz = qobject_cast<JsonWizard *>(wizard());
+ QTC_ASSERT(wiz, return);
+ connect(wiz, &JsonWizard::filesPolished,
+ this, &PythonWizardPage::setupProject,
+ Qt::UniqueConnection);
+
+ const FilePath projectDir = FilePath::fromString(wiz->property("ProjectDirectory").toString());
+ m_createVenv.setValue(!projectDir.isEmpty());
+ if (m_venvPath.filePath().isEmpty())
+ m_venvPath.setFilePath(projectDir.isEmpty() ? FilePath{} : projectDir / "venv");
+
+ updateInterpreters();
+ updateStateLabel();
+}
+
+bool PythonWizardPage::validatePage()
+{
+ if (m_createVenv.value() && !m_venvPath.pathChooser()->isValid())
+ return false;
+ auto wiz = qobject_cast<JsonWizard *>(wizard());
+ const QMap<QString, QVariant> data = m_pySideVersion.itemValue().toMap();
+ for (auto it = data.begin(), end = data.end(); it != end; ++it)
+ wiz->setValue(it.key(), it.value());
+ return true;
+}
+
+void PythonWizardPage::setupProject(const JsonWizard::GeneratorFiles &files)
+{
+ for (const JsonWizard::GeneratorFile &f : files) {
+ if (f.file.attributes() & Core::GeneratedFile::OpenProjectAttribute) {
+ Interpreter interpreter = m_interpreter.currentInterpreter();
+ Project *project = ProjectManager::openProject(Utils::mimeTypeForFile(f.file.filePath()),
+ f.file.filePath().absoluteFilePath());
+ if (m_createVenv.value()) {
+ auto openProjectWithInterpreter = [f](const std::optional<Interpreter> &interpreter) {
+ if (!interpreter)
+ return;
+ Project *project = ProjectManager::projectWithProjectFilePath(f.file.filePath());
+ if (!project)
+ return;
+ if (Target *target = project->activeTarget()) {
+ if (RunConfiguration *rc = target->activeRunConfiguration()) {
+ if (auto interpreters = rc->aspect<InterpreterAspect>())
+ interpreters->setCurrentInterpreter(*interpreter);
+ }
+ }
+ };
+ PythonSettings::createVirtualEnvironment(m_venvPath.filePath(),
+ interpreter,
+ openProjectWithInterpreter,
+ project ? project->displayName()
+ : QString{});
+ }
+
+ if (project) {
+ project->addTargetForDefaultKit();
+ if (Target *target = project->activeTarget()) {
+ if (RunConfiguration *rc = target->activeRunConfiguration()) {
+ if (auto interpreters = rc->aspect<InterpreterAspect>()) {
+ interpreters->setCurrentInterpreter(interpreter);
+ project->saveSettings();
+ }
+ }
+ }
+ delete project;
+ }
+ }
+ }
+}
+
+void PythonWizardPage::updateInterpreters()
+{
+ m_interpreter.setDefaultInterpreter(PythonSettings::defaultInterpreter());
+ m_interpreter.updateInterpreters(PythonSettings::interpreters());
+}
+
+void PythonWizardPage::updateStateLabel()
+{
+ QTC_ASSERT(m_stateLabel, return);
+ if (m_createVenv.value()) {
+ if (PathChooser *pathChooser = m_venvPath.pathChooser()) {
+ if (!pathChooser->isValid()) {
+ m_stateLabel->show();
+ m_stateLabel->setText(pathChooser->errorMessage());
+ return;
+ }
+ }
+ }
+ m_stateLabel->hide();
+}
+
+} // namespace Python::Internal
+