diff --git a/shell/settings/environmentgroupmodel.cpp b/shell/settings/environmentgroupmodel.cpp index 1eb544094..7b10fe439 100644 --- a/shell/settings/environmentgroupmodel.cpp +++ b/shell/settings/environmentgroupmodel.cpp @@ -1,221 +1,242 @@ /* This file is part of KDevelop Copyright 2007 Andreas Pakulat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "environmentgroupmodel.h" + #include #include #include #include namespace KDevelop { EnvironmentGroupModel::EnvironmentGroupModel() : QAbstractTableModel() { } int EnvironmentGroupModel::rowCount( const QModelIndex& parent ) const { if( parent.isValid() ) return 0; if( !m_currentGroup.isEmpty() ) return m_varsByIndex.count(); return 0; } int EnvironmentGroupModel::columnCount( const QModelIndex& parent ) const { if( parent.isValid() ) return 0; return 2; } Qt::ItemFlags EnvironmentGroupModel::flags( const QModelIndex& idx ) const { if( !idx.isValid() || m_currentGroup.isEmpty() ) { return Qt::NoItemFlags ; } return ( Qt::ItemIsSelectable | Qt::ItemIsEditable | Qt::ItemIsEnabled ); } QVariant EnvironmentGroupModel::data( const QModelIndex& idx, int role ) const { if( !idx.isValid() || m_currentGroup.isEmpty() || idx.row() < 0 || idx.row() >= rowCount() || idx.column() < 0 || idx.column() >= columnCount(QModelIndex()) ) { return QVariant(); } const QString variable = m_varsByIndex[idx.row()]; if (role == VariableRole) { return variable; } else if (role == ValueRole) { return variables( m_currentGroup ).value(variable); } else if (role == Qt::DisplayRole || role == Qt::EditRole) { if(idx.column() == VariableColumn) { return variable; } else { return variables( m_currentGroup ).value(variable); } } return QVariant(); } QVariant EnvironmentGroupModel::headerData( int section, Qt::Orientation orientation, int role ) const { if( section < 0 || section >= columnCount(QModelIndex()) || m_currentGroup.isEmpty() || orientation != Qt::Horizontal || role != Qt::DisplayRole ) { return QVariant(); } if( section == VariableColumn ) { return i18n( "Variable" ); } else { return i18n( "Value" ); } } bool EnvironmentGroupModel::setData( const QModelIndex& idx, const QVariant& data, int role ) { if( !idx.isValid() || m_currentGroup.isEmpty() || idx.row() < 0 || idx.row() >= rowCount() || idx.column() < 0 || idx.column() >= columnCount(QModelIndex()) ) { return false; } if (role == Qt::EditRole) { if (idx.column() == VariableColumn) { const QString oldVariable = m_varsByIndex[idx.row()]; const QString value = variables(m_currentGroup).take(oldVariable); const QString newVariable = data.toString(); variables(m_currentGroup).insert(newVariable, value); m_varsByIndex[idx.row()] = newVariable; } else { variables(m_currentGroup).insert(m_varsByIndex[idx.row()], data.toString()); } emit dataChanged(idx, idx); } return true; } QModelIndex EnvironmentGroupModel::addVariable( const QString& var, const QString& value ) { const int pos = m_varsByIndex.indexOf(var); if (pos != -1) { return index(pos, 0, QModelIndex()); // No duplicates } const int insertPos = rowCount(); beginInsertRows( QModelIndex(), insertPos, insertPos ); m_varsByIndex << var; variables( m_currentGroup ).insert( var, value ); endInsertRows(); return index(insertPos, 0, QModelIndex()); } void EnvironmentGroupModel::removeGroup( const QString& grp ) { if( groups().contains( grp ) ) { EnvironmentGroupList::removeGroup( grp ); setCurrentGroup(defaultGroup()); } } void EnvironmentGroupModel::removeVariables(const QStringList& variables) { foreach (const QString& variable, variables) { removeVariable(variable); } } void EnvironmentGroupModel::removeVariable(const QString& variable) { if (m_currentGroup.isEmpty()) return; const int pos = m_varsByIndex.indexOf(variable); if (pos == -1) return; beginRemoveRows(QModelIndex(), pos, pos); m_varsByIndex.removeAt(pos); variables(m_currentGroup).remove(variable); endRemoveRows(); } void EnvironmentGroupModel::setCurrentGroup( const QString& group ) { if( group.isEmpty() ) return; beginResetModel(); m_currentGroup = group; m_varsByIndex.clear(); foreach( const QString &var, variables( m_currentGroup ).keys() ) { m_varsByIndex << var; } endResetModel(); } bool EnvironmentGroupModel::cloneCurrentGroup( const QString& newGroup ) { if( newGroup.isEmpty() || groups().contains( newGroup ) ) { return false; } beginResetModel(); foreach( const QString &key, m_varsByIndex ) { variables( newGroup ).insert( key, variables( m_currentGroup ).value( key ) ); } m_currentGroup = newGroup; endResetModel(); return true; } void EnvironmentGroupModel::changeDefaultGroup( const QString& grp ) { if( !grp.isEmpty() ) setDefaultGroup( grp ); } +void EnvironmentGroupModel::loadEnvironmentFromString(const QString& plainText) +{ + beginResetModel(); + + m_varsByIndex.clear(); + variables(m_currentGroup).clear(); + + const QStringList lines = plainText.split(QLatin1Char('\n'), QString::SkipEmptyParts); + foreach (const auto& line, lines) { + const QString var = line.section('=', 0, 0); + const QString value = line.section('=', 1, -1).trimmed(); + if (!var.isEmpty()) { + m_varsByIndex << var; + variables(m_currentGroup).insert(var, value); + } + } + + endResetModel(); +} + void EnvironmentGroupModel::loadFromConfig( KConfig* cfg ) { loadSettings( cfg ); setCurrentGroup(defaultGroup()); } void EnvironmentGroupModel::saveToConfig( KConfig* cfg ) { saveSettings( cfg ); } } diff --git a/shell/settings/environmentgroupmodel.h b/shell/settings/environmentgroupmodel.h index 2573e7351..831ec7aec 100644 --- a/shell/settings/environmentgroupmodel.h +++ b/shell/settings/environmentgroupmodel.h @@ -1,72 +1,80 @@ /* This file is part of KDevelop Copyright 2007 Andreas Pakulat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #ifndef KDEVPLATFORM_ENVIRONMENTGROUPMODEL_H #define KDEVPLATFORM_ENVIRONMENTGROUPMODEL_H #include #include #include "util/environmentgrouplist.h" class QVariant; class QModelIndex; namespace KDevelop { class EnvironmentGroupModel : public QAbstractTableModel, public EnvironmentGroupList { Q_OBJECT public: enum Role { VariableRole = Qt::UserRole + 1, ValueRole }; enum Column { VariableColumn, ValueColumn }; EnvironmentGroupModel(); int rowCount( const QModelIndex &parent = QModelIndex() ) const override; int columnCount( const QModelIndex &parent = QModelIndex() ) const override; Qt::ItemFlags flags( const QModelIndex& idx ) const override; QVariant data( const QModelIndex& idx, int role = Qt::DisplayRole) const override; QVariant headerData( int section, Qt::Orientation orientation, int role = Qt::DisplayRole) const override; bool setData( const QModelIndex& idx, const QVariant&, int role = Qt::EditRole) override; void setCurrentGroup( const QString& group ); bool cloneCurrentGroup( const QString& newGroup ); + + /** + * Load a set of environment variables from a string. + * + * @p plainText In the form "FOO=1\nBAR=2" + */ + void loadEnvironmentFromString(const QString& plainText); + void loadFromConfig( KConfig* ); void saveToConfig( KConfig* ); QModelIndex addVariable( const QString& var, const QString& value ); void removeVariable(const QString& variable); void removeVariables(const QStringList& variables); void removeGroup( const QString& grp ); void changeDefaultGroup( const QString& grp ); private: QStringList m_varsByIndex; QString m_currentGroup; }; } #endif diff --git a/shell/settings/environmentwidget.cpp b/shell/settings/environmentwidget.cpp index 2e1dfd3ce..59349612e 100644 --- a/shell/settings/environmentwidget.cpp +++ b/shell/settings/environmentwidget.cpp @@ -1,249 +1,241 @@ /* This file is part of KDevelop Copyright 2006 Adam Treat Copyright 2007 Dukju Ahn Copyright 2008 Andreas Pakuat This library is free software; you can redistribute it and/or modify it under the terms of the GNU Library General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This library 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 Library General Public License for more details. You should have received a copy of the GNU Library General Public License along with this library; see the file COPYING.LIB. If not, write to the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include "environmentwidget.h" #include #include #include #include #include #include #include #include #include "environmentgroupmodel.h" #include "placeholderitemproxymodel.h" #include "../debug.h" namespace KDevelop { EnvironmentWidget::EnvironmentWidget( QWidget *parent ) : QWidget( parent ), groupModel( new EnvironmentGroupModel() ), proxyModel( new QSortFilterProxyModel() ) { // setup ui ui.setupUi( this ); ui.variableTable->verticalHeader()->hide(); proxyModel->setSourceModel( groupModel ); PlaceholderItemProxyModel* topProxyModel = new PlaceholderItemProxyModel(this); topProxyModel->setSourceModel(proxyModel); topProxyModel->setColumnHint(0, i18n("Enter variable ...")); connect(topProxyModel, &PlaceholderItemProxyModel::dataInserted, this, &EnvironmentWidget::handleVariableInserted); ui.variableTable->setModel( topProxyModel ); ui.variableTable->horizontalHeader()->setSectionResizeMode( 1, QHeaderView::Stretch ); ui.addgrpBtn->setIcon(QIcon::fromTheme(QStringLiteral("list-add"))); ui.clonegrpBtn->setIcon(QIcon::fromTheme(QStringLiteral("edit-clone"))); ui.removegrpBtn->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); ui.deleteButton->setIcon(QIcon::fromTheme(QStringLiteral("list-remove"))); ui.deleteButton->setShortcut(Qt::Key_Delete); ui.batchModeEditButton->setIcon(QIcon::fromTheme(QStringLiteral("format-list-unordered"))); connect( ui.deleteButton, &QPushButton::clicked, this, &EnvironmentWidget::deleteButtonClicked ); connect( ui.batchModeEditButton, &QPushButton::clicked, this, &EnvironmentWidget::batchModeEditButtonClicked ); connect( ui.clonegrpBtn, &QPushButton::clicked, this, &EnvironmentWidget::cloneGroupClicked ); connect( ui.addgrpBtn, &QPushButton::clicked, this, &EnvironmentWidget::addGroupClicked ); connect( ui.addgrpBtn, &QPushButton::clicked, this, &EnvironmentWidget::changed ); connect( ui.removegrpBtn, &QPushButton::clicked, this, &EnvironmentWidget::removeGroupClicked ); connect( ui.removegrpBtn, &QPushButton::clicked, this, &EnvironmentWidget::changed ); connect( ui.setAsDefaultBtn, &QPushButton::clicked, this, &EnvironmentWidget::setAsDefault ); connect( ui.setAsDefaultBtn, &QPushButton::clicked, this, &EnvironmentWidget::changed ); connect( ui.activeCombo, static_cast(&KComboBox::currentIndexChanged), this, &EnvironmentWidget::activeGroupChanged ); connect( ui.activeCombo, &KComboBox::editTextChanged, this, &EnvironmentWidget::enableButtons); connect( groupModel, &EnvironmentGroupModel::dataChanged, this, &EnvironmentWidget::changed ); connect( groupModel, &EnvironmentGroupModel::rowsRemoved, this, &EnvironmentWidget::changed ); connect( groupModel, &EnvironmentGroupModel::rowsInserted, this, &EnvironmentWidget::changed ); connect( groupModel, &EnvironmentGroupModel::rowsRemoved, this, &EnvironmentWidget::enableDeleteButton ); connect( groupModel, &EnvironmentGroupModel::rowsInserted, this, &EnvironmentWidget::enableDeleteButton ); connect( groupModel, &EnvironmentGroupModel::modelReset, this, &EnvironmentWidget::enableDeleteButton ); } void EnvironmentWidget::setActiveGroup( const QString& group ) { ui.activeCombo->setCurrentItem(group); } void EnvironmentWidget::enableDeleteButton() { ui.deleteButton->setEnabled( groupModel->rowCount() > 0 ); } void EnvironmentWidget::setAsDefault() { groupModel->changeDefaultGroup( ui.activeCombo->currentText() ); enableButtons( ui.activeCombo->currentText() ); emit changed(); } void EnvironmentWidget::loadSettings( KConfig* config ) { qCDebug(SHELL) << "Loading groups from config"; groupModel->loadFromConfig( config ); ui.activeCombo->clear(); QStringList groupList = groupModel->groups(); qCDebug(SHELL) << "Grouplist:" << groupList << "default group:" << groupModel->defaultGroup(); ui.activeCombo->addItems( groupList ); int idx = ui.activeCombo->findText( groupModel->defaultGroup() ); ui.activeCombo->setCurrentIndex( idx ); } void EnvironmentWidget::saveSettings( KConfig* config ) { groupModel->saveToConfig( config ); } void EnvironmentWidget::defaults( KConfig* config ) { loadSettings( config ); } void EnvironmentWidget::deleteButtonClicked() { QModelIndexList selected = ui.variableTable->selectionModel()->selectedRows(); if( selected.isEmpty() ) return; QStringList variables; foreach( const QModelIndex &idx, selected ) { const QString variable = idx.data(EnvironmentGroupModel::VariableRole).toString(); variables << variable; } groupModel->removeVariables(variables); } void EnvironmentWidget::handleVariableInserted(int /*column*/, const QVariant& value) { groupModel->addVariable(value.toString(), QString()); } void EnvironmentWidget::batchModeEditButtonClicked() { QDialog * dialog = new QDialog( this ); dialog->setWindowTitle( i18n( "Batch Edit Mode" ) ); QVBoxLayout *layout = new QVBoxLayout(dialog); QTextEdit *edit = new QTextEdit; edit->setPlaceholderText(QStringLiteral("VARIABLE1=VALUE1\nVARIABLE2=VALUE2")); QString text; for (int i = 0; i < proxyModel->rowCount(); ++i) { const auto variable = proxyModel->index(i, EnvironmentGroupModel::VariableColumn).data().toString(); const auto value = proxyModel->index(i, EnvironmentGroupModel::ValueColumn).data().toString(); text.append(QStringLiteral("%1=%2\n").arg(variable, value)); } edit->setText(text); layout->addWidget( edit ); auto buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok|QDialogButtonBox::Cancel); auto okButton = buttonBox->button(QDialogButtonBox::Ok); okButton->setDefault(true); okButton->setShortcut(Qt::CTRL | Qt::Key_Return); dialog->connect(buttonBox, &QDialogButtonBox::accepted, dialog, &QDialog::accept); dialog->connect(buttonBox, &QDialogButtonBox::rejected, dialog, &QDialog::reject); layout->addWidget(buttonBox); dialog->resize(600, 400); if ( dialog->exec() != QDialog::Accepted ) { return; } - QStringList lines = edit->toPlainText().split( QStringLiteral("\n"), QString::SkipEmptyParts ); - - foreach(const QString &line, lines) { - QString name = line.section('=', 0, 0); - QString value = line.section('=', 1, -1).trimmed(); - if (!name.isEmpty() && !value.isEmpty()) { - groupModel->addVariable( name, value ); - } - } + groupModel->loadEnvironmentFromString(edit->toPlainText()); } void EnvironmentWidget::addGroupClicked() { QString curText = ui.activeCombo->currentText(); if( groupModel->groups().contains( curText ) ) { return; // same group name cannot be added twice. } ui.activeCombo->addItem( curText ); ui.activeCombo->setCurrentItem( curText ); } void EnvironmentWidget::cloneGroupClicked() { QString newGroup = ui.activeCombo->currentText(); if( !groupModel->cloneCurrentGroup( newGroup ) ) { int id = 1; newGroup = i18nc("a copy of the existing environment was created", "%1 (Cloned %2)", newGroup, id); while( !groupModel->cloneCurrentGroup( newGroup.arg( id ) ) ) { ++id; } newGroup = newGroup.arg( id ); } ui.activeCombo->addItem( newGroup ); ui.activeCombo->setCurrentItem( newGroup ); } void EnvironmentWidget::removeGroupClicked() { int idx = ui.activeCombo->currentIndex(); if( idx < 0 || ui.activeCombo->count() == 1 ) { return; } QString curText = ui.activeCombo->currentText(); groupModel->removeGroup( curText ); ui.activeCombo->removeItem( idx ); ui.activeCombo->setCurrentItem( groupModel->defaultGroup() ); } void EnvironmentWidget::activeGroupChanged( int /*idx*/ ) { groupModel->setCurrentGroup( ui.activeCombo->currentText() ); enableButtons( ui.activeCombo->currentText() ); } void EnvironmentWidget::enableButtons( const QString& txt ) { ui.addgrpBtn->setEnabled( !groupModel->groups().contains( txt ) ); ui.removegrpBtn->setEnabled( ( groupModel->groups().contains( txt ) && groupModel->defaultGroup() != txt ) ); ui.setAsDefaultBtn->setEnabled( ( groupModel->groups().contains( txt ) && groupModel->defaultGroup() != txt ) ); } } #include "moc_environmentwidget.cpp"