kde-extraapps/kdevplatform/shell/launchconfigurationdialog.cpp
2015-07-26 14:23:17 +03:00

1019 lines
36 KiB
C++

/* This file is part of KDevelop
Copyright 2009 Andreas Pakulat <apaku@gmx.de>
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 "launchconfigurationdialog.h"
#include <QtGui/QSplitter>
#include <QtGui/QTreeView>
#include <QtGui/QStackedWidget>
#include <QtGui/QGridLayout>
#include <QtGui/QToolButton>
#include <klocale.h>
#include <klineedit.h>
#include <kcombobox.h>
#include <kdebug.h>
#include <kpushbutton.h>
#include <ktabwidget.h>
#include <kmessagebox.h>
#include <interfaces/launchconfigurationpage.h>
#include <interfaces/iproject.h>
#include <interfaces/iprojectcontroller.h>
#include <interfaces/isession.h>
#include "core.h"
#include "runcontroller.h"
#include "launchconfiguration.h"
#include <interfaces/ilauncher.h>
#include <interfaces/ilaunchmode.h>
#include <interfaces/launchconfigurationtype.h>
#include <QLayout>
#include <QMenu>
#include <QLabel>
namespace KDevelop
{
bool launchConfigGreaterThan(KDevelop::LaunchConfigurationType* a, KDevelop::LaunchConfigurationType* b)
{
return a->name()>b->name();
}
//TODO: Maybe use KPageDialog instead, might make the model stuff easier and the default-size stuff as well
LaunchConfigurationDialog::LaunchConfigurationDialog(QWidget* parent): KDialog(parent), currentPageChanged( false )
{
setButtons( KDialog::Ok | KDialog::Cancel | KDialog::Apply );
setButtonFocus( KDialog::Ok );
setWindowTitle( i18n( "Launch Configurations" ) );
button( KDialog::Apply )->setEnabled( false );
setupUi( mainWidget() );
mainWidget()->layout()->setContentsMargins( 0, 0, 0, 0 );
splitter->setSizes(QList<int>() << 260 << 620);
addConfig->setIcon( KIcon("list-add") );
addConfig->setEnabled( false );
addConfig->setToolTip(i18nc("@info:tooltip", "Add a new launch configuration."));
deleteConfig->setIcon( KIcon("list-remove") );
deleteConfig->setEnabled( false );
deleteConfig->setToolTip(i18nc("@info:tooltip", "Delete selected launch configuration."));
model = new LaunchConfigurationsModel( tree );
tree->setModel( model );
tree->setExpandsOnDoubleClick( true );
tree->setSelectionBehavior( QAbstractItemView::SelectRows );
tree->setSelectionMode( QAbstractItemView::SingleSelection );
tree->setUniformRowHeights( true );
tree->setItemDelegate( new LaunchConfigurationModelDelegate() );
tree->setColumnHidden(1, true);
for(int row=0; row<model->rowCount(); row++) {
tree->setExpanded(model->index(row, 0), true);
}
tree->setContextMenuPolicy(Qt::CustomContextMenu);
connect( tree, SIGNAL(customContextMenuRequested(QPoint)), this, SLOT(doTreeContextMenu(QPoint)) );
connect( deleteConfig, SIGNAL(clicked()), this, SLOT(deleteConfiguration()));
connect( model, SIGNAL(dataChanged(QModelIndex,QModelIndex)), SLOT(modelChanged(QModelIndex,QModelIndex)) );
connect( tree->selectionModel(), SIGNAL(selectionChanged(QItemSelection,QItemSelection)), SLOT(selectionChanged(QItemSelection,QItemSelection)));
QModelIndex idx = model->indexForConfig( Core::self()->runControllerInternal()->defaultLaunch() );
kDebug() << "selecting index:" << idx;
if( !idx.isValid() )
{
for( int i = 0; i < model->rowCount(); i++ )
{
if( model->rowCount( model->index( i, 0, QModelIndex() ) ) > 0 )
{
idx = model->index( 1, 0, model->index( i, 0, QModelIndex() ) );
break;
}
}
if( !idx.isValid() )
{
idx = model->index( 0, 0, QModelIndex() );
}
}
tree->selectionModel()->select( QItemSelection( idx, idx ), QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
tree->selectionModel()->setCurrentIndex( idx, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
// Unfortunately tree->resizeColumnToContents() only looks at the top-level
// items, instead of all open ones. Hence we're calculating it ourselves like
// this:
// Take the selected index, check if it has childs, if so take the first child
// Then count the level by going up, then let the tree calculate the width
// for the selected or its first child index and add indentation*level
//
// If Qt Software ever fixes resizeColumnToContents, the following line
// can be enabled and the rest be removed
// tree->resizeColumnToContents( 0 );
int level = 0;
QModelIndex widthidx = idx;
if( model->rowCount( idx ) > 0 )
{
widthidx = idx.child( 0, 0 );
}
QModelIndex parentidx = widthidx.parent();
while( parentidx.isValid() )
{
level++;
parentidx = parentidx.parent();
}
// make sure the base column width is honored, e.g. when no launch configs exist
tree->resizeColumnToContents(0);
int width = tree->columnWidth( 0 );
while ( widthidx.isValid() )
{
width = qMax( width, level*tree->indentation() + tree->indentation() + tree->sizeHintForIndex( widthidx ).width() );
widthidx = widthidx.parent();
}
tree->setColumnWidth( 0, width );
QMenu* m = new QMenu(this);
QList<LaunchConfigurationType*> types = Core::self()->runController()->launchConfigurationTypes();
qSort(types.begin(), types.end(), launchConfigGreaterThan); //we want it in reverse order
foreach(LaunchConfigurationType* type, types)
{
connect(type, SIGNAL(signalAddLaunchConfiguration(KDevelop::ILaunchConfiguration*)), SLOT(addConfiguration(KDevelop::ILaunchConfiguration*)));
QMenu* suggestionsMenu = type->launcherSuggestions();
if(suggestionsMenu) {
m->addMenu(suggestionsMenu);
}
}
// Simplify menu structure to get rid of 1-entry levels
while (m->actions().count() == 1) {
QMenu* subMenu = m->actions().first()->menu();
if (subMenu && subMenu->isEnabled() && subMenu->actions().count()<5) {
m = subMenu;
} else {
break;
}
}
if(!m->isEmpty()) {
QAction* separator = new QAction(m);
separator->setSeparator(true);
m->insertAction(m->actions().first(), separator);
}
foreach(LaunchConfigurationType* type, types) {
QAction* action = new QAction(type->icon(), type->name(), m);
action->setProperty("configtype", qVariantFromValue<QObject*>(type));
connect(action, SIGNAL(triggered(bool)), SLOT(createEmptyLauncher()));
if(!m->actions().isEmpty())
m->insertAction(m->actions().first(), action);
else
m->addAction(action);
}
addConfig->setMenu(m);
connect(debugger, SIGNAL(currentIndexChanged(int)), SLOT(launchModeChanged(int)));
connect( this, SIGNAL(okClicked()), SLOT(saveConfig()) );
connect( this, SIGNAL(applyClicked()), SLOT(saveConfig()) );
setInitialSize( QSize(qMax(700, sizeHint().width()), qMax(500, sizeHint().height())) );
}
void LaunchConfigurationDialog::doTreeContextMenu(QPoint point)
{
if ( ! tree->selectionModel()->selectedRows().isEmpty() ) {
QModelIndex selected = tree->selectionModel()->selectedRows().first();
if ( selected.parent().isValid() && ! selected.parent().parent().isValid() ) {
// only display the menu if a launch config is clicked
QMenu menu;
QAction* rename = new QAction(KIcon("edit-rename"), i18n("Rename configuration"), &menu);
QAction* delete_ = new QAction(KIcon("edit-delete"), i18n("Delete configuration"), &menu);
connect(rename, SIGNAL(triggered(bool)), this, SLOT(renameSelected()));
connect(delete_, SIGNAL(triggered(bool)), this, SLOT(deleteConfiguration()));
menu.addAction(rename);
menu.addAction(delete_);
menu.exec(tree->mapToGlobal(point));
}
}
}
void LaunchConfigurationDialog::renameSelected()
{
if( !tree->selectionModel()->selectedRows().isEmpty() )
{
QModelIndex parent = tree->selectionModel()->selectedRows().first();
if( parent.parent().isValid() )
{
parent = parent.parent();
}
QModelIndex index = model->index(tree->selectionModel()->selectedRows().first().row(), 0, parent);
tree->edit( index );
}
}
QSize LaunchConfigurationDialog::sizeHint() const
{
QSize s = KDialog::sizeHint();
return s.expandedTo(QSize(880, 520));
}
void LaunchConfigurationDialog::createEmptyLauncher()
{
QAction* action = qobject_cast<QAction*>(sender());
Q_ASSERT(action);
LaunchConfigurationType* type = qobject_cast<LaunchConfigurationType*>(action->property("configtype").value<QObject*>());
Q_ASSERT(type);
IProject* p = model->projectForIndex(tree->currentIndex());
QPair< QString, QString > launcher( type->launchers().at( 0 )->supportedModes().at(0), type->launchers().at( 0 )->id() );
ILaunchConfiguration* l = ICore::self()->runController()->createLaunchConfiguration(type, launcher, p);
addConfiguration(l);
}
void LaunchConfigurationDialog::selectionChanged(QItemSelection selected, QItemSelection deselected )
{
if( !deselected.indexes().isEmpty() )
{
LaunchConfiguration* l = model->configForIndex( deselected.indexes().first() );
if( l )
{
disconnect(l, SIGNAL(nameChanged(LaunchConfiguration*)), this, SLOT(updateNameLabel(LaunchConfiguration*)));
if( currentPageChanged )
{
if( KMessageBox::questionYesNo( this, i18n("Selected Launch Configuration has unsaved changes. Do you want to save it?"), i18n("Unsaved Changes") ) == KMessageBox::Yes )
{
saveConfig( deselected.indexes().first() );
} else {
LaunchConfigPagesContainer* tab = qobject_cast<LaunchConfigPagesContainer*>( stack->currentWidget() );
tab->setLaunchConfiguration( l );
button( KDialog::Apply )->setEnabled( false );
currentPageChanged = false;
}
}
}
}
updateNameLabel(0);
for( int i = 1; i < stack->count(); i++ )
{
QWidget* w = stack->widget(i);
stack->removeWidget(w);
delete w;
}
debugger->clear();
if( !selected.indexes().isEmpty() )
{
QModelIndex idx = selected.indexes().first();
LaunchConfiguration* l = model->configForIndex( idx );
ILaunchMode* lm = model->modeForIndex( idx );
if( l )
{
updateNameLabel( l );
tree->expand( model->indexForConfig( l ) );
connect( l, SIGNAL(nameChanged(LaunchConfiguration*)), SLOT(updateNameLabel(LaunchConfiguration*)) );
if( lm )
{
bool b = debugger->blockSignals(true);
QList<ILauncher*> launchers = l->type()->launchers();
for( QList<ILauncher*>::const_iterator it = launchers.constBegin(); it != launchers.constEnd(); it++ )
{
if( ((*it)->supportedModes().contains( lm->id() ) ) ) {
debugger->addItem( (*it)->name(), (*it)->id() );
}
}
debugger->blockSignals(b);
debugger->setVisible(debugger->count()>0);
debugLabel->setVisible(debugger->count()>0);
QVariant currentLaunchMode = idx.sibling(idx.row(), 1).data(Qt::EditRole);
debugger->setCurrentIndex(debugger->findData(currentLaunchMode));
ILauncher* launcher = l->type()->launcherForId( currentLaunchMode.toString() );
if( launcher )
{
LaunchConfigPagesContainer* tab = launcherWidgets.value( launcher );
if(!tab)
{
QList<KDevelop::LaunchConfigurationPageFactory*> pages = launcher->configPages();
if(!pages.isEmpty()) {
tab = new LaunchConfigPagesContainer( launcher->configPages(), stack );
connect( tab, SIGNAL(changed()), SLOT(pageChanged()) );
stack->addWidget( tab );
}
}
if(tab) {
tab->setLaunchConfiguration( l );
stack->setCurrentWidget( tab );
} else {
QLabel* label = new QLabel(i18nc("%1 is a launcher name",
"No configuration is needed for '%1'",
launcher->name()), stack);
label->setAlignment(Qt::AlignCenter);
QFont font = label->font();
font.setItalic(true);
label->setFont(font);
stack->addWidget(label);
stack->setCurrentWidget(label);
}
updateNameLabel( l );
addConfig->setEnabled( false );
deleteConfig->setEnabled( false );
} else
{
addConfig->setEnabled( false );
deleteConfig->setEnabled( false );
stack->setCurrentIndex( 0 );
}
} else
{
//TODO: enable removal button
LaunchConfigurationType* type = l->type();
LaunchConfigPagesContainer* tab = typeWidgets.value( type );
if( !tab )
{
tab = new LaunchConfigPagesContainer( type->configPages(), stack );
connect( tab, SIGNAL(changed()), SLOT(pageChanged()) );
stack->addWidget( tab );
}
kDebug() << "created pages, setting config up";
tab->setLaunchConfiguration( l );
stack->setCurrentWidget( tab );
addConfig->setEnabled( true );
deleteConfig->setEnabled( true );
debugger->setVisible( false );
debugLabel->setVisible( false );
}
} else
{
addConfig->setEnabled( true );
deleteConfig->setEnabled( false );
stack->setCurrentIndex( 0 );
QLabel* l = new QLabel(i18n("<i>Select a configuration to edit from the left,<br>"
"or click the \"Add New\" button to add a new one.</i>"), stack);
l->setAlignment(Qt::AlignCenter);
stack->addWidget(l);
stack->setCurrentWidget(l);
debugger->setVisible( false );
debugLabel->setVisible( false );
}
} else
{
debugger->setVisible( false );
debugLabel->setVisible( false );
addConfig->setEnabled( false );
deleteConfig->setEnabled( false );
stack->setCurrentIndex( 0 );
}
}
void LaunchConfigurationDialog::saveConfig( const QModelIndex& idx )
{
Q_UNUSED( idx );
LaunchConfigPagesContainer* tab = qobject_cast<LaunchConfigPagesContainer*>( stack->currentWidget() );
if( tab )
{
tab->save();
button( KDialog::Apply )->setEnabled( false );
currentPageChanged = false;
}
}
void LaunchConfigurationDialog::saveConfig()
{
if( !tree->selectionModel()->selectedRows().isEmpty() )
{
saveConfig( tree->selectionModel()->selectedRows().first() );
}
}
void LaunchConfigurationDialog::pageChanged()
{
currentPageChanged = true;
button( KDialog::Apply )->setEnabled( true );
}
void LaunchConfigurationDialog::modelChanged(QModelIndex topLeft, QModelIndex bottomRight)
{
if (tree->selectionModel())
{
QModelIndex index = tree->selectionModel()->selectedRows().first();
if (index.row() >= topLeft.row() && index.row() <= bottomRight.row() && bottomRight.column() == 1)
selectionChanged(tree->selectionModel()->selection(), tree->selectionModel()->selection());
}
}
void LaunchConfigurationDialog::deleteConfiguration()
{
if( !tree->selectionModel()->selectedRows().isEmpty() )
{
model->deleteConfiguration( tree->selectionModel()->selectedRows().first() );
tree->resizeColumnToContents( 0 );
}
}
void LaunchConfigurationDialog::updateNameLabel( LaunchConfiguration* l )
{
if( l )
{
configName->setText( i18n("Editing %2: <b>%1</b>", l->name(), l->type()->name() ) );
} else
{
configName->clear();
}
}
void LaunchConfigurationDialog::createConfiguration()
{
if( !tree->selectionModel()->selectedRows().isEmpty() )
{
QModelIndex idx = tree->selectionModel()->selectedRows().first();
if( idx.parent().isValid() )
{
idx = idx.parent();
}
model->createConfiguration( idx );
QModelIndex newindex = model->index( model->rowCount( idx ) - 1, 0, idx );
tree->selectionModel()->select( newindex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
tree->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
tree->edit( newindex );
tree->resizeColumnToContents( 0 );
}
}
void LaunchConfigurationDialog::addConfiguration(ILaunchConfiguration* _launch)
{
LaunchConfiguration* launch = dynamic_cast<LaunchConfiguration*>(_launch);
Q_ASSERT(launch);
int row = launch->project() ? model->findItemForProject(launch->project())->row : 0;
QModelIndex idx = model->index(row, 0);
model->addConfiguration(launch, idx);
QModelIndex newindex = model->index( model->rowCount( idx ) - 1, 0, idx );
tree->selectionModel()->select( newindex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
tree->selectionModel()->setCurrentIndex( newindex, QItemSelectionModel::ClearAndSelect | QItemSelectionModel::Rows );
tree->edit( newindex );
tree->resizeColumnToContents( 0 );
}
LaunchConfigurationsModel::LaunchConfigurationsModel(QObject* parent): QAbstractItemModel(parent)
{
GenericPageItem* global = new GenericPageItem;
global->text = i18n("Global");
global->row = 0;
topItems << global;
foreach( IProject* p, Core::self()->projectController()->projects() )
{
ProjectItem* t = new ProjectItem;
t->project = p;
t->row = topItems.count();
topItems << t;
}
foreach( LaunchConfiguration* l, Core::self()->runControllerInternal()->launchConfigurationsInternal() )
{
addItemForLaunchConfig( l );
}
}
void LaunchConfigurationsModel::addItemForLaunchConfig( LaunchConfiguration* l )
{
LaunchItem* t = new LaunchItem;
t->launch = l;
TreeItem* parent;
if( l->project() ) {
parent = findItemForProject( l->project() );
} else {
parent = topItems.at(0);
}
t->parent = parent;
t->row = parent->children.count();
parent->children.append( t );
addLaunchModeItemsForLaunchConfig ( t );
}
void LaunchConfigurationsModel::addLaunchModeItemsForLaunchConfig ( LaunchItem* t )
{
QList<TreeItem*> items;
QSet<QString> modes;
foreach( ILauncher* launcher, t->launch->type()->launchers() )
{
foreach( const QString& mode, launcher->supportedModes() )
{
if( !modes.contains( mode ) && launcher->configPages().count() > 0 )
{
modes.insert( mode );
LaunchModeItem* lmi = new LaunchModeItem;
lmi->mode = Core::self()->runController()->launchModeForId( mode );
lmi->parent = t;
lmi->row = t->children.count();
items.append( lmi );
}
}
}
if( !items.isEmpty() )
{
QModelIndex p = indexForConfig( t->launch );
beginInsertRows( p, t->children.count(), t->children.count() + items.count() - 1 );
t->children.append( items );
endInsertRows();
}
}
LaunchConfigurationsModel::ProjectItem* LaunchConfigurationsModel::findItemForProject( IProject* p )
{
foreach( TreeItem* t, topItems )
{
ProjectItem* pi = dynamic_cast<ProjectItem*>( t );
if( pi && pi->project == p )
{
return pi;
}
}
Q_ASSERT(false);
return 0;
}
int LaunchConfigurationsModel::columnCount(const QModelIndex& parent) const
{
Q_UNUSED( parent );
return 2;
}
QVariant LaunchConfigurationsModel::data(const QModelIndex& index, int role) const
{
if( index.isValid() && index.column() >= 0 && index.column() < 2 )
{
TreeItem* t = static_cast<TreeItem*>( index.internalPointer() );
switch( role )
{
case Qt::DisplayRole:
{
LaunchItem* li = dynamic_cast<LaunchItem*>( t );
if( li )
{
if( index.column() == 0 )
{
return li->launch->name();
} else if( index.column() == 1 )
{
return li->launch->type()->name();
}
}
ProjectItem* pi = dynamic_cast<ProjectItem*>( t );
if( pi && index.column() == 0 )
{
return pi->project->name();
}
GenericPageItem* gpi = dynamic_cast<GenericPageItem*>( t );
if( gpi && index.column() == 0 )
{
return gpi->text;
}
LaunchModeItem* lmi = dynamic_cast<LaunchModeItem*>( t );
if( lmi )
{
if( index.column() == 0 )
{
return lmi->mode->name();
} else if( index.column() == 1 )
{
LaunchConfiguration* l = configForIndex( index );
return l->type()->launcherForId( l->launcherForMode( lmi->mode->id() ) )->name();
}
}
break;
}
case Qt::DecorationRole:
{
LaunchItem* li = dynamic_cast<LaunchItem*>( t );
if( index.column() == 0 && li )
{
return li->launch->type()->icon();
}
LaunchModeItem* lmi = dynamic_cast<LaunchModeItem*>( t );
if( lmi && index.column() == 0 )
{
return lmi->mode->icon();
}
if ( index.column() == 0 && !index.parent().isValid() ) {
if (index.row() == 0) {
// global item
return KIcon("folder");
} else {
// project item
return KIcon("folder-development");
}
}
}
case Qt::EditRole:
{
LaunchItem* li = dynamic_cast<LaunchItem*>( t );
if( li )
{
if( index.column() == 0 )
{
return li->launch->name();
} else if ( index.column() == 1 )
{
return li->launch->type()->id();
}
}
LaunchModeItem* lmi = dynamic_cast<LaunchModeItem*>( t );
if( lmi && index.column() == 1 )
{
return configForIndex( index )->launcherForMode( lmi->mode->id() );
}
break;
}
default:
break;
}
}
return QVariant();
}
QModelIndex LaunchConfigurationsModel::index(int row, int column, const QModelIndex& parent) const
{
if( !hasIndex( row, column, parent ) )
return QModelIndex();
TreeItem* tree;
if( !parent.isValid() )
{
tree = topItems.at( row );
} else
{
TreeItem* t = static_cast<TreeItem*>( parent.internalPointer() );
tree = t->children.at( row );
}
if( tree )
{
return createIndex( row, column, tree );
}
return QModelIndex();
}
QModelIndex LaunchConfigurationsModel::parent(const QModelIndex& child) const
{
if( child.isValid() )
{
TreeItem* t = static_cast<TreeItem*>( child.internalPointer() );
if( t->parent )
{
return createIndex( t->parent->row, 0, t->parent );
}
}
return QModelIndex();
}
int LaunchConfigurationsModel::rowCount(const QModelIndex& parent) const
{
if( parent.column() > 0 )
return 0;
if( parent.isValid() )
{
TreeItem* t = static_cast<TreeItem*>( parent.internalPointer() );
return t->children.count();
} else
{
return topItems.count();
}
return 0;
}
QVariant LaunchConfigurationsModel::headerData(int section, Qt::Orientation orientation, int role) const
{
if( orientation == Qt::Horizontal && role == Qt::DisplayRole )
{
if( section == 0 )
{
return i18nc("Name of the Launch Configurations", "Name");
} else if( section == 1 )
{
return i18nc("The type of the Launch Configurations (i.e. Python Application, C++ Application)", "Type");
}
}
return QVariant();
}
Qt::ItemFlags LaunchConfigurationsModel::flags(const QModelIndex& index) const
{
if( index.isValid() && index.column() >= 0
&& index.column() < columnCount( QModelIndex() ) )
{
TreeItem* t = static_cast<TreeItem*>( index.internalPointer() );
if( t && ( dynamic_cast<LaunchItem*>( t ) || ( dynamic_cast<LaunchModeItem*>( t ) && index.column() == 1 ) ) )
{
return Qt::ItemFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable | Qt::ItemIsEditable );
} else if( t )
{
return Qt::ItemFlags( Qt::ItemIsEnabled | Qt::ItemIsSelectable );
}
}
return Qt::NoItemFlags;
}
bool LaunchConfigurationsModel::setData(const QModelIndex& index, const QVariant& value, int role)
{
if( index.isValid() && index.parent().isValid() && role == Qt::EditRole )
{
if( index.row() >= 0 && index.row() < rowCount( index.parent() ) )
{
LaunchItem* t = dynamic_cast<LaunchItem*>( static_cast<TreeItem*>( index.internalPointer() ) );
if( t )
{
if( index.column() == 0 )
{
t->launch->setName( value.toString() );
} else if( index.column() == 1 )
{
if (t->launch->type()->id() != value.toString()) {
t->launch->setType( value.toString() );
QModelIndex p = indexForConfig(t->launch);
kDebug() << data(p);
beginRemoveRows( p, 0, t->children.count() );
qDeleteAll( t->children );
t->children.clear();
endRemoveRows();
addLaunchModeItemsForLaunchConfig( t );
}
}
emit dataChanged(index, index);
return true;
}
LaunchModeItem* lmi = dynamic_cast<LaunchModeItem*>( static_cast<TreeItem*>( index.internalPointer() ) );
if( lmi )
{
if( index.column() == 1 && index.data(Qt::EditRole)!=value)
{
LaunchConfiguration* l = configForIndex( index );
l->setLauncherForMode( lmi->mode->id(), value.toString() );
emit dataChanged(index, index);
return true;
}
}
}
}
return false;
}
ILaunchMode* LaunchConfigurationsModel::modeForIndex( const QModelIndex& idx ) const
{
if( idx.isValid() )
{
LaunchModeItem* item = dynamic_cast<LaunchModeItem*>( static_cast<TreeItem*>( idx.internalPointer() ) );
if( item )
{
return item->mode;
}
}
return 0;
}
LaunchConfiguration* LaunchConfigurationsModel::configForIndex(const QModelIndex& idx ) const
{
if( idx.isValid() )
{
LaunchItem* item = dynamic_cast<LaunchItem*>( static_cast<TreeItem*>( idx.internalPointer() ) );
if( item )
{
return item->launch;
}
LaunchModeItem* lmitem = dynamic_cast<LaunchModeItem*>( static_cast<TreeItem*>( idx.internalPointer() ) );
if( lmitem )
{
return dynamic_cast<LaunchItem*>( lmitem->parent )->launch;
}
}
return 0;
}
QModelIndex LaunchConfigurationsModel::indexForConfig( LaunchConfiguration* l ) const
{
if( l )
{
TreeItem* tparent = topItems.at( 0 );
if( l->project() )
{
foreach( TreeItem* t, topItems )
{
ProjectItem* pi = dynamic_cast<ProjectItem*>( t );
if( pi && pi->project == l->project() )
{
tparent = t;
break;
}
}
}
if( tparent )
{
foreach( TreeItem* c, tparent->children )
{
LaunchItem* li = dynamic_cast<LaunchItem*>( c );
if( li->launch && li->launch == l )
{
return index( c->row, 0, index( tparent->row, 0, QModelIndex() ) );
}
}
}
}
return QModelIndex();
}
void LaunchConfigurationsModel::deleteConfiguration( const QModelIndex& index )
{
LaunchItem* t = dynamic_cast<LaunchItem*>( static_cast<TreeItem*>( index.internalPointer() ) );
if( !t )
return;
beginRemoveRows( parent( index ), index.row(), index.row() );
t->parent->children.removeAll( t );
Core::self()->runControllerInternal()->removeLaunchConfiguration( t->launch );
endRemoveRows();
}
void LaunchConfigurationsModel::createConfiguration(const QModelIndex& parent )
{
if(!Core::self()->runController()->launchConfigurationTypes().isEmpty())
{
TreeItem* t = static_cast<TreeItem*>( parent.internalPointer() );
ProjectItem* ti = dynamic_cast<ProjectItem*>( t );
LaunchConfigurationType* type = Core::self()->runController()->launchConfigurationTypes().at(0);
QPair<QString,QString> launcher = qMakePair( type->launchers().at( 0 )->supportedModes().at(0), type->launchers().at( 0 )->id() );
IProject* p = ( ti ? ti->project : 0 );
ILaunchConfiguration* l = Core::self()->runController()->createLaunchConfiguration( type, launcher, p );
addConfiguration(l, parent);
}
}
void LaunchConfigurationsModel::addConfiguration(ILaunchConfiguration* l, const QModelIndex& parent)
{
if( parent.isValid() )
{
beginInsertRows( parent, rowCount( parent ), rowCount( parent ) );
addItemForLaunchConfig( dynamic_cast<LaunchConfiguration*>( l ) );
endInsertRows();
}
else
{
delete l;
Q_ASSERT(false && "could not add the configuration");
}
}
IProject* LaunchConfigurationsModel::projectForIndex(const QModelIndex& idx)
{
if(idx.parent().isValid()) {
return projectForIndex(idx.parent());
} else {
const ProjectItem* item = dynamic_cast<const ProjectItem*>(topItems[idx.row()]);
return item ? item->project : 0;
}
}
LaunchConfigPagesContainer::LaunchConfigPagesContainer( const QList<LaunchConfigurationPageFactory*>& factories, QWidget* parent )
: QWidget(parent)
{
setLayout( new QVBoxLayout( this ) );
layout()->setContentsMargins( 0, 0, 0, 0 );
QWidget* parentwidget = this;
KTabWidget* tab = 0;
if( factories.count() > 1 )
{
tab = new KTabWidget( this );
parentwidget = tab;
layout()->addWidget( tab );
}
foreach( LaunchConfigurationPageFactory* fac, factories )
{
LaunchConfigurationPage* page = fac->createWidget( parentwidget );
if ( page->layout() ) {
page->layout()->setContentsMargins( 0, 0, 0, 0 );
}
pages.append( page );
connect( page, SIGNAL(changed()), SIGNAL(changed()) );
if( tab ) {
tab->addTab( page, page->icon(), page->title() );
} else
{
layout()->addWidget( page );
}
}
}
void LaunchConfigPagesContainer::setLaunchConfiguration( KDevelop::LaunchConfiguration* l )
{
config = l;
foreach( LaunchConfigurationPage* p, pages )
{
p->loadFromConfiguration( config->config(), config->project() );
}
}
void LaunchConfigPagesContainer::save()
{
foreach( LaunchConfigurationPage* p, pages )
{
p->saveToConfiguration( config->config() );
}
config->config().sync();
}
QWidget* LaunchConfigurationModelDelegate::createEditor ( QWidget* parent, const QStyleOptionViewItem& option, const QModelIndex& index ) const
{
const LaunchConfigurationsModel* model = dynamic_cast<const LaunchConfigurationsModel*>( index.model() );
ILaunchMode* mode = model->modeForIndex( index );
LaunchConfiguration* config = model->configForIndex( index );
if( index.column() == 1 && mode && config )
{
KComboBox* box = new KComboBox( parent );
QList<ILauncher*> launchers = config->type()->launchers();
for( QList<ILauncher*>::const_iterator it = launchers.constBegin(); it != launchers.constEnd(); it++ )
{
if( ((*it)->supportedModes().contains( mode->id() ) ) )
{
box->addItem( (*it)->name(), (*it)->id() );
}
}
return box;
} else if( !mode && config && index.column() == 1 )
{
KComboBox* box = new KComboBox( parent );
const QList<LaunchConfigurationType*> types = Core::self()->runController()->launchConfigurationTypes();
for( QList<LaunchConfigurationType*>::const_iterator it = types.begin(); it != types.end(); it++ )
{
box->addItem( (*it)->name(), (*it)->id() );
}
return box;
}
return QStyledItemDelegate::createEditor ( parent, option, index );
}
LaunchConfigurationModelDelegate::LaunchConfigurationModelDelegate()
{
}
void LaunchConfigurationModelDelegate::setEditorData ( QWidget* editor, const QModelIndex& index ) const
{
const LaunchConfigurationsModel* model = dynamic_cast<const LaunchConfigurationsModel*>( index.model() );
LaunchConfiguration* config = model->configForIndex( index );
if( index.column() == 1 && config )
{
KComboBox* box = qobject_cast<KComboBox*>( editor );
box->setCurrentIndex( box->findData( index.data( Qt::EditRole ) ) );
}
else
{
QStyledItemDelegate::setEditorData ( editor, index );
}
}
void LaunchConfigurationModelDelegate::setModelData ( QWidget* editor, QAbstractItemModel* model, const QModelIndex& index ) const
{
LaunchConfigurationsModel* lmodel = dynamic_cast<LaunchConfigurationsModel*>( model );
LaunchConfiguration* config = lmodel->configForIndex( index );
if( index.column() == 1 && config )
{
KComboBox* box = qobject_cast<KComboBox*>( editor );
lmodel->setData( index, box->itemData( box->currentIndex() ) );
}
else
{
QStyledItemDelegate::setModelData ( editor, model, index );
}
}
void LaunchConfigurationDialog::launchModeChanged(int item)
{
QModelIndex index = tree->currentIndex();
if(debugger->isVisible() && item>=0)
tree->model()->setData(index.sibling(index.row(), 1), debugger->itemData(item), Qt::EditRole);
}
}
#include "moc_launchconfigurationdialog.cpp"