File indexing completed on 2024-05-05 16:46:16

0001 /*
0002     SPDX-FileCopyrightText: 2011 Martin Heide <martin.heide@gmx.net>
0003     SPDX-FileCopyrightText: 2011 Julien Desgats <julien.desgats@gmail.com>
0004 
0005     SPDX-License-Identifier: LGPL-2.0-or-later
0006 */
0007 
0008 #include "qmakebuilddirchooser.h"
0009 #include "qmakeconfig.h"
0010 
0011 #include <KLocalizedString>
0012 #include <KMessageWidget>
0013 
0014 #include <QSignalBlocker>
0015 #include <QUrl>
0016 
0017 #include <util/path.h>
0018 
0019 #include <project/helper.h>
0020 #include <project/interfaces/iprojectbuilder.h>
0021 
0022 #include <interfaces/iproject.h>
0023 #include <debug.h>
0024 
0025 using namespace KDevelop;
0026 
0027 QMakeBuildDirChooser::QMakeBuildDirChooser(KDevelop::IProject* project, QWidget* parent)
0028     : QWidget(parent)
0029     , Ui::QMakeBuildDirChooser()
0030     , m_project(project)
0031 {
0032     setupUi(this);
0033 
0034     status->hide();
0035     status->setCloseButtonVisible(false);
0036     status->setMessageType(KMessageWidget::Error);
0037     status->setWordWrap(true);
0038 
0039     kcfg_buildDir->setMode(KFile::Directory | KFile::LocalOnly);
0040     kcfg_installPrefix->setMode(KFile::Directory | KFile::LocalOnly);
0041     kcfg_qmakeExecutable->setMode(KFile::File | KFile::ExistingOnly | KFile::LocalOnly);
0042 
0043     connect(kcfg_qmakeExecutable, &KUrlRequester::textChanged, this, &QMakeBuildDirChooser::changed);
0044     connect(kcfg_buildDir, &KUrlRequester::textChanged, this, &QMakeBuildDirChooser::changed);
0045     connect(kcfg_installPrefix, &KUrlRequester::textChanged, this, &QMakeBuildDirChooser::changed);
0046     connect(kcfg_buildType, QOverload<int>::of(&QComboBox::currentIndexChanged),
0047             this, &QMakeBuildDirChooser::changed);
0048     connect(kcfg_extraArgs, &KLineEdit::textChanged, this, &QMakeBuildDirChooser::changed);
0049 }
0050 
0051 QMakeBuildDirChooser::~QMakeBuildDirChooser()
0052 {
0053     // don't save in destructor; instead, on click of OK-button
0054     // saveConfig();
0055 }
0056 
0057 QString QMakeBuildDirChooser::errorString() const
0058 {
0059     return status->text();
0060 }
0061 
0062 void QMakeBuildDirChooser::setErrorString(const QString& errorString)
0063 {
0064     if (errorString.isEmpty()) {
0065         status->animatedHide();
0066     } else {
0067         status->setText(errorString);
0068         status->animatedShow();
0069     }
0070 }
0071 
0072 IProject* QMakeBuildDirChooser::project() const
0073 {
0074     return m_project;
0075 }
0076 
0077 void QMakeBuildDirChooser::saveConfig()
0078 {
0079     KConfigGroup config = KConfigGroup(m_project->projectConfiguration(), QMakeConfig::CONFIG_GROUP).group(buildDir());
0080     saveConfig(config);
0081 }
0082 
0083 void QMakeBuildDirChooser::saveConfig(KConfigGroup& config)
0084 {
0085     qCDebug(KDEV_QMAKE) << "Writing config for" << buildDir() << "to config" << config.name();
0086 
0087     config.writeEntry(QMakeConfig::QMAKE_EXECUTABLE, qmakeExecutable());
0088     config.writeEntry(QMakeConfig::INSTALL_PREFIX, installPrefix());
0089     config.writeEntry(QMakeConfig::EXTRA_ARGUMENTS, extraArgs());
0090     config.writeEntry(QMakeConfig::BUILD_TYPE, buildType());
0091     config.sync();
0092 }
0093 
0094 void QMakeBuildDirChooser::loadConfig()
0095 {
0096     KConfigGroup cg(m_project->projectConfiguration(), QMakeConfig::CONFIG_GROUP);
0097     loadConfig(cg.readEntry(QMakeConfig::BUILD_FOLDER, KDevelop::proposedBuildFolder(m_project->path()).toLocalFile()));
0098 }
0099 
0100 void QMakeBuildDirChooser::loadConfig(const QString& config)
0101 {
0102     // get correct group
0103     KConfigGroup cg(m_project->projectConfiguration(), QMakeConfig::CONFIG_GROUP);
0104     const KConfigGroup build = cg.group(config);
0105 
0106     {
0107         QSignalBlocker blocker(this); // only emit changed once
0108 
0109         // sets values into fields
0110         setQMakeExecutable(QMakeConfig::qmakeExecutable(m_project));
0111         setBuildDir(config);
0112         setInstallPrefix(build.readEntry(QMakeConfig::INSTALL_PREFIX, QString()));
0113         setExtraArgs(build.readEntry(QMakeConfig::EXTRA_ARGUMENTS, QString()));
0114         setBuildType(build.readEntry(QMakeConfig::BUILD_TYPE, 0));
0115     }
0116     emit changed();
0117 }
0118 
0119 bool QMakeBuildDirChooser::validate(QString* message)
0120 {
0121     bool valid = true;
0122     QString msg;
0123     if (qmakeExecutable().isEmpty()) {
0124         msg = i18n("Please specify path to QMake executable.");
0125         valid = false;
0126     } else {
0127         QFileInfo info(qmakeExecutable());
0128         if (!info.exists()) {
0129             msg = i18n("QMake executable \"%1\" does not exist.", qmakeExecutable());
0130             valid = false;
0131         } else if (!info.isFile()) {
0132             msg = i18n("QMake executable is not a file.");
0133             valid = false;
0134         } else if (!info.isExecutable()) {
0135             msg = i18n("QMake executable is not executable.");
0136             valid = false;
0137         } else {
0138             const QHash<QString, QString> vars = QMakeConfig::queryQMake(info.absoluteFilePath());
0139             if (vars.isEmpty()) {
0140                 msg = i18n("QMake executable cannot be queried for variables.");
0141                 valid = false;
0142             } else if (QMakeConfig::findBasicMkSpec(vars).isEmpty()) {
0143                 msg = i18n("No basic MkSpec file could be found for the given QMake executable.");
0144                 valid = false;
0145             }
0146         }
0147     }
0148 
0149     if (buildDir().isEmpty()) {
0150         msg = i18n("Please specify a build folder.");
0151         valid = false;
0152     }
0153     if (message) {
0154         *message = msg;
0155     }
0156     setErrorString(msg);
0157     qCDebug(KDEV_QMAKE) << "VALID == " << valid;
0158     return valid;
0159 }
0160 
0161 QString QMakeBuildDirChooser::qmakeExecutable() const
0162 {
0163     return kcfg_qmakeExecutable->url().toLocalFile();
0164 }
0165 
0166 QString QMakeBuildDirChooser::buildDir() const
0167 {
0168     return kcfg_buildDir->url().toLocalFile();
0169 }
0170 
0171 QString QMakeBuildDirChooser::installPrefix() const
0172 {
0173     return kcfg_installPrefix->url().toLocalFile();
0174 }
0175 
0176 int QMakeBuildDirChooser::buildType() const
0177 {
0178     return kcfg_buildType->currentIndex();
0179 }
0180 
0181 QString QMakeBuildDirChooser::extraArgs() const
0182 {
0183     return kcfg_extraArgs->text();
0184 }
0185 
0186 void QMakeBuildDirChooser::setQMakeExecutable(const QString& executable)
0187 {
0188     kcfg_qmakeExecutable->setUrl(QUrl::fromLocalFile(executable));
0189 }
0190 
0191 void QMakeBuildDirChooser::setBuildDir(const QString& buildDir)
0192 {
0193     kcfg_buildDir->setUrl(QUrl::fromLocalFile(buildDir));
0194 }
0195 
0196 void QMakeBuildDirChooser::setInstallPrefix(const QString& prefix)
0197 {
0198     kcfg_installPrefix->setUrl(QUrl::fromLocalFile(prefix));
0199 }
0200 
0201 void QMakeBuildDirChooser::setBuildType(int type)
0202 {
0203     kcfg_buildType->setCurrentIndex(type);
0204 }
0205 
0206 void QMakeBuildDirChooser::setExtraArgs(const QString& args)
0207 {
0208     kcfg_extraArgs->setText(args);
0209 }
0210 
0211 #include "moc_qmakebuilddirchooser.cpp"