diff --git a/plugins/externalscript/externalscriptitem.h b/plugins/externalscript/externalscriptitem.h --- a/plugins/externalscript/externalscriptitem.h +++ b/plugins/externalscript/externalscriptitem.h @@ -33,6 +33,16 @@ public: ExternalScriptItem(); + /** + * The key is supposed to be unique inside the model + * @return The key of this script item + */ + QString key() const; + /** + * Sets the label + */ + void setKey( const QString& key ); + /** * @return The command to execute. */ @@ -196,8 +206,9 @@ /** * Saves this item after changes. */ - void save() const; + void update() const; private: + QString m_key; QString m_command; QString m_workingDirectory; SaveMode m_saveMode = SaveNone; diff --git a/plugins/externalscript/externalscriptitem.cpp b/plugins/externalscript/externalscriptitem.cpp --- a/plugins/externalscript/externalscriptitem.cpp +++ b/plugins/externalscript/externalscriptitem.cpp @@ -34,6 +34,17 @@ { } +QString ExternalScriptItem::key() const +{ + return m_key; +} + +void ExternalScriptItem::setKey(const QString& key) +{ + m_key = key; +} + + QString ExternalScriptItem::command() const { return m_command; @@ -144,9 +155,9 @@ m_performReplacements = perform; } -void ExternalScriptItem::save() const +void ExternalScriptItem::update() const { - ExternalScriptPlugin::self()->saveItem( this ); + ExternalScriptPlugin::self()->updateItem( this ); } // kate: indent-mode cstyle; space-indent on; indent-width 2; replace-tabs on; diff --git a/plugins/externalscript/externalscriptplugin.h b/plugins/externalscript/externalscriptplugin.h --- a/plugins/externalscript/externalscriptplugin.h +++ b/plugins/externalscript/externalscriptplugin.h @@ -68,7 +68,7 @@ */ KConfigGroup getConfig() const; - void saveItem(const ExternalScriptItem* item); + void updateItem(const ExternalScriptItem* item); public Q_SLOTS: void executeScriptFromActionData() const; @@ -82,16 +82,23 @@ * Executes the command synchronously and returns the output text (Used by the shell-integration) * */ Q_SCRIPTABLE QString executeCommandSync(const QString& command, const QString& workingDirectory) const; - + private Q_SLOTS: - void rowsRemoved( const QModelIndex& parent, int start, int end ); + void rowsAboutToBeRemoved( const QModelIndex& parent, int start, int end ); void rowsInserted( const QModelIndex& parent, int start, int end ); void executeScriptFromContextMenu() const; private: /// @param row row in the model for the item to save void saveItemForRow( int row ); + /** + * Sets up unique keys for items in the range [start, end] + * @param start start of the range + * @param end end of the range + */ + void setupKeys( int start, int end ); + QStandardItemModel* m_model; QList m_urls; static ExternalScriptPlugin* m_self; diff --git a/plugins/externalscript/externalscriptplugin.cpp b/plugins/externalscript/externalscriptplugin.cpp --- a/plugins/externalscript/externalscriptplugin.cpp +++ b/plugins/externalscript/externalscriptplugin.cpp @@ -49,6 +49,7 @@ #include #include #include +#include K_PLUGIN_FACTORY_WITH_JSON(ExternalScriptFactory, "kdevexternalscript.json", registerPlugin();) @@ -108,6 +109,7 @@ KConfigGroup script = config.group( group ); if ( script.hasKey( "name" ) && script.hasKey( "command" ) ) { ExternalScriptItem* item = new ExternalScriptItem; + item->setKey( script.name() ); item->setText( script.readEntry( "name" ) ); item->setCommand( script.readEntry( "command" )); item->setInputMode( static_cast( script.readEntry( "inputMode", 0u ) ) ); @@ -124,8 +126,8 @@ core()->uiController()->addToolView( i18n( "External Scripts" ), m_factory ); - connect( m_model, &QStandardItemModel::rowsRemoved, - this, &ExternalScriptPlugin::rowsRemoved ); + connect( m_model, &QStandardItemModel::rowsAboutToBeRemoved, + this, &ExternalScriptPlugin::rowsAboutToBeRemoved ); connect( m_model, &QStandardItemModel::rowsInserted, this, &ExternalScriptPlugin::rowsInserted ); @@ -335,27 +337,32 @@ void ExternalScriptPlugin::rowsInserted( const QModelIndex& /*parent*/, int start, int end ) { - for ( int i = start; i <= end; ++i ) { - saveItemForRow( i ); + setupKeys( start, end ); + for ( int row = start; row <= end; ++row ) { + saveItemForRow( row ); } } -void ExternalScriptPlugin::rowsRemoved( const QModelIndex& /*parent*/, int start, int end ) +void ExternalScriptPlugin::rowsAboutToBeRemoved( const QModelIndex& /*parent*/, int start, int end ) { KConfigGroup config = getConfig(); - for ( int i = start; i <= end; ++i ) { - KConfigGroup child = config.group( QStringLiteral("script %1").arg(i) ); + for ( int row = start; row <= end; ++row ) { + const ExternalScriptItem* const item = static_cast( m_model->item( row ) ); + KConfigGroup child = config.group( item->key() ); qCDebug(PLUGIN_EXTERNALSCRIPT) << "removing config group:" << child.name(); child.deleteGroup(); } config.sync(); } -void ExternalScriptPlugin::saveItem( const ExternalScriptItem* item ) +void ExternalScriptPlugin::updateItem( const ExternalScriptItem* item ) { const QModelIndex index = m_model->indexFromItem( item ); Q_ASSERT( index.isValid() ); - saveItemForRow( index.row() ); + + getConfig().group( item->key() ).deleteGroup(); // delete the previous group + setupKeys( index.row(), index.row() ); + saveItemForRow( index.row() ); // save the new group } void ExternalScriptPlugin::saveItemForRow( int row ) @@ -367,7 +374,7 @@ Q_ASSERT( item ); qCDebug(PLUGIN_EXTERNALSCRIPT) << "save extern script:" << item << idx; - KConfigGroup config = getConfig().group( QStringLiteral("script %1").arg( row ) ); + KConfigGroup config = getConfig().group( item->key() ); config.writeEntry( "name", item->text() ); config.writeEntry( "command", item->command() ); config.writeEntry( "inputMode", (uint) item->inputMode() ); @@ -380,6 +387,33 @@ config.sync(); } +void ExternalScriptPlugin::setupKeys(int start, int end) +{ + QSet keySet; + for ( int row = 0; row < m_model->rowCount(); ++row ) { + if (row == start) { + row = end; + } else { + const ExternalScriptItem* const item = static_cast( m_model->item( row ) ); + keySet.insert( item->key() ); + } + } + + for ( int row = start; row <= end; ++row ) { + ExternalScriptItem* const item = static_cast( m_model->item( row ) ); + + int maxSuffix = 0; + QString keyCandidate = item->text() + QString::number( maxSuffix ); + for (; keySet.contains( keyCandidate ); ++maxSuffix) { + keyCandidate = item->text() + QString::number( maxSuffix); + } + + qCDebug(PLUGIN_EXTERNALSCRIPT) << "set key" << keyCandidate << "for" << item << item->command(); + item->setKey(keyCandidate); + keySet.insert(keyCandidate); + } +} + #include "externalscriptplugin.moc" // kate: indent-mode cstyle; space-indent on; indent-width 2; replace-tabs on; diff --git a/plugins/externalscript/externalscriptview.cpp b/plugins/externalscript/externalscriptview.cpp --- a/plugins/externalscript/externalscriptview.cpp +++ b/plugins/externalscript/externalscriptview.cpp @@ -173,7 +173,7 @@ KDevelop::ScopedDialog dlg( item, this ); if (dlg->exec() == QDialog::Accepted) { - item->save(); + item->update(); } }