mirror of
https://bitbucket.org/smil3y/kde-extraapps.git
synced 2025-02-27 12:22:54 +00:00
297 lines
10 KiB
C++
297 lines
10 KiB
C++
/************************************************************************
|
|
* *
|
|
* Copyright 2010 Andreas Pakulat <apaku@gmx.de> *
|
|
* Copyright 2014 Sergey Kalinichev <kalinichev.so.0@gmail.com> *
|
|
* *
|
|
* This program is free software; you can redistribute it and/or modify *
|
|
* it under the terms of the GNU General Public License as published by *
|
|
* the Free Software Foundation; either version 2 of the License, or *
|
|
* (at your option) any later version. *
|
|
* *
|
|
* This program is distributed in the hope that it will be useful, but *
|
|
* WITHOUT ANY WARRANTY; without even the implied warranty of *
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU *
|
|
* General Public License for more details. *
|
|
* *
|
|
* You should have received a copy of the GNU General Public License *
|
|
* along with this program; if not, see <http://www.gnu.org/licenses/>. *
|
|
************************************************************************/
|
|
|
|
#include "projectpathswidget.h"
|
|
|
|
#include <kfiledialog.h>
|
|
#include <kmessagebox.h>
|
|
|
|
#include <QRegExp>
|
|
|
|
#include <util/environmentgrouplist.h>
|
|
#include <interfaces/iproject.h>
|
|
#include <interfaces/icore.h>
|
|
#include <interfaces/iplugincontroller.h>
|
|
|
|
#include "../compilerprovider/compilerprovider.h"
|
|
|
|
#include "compilerswidget.h"
|
|
|
|
#include "ui_projectpathswidget.h"
|
|
#include "ui_batchedit.h"
|
|
#include "projectpathsmodel.h"
|
|
#include "debugarea.h"
|
|
|
|
using namespace KDevelop;
|
|
|
|
ProjectPathsWidget::ProjectPathsWidget( QWidget* parent )
|
|
: QWidget(parent),
|
|
ui(new Ui::ProjectPathsWidget),
|
|
pathsModel(new ProjectPathsModel(this))
|
|
{
|
|
ui->setupUi( this );
|
|
|
|
// Hack to workaround broken setIcon(QIcon) overload in KPushButton, the function does not set the icon at all
|
|
// So need to explicitly use the KIcon overload
|
|
ui->addPath->setIcon(KIcon("list-add"));
|
|
ui->removePath->setIcon(KIcon("list-remove"));
|
|
|
|
// hack taken from kurlrequester, make the buttons a bit less in height so they better match the url-requester
|
|
ui->addPath->setFixedHeight( ui->projectPaths->sizeHint().height() );
|
|
ui->removePath->setFixedHeight( ui->projectPaths->sizeHint().height() );
|
|
|
|
connect( ui->addPath, SIGNAL(clicked(bool)), SLOT(addProjectPath()) );
|
|
connect( ui->removePath, SIGNAL(clicked(bool)), SLOT(deleteProjectPath()) );
|
|
connect( ui->batchEdit, SIGNAL(clicked(bool)), SLOT(batchEdit()) );
|
|
|
|
ui->projectPaths->setModel( pathsModel );
|
|
connect( ui->projectPaths, SIGNAL(currentIndexChanged(int)), SLOT(projectPathSelected(int)) );
|
|
connect( pathsModel, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SIGNAL(changed()) );
|
|
connect( pathsModel, SIGNAL(rowsInserted(QModelIndex,int,int)), SIGNAL(changed()) );
|
|
connect( pathsModel, SIGNAL(rowsRemoved(QModelIndex,int,int)), SIGNAL(changed()) );
|
|
connect( ui->compiler, SIGNAL(activated(QString)), SIGNAL(changed()) );
|
|
|
|
connect( ui->includesWidget, SIGNAL(includesChanged(QStringList)), SLOT(includesChanged(QStringList)) );
|
|
connect( ui->definesWidget, SIGNAL(definesChanged(KDevelop::Defines)), SLOT(definesChanged(KDevelop::Defines)) );
|
|
|
|
connect(ui->configureCompilers, SIGNAL(clicked(bool)), SLOT(configureCompilers()));
|
|
}
|
|
|
|
QList<ConfigEntry> ProjectPathsWidget::paths() const
|
|
{
|
|
return pathsModel->paths();
|
|
}
|
|
|
|
void ProjectPathsWidget::setPaths( const QList<ConfigEntry>& paths )
|
|
{
|
|
bool b = blockSignals( true );
|
|
clear();
|
|
pathsModel->setPaths( paths );
|
|
blockSignals( b );
|
|
ui->projectPaths->setCurrentIndex(0); // at least a project root item is present
|
|
projectPathSelected(0);
|
|
ui->languageParameters->setCurrentIndex(0);
|
|
updateEnablements();
|
|
}
|
|
|
|
void ProjectPathsWidget::definesChanged( const Defines& defines )
|
|
{
|
|
definesAndIncludesDebug() << "defines changed";
|
|
updatePathsModel( QVariant::fromValue(defines), ProjectPathsModel::DefinesDataRole );
|
|
}
|
|
|
|
void ProjectPathsWidget::includesChanged( const QStringList& includes )
|
|
{
|
|
definesAndIncludesDebug() << "includes changed";
|
|
updatePathsModel( includes, ProjectPathsModel::IncludesDataRole );
|
|
}
|
|
|
|
void ProjectPathsWidget::updatePathsModel(const QVariant& newData, int role)
|
|
{
|
|
QModelIndex idx = pathsModel->index( ui->projectPaths->currentIndex(), 0, QModelIndex() );
|
|
if( idx.isValid() ) {
|
|
bool b = pathsModel->setData( idx, newData, role );
|
|
if( b ) {
|
|
emit changed();
|
|
}
|
|
}
|
|
}
|
|
|
|
void ProjectPathsWidget::projectPathSelected( int index )
|
|
{
|
|
if( index < 0 && pathsModel->rowCount() > 0 ) {
|
|
index = 0;
|
|
}
|
|
Q_ASSERT(index >= 0);
|
|
const QModelIndex midx = pathsModel->index( index, 0 );
|
|
ui->includesWidget->setIncludes( pathsModel->data( midx, ProjectPathsModel::IncludesDataRole ).toStringList() );
|
|
ui->definesWidget->setDefines( pathsModel->data( midx, ProjectPathsModel::DefinesDataRole ).value<Defines>() );
|
|
updateEnablements();
|
|
}
|
|
|
|
void ProjectPathsWidget::clear()
|
|
{
|
|
bool sigDisabled = ui->projectPaths->blockSignals( true );
|
|
pathsModel->setPaths( QList<ConfigEntry>() );
|
|
ui->includesWidget->clear();
|
|
ui->definesWidget->clear();
|
|
updateEnablements();
|
|
ui->projectPaths->blockSignals( sigDisabled );
|
|
}
|
|
|
|
void ProjectPathsWidget::addProjectPath()
|
|
{
|
|
KFileDialog dlg(pathsModel->data(pathsModel->index(0, 0), ProjectPathsModel::FullUrlDataRole).value<KUrl>(), "", this);
|
|
dlg.setMode( KFile::LocalOnly | KFile::ExistingOnly | KFile::File | KFile::Directory );
|
|
dlg.exec();
|
|
pathsModel->addPath(dlg.selectedUrl());
|
|
ui->projectPaths->setCurrentIndex(pathsModel->rowCount() - 1);
|
|
updateEnablements();
|
|
}
|
|
|
|
void ProjectPathsWidget::deleteProjectPath()
|
|
{
|
|
const QModelIndex idx = pathsModel->index( ui->projectPaths->currentIndex(), 0 );
|
|
if( KMessageBox::questionYesNo( this, i18n("Are you sure you want to remove the configuration for the path '%1'?", pathsModel->data( idx, Qt::DisplayRole ).toString() ), "Remove Path Configuration" ) == KMessageBox::Yes ) {
|
|
pathsModel->removeRows( ui->projectPaths->currentIndex(), 1 );
|
|
}
|
|
updateEnablements();
|
|
}
|
|
|
|
void ProjectPathsWidget::setProject(KDevelop::IProject* w_project)
|
|
{
|
|
m_project = w_project;
|
|
pathsModel->setProject( m_project );
|
|
ui->includesWidget->setProject( m_project );
|
|
}
|
|
|
|
void ProjectPathsWidget::updateEnablements() {
|
|
// Disable removal of the project root entry which is always first in the list
|
|
ui->removePath->setEnabled( ui->projectPaths->currentIndex() > 0 );
|
|
}
|
|
|
|
void ProjectPathsWidget::batchEdit()
|
|
{
|
|
Ui::BatchEdit be;
|
|
QDialog dialog(this);
|
|
be.setupUi(&dialog);
|
|
|
|
const int index = qMax(ui->projectPaths->currentIndex(), 0);
|
|
|
|
const QModelIndex midx = pathsModel->index(index, 0);
|
|
|
|
if (!midx.isValid()) {
|
|
return;
|
|
}
|
|
|
|
bool includesTab = ui->languageParameters->currentIndex() == 0;
|
|
if (includesTab) {
|
|
auto includes = pathsModel->data(midx, ProjectPathsModel::IncludesDataRole).toStringList();
|
|
be.textEdit->setPlainText(includes.join("\n"));
|
|
|
|
dialog.setWindowTitle(i18n("Edit include directories/files"));
|
|
} else {
|
|
auto defines = pathsModel->data(midx, ProjectPathsModel::DefinesDataRole).value<Defines>();
|
|
|
|
for (auto it = defines.constBegin(); it != defines.constEnd(); it++) {
|
|
be.textEdit->append(it.key() + "=" + it.value());
|
|
}
|
|
|
|
dialog.setWindowTitle(i18n("Edit defined macros"));
|
|
}
|
|
|
|
if (dialog.exec() != QDialog::Accepted) {
|
|
return;
|
|
}
|
|
|
|
if (includesTab) {
|
|
auto includes = be.textEdit->toPlainText().split('\n', QString::SkipEmptyParts);
|
|
for (auto& s : includes) {
|
|
s = s.trimmed();
|
|
}
|
|
|
|
pathsModel->setData(midx, includes, ProjectPathsModel::IncludesDataRole);
|
|
} else {
|
|
auto list = be.textEdit->toPlainText().split('\n', QString::SkipEmptyParts);
|
|
Defines defines;
|
|
|
|
for (auto& d : list) {
|
|
//This matches: a=b, a=, a
|
|
QRegExp r("^([^=]+)(=(.*))?$");
|
|
|
|
if (!r.exactMatch(d)) {
|
|
continue;
|
|
}
|
|
defines[r.cap(1).trimmed()] = r.cap(3).trimmed();
|
|
}
|
|
|
|
pathsModel->setData(midx, QVariant::fromValue(defines), ProjectPathsModel::DefinesDataRole);
|
|
}
|
|
|
|
projectPathSelected(index);
|
|
}
|
|
|
|
void ProjectPathsWidget::setCurrentCompiler(const QString& name)
|
|
{
|
|
for (int i = 0 ; i < ui->compiler->count(); ++i) {
|
|
if(ui->compiler->itemText(i) == name)
|
|
{
|
|
ui->compiler->setCurrentIndex(i);
|
|
}
|
|
}
|
|
}
|
|
|
|
CompilerPointer ProjectPathsWidget::currentCompiler() const
|
|
{
|
|
return ui->compiler->itemData(ui->compiler->currentIndex()).value<CompilerPointer>();
|
|
}
|
|
|
|
void ProjectPathsWidget::setCompilers(const QVector<CompilerPointer>& compilers)
|
|
{
|
|
ui->compiler->clear();
|
|
for (int i = 0 ; i < compilers.count(); ++i) {
|
|
Q_ASSERT(compilers[i]);
|
|
if (!compilers[i]) {
|
|
continue;
|
|
}
|
|
ui->compiler->addItem(compilers[i]->name());
|
|
QVariant val; val.setValue(compilers[i]);
|
|
ui->compiler->setItemData(i, val);
|
|
}
|
|
|
|
m_compilers = compilers;
|
|
}
|
|
|
|
void ProjectPathsWidget::configureCompilers()
|
|
{
|
|
CompilersWidget cw;
|
|
cw.setCompilers(m_compilers);
|
|
if (cw.exec() != QDialog::Accepted) {
|
|
return;
|
|
}
|
|
|
|
auto settings = SettingsManager::globalInstance();
|
|
auto provider = settings->provider();
|
|
auto compilers = provider->compilers();
|
|
|
|
for (auto c: cw.compilers()) {
|
|
if (!compilers.contains(c)) {
|
|
provider->registerCompiler(c);
|
|
}
|
|
}
|
|
|
|
compilers = provider->compilers();
|
|
for (auto c: compilers) {
|
|
if (!cw.compilers().contains(c)) {
|
|
provider->unregisterCompiler(c);
|
|
}
|
|
}
|
|
|
|
setCompilers(provider->compilers());
|
|
setCurrentCompiler(provider->currentCompiler(m_project)->name());
|
|
emit changed();
|
|
}
|
|
|
|
QVector< CompilerPointer > ProjectPathsWidget::compilers() const
|
|
{
|
|
return m_compilers;
|
|
}
|
|
|
|
#include "moc_projectpathswidget.cpp"
|
|
|