diff options
Diffstat (limited to 'shared/proparser/valueeditor.cpp')
-rw-r--r-- | shared/proparser/valueeditor.cpp | 494 |
1 files changed, 494 insertions, 0 deletions
diff --git a/shared/proparser/valueeditor.cpp b/shared/proparser/valueeditor.cpp new file mode 100644 index 0000000000..9d367dad1e --- /dev/null +++ b/shared/proparser/valueeditor.cpp @@ -0,0 +1,494 @@ +/*************************************************************************** +** +** 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 <QtGui/QMenu> +#include <QtGui/QKeyEvent> + +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<ProVariable*>(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<QString> values; + foreach(ProItem *proitem, variable->items()) { + if (proitem->kind() == ProItem::ValueKind) { + ProValue *val = static_cast<ProValue *>(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<ProVariable *>(m_model->proBlock(parent)); + + if (value.isEmpty()) { + value = QLatin1String("..."); + + if (ProVariableInfo *varinfo = m_infomanager->variable(var->variable())) { + const QList<ProValueInfo *> 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; row<rows; ++row) { + const QModelIndex index = m_model->index(row, 0, parent); + ProItem *item = m_model->proItem(index); + if (!item || item->kind() != ProItem::ValueKind) + continue; + + if (static_cast<ProValue*>(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<ProVariable *>(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; +} |