File indexing completed on 2024-04-28 04:38:24

0001 /*
0002     SPDX-FileCopyrightText: 2010 Andreas Pakulat <apaku@gmx.de>
0003 
0004     SPDX-License-Identifier: GPL-2.0-only OR GPL-3.0-or-later
0005 */
0006 
0007 #include "custombuildsystemconfigwidget.h"
0008 
0009 #include <KConfig>
0010 #include <KConfigGroup>
0011 
0012 #include "ui_custombuildsystemconfigwidget.h"
0013 #include "configconstants.h"
0014 
0015 namespace
0016 {
0017 
0018 QString generateToolGroupName( CustomBuildSystemTool::ActionType type )
0019 {
0020     static const int toolTypeCount = CustomBuildSystemTool::Undefined + 1;
0021     // Static Qt-based objects are discouraged (MSVC-incompatible), so use raw strings
0022     static const char* const toolTypes[toolTypeCount] = {
0023         "Build",
0024         "Configure",
0025         "Install",
0026         "Clean",
0027         "Prune",
0028         "Undefined"
0029     };
0030 
0031     Q_ASSERT( type >= 0 && type < toolTypeCount );
0032     Q_UNUSED( toolTypeCount );
0033 
0034     return ConfigConstants::toolGroupPrefix() + QLatin1String(toolTypes[type]);
0035 }
0036 
0037 }
0038 
0039 CustomBuildSystemConfigWidget::CustomBuildSystemConfigWidget( QWidget* parent )
0040     : QWidget( parent ), ui( new Ui::CustomBuildSystemConfigWidget )
0041 {
0042     ui->setupUi( this );
0043 
0044     // hack taken from kurlrequester, make the buttons a bit less in height so they better match the url-requester
0045     ui->addConfig->setFixedHeight( ui->currentConfig->sizeHint().height() );
0046     ui->removeConfig->setFixedHeight( ui->currentConfig->sizeHint().height() );
0047 
0048     connect( ui->currentConfig, QOverload<int>::of(&QComboBox::activated), this, &CustomBuildSystemConfigWidget::changeCurrentConfig);
0049     connect( ui->configWidget, &ConfigWidget::changed, this, &CustomBuildSystemConfigWidget::configChanged );
0050 
0051     connect( ui->addConfig, &QPushButton::clicked, this, &CustomBuildSystemConfigWidget::addConfig);
0052     connect( ui->removeConfig, &QPushButton::clicked, this, &CustomBuildSystemConfigWidget::removeConfig);
0053     connect( ui->currentConfig, &QComboBox::editTextChanged, this, &CustomBuildSystemConfigWidget::renameCurrentConfig );
0054 
0055     connect( this, &CustomBuildSystemConfigWidget::changed, this, &CustomBuildSystemConfigWidget::verify );
0056 }
0057 
0058 void CustomBuildSystemConfigWidget::loadDefaults()
0059 {
0060 }
0061 
0062 void CustomBuildSystemConfigWidget::loadFrom( KConfig* cfg )
0063 {
0064     ui->currentConfig->clear();
0065     configs.clear();
0066     QStringList groupNameList;
0067     KConfigGroup grp = cfg->group(ConfigConstants::customBuildSystemGroup());
0068     const auto groupList = grp.groupList();
0069     groupNameList.reserve(groupList.size());
0070     configs.reserve(groupList.size());
0071     for (const auto& grpName : groupList) {
0072         KConfigGroup subgrp = grp.group( grpName );
0073         CustomBuildSystemConfig config;
0074 
0075         config.title = subgrp.readEntry(ConfigConstants::configTitleKey(), QString());
0076         config.buildDir = subgrp.readEntry(ConfigConstants::buildDirKey(), QUrl());
0077 
0078         const auto subgrpNames = subgrp.groupList();
0079         for (const QString& subgrpName : subgrpNames) {
0080             if (subgrpName.startsWith(ConfigConstants::toolGroupPrefix())) {
0081                 KConfigGroup toolgrp = subgrp.group( subgrpName );
0082                 CustomBuildSystemTool tool;
0083                 tool.arguments = toolgrp.readEntry(ConfigConstants::toolArguments(), QString());
0084                 tool.executable = toolgrp.readEntry(ConfigConstants::toolExecutable(), QUrl());
0085                 tool.envGrp = toolgrp.readEntry(ConfigConstants::toolEnvironment(), QString());
0086                 tool.enabled = toolgrp.readEntry(ConfigConstants::toolEnabled(), false);
0087                 tool.type = CustomBuildSystemTool::ActionType(toolgrp.readEntry(ConfigConstants::toolType(), 0));
0088                 config.tools[tool.type] = tool;
0089             }
0090         }
0091         configs << config;
0092         ui->currentConfig->addItem( config.title );
0093         groupNameList << grpName;
0094     }
0095     int idx = groupNameList.indexOf(grp.readEntry(ConfigConstants::currentConfigKey(), QString()));
0096     if( !groupNameList.isEmpty() && idx < 0 )
0097         idx = 0;
0098 
0099     ui->currentConfig->setCurrentIndex( idx );
0100     changeCurrentConfig( idx );
0101 }
0102 
0103 void CustomBuildSystemConfigWidget::saveConfig( KConfigGroup& grp, const CustomBuildSystemConfig& c, int index )
0104 {
0105     // Generate group name, access and clear it
0106     KConfigGroup subgrp = grp.group(ConfigConstants::buildConfigPrefix() + QString::number(index));
0107     subgrp.deleteGroup();
0108 
0109     // Write current configuration key, if our group is current
0110     if( ui->currentConfig->currentIndex() == index )
0111         grp.writeEntry(ConfigConstants::currentConfigKey(), subgrp.name());
0112 
0113     subgrp.writeEntry(ConfigConstants::configTitleKey(), c.title);
0114     subgrp.writeEntry<QUrl>(ConfigConstants::buildDirKey(), c.buildDir);
0115     for (const CustomBuildSystemTool& tool : c.tools) {
0116         KConfigGroup toolgrp = subgrp.group( generateToolGroupName( tool.type ) );
0117         toolgrp.writeEntry(ConfigConstants::toolType(), int(tool.type));
0118         toolgrp.writeEntry(ConfigConstants::toolEnvironment(), tool.envGrp);
0119         toolgrp.writeEntry(ConfigConstants::toolEnabled(), tool.enabled);
0120         toolgrp.writeEntry<QUrl>(ConfigConstants::toolExecutable(), tool.executable);
0121         toolgrp.writeEntry(ConfigConstants::toolArguments(), tool.arguments);
0122     }
0123 }
0124 
0125 void CustomBuildSystemConfigWidget::saveTo( KConfig* cfg, KDevelop::IProject* /*project*/ )
0126 {
0127     KConfigGroup subgrp = cfg->group(ConfigConstants::customBuildSystemGroup());
0128     subgrp.deleteGroup();
0129     for( int i = 0; i < ui->currentConfig->count(); i++ ) {
0130         configs[i].title = ui->currentConfig->itemText(i);
0131         saveConfig( subgrp, configs[i], i );
0132     }
0133     cfg->sync();
0134 }
0135 
0136 void CustomBuildSystemConfigWidget::configChanged()
0137 {
0138     int idx = ui->currentConfig->currentIndex();
0139     if( idx >= 0 && idx < configs.count() ) {
0140         configs[idx] = ui->configWidget->config();
0141         emit changed();
0142     }
0143 }
0144 
0145 void CustomBuildSystemConfigWidget::changeCurrentConfig( int idx )
0146 {
0147     if( idx < 0 || idx >= configs.size() ) {
0148         ui->configWidget->clear();
0149         emit changed();
0150         return;
0151     }
0152     CustomBuildSystemConfig cfg = configs.at( idx );
0153     ui->configWidget->loadConfig( cfg );
0154     emit changed();
0155 }
0156 
0157 void CustomBuildSystemConfigWidget::addConfig()
0158 {
0159     CustomBuildSystemConfig c;
0160     configs.append( c );
0161     ui->currentConfig->addItem( c.title );
0162     ui->currentConfig->setCurrentIndex( ui->currentConfig->count() - 1 );
0163     changeCurrentConfig( ui->currentConfig->currentIndex() );
0164 }
0165 
0166 void CustomBuildSystemConfigWidget::removeConfig()
0167 {
0168     int curidx = ui->currentConfig->currentIndex();
0169     Q_ASSERT( curidx < configs.length() && curidx >= 0 );
0170     configs.removeAt( curidx );
0171     ui->currentConfig->removeItem( curidx );
0172 
0173     // Make sure the new index is valid if possible, removing the first index
0174     // would otherwise set the index to -1 and that will cause havoc in changeCurrentConfig
0175     // since it clears the config if a negative index comes in. I'm not sure that is actually
0176     // correct, but well easier to fix and understand here right now and the combobox should
0177     // be dropped ultimately anyway I guess - or at least not be editable anymore.
0178     int newidx = curidx > 0 ? curidx - 1 : 0;
0179     ui->currentConfig->setCurrentIndex( newidx );
0180     changeCurrentConfig( ui->currentConfig->currentIndex() );
0181 }
0182 
0183 void CustomBuildSystemConfigWidget::verify() {
0184     Q_ASSERT( ui->currentConfig->count() == configs.count() );
0185 
0186 
0187     const bool hasAnyConfigurations = (configs.count() != 0);
0188 
0189     Q_ASSERT( !hasAnyConfigurations || (ui->currentConfig->currentIndex() >= 0) );
0190 
0191     ui->configWidget->setEnabled( hasAnyConfigurations );
0192     ui->removeConfig->setEnabled( hasAnyConfigurations );
0193     ui->currentConfig->setEditable( hasAnyConfigurations );
0194 }
0195 
0196 void CustomBuildSystemConfigWidget::renameCurrentConfig(const QString& name) {
0197     int idx = ui->currentConfig->currentIndex();
0198     if( idx >= 0 && idx < configs.count() ) {
0199         ui->currentConfig->setItemText( idx, name );
0200         emit changed();
0201     }
0202 }
0203 
0204 #include "moc_custombuildsystemconfigwidget.cpp"