diff --git a/languages/plugins/custom-definesandincludes/CMakeLists.txt b/languages/plugins/custom-definesandincludes/CMakeLists.txt
index 42c0bc6c8c..909fe08e19 100644
--- a/languages/plugins/custom-definesandincludes/CMakeLists.txt
+++ b/languages/plugins/custom-definesandincludes/CMakeLists.txt
@@ -1,62 +1,59 @@
add_subdirectory(tests)
add_subdirectory(compilerprovider)
add_subdirectory(noprojectincludesanddefines)
set( kdevdefinesandincludesmanager_SRCS
definesandincludesmanager.cpp
debugarea.cpp
kcm_widget/projectpathsmodel.cpp
kcm_widget/definesmodel.cpp
kcm_widget/includesmodel.cpp
kcm_widget/includeswidget.cpp
kcm_widget/defineswidget.cpp
kcm_widget/projectpathswidget.cpp
kcm_widget/definesandincludesconfigpage.cpp
- kcm_widget/compilersmodel.cpp
- kcm_widget/compilerswidget.cpp
kcm_widget/parserwidget.cpp
compilerprovider/icompiler.cpp # TODO: is this really neccessary
)
ki18n_wrap_ui(kdevdefinesandincludesmanager_SRCS
kcm_widget/batchedit.ui
kcm_widget/includeswidget.ui
kcm_widget/defineswidget.ui
kcm_widget/projectpathswidget.ui
- kcm_widget/compilerswidget.ui
kcm_widget/parserwidget.ui
)
kconfig_add_kcfg_files( kdevdefinesandincludesmanager_SRCS kcm_widget/customdefinesandincludes.kcfgc)
kdevplatform_add_plugin(kdevdefinesandincludesmanager JSON kdevdefinesandincludesmanager.json SOURCES ${kdevdefinesandincludesmanager_SRCS})
target_link_libraries( kdevdefinesandincludesmanager LINK_PRIVATE
KDev::Project
KDev::Util
KDev::Language
kdevnoprojectincludesanddefines
kdevcompilerprovider)
option(BUILD_kdev_includepathsconverter "Build utility to modify include paths of a project from command line." ON)
if(BUILD_kdev_includepathsconverter)
add_executable(kdev_includepathsconverter includepathsconverter.cpp)
target_link_libraries(kdev_includepathsconverter LINK_PRIVATE
KDev::Project
kdevcompilerprovider
)
install(TARGETS kdev_includepathsconverter ${INSTALL_TARGETS_DEFAULT_ARGS} )
endif()
install(FILES
idefinesandincludesmanager.h
DESTINATION ${INCLUDE_INSTALL_DIR}/kdevelop/custom-definesandincludes COMPONENT Devel
)
add_library(KDev::DefinesAndIncludesManager ALIAS kdevdefinesandincludesmanager)
target_include_directories(kdevdefinesandincludesmanager INTERFACE
"$"
"$"
)
set_target_properties(kdevdefinesandincludesmanager PROPERTIES
EXPORT_NAME DefinesAndIncludesManager
)
install(TARGETS kdevdefinesandincludesmanager EXPORT KDevelopTargets ${KDE_INSTALL_TARGETS_DEFAULT_ARGS})
diff --git a/languages/plugins/custom-definesandincludes/compilerprovider/CMakeLists.txt b/languages/plugins/custom-definesandincludes/compilerprovider/CMakeLists.txt
index 2782dcd04e..6f26f0b20a 100644
--- a/languages/plugins/custom-definesandincludes/compilerprovider/CMakeLists.txt
+++ b/languages/plugins/custom-definesandincludes/compilerprovider/CMakeLists.txt
@@ -1,28 +1,34 @@
set( compilerprovider_SRCS
compilerprovider.cpp
icompiler.cpp
gcclikecompiler.cpp
msvccompiler.cpp
compilerfactories.cpp
settingsmanager.cpp
../debugarea.cpp
+ widget/compilersmodel.cpp
+ widget/compilerswidget.cpp
)
+ki18n_wrap_ui(compilerprovider_SRCS
+ widget/compilerswidget.ui
+)
+
add_library(kdevcompilerprovider STATIC
${compilerprovider_SRCS})
target_link_libraries( kdevcompilerprovider LINK_PRIVATE
KDev::Project
KDev::Util
KDev::Language )
set_target_properties(kdevcompilerprovider PROPERTIES POSITION_INDEPENDENT_CODE ON)
option(BUILD_kdev_msvcdefinehelper "Build the msvcdefinehelper tool for retrieving msvc standard macro definitions" OFF)
if(BUILD_kdev_msvcdefinehelper)
set(kdevmsvcdefinehelper_SRCS msvcdefinehelper.cpp)
add_executable(kdevmsvcdefinehelper ${kdevmsvcdefinehelper_SRCS})
install(TARGETS kdevmsvcdefinehelper RUNTIME DESTINATION bin
LIBRARY DESTINATION lib)
endif()
add_subdirectory(tests)
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/compilersmodel.cpp b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilersmodel.cpp
similarity index 100%
rename from languages/plugins/custom-definesandincludes/kcm_widget/compilersmodel.cpp
rename to languages/plugins/custom-definesandincludes/compilerprovider/widget/compilersmodel.cpp
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/compilersmodel.h b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilersmodel.h
similarity index 100%
rename from languages/plugins/custom-definesandincludes/kcm_widget/compilersmodel.h
rename to languages/plugins/custom-definesandincludes/compilerprovider/widget/compilersmodel.h
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.cpp b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.cpp
similarity index 82%
rename from languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.cpp
rename to languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.cpp
index aebbf5a72b..38d78225bd 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.cpp
+++ b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.cpp
@@ -1,183 +1,242 @@
/*
* This file is part of KDevelop
*
* Copyright 2014 Sergey Kalinichev
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 .
*
*/
#include "compilerswidget.h"
#include
#include
#include
#include
#include
#include
#include "../ui_compilerswidget.h"
#include "compilersmodel.h"
-#include "debugarea.h"
+#include "../../debugarea.h"
#include "../compilerprovider/settingsmanager.h"
#include "../compilerprovider/compilerprovider.h"
using namespace KDevelop;
CompilersWidget::CompilersWidget(QWidget* parent)
- : QWidget(parent), m_ui(new Ui::CompilersWidget)
+ : ConfigPage(nullptr, nullptr, parent)
+ , m_ui(new Ui::CompilersWidget)
, m_compilersModel(new CompilersModel(this))
{
m_ui->setupUi(this);
m_ui->compilers->setModel(m_compilersModel);
m_ui->compilers->header()->setSectionResizeMode(QHeaderView::Stretch);
m_addMenu = new QMenu(m_ui->addButton);
m_mapper = new QSignalMapper(m_addMenu);
connect(m_mapper, static_cast(&QSignalMapper::mapped), this, &CompilersWidget::addCompiler);
m_addMenu->clear();
auto settings = SettingsManager::globalInstance();
auto provider = settings->provider();
foreach (const auto& factory, provider->compilerFactories()) {
QAction* action = new QAction(m_addMenu);
action->setText(factory->name());
connect(action, &QAction::triggered,
m_mapper, static_cast(&QSignalMapper::map));
m_mapper->setMapping(action, factory->name());
m_addMenu->addAction(action);
}
m_ui->addButton->setMenu(m_addMenu);
connect(m_ui->removeButton, &QPushButton::clicked, this, &CompilersWidget::deleteCompiler);
auto delAction = new QAction( i18n("Delete compiler"), this );
delAction->setShortcut( QKeySequence( "Del" ) );
delAction->setShortcutContext( Qt::WidgetWithChildrenShortcut );
m_ui->compilers->addAction( delAction );
connect( delAction, &QAction::triggered, this, &CompilersWidget::deleteCompiler );
connect(m_ui->compilers->selectionModel(), &QItemSelectionModel::currentChanged, this, &CompilersWidget::compilerSelected);
connect(m_ui->compilerName, &QLineEdit::editingFinished, this, &CompilersWidget::compilerEdited);
connect(m_ui->compilerPath, &QLineEdit::editingFinished, this, &CompilersWidget::compilerEdited);
connect(m_ui->compilerSelector, &QPushButton::clicked, this, &CompilersWidget::selectCompilerPathDialog);
connect(m_compilersModel, &CompilersModel::compilerChanged, this, &CompilersWidget::compilerChanged);
enableItems(false);
}
void CompilersWidget::setCompilers(const QVector< CompilerPointer >& compilers)
{
m_compilersModel->setCompilers(compilers);
}
void CompilersWidget::clear()
{
m_compilersModel->setCompilers({});
}
void CompilersWidget::deleteCompiler()
{
definesAndIncludesDebug() << "Deleting compiler";
auto selectionModel = m_ui->compilers->selectionModel();
foreach (const QModelIndex& row, selectionModel->selectedIndexes()) {
if (row.column() == 1) {
//Don't remove the same compiler twice
continue;
}
if(m_compilersModel->removeRows(row.row(), 1, row.parent())) {
auto selectedCompiler = selectionModel->selectedIndexes();
compilerSelected(selectedCompiler.isEmpty() ? QModelIndex() : selectedCompiler.first());
}
}
+
+ emit changed();
}
void CompilersWidget::addCompiler(const QString& factoryName)
{
auto settings = SettingsManager::globalInstance();
auto provider = settings->provider();
foreach (const auto& factory, provider->compilerFactories()) {
if (factoryName == factory->name()) {
//add compiler without any information, the user will fill the data in later
auto compilerIndex = m_compilersModel->addCompiler(factory->createCompiler(QString(), QString()));
m_ui->compilers->selectionModel()->select(compilerIndex, QItemSelectionModel::Clear | QItemSelectionModel::SelectCurrent | QItemSelectionModel::Rows);
compilerSelected(compilerIndex);
break;
}
}
+
+ emit changed();
}
QVector< CompilerPointer > CompilersWidget::compilers() const
{
return m_compilersModel->compilers();
}
void CompilersWidget::compilerSelected(const QModelIndex& index)
{
auto compiler = index.data(CompilersModel::CompilerDataRole);
if (compiler.value()) {
m_ui->compilerName->setText(compiler.value()->name());
m_ui->compilerPath->setText(compiler.value()->path());
enableItems(true);
} else {
enableItems(false);
}
}
void CompilersWidget::compilerEdited()
{
auto indexes = m_ui->compilers->selectionModel()->selectedIndexes();
Q_ASSERT(!indexes.isEmpty());
auto compiler = indexes.first().data(CompilersModel::CompilerDataRole);
if (!compiler.value()) {
return;
}
compiler.value()->setName(m_ui->compilerName->text());
compiler.value()->setPath(m_ui->compilerPath->text());
m_compilersModel->updateCompiler(m_ui->compilers->selectionModel()->selection());
+
+ emit changed();
}
void CompilersWidget::selectCompilerPathDialog()
{
const QString compilerPath = QFileDialog::getOpenFileName(this, tr("Select path to compiler"));
if (compilerPath.isEmpty())
return;
m_ui->compilerPath->setText(compilerPath);
compilerEdited();
}
void CompilersWidget::enableItems(bool enable)
{
m_ui->compilerName->setEnabled(enable);
m_ui->compilerPath->setEnabled(enable);
m_ui->compilerSelector->setEnabled(enable);
if(!enable) {
m_ui->compilerName->clear();
m_ui->compilerPath->clear();
}
}
+
+void CompilersWidget::reset()
+{
+ auto settings = SettingsManager::globalInstance();
+ setCompilers(settings->provider()->compilers());
+}
+
+void CompilersWidget::apply()
+{
+ auto settings = SettingsManager::globalInstance();
+ auto provider = settings->provider();
+
+ settings->writeUserDefinedCompilers(compilers());
+
+ const auto& providerCompilers = provider->compilers();
+ const auto& widgetCompilers = compilers();
+ for (auto compiler: providerCompilers) {
+ if (!widgetCompilers.contains(compiler)) {
+ provider->unregisterCompiler(compiler);
+ }
+ }
+
+ for (auto compiler: widgetCompilers) {
+ if (!providerCompilers.contains(compiler)) {
+ provider->registerCompiler(compiler);
+ }
+ }
+}
+
+void CompilersWidget::defaults()
+{
+}
+
+QString CompilersWidget::name() const
+{
+ return i18n("Compilers");
+}
+
+QString CompilersWidget::fullName() const
+{
+ return i18n("Configure Compilers");
+}
+
+QIcon CompilersWidget::icon() const
+{
+ return QIcon::fromTheme(QStringLiteral("kdevelop"));
+}
+
+KDevelop::ConfigPage::ConfigPageType CompilersWidget::configPageType() const
+{
+ return ConfigPage::LanguageConfigPage;
+}
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.h b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.h
similarity index 78%
rename from languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.h
rename to languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.h
index 66db39a443..c776b6bfaf 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.h
+++ b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.h
@@ -1,71 +1,83 @@
/*
* This file is part of KDevelop
*
* Copyright 2014 Sergey Kalinichev
*
* 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) version 3 or any later version
* accepted by the membership of KDE e.V. (or its successor approved
* by the membership of KDE e.V.), which shall act as a proxy
* defined in Section 14 of version 3 of the license.
*
* 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 .
*
*/
#ifndef COMPILERWIDGET_H
#define COMPILERWIDGET_H
#include
#include
#include
+#include
+
#include "../compilerprovider/icompiler.h"
namespace Ui
{
class CompilersWidget;
}
class CompilersModel;
class QMenu;
class QSignalMapper;
-class CompilersWidget : public QWidget
+class CompilersWidget : public KDevelop::ConfigPage
{
Q_OBJECT
public:
- CompilersWidget( QWidget* parent = 0 );
- void setCompilers( const QVector& compilers );
+ explicit CompilersWidget(QWidget* parent = 0);
+ void setCompilers(const QVector& compilers);
QVector compilers() const;
void clear();
+ QString name() const override;
+ QString fullName() const override;
+ QIcon icon() const override;
+
+ KDevelop::ConfigPage::ConfigPageType configPageType() const override;
+
+ void apply() override;
+ void reset() override;
+ void defaults() override;
+
private slots:
void deleteCompiler();
void addCompiler(const QString& factoryName);
void compilerSelected(const QModelIndex& index);
void compilerEdited();
void selectCompilerPathDialog();
signals:
void compilerChanged();
private:
void enableItems(bool enable);
Ui::CompilersWidget* m_ui;
CompilersModel* m_compilersModel;
QMenu *m_addMenu;
QSignalMapper *m_mapper;
};
#endif
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.ui b/languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.ui
similarity index 100%
rename from languages/plugins/custom-definesandincludes/kcm_widget/compilerswidget.ui
rename to languages/plugins/custom-definesandincludes/compilerprovider/widget/compilerswidget.ui
diff --git a/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp b/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
index 8a912cc995..ad7d3e1e25 100644
--- a/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
+++ b/languages/plugins/custom-definesandincludes/definesandincludesmanager.cpp
@@ -1,292 +1,303 @@
/*
* This file is part of KDevelop
*
* Copyright 2014 Sergey Kalinichev
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#include "definesandincludesmanager.h"
#include "kcm_widget/definesandincludesconfigpage.h"
#include "compilerprovider/compilerprovider.h"
+#include "compilerprovider/widget/compilerswidget.h"
#include "noprojectincludesanddefines/noprojectincludepathsmanager.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace KDevelop;
namespace
{
///@return: The ConfigEntry, with includes/defines from @p paths for all parent folders of @p item.
static ConfigEntry findConfigForItem(QList paths, const KDevelop::ProjectBaseItem* item)
{
ConfigEntry ret;
const Path itemPath = item->path();
const Path rootDirectory = item->project()->path();
Path closestPath;
std::sort(paths.begin(), paths.end(), [] (const ConfigEntry& lhs, const ConfigEntry& rhs) {
// sort in reverse order to do a bottom-up search
return lhs.path > rhs.path;
});
for (const ConfigEntry & entry : paths) {
Path targetDirectory = rootDirectory;
// note: a dot represents the project root
if (entry.path != ".") {
targetDirectory.addPath(entry.path);
}
if (targetDirectory == itemPath || targetDirectory.isParentOf(itemPath)) {
ret.includes += entry.includes;
for (auto it = entry.defines.constBegin(); it != entry.defines.constEnd(); it++) {
if (!ret.defines.contains(it.key())) {
ret.defines[it.key()] = it.value();
}
}
if (ret.parserArguments.isEmpty() || targetDirectory.segments().size() > closestPath.segments().size()) {
ret.parserArguments = entry.parserArguments;
closestPath = targetDirectory;
}
}
}
ret.includes.removeDuplicates();
Q_ASSERT(!ret.parserArguments.isEmpty());
return ret;
}
void merge(Defines* target, const Defines& source)
{
if (target->isEmpty()) {
*target = source;
return;
}
for (auto it = source.constBegin(); it != source.constEnd(); ++it) {
target->insert(it.key(), it.value());
}
}
}
K_PLUGIN_FACTORY_WITH_JSON(DefinesAndIncludesManagerFactory, "kdevdefinesandincludesmanager.json", registerPlugin(); )
DefinesAndIncludesManager::DefinesAndIncludesManager( QObject* parent, const QVariantList& )
: IPlugin("kdevdefinesandincludesmanager", parent )
, m_settings(SettingsManager::globalInstance())
, m_noProjectIPM(new NoProjectIncludePathsManager())
{
KDEV_USE_EXTENSION_INTERFACE(IDefinesAndIncludesManager);
registerProvider(m_settings->provider());
}
DefinesAndIncludesManager::~DefinesAndIncludesManager() = default;
Defines DefinesAndIncludesManager::defines( ProjectBaseItem* item, Type type ) const
{
Q_ASSERT(QThread::currentThread() == qApp->thread());
if (!item) {
return m_settings->provider()->defines(nullptr);
}
Defines defines;
for (auto provider : m_providers) {
if (provider->type() & type) {
merge(&defines, provider->defines(item));
}
}
if ( type & ProjectSpecific ) {
auto buildManager = item->project()->buildSystemManager();
if ( buildManager ) {
merge(&defines, buildManager->defines(item));
}
}
// Manually set defines have the highest priority and overwrite values of all other types of defines.
if (type & UserDefined) {
auto cfg = item->project()->projectConfiguration().data();
merge(&defines, findConfigForItem(m_settings->readPaths(cfg), item).defines);
}
return defines;
}
Path::List DefinesAndIncludesManager::includes( ProjectBaseItem* item, Type type ) const
{
Q_ASSERT(QThread::currentThread() == qApp->thread());
if (!item) {
return m_settings->provider()->includes(nullptr);
}
Path::List includes;
if (type & UserDefined) {
auto cfg = item->project()->projectConfiguration().data();
includes += KDevelop::toPathList(findConfigForItem(m_settings->readPaths(cfg), item).includes);
}
if ( type & ProjectSpecific ) {
auto buildManager = item->project()->buildSystemManager();
if ( buildManager ) {
includes += buildManager->includeDirectories(item);
}
}
for (auto provider : m_providers) {
if (provider->type() & type) {
includes += provider->includes(item);
}
}
return includes;
}
bool DefinesAndIncludesManager::unregisterProvider(IDefinesAndIncludesManager::Provider* provider)
{
int idx = m_providers.indexOf(provider);
if (idx != -1) {
m_providers.remove(idx);
return true;
}
return false;
}
void DefinesAndIncludesManager::registerProvider(IDefinesAndIncludesManager::Provider* provider)
{
Q_ASSERT(provider);
if (m_providers.contains(provider)) {
return;
}
m_providers.push_back(provider);
}
Defines DefinesAndIncludesManager::defines(const QString&) const
{
return m_settings->provider()->defines(nullptr);
}
Path::List DefinesAndIncludesManager::includes(const QString& path) const
{
return m_settings->provider()->includes(nullptr) + m_noProjectIPM->includes(path);
}
void DefinesAndIncludesManager::openConfigurationDialog(const QString& pathToFile)
{
if (auto project = KDevelop::ICore::self()->projectController()->findProjectForUrl(QUrl::fromLocalFile(pathToFile))) {
KDevelop::ICore::self()->projectController()->configureProject(project);
} else {
m_noProjectIPM->openConfigurationDialog(pathToFile);
}
}
Path::List DefinesAndIncludesManager::includesInBackground(const QString& path) const
{
Path::List includes;
for (auto provider: m_backgroundProviders) {
includes += provider->includesInBackground(path);
}
return includes;
}
Defines DefinesAndIncludesManager::definesInBackground(const QString& path) const
{
QHash defines;
for (auto provider: m_backgroundProviders) {
auto result = provider->definesInBackground(path);
for (auto it = result.constBegin(); it != result.constEnd(); it++) {
defines[it.key()] = it.value();
}
}
return defines;
}
bool DefinesAndIncludesManager::unregisterBackgroundProvider(IDefinesAndIncludesManager::BackgroundProvider* provider)
{
int idx = m_backgroundProviders.indexOf(provider);
if (idx != -1) {
m_backgroundProviders.remove(idx);
return true;
}
return false;
}
void DefinesAndIncludesManager::registerBackgroundProvider(IDefinesAndIncludesManager::BackgroundProvider* provider)
{
Q_ASSERT(provider);
if (m_backgroundProviders.contains(provider)) {
return;
}
m_backgroundProviders.push_back(provider);
}
QString DefinesAndIncludesManager::parserArguments(KDevelop::ProjectBaseItem* item) const
{
if(!item){
return m_settings->defaultParserArguments();
}
Q_ASSERT(QThread::currentThread() == qApp->thread());
auto cfg = item->project()->projectConfiguration().data();
return findConfigForItem(m_settings->readPaths(cfg), item).parserArguments;
}
int DefinesAndIncludesManager::perProjectConfigPages() const
{
return 1;
}
ConfigPage* DefinesAndIncludesManager::perProjectConfigPage(int number, const ProjectConfigOptions& options, QWidget* parent)
{
if (number == 0) {
return new DefinesAndIncludesConfigPage(this, options, parent);
}
return nullptr;
}
+KDevelop::ConfigPage* DefinesAndIncludesManager::configPage(int number, QWidget* parent)
+{
+ return number == 0 ? new CompilersWidget(parent) : nullptr;
+}
+
+int DefinesAndIncludesManager::configPages() const
+{
+ return 1;
+}
+
#include "definesandincludesmanager.moc"
diff --git a/languages/plugins/custom-definesandincludes/definesandincludesmanager.h b/languages/plugins/custom-definesandincludes/definesandincludesmanager.h
index 8c7c92cb13..3e661917e7 100644
--- a/languages/plugins/custom-definesandincludes/definesandincludesmanager.h
+++ b/languages/plugins/custom-definesandincludes/definesandincludesmanager.h
@@ -1,79 +1,82 @@
/*
* This file is part of KDevelop
*
* Copyright 2014 Sergey Kalinichev
*
* 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, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
*/
#ifndef CUSTOMDEFINESANDINCLUDESMANAGER_H
#define CUSTOMDEFINESANDINCLUDESMANAGER_H
#include
#include
#include
#include
#include "idefinesandincludesmanager.h"
#include "compilerprovider/settingsmanager.h"
class CompilerProvider;
class NoProjectIncludePathsManager;
/// @brief: Class for retrieving custom defines and includes.
class DefinesAndIncludesManager : public KDevelop::IPlugin, public KDevelop::IDefinesAndIncludesManager
{
Q_OBJECT
Q_INTERFACES( KDevelop::IDefinesAndIncludesManager )
public:
explicit DefinesAndIncludesManager( QObject* parent, const QVariantList& args = QVariantList() );
~DefinesAndIncludesManager() override;
///@return list of all custom defines for @p item
KDevelop::Defines defines( KDevelop::ProjectBaseItem* item, Type type ) const override;
///@return list of all custom includes for @p item
KDevelop::Path::List includes( KDevelop::ProjectBaseItem* item, Type type ) const override;
KDevelop::Defines defines( const QString& path ) const override;
KDevelop::Path::List includes( const QString& path ) const override;
void registerProvider( Provider* provider ) override;
bool unregisterProvider( Provider* provider ) override;
KDevelop::Path::List includesInBackground( const QString& path ) const override;
KDevelop::Defines definesInBackground(const QString& path) const override;
void registerBackgroundProvider(BackgroundProvider* provider) override;
bool unregisterBackgroundProvider(BackgroundProvider* provider) override;
QString parserArguments(KDevelop::ProjectBaseItem* item) const override;
void openConfigurationDialog( const QString& pathToFile ) override;
int perProjectConfigPages() const override;
KDevelop::ConfigPage* perProjectConfigPage(int number, const KDevelop::ProjectConfigOptions& options,
QWidget* parent) override;
+ KDevelop::ConfigPage* configPage(int number, QWidget *parent) override;
+ int configPages() const override;
+
private:
QVector m_providers;
QVector m_backgroundProviders;
SettingsManager* m_settings;
QScopedPointer m_noProjectIPM;
};
#endif // CUSTOMDEFINESANDINCLUDESMANAGER_H
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/definesandincludesconfigpage.cpp b/languages/plugins/custom-definesandincludes/kcm_widget/definesandincludesconfigpage.cpp
index 1acd778601..b186c13be7 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/definesandincludesconfigpage.cpp
+++ b/languages/plugins/custom-definesandincludes/kcm_widget/definesandincludesconfigpage.cpp
@@ -1,118 +1,99 @@
/************************************************************************
* *
* Copyright 2010 Andreas Pakulat *
* *
* 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 or version 3 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 . *
************************************************************************/
#include
#include
#include
#include
#include "projectpathswidget.h"
#include "customdefinesandincludes.h"
#include "../compilerprovider/compilerprovider.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include "definesandincludesconfigpage.h"
DefinesAndIncludesConfigPage::DefinesAndIncludesConfigPage(KDevelop::IPlugin* plugin, const KDevelop::ProjectConfigOptions& options, QWidget* parent)
: ProjectConfigPage(plugin, options, parent)
{
QVBoxLayout* layout = new QVBoxLayout( this );
configWidget = new ProjectPathsWidget( this );
configWidget->setProject( project() );
connect(configWidget, &ProjectPathsWidget::changed, this, &DefinesAndIncludesConfigPage::changed);
layout->addWidget( configWidget );
}
DefinesAndIncludesConfigPage::~DefinesAndIncludesConfigPage()
{
}
void DefinesAndIncludesConfigPage::loadFrom( KConfig* cfg )
{
configWidget->clear();
auto settings = SettingsManager::globalInstance();
- auto provider = settings->provider();
- configWidget->setCompilers(provider->compilers());
configWidget->setPaths( settings->readPaths( cfg ) );
}
void DefinesAndIncludesConfigPage::saveTo(KConfig* cfg, KDevelop::IProject*)
{
auto settings = SettingsManager::globalInstance();
settings->writePaths( cfg, configWidget->paths() );
- auto provider = settings->provider();
- settings->writeUserDefinedCompilers(configWidget->compilers());
-
- const auto& providerCompilers = provider->compilers();
- const auto& widgetCompilers = configWidget->compilers();
- for (auto compiler: providerCompilers) {
- if (!widgetCompilers.contains(compiler)) {
- provider->unregisterCompiler(compiler);
- }
- }
-
- for (auto compiler: widgetCompilers) {
- if (!providerCompilers.contains(compiler)) {
- provider->registerCompiler(compiler);
- }
- }
-
if ( settings->needToReparseCurrentProject( cfg ) ) {
KDevelop::ICore::self()->projectController()->reparseProject(project(), true);
}
}
void DefinesAndIncludesConfigPage::reset()
{
ProjectConfigPage::reset();
loadFrom(CustomDefinesAndIncludes::self()->config());
}
void DefinesAndIncludesConfigPage::apply()
{
ProjectConfigPage::apply();
saveTo(CustomDefinesAndIncludes::self()->config(), project());
}
QString DefinesAndIncludesConfigPage::name() const
{
return i18n("Language Support");
}
QString DefinesAndIncludesConfigPage::fullName() const
{
return i18n("Configure Language Support");
}
QIcon DefinesAndIncludesConfigPage::icon() const
{
return QIcon::fromTheme("kdevelop");
}
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.cpp b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.cpp
index aec83c3929..86f9ca7493 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.cpp
+++ b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.cpp
@@ -1,327 +1,304 @@
/************************************************************************
* *
* Copyright 2010 Andreas Pakulat *
* Copyright 2014 Sergey Kalinichev *
* *
* 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 . *
************************************************************************/
#include "projectpathswidget.h"
#include
#include
#include
#include
#include
#include
#include
#include
#include "../compilerprovider/compilerprovider.h"
-#include "compilerswidget.h"
-
#include "ui_projectpathswidget.h"
#include "ui_batchedit.h"
#include "projectpathsmodel.h"
#include "debugarea.h"
using namespace KDevelop;
namespace
{
enum PageType {
IncludesPage,
DefinesPage,
- CompilerPage,
ParserArgumentsPage
};
}
ProjectPathsWidget::ProjectPathsWidget( QWidget* parent )
: QWidget(parent),
ui(new Ui::ProjectPathsWidget),
pathsModel(new ProjectPathsModel(this))
{
ui->setupUi( this );
ui->addPath->setIcon(QIcon::fromTheme("list-add"));
ui->removePath->setIcon(QIcon::fromTheme("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, &QPushButton::clicked, this, &ProjectPathsWidget::addProjectPath );
connect( ui->removePath, &QPushButton::clicked, this, &ProjectPathsWidget::deleteProjectPath );
connect( ui->batchEdit, &QPushButton::clicked, this, &ProjectPathsWidget::batchEdit );
ui->projectPaths->setModel( pathsModel );
connect( ui->projectPaths, static_cast(&KComboBox::currentIndexChanged), this, &ProjectPathsWidget::projectPathSelected );
connect( pathsModel, &ProjectPathsModel::dataChanged, this, &ProjectPathsWidget::changed );
connect( pathsModel, &ProjectPathsModel::rowsInserted, this, &ProjectPathsWidget::changed );
connect( pathsModel, &ProjectPathsModel::rowsRemoved, this, &ProjectPathsWidget::changed );
connect( ui->compiler, static_cast(&QComboBox::activated), this, &ProjectPathsWidget::changed );
connect( ui->compiler, static_cast(&QComboBox::activated), this, &ProjectPathsWidget::changeCompilerForPath );
- connect(ui->compilersWidget, &CompilersWidget::compilerChanged, this, &ProjectPathsWidget::changed);
-
connect( ui->includesWidget, static_cast(&IncludesWidget::includesChanged), this, &ProjectPathsWidget::includesChanged );
connect( ui->definesWidget, static_cast(&DefinesWidget::definesChanged), this, &ProjectPathsWidget::definesChanged );
- connect(ui->compilersWidget, &CompilersWidget::compilerChanged,
- this, &ProjectPathsWidget::userDefinedCompilerChanged);
-
connect(ui->languageParameters, &QTabWidget::currentChanged, this, &ProjectPathsWidget::tabChanged);
connect(ui->parserWidget, &ParserWidget::changed, this, &ProjectPathsWidget::parserArgumentsChanged);
+
+ tabChanged(IncludesPage);
}
QList ProjectPathsWidget::paths() const
{
return pathsModel->paths();
}
void ProjectPathsWidget::setPaths( const QList& 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();
+
+ // Set compilers
+ ui->compiler->clear();
+ auto settings = SettingsManager::globalInstance();
+ auto compilers = settings->provider()->compilers();
+ 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);
+ }
}
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::parserArgumentsChanged()
{
updatePathsModel(ui->parserWidget->parserArguments(), ProjectPathsModel::ParserArgumentsRole);
}
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() );
Q_ASSERT(pathsModel->data(midx, ProjectPathsModel::CompilerDataRole).value());
ui->compiler->setCurrentText(pathsModel->data(midx, ProjectPathsModel::CompilerDataRole).value()->name());
ui->parserWidget->setParserArguments(pathsModel->data(midx, ProjectPathsModel::ParserArgumentsRole ).toString());
updateEnablements();
}
void ProjectPathsWidget::clear()
{
bool sigDisabled = ui->projectPaths->blockSignals( true );
pathsModel->setPaths( QList() );
ui->includesWidget->clear();
ui->definesWidget->clear();
updateEnablements();
ui->projectPaths->blockSignals( sigDisabled );
}
void ProjectPathsWidget::addProjectPath()
{
const QUrl directory = pathsModel->data(pathsModel->index(0, 0), ProjectPathsModel::FullUrlDataRole).value();
QFileDialog dlg(this, tr("Select Project Path"), directory.toLocalFile());
dlg.setFileMode(QFileDialog::Directory);
dlg.setOption(QFileDialog::ShowDirsOnly);
dlg.exec();
pathsModel->addPath(dlg.selectedUrls().value(0));
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();
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();
}
-void ProjectPathsWidget::setCompilers(const QVector< CompilerPointer >& compilers, bool updateCompilersModel)
-{
- 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);
- }
-
- if (updateCompilersModel) {
- ui->compilersWidget->setCompilers(compilers);
- }
-}
-
-QVector< CompilerPointer > ProjectPathsWidget::compilers() const
-{
- return ui->compilersWidget->compilers();
-}
-
-void ProjectPathsWidget::userDefinedCompilerChanged()
-{
- //TODO: if some compiler was deleted remove it from the pathsModel too.
- auto current = currentCompiler()->name();
- setCompilers(ui->compilersWidget->compilers(), false);
- setCurrentCompiler(current);
-}
-
void ProjectPathsWidget::tabChanged(int idx)
{
- if (idx == CompilerPage || idx == ParserArgumentsPage) {
+ if (idx == ParserArgumentsPage) {
ui->batchEdit->setVisible(false);
ui->compilerBox->setVisible(true);
} else {
ui->batchEdit->setVisible(true);
ui->compilerBox->setVisible(false);
}
}
void ProjectPathsWidget::changeCompilerForPath()
{
for (int idx = 0; idx < pathsModel->rowCount(); idx++) {
const QModelIndex midx = pathsModel->index(idx, 0);
if (pathsModel->data(midx, Qt::DisplayRole) == ui->projectPaths->currentText()) {
pathsModel->setData(midx, QVariant::fromValue(currentCompiler()), ProjectPathsModel::CompilerDataRole);
break;
}
}
}
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.h b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.h
index 0be0ce06a7..91ed084997 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.h
+++ b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.h
@@ -1,94 +1,88 @@
/************************************************************************
* *
* Copyright 2010 Andreas Pakulat *
* *
* 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 or version 3 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 . *
************************************************************************/
#ifndef KDEVELOP_PROJECTMANAGERS_CUSTOM_BUILDSYSTEM_PROJECTPATHSWIDGET_H
#define KDEVELOP_PROJECTMANAGERS_CUSTOM_BUILDSYSTEM_PROJECTPATHSWIDGET_H
#include
#include
#include "../compilerprovider/icompiler.h"
#include "../compilerprovider/settingsmanager.h"
class KUrlRequester;
namespace Ui
{
class ProjectPathsWidget;
}
namespace KDevelop
{
class IProject;
}
class ProjectPathsModel;
class QItemSelection;
class ProjectPathsWidget : public QWidget
{
Q_OBJECT
public:
ProjectPathsWidget( QWidget* parent = 0 );
void setProject(KDevelop::IProject* w_project);
void setPaths( const QList& );
QList paths() const;
void clear();
- void setCompilers(const QVector& compilers, bool updateCompilersModel = true);
-
- QVector compilers() const;
-
signals:
void changed();
private:
void setCurrentCompiler(const QString& name);
CompilerPointer currentCompiler() const;
private slots:
// Handling of project-path combobox, add and remove buttons
void projectPathSelected( int index );
void addProjectPath();
void deleteProjectPath();
void batchEdit();
void tabChanged(int);
void changeCompilerForPath();
// Forward includes model changes into the pathsModel
void includesChanged( const QStringList& includes );
// Forward defines model changes into the pathsModel
void definesChanged( const KDevelop::Defines& defines );
- void userDefinedCompilerChanged();
-
void parserArgumentsChanged();
private:
Ui::ProjectPathsWidget* ui;
ProjectPathsModel* pathsModel;
KDevelop::IProject* m_project;
// Enables/Disables widgets based on UI state/selection
void updateEnablements();
void updatePathsModel( const QVariant& newData, int role );
};
#endif
diff --git a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.ui b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.ui
index 1ea16a6ade..a66086396e 100644
--- a/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.ui
+++ b/languages/plugins/custom-definesandincludes/kcm_widget/projectpathswidget.ui
@@ -1,313 +1,274 @@
ProjectPathsWidget
0
0
667
621
9
9
9
9
-
Configure which macros and include directories/files will be added to the parser during project parsing:
-
-
Check this if you want the project to be reparsed to apply the changes.
Reparse the project
true
-
Qt::Horizontal
40
20
-
0
0
0
0
-
<html><head/><body><p>Select compiler that will be used to retrieve standard include directories and defined macros.</p></body></html>
Compiler for path
-
<html><head/><body><p>Select compiler that will be used to retrieve standard include directories and defined macros.</p></body></html>
-
Edit multiply includes/defines at the same time.
&Batch Edit...
-
-
-
0
0
-
Add a new sub-project path entry.
-
-
+ ..
-
false
Delete current sub-project path entry.
-
-
+ ..
-
true
0
8
- 3
+ 0
Includes/Imports
0
0
0
0
-
0
8
Defines
0
0
0
0
0
-
0
8
-
-
- Compilers
-
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
-
- 0
-
- -
-
-
-
- 0
- 8
-
-
-
-
-
-
C/C++ parser
-
KComboBox
QComboBox
DefinesWidget
QWidget
kcm_widget/defineswidget.h
IncludesWidget
QWidget
kcm_widget/includeswidget.h
-
- CompilersWidget
- QWidget
- kcm_widget/compilerswidget.h
-
ParserWidget
QWidget
kcm_widget/parserwidget.h
1