/*************************************************************************** ** ** This file is part of Qt Creator ** ** Copyright (c) 2008 Nokia Corporation and/or its subsidiary(-ies). ** ** Contact: Qt Software Information (qt-info@nokia.com) ** ** ** Non-Open Source Usage ** ** Licensees may use this file in accordance with the Qt Beta Version ** License Agreement, Agreement version 2.2 provided with the Software or, ** alternatively, in accordance with the terms contained in a written ** agreement between you and Nokia. ** ** GNU General Public License Usage ** ** Alternatively, this file may be used under the terms of the GNU General ** Public License versions 2.0 or 3.0 as published by the Free Software ** Foundation and appearing in the file LICENSE.GPL included in the packaging ** of this file. Please review the following information to ensure GNU ** General Public Licensing requirements will be met: ** ** http://www.fsf.org/licensing/licenses/info/GPLv2.html and ** http://www.gnu.org/copyleft/gpl.html. ** ** In addition, as a special exception, Nokia gives you certain additional ** rights. These rights are described in the Nokia Qt GPL Exception ** version 1.2, included in the file GPL_EXCEPTION.txt in this package. ** ***************************************************************************/ #include "valueeditor.h" #include "proitems.h" #include "proeditormodel.h" #include "proiteminfo.h" #include #include using namespace Qt4ProjectManager::Internal; ValueEditor::ValueEditor(QWidget *parent) : QWidget(parent), m_model(0), m_handleModelChanges(true), m_infomanager(0) { setupUi(this); } ValueEditor::~ValueEditor() { } void ValueEditor::initialize(ProEditorModel *model, ProItemInfoManager *infomanager) { m_model = model; m_infomanager = infomanager; initialize(); } void ValueEditor::hideVariable() { m_varGroupBox->setVisible(false); } void ValueEditor::showVariable(bool advanced) { m_varComboBoxLabel->setVisible(!advanced); m_varComboBox->setVisible(!advanced); m_varLineEditLabel->setVisible(advanced); m_varLineEdit->setVisible(advanced); m_assignComboBoxLabel->setVisible(advanced); m_assignComboBox->setVisible(advanced); m_varGroupBox->setVisible(true); } void ValueEditor::setItemEditType(ItemEditType type) { m_editStackWidget->setCurrentIndex(type); } void ValueEditor::setDescription(ItemEditType type, const QString &header, const QString &description) { switch (type) { case MultiUndefined: m_multiUndefinedGroupBox->setTitle(header); m_multiUndefinedDescriptionLabel->setVisible(!description.isEmpty()); m_multiUndefinedDescriptionLabel->setText(description); break; case MultiDefined: m_multiDefinedGroupBox->setTitle(header); m_multiDefinedDescriptionLabel->setVisible(!description.isEmpty()); m_multiDefinedDescriptionLabel->setText(description); break; case SingleUndefined: m_singleUndefinedGroupBox->setTitle(header); m_singleUndefinedDescriptionLabel->setVisible(!description.isEmpty()); m_singleUndefinedDescriptionLabel->setText(description); break; default: m_singleDefinedGroupBox->setTitle(header); m_singleDefinedDescriptionLabel->setVisible(!description.isEmpty()); m_singleDefinedDescriptionLabel->setText(description); break; } } void ValueEditor::initialize() { hideVariable(); setItemEditType(MultiUndefined); m_itemListView->setModel(m_model); m_itemListView->setRootIndex(QModelIndex()); connect(m_itemAddButton, SIGNAL(clicked()), this, SLOT(addItem())); connect(m_itemRemoveButton, SIGNAL(clicked()), this, SLOT(removeItem())); connect(m_itemListView->selectionModel(), SIGNAL(currentChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(updateItemList(const QModelIndex &))); connect(m_itemListWidget, SIGNAL(itemChanged(QListWidgetItem *)), this, SLOT(updateItemChanges(QListWidgetItem *))); foreach (ProVariableInfo *varinfo, m_infomanager->variables()) { m_varComboBox->addItem(varinfo->name(), varinfo->id()); } connect(m_varLineEdit, SIGNAL(editingFinished()), this, SLOT(updateVariableId())); connect(m_varComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateVariableId(int))); connect(m_assignComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateVariableOp(int))); connect(m_itemLineEdit, SIGNAL(editingFinished()), this, SLOT(updateItemId())); connect(m_itemComboBox, SIGNAL(currentIndexChanged(int)), this, SLOT(updateItemId(int))); connect(m_model, SIGNAL(rowsInserted(const QModelIndex &, int, int)), this, SLOT(modelChanged(const QModelIndex &))); connect(m_model, SIGNAL(rowsRemoved(const QModelIndex &, int, int)), this, SLOT(modelChanged(const QModelIndex &))); connect(m_model, SIGNAL(dataChanged(const QModelIndex &, const QModelIndex &)), this, SLOT(modelChanged(const QModelIndex &))); updateItemList(QModelIndex()); } void ValueEditor::modelChanged(const QModelIndex &index) { if (m_handleModelChanges) { if (m_currentIndex == index || m_currentIndex == index.parent()) editIndex(m_currentIndex); } } void ValueEditor::editIndex(const QModelIndex &index) { if (!m_model) return; m_currentIndex = index; ProBlock *block = m_model->proBlock(index); m_varGroupBox->setEnabled(block != 0); m_editStackWidget->setEnabled(block != 0); if (!block) return; if (block->blockKind() & ProBlock::ScopeContentsKind) { showScope(block); } else if (block->blockKind() & ProBlock::VariableKind) { showVariable(static_cast(block)); } else { showOther(block); } } ValueEditor::ItemEditType ValueEditor::itemType(bool defined, bool multiple) const { if (defined) { if (multiple) return MultiDefined; else return SingleDefined; } else { if (multiple) return MultiUndefined; else return SingleUndefined; } } void ValueEditor::showVariable(ProVariable *variable) { if (!m_model) return; ProVariableInfo *info = m_infomanager->variable(variable->variable()); const bool advanced = (!m_model->infoManager() || (info == 0)); bool defined = false; bool multiple = true; QSet values; foreach(ProItem *proitem, variable->items()) { if (proitem->kind() == ProItem::ValueKind) { ProValue *val = static_cast(proitem); values.insert(val->value()); } } if (!advanced && info) { defined = !info->values().isEmpty(); // check if all values are known foreach(QString val, values) { if (!info->value(val)) { defined = false; break; } } multiple = info->multiple(); } if (values.count() > 1) multiple = true; bool wasblocked; if (!advanced) { const int index = m_varComboBox->findData(variable->variable(), Qt::UserRole, Qt::MatchExactly); wasblocked = m_varComboBox->blockSignals(true); m_varComboBox->setCurrentIndex(index); m_varComboBox->blockSignals(wasblocked); } else { wasblocked = m_varLineEdit->blockSignals(true); m_varLineEdit->setText(variable->variable()); m_varLineEdit->blockSignals(wasblocked); } ItemEditType type = itemType(defined, multiple); wasblocked = m_assignComboBox->blockSignals(true); m_assignComboBox->setCurrentIndex(variable->variableOperator()); m_assignComboBox->blockSignals(wasblocked); QString header = tr("Edit Values"); QString desc; if (info) { header = tr("Edit %1").arg(info->name()); desc = info->description(); } setDescription(type, header, desc); m_itemListWidget->clear(); switch (type) { case MultiUndefined: { const QModelIndex parent = m_currentIndex; m_itemListView->setRootIndex(parent); m_itemListView->setCurrentIndex(m_model->index(0,0,parent)); } break; case MultiDefined: wasblocked = m_itemListWidget->blockSignals(true); foreach(ProValueInfo *valinfo, info->values()) { QListWidgetItem *item = new QListWidgetItem(m_itemListWidget); item->setText(valinfo->name()); item->setData(Qt::UserRole, valinfo->id()); if (values.contains(valinfo->id())) item->setCheckState(Qt::Checked); else item->setCheckState(Qt::Unchecked); } m_itemListWidget->blockSignals(wasblocked); break; case SingleUndefined: wasblocked = m_itemLineEdit->blockSignals(true); if (values.isEmpty()) m_itemLineEdit->setText(QString()); else m_itemLineEdit->setText(values.toList().first()); m_itemLineEdit->blockSignals(wasblocked); break; case SingleDefined: wasblocked = m_itemComboBox->blockSignals(true); m_itemComboBox->clear(); foreach(ProValueInfo *valinfo, info->values()) { m_itemComboBox->addItem(valinfo->name(), valinfo->id()); } int index = -1; if (!values.isEmpty()) { const QString id = values.toList().first(); index = m_itemComboBox->findData(id, Qt::UserRole, Qt::MatchExactly); } m_itemComboBox->setCurrentIndex(index); m_itemComboBox->blockSignals(wasblocked); break; } showVariable(advanced); setItemEditType(type); } void ValueEditor::showScope(ProBlock *) { if (!m_model) return; const bool wasblocked = m_itemLineEdit->blockSignals(true); m_itemLineEdit->setText(m_model->data(m_currentIndex, Qt::EditRole).toString()); m_itemLineEdit->blockSignals(wasblocked); setDescription(SingleUndefined, tr("Edit Scope")); hideVariable(); setItemEditType(SingleUndefined); } void ValueEditor::showOther(ProBlock *) { if (!m_model) return; const bool wasblocked = m_itemLineEdit->blockSignals(true); m_itemLineEdit->setText(m_model->data(m_currentIndex, Qt::EditRole).toString()); m_itemLineEdit->blockSignals(wasblocked); setDescription(SingleUndefined, tr("Edit Advanced Expression")); hideVariable(); setItemEditType(SingleUndefined); } void ValueEditor::addItem(QString value) { if (!m_model) return; QModelIndex parent = m_currentIndex; ProVariable *var = static_cast(m_model->proBlock(parent)); if (value.isEmpty()) { value = QLatin1String("..."); if (ProVariableInfo *varinfo = m_infomanager->variable(var->variable())) { const QList vals = varinfo->values(); if (!vals.isEmpty()) value = vals.first()->id(); } } m_handleModelChanges = false; m_model->insertItem(new ProValue(value, var), m_model->rowCount(parent), parent); const QModelIndex idx = m_model->index(m_model->rowCount(parent)-1, 0, parent); m_itemListView->setCurrentIndex(idx); m_itemListView->edit(idx); m_itemListView->scrollToBottom(); m_handleModelChanges = true; } void ValueEditor::removeItem() { if (!m_model) return; m_handleModelChanges = false; const QModelIndex idx = m_itemListView->currentIndex(); m_itemListView->closePersistentEditor(idx); m_model->removeItem(idx); m_handleModelChanges = true; } void ValueEditor::updateItemList(const QModelIndex &) { if (!m_model) return; m_itemRemoveButton->setEnabled(m_model->rowCount(m_currentIndex)); } QModelIndex ValueEditor::findValueIndex(const QString &id) const { if (!m_model) return QModelIndex(); const QModelIndex parent = m_currentIndex; const int rows = m_model->rowCount(parent); for (int row=0; rowindex(row, 0, parent); ProItem *item = m_model->proItem(index); if (!item || item->kind() != ProItem::ValueKind) continue; if (static_cast(item)->value() == id) return index; } return QModelIndex(); } void ValueEditor::updateItemChanges(QListWidgetItem *item) { if (!m_model) return; const QModelIndex parent = m_currentIndex; ProBlock *block = m_model->proBlock(parent); if (!block || !(block->blockKind() & ProBlock::VariableKind)) return; ProVariable *var = static_cast(block); const QString id = item->data(Qt::UserRole).toString(); m_handleModelChanges = false; const QModelIndex index = findValueIndex(id); if (item->checkState() == Qt::Checked && !index.isValid()) { m_model->insertItem(new ProValue(id, var), m_model->rowCount(parent), m_currentIndex); } else if (item->checkState() != Qt::Checked && index.isValid()) { m_model->removeItem(index); } m_handleModelChanges = true; } void ValueEditor::updateVariableId() { if (!m_model) return; m_handleModelChanges = false; m_model->setData(m_currentIndex, QVariant(m_varLineEdit->text())); m_handleModelChanges = true; } void ValueEditor::updateVariableId(int index) { if (!m_model) return; ProVariableInfo *info = m_infomanager->variable(m_varComboBox->itemData(index).toString()); m_model->setData(m_currentIndex, info->id()); m_model->setData(m_currentIndex, info->defaultOperator()); } void ValueEditor::updateVariableOp(int index) { if (!m_model) return; m_handleModelChanges = false; m_model->setData(m_currentIndex, QVariant(index)); m_handleModelChanges = true; } void ValueEditor::updateItemId() { if (!m_model) return; QModelIndex index = m_currentIndex; if (m_varGroupBox->isVisible()) { index = m_model->index(0,0,index); if (!index.isValid()) { addItem(m_itemLineEdit->text()); return; } } m_handleModelChanges = false; m_model->setData(index, QVariant(m_itemLineEdit->text())); m_handleModelChanges = true; } void ValueEditor::updateItemId(int index) { if (!m_model) return; QModelIndex idx = m_currentIndex; if (m_varGroupBox->isVisible()) { idx = m_model->index(0,0,idx); if (!idx.isValid()) { addItem(m_itemComboBox->itemData(index).toString()); return; } } m_handleModelChanges = false; m_model->setData(idx, m_itemComboBox->itemData(index)); m_handleModelChanges = true; }