diff --git a/src/plugins/python/installer/pipinstaller.cpp b/src/plugins/python/installer/pipinstaller.cpp index 72c1c937b..2fe9cfa6a 100644 --- a/src/plugins/python/installer/pipinstaller.cpp +++ b/src/plugins/python/installer/pipinstaller.cpp @@ -6,6 +6,7 @@ #include "utils/utils.h" #include "common/util/eventdefinitions.h" +#include "services/option/optionmanager.h" #include "services/terminal/terminalservice.h" #include "services/window/windowelement.h" @@ -65,6 +66,11 @@ void PIPInstaller::install(const QString &python, const InstallInfo &info) << "--target" << Utils::packageInstallPath(python); + const auto &map = OptionManager::getInstance()->getValue(option::CATEGORY_PYTHON, "Interpreter").toMap(); + const auto &pipSrc = map.value("pipSource").toString(); + if (!pipSrc.isEmpty()) + args << "-i" << pipSrc; + uiController.switchContext(TERMINAL_TAB_TEXT); termSrv->executeCommand(info.plugin.isEmpty() ? "PIPInstaller" : info.plugin, python, args, "", QStringList()); } diff --git a/src/plugins/python/python/option/interpreterwidget.cpp b/src/plugins/python/python/option/interpreterwidget.cpp index 797744b4a..c0f0d9f4c 100644 --- a/src/plugins/python/python/option/interpreterwidget.cpp +++ b/src/plugins/python/python/option/interpreterwidget.cpp @@ -3,6 +3,7 @@ // SPDX-License-Identifier: GPL-3.0-or-later #include "interpreterwidget.h" +#include "utils/utils.h" #include "services/option/toolchaindata.h" #include "common/util/custompaths.h" #include "common/toolchain/toolchain.h" @@ -16,6 +17,7 @@ #include #include #include +#include #include #include @@ -31,15 +33,12 @@ class InterpreterModelPrivate }; InterpreterModel::InterpreterModel(QObject *parent) - : QAbstractTableModel(parent) - , d(new InterpreterModelPrivate()) + : QAbstractTableModel(parent), d(new InterpreterModelPrivate()) { - } InterpreterModel::~InterpreterModel() { - } int InterpreterModel::rowCount(const QModelIndex &parent) const @@ -71,12 +70,12 @@ QVariant InterpreterModel::data(const QModelIndex &index, int role) const QString version = d->packageVector.at(index.row()).second; switch (index.column()) { - case ColumnID::kPackage: - return package; - case ColumnID::kVersion: - return version; - default: - return QVariant(); + case ColumnID::kPackage: + return package; + case ColumnID::kVersion: + return version; + default: + return QVariant(); } } @@ -89,16 +88,16 @@ QVariant InterpreterModel::headerData(int section, Qt::Orientation orientation, return QVariant(); switch (section) { - case ColumnID::kPackage: - return tr("Package"); - case ColumnID::kVersion: - return tr("Version"); - default: - return QVariant(); + case ColumnID::kPackage: + return tr("Package"); + case ColumnID::kVersion: + return tr("Version"); + default: + return QVariant(); } } -void InterpreterModel::setCustomData(QVector>& data) +void InterpreterModel::setCustomData(QVector> &data) { beginResetModel(); d->packageVector = data; @@ -110,6 +109,7 @@ class InterpreterWidgetPrivate friend class InterpreterWidget; DComboBox *interpreterComboBox = nullptr; + DLineEdit *pipSourceEdit = nullptr; //todo: modified it later: creating a generic component to manage the toolchain DPushButton *selectCustomInterpreter = nullptr; @@ -124,8 +124,7 @@ class InterpreterWidgetPrivate }; InterpreterWidget::InterpreterWidget(QWidget *parent) - : PageWidget(parent) - , d(new InterpreterWidgetPrivate()) + : PageWidget(parent), d(new InterpreterWidgetPrivate()) { d->toolChainData.reset(new ToolChainData()); QString retMsg; @@ -147,10 +146,9 @@ InterpreterWidget::~InterpreterWidget() void InterpreterWidget::setupUi() { - QVBoxLayout *vLayout = new QVBoxLayout(); - setLayout(vLayout); + QGridLayout *mainLayout = new QGridLayout(this); + mainLayout->setColumnStretch(1, 1); - QHBoxLayout *hLayout = new QHBoxLayout(); DLabel *label = new DLabel(tr("Python Interpreter:")); label->setFixedWidth(180); d->interpreterComboBox = new DComboBox(); @@ -161,10 +159,10 @@ void InterpreterWidget::setupUi() d->selectCustomInterpreter = new DPushButton(tr("Browse"), this); d->removeCustomInterpreter = new DPushButton(tr("Remove"), this); - hLayout->addWidget(label); - hLayout->addWidget(d->interpreterComboBox); - hLayout->addWidget(d->selectCustomInterpreter); - hLayout->addWidget(d->removeCustomInterpreter); + mainLayout->addWidget(label, 0, 0); + mainLayout->addWidget(d->interpreterComboBox, 0, 1); + mainLayout->addWidget(d->selectCustomInterpreter, 0, 2); + mainLayout->addWidget(d->removeCustomInterpreter, 0, 3); auto tableframe = new DFrame(this); auto tablelayout = new QVBoxLayout(tableframe); @@ -186,15 +184,18 @@ void InterpreterWidget::setupUi() d->model = new InterpreterModel(); tableView->setModel(d->model); tableView->setFixedHeight(180); - vLayout->addLayout(hLayout); - vLayout->addWidget(tableframe); + mainLayout->addWidget(tableframe, 1, 0, 1, 4); + + d->pipSourceEdit = new DLineEdit(this); + mainLayout->addWidget(new DLabel(tr("PIP Source:"), this), 2, 0); + mainLayout->addWidget(d->pipSourceEdit, 2, 1, 1, 3); - connect(d->selectCustomInterpreter, &QPushButton::clicked, this, [=](){ + connect(d->selectCustomInterpreter, &QPushButton::clicked, this, [=]() { auto path = DFileDialog::getOpenFileName(this, tr("Select Local Interpreter"), QDir::homePath(), "Python interpreters (python* python3*)"); if (path.isEmpty()) return; auto name = QFileInfo(path).fileName(); - ToolChainData::ToolChainParam param {name, path}; + ToolChainData::ToolChainParam param { name, path }; int index = 0; while (index < d->interpreterComboBox->count()) { auto temp = qvariant_cast(d->interpreterComboBox->itemData(index, Qt::UserRole + 1)); @@ -214,7 +215,7 @@ void InterpreterWidget::setupUi() d->interpreterComboBox->setCurrentIndex(index); d->customInterpreters.append(param); }); - connect(d->removeCustomInterpreter, &QPushButton::clicked, this, [=](){ + connect(d->removeCustomInterpreter, &QPushButton::clicked, this, [=]() { DDialog dialog; dialog.setMessage(tr("Confirm the removal of this interpreter?")); dialog.setWindowTitle(tr("Remove")); @@ -264,31 +265,31 @@ void InterpreterWidget::setPackageData(const QString &text) void InterpreterWidget::findPackages(const QString &cmd) { QProcess process; - connect(&process, static_cast(&QProcess::finished), + connect(&process, static_cast(&QProcess::finished), &process, [&](int exitcode, QProcess::ExitStatus exitStatus) { - if (0 == exitcode && exitStatus == QProcess::ExitStatus::NormalExit) { - QString output = QString(process.readAllStandardOutput()); - - QVector> dataVector; - QStringList list = output.split("\n"); - foreach (QString value, list) { - value = value.trimmed(); - value = value.replace(QRegExp("[\\s]+"), ","); - QStringList sublist = value.split(","); - if (sublist.count() > 1) { - if (sublist.at(0).indexOf("Package") > -1 - || sublist.at(0).indexOf("----") > -1) { - continue; + if (0 == exitcode && exitStatus == QProcess::ExitStatus::NormalExit) { + QString output = QString(process.readAllStandardOutput()); + + QVector> dataVector; + QStringList list = output.split("\n"); + foreach (QString value, list) { + value = value.trimmed(); + value = value.replace(QRegExp("[\\s]+"), ","); + QStringList sublist = value.split(","); + if (sublist.count() > 1) { + if (sublist.at(0).indexOf("Package") > -1 + || sublist.at(0).indexOf("----") > -1) { + continue; + } + dataVector.append(QPair(sublist.at(0).trimmed(), sublist.at(1).trimmed())); + } } - dataVector.append(QPair(sublist.at(0).trimmed(), sublist.at(1).trimmed())); + QMutexLocker lk(&d->mutex); + d->model->setCustomData(dataVector); + } else { + qInfo() << "Error" << exitcode << exitStatus; } - } - QMutexLocker lk(&d->mutex); - d->model->setCustomData(dataVector); - } else { - qInfo() << "Error" << exitcode << exitStatus; - } - }); + }); process.start(cmd); process.waitForFinished(); @@ -348,6 +349,7 @@ bool InterpreterWidget::dataToMap(QMap &map) map.insert("version", currentInterpreter); map.insert("customInterpreters", list); + map.insert("pipSource", d->pipSourceEdit->text()); return true; } @@ -364,6 +366,13 @@ bool InterpreterWidget::mapToData(const QMap &map) d->customInterpreters.append(interpreter); } + if (map.contains("pipSource")) { + const auto &pipSrc = map.value("pipSource").toString(); + d->pipSourceEdit->setText(pipSrc); + } else { + d->pipSourceEdit->setText(Utils::defaultPIPSource()); + } + return true; } @@ -376,4 +385,3 @@ void InterpreterWidget::getUserConfig(QMap &map) { getControlValue(map); } - diff --git a/src/plugins/python/utils/utils.cpp b/src/plugins/python/utils/utils.cpp index 899c24fb3..ac5b87e53 100644 --- a/src/plugins/python/utils/utils.cpp +++ b/src/plugins/python/utils/utils.cpp @@ -82,3 +82,8 @@ QString Utils::packageInstallPath(const QString &python) return QStandardPaths::writableLocation(QStandardPaths::HomeLocation) + "/.unioncode/packages/Python" + version; } + +QString Utils::defaultPIPSource() +{ + return "https://pypi.tuna.tsinghua.edu.cn/simple"; +} diff --git a/src/plugins/python/utils/utils.h b/src/plugins/python/utils/utils.h index 8c0e01583..911686e45 100644 --- a/src/plugins/python/utils/utils.h +++ b/src/plugins/python/utils/utils.h @@ -14,6 +14,7 @@ class Utils static bool createVenv(const QString &python, const QString &venvPath); static QString pythonVersion(const QString &python); static QString packageInstallPath(const QString &python); + static QString defaultPIPSource(); }; #endif // UTILS_H