2009-02-25 09:15:00 +01:00
|
|
|
/**************************************************************************
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
|
|
|
|
** This file is part of Qt Creator
|
|
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-06-17 00:01:27 +10:00
|
|
|
** Contact: Nokia Corporation (qt-info@nokia.com)
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Commercial Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Licensees holding valid Qt Commercial licenses may use this file in
|
|
|
|
|
** accordance with the Qt Commercial License Agreement provided with the
|
|
|
|
|
** Software or, alternatively, in accordance with the terms contained in
|
|
|
|
|
** a written agreement between you and Nokia.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** GNU Lesser General Public License Usage
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** Alternatively, this file may be used under the terms of the GNU Lesser
|
|
|
|
|
** General Public License version 2.1 as published by the Free Software
|
|
|
|
|
** Foundation and appearing in the file LICENSE.LGPL included in the
|
|
|
|
|
** packaging of this file. Please review the following information to
|
|
|
|
|
** ensure the GNU Lesser General Public License version 2.1 requirements
|
|
|
|
|
** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
|
2008-12-02 14:17:16 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
** If you are unsure which license is appropriate for your use, please
|
2009-08-14 09:30:56 +02:00
|
|
|
** contact the sales department at http://qt.nokia.com/contact.
|
2008-12-02 12:01:29 +01:00
|
|
|
**
|
2009-02-25 09:15:00 +01:00
|
|
|
**************************************************************************/
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
#include "proxml.h"
|
|
|
|
|
#include "proitems.h"
|
|
|
|
|
#include "proeditormodel.h"
|
|
|
|
|
#include "procommandmanager.h"
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
#include <QtCore/QDebug>
|
|
|
|
|
#include <QtCore/QMimeData>
|
|
|
|
|
#include <QtCore/QStringList>
|
|
|
|
|
#include <QtGui/QIcon>
|
|
|
|
|
|
2008-12-02 12:01:29 +01:00
|
|
|
using namespace Qt4ProjectManager::Internal;
|
|
|
|
|
|
|
|
|
|
namespace Qt4ProjectManager {
|
|
|
|
|
namespace Internal {
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ProAddCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ProAddCommand(ProEditorModel *model, ProItem *item, int row, const QModelIndex &parent, bool dodelete = true)
|
|
|
|
|
: m_model(model), m_item(item), m_row(row), m_parent(parent), m_dodelete(dodelete), m_delete(false) { }
|
|
|
|
|
|
|
|
|
|
~ProAddCommand() {
|
|
|
|
|
if (m_delete)
|
|
|
|
|
delete m_item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
m_delete = false;
|
|
|
|
|
return m_model->insertModelItem(m_item, m_row, m_parent);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
m_delete = m_dodelete;
|
|
|
|
|
m_model->removeModelItem(m_model->index(m_row, 0, m_parent));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
ProItem *m_item;
|
|
|
|
|
int m_row;
|
|
|
|
|
const QModelIndex m_parent;
|
|
|
|
|
bool m_dodelete;
|
|
|
|
|
bool m_delete;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ProRemoveCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ProRemoveCommand(ProEditorModel *model, const QModelIndex &index, bool dodelete = true)
|
|
|
|
|
: m_model(model), m_index(index), m_dodelete(dodelete), m_delete(dodelete) { }
|
|
|
|
|
|
|
|
|
|
~ProRemoveCommand() {
|
|
|
|
|
if (m_delete)
|
|
|
|
|
delete m_model->proItem(m_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
m_delete = m_dodelete;
|
|
|
|
|
return m_model->removeModelItem(m_index);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
m_delete = false;
|
|
|
|
|
m_model->insertModelItem(m_model->proItem(m_index),
|
|
|
|
|
m_index.row(), m_index.parent());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
const QModelIndex m_index;
|
|
|
|
|
bool m_dodelete;
|
|
|
|
|
bool m_delete;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ChangeProVariableIdCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ChangeProVariableIdCommand(ProEditorModel *model, ProVariable *variable, const QString &newId)
|
|
|
|
|
: m_newId(newId), m_model(model), m_variable(variable)
|
|
|
|
|
{
|
|
|
|
|
m_oldId = m_variable->variable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ChangeProVariableIdCommand() { }
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
m_variable->setVariable(m_newId);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
m_variable->setVariable(m_oldId);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
QString m_oldId;
|
|
|
|
|
QString m_newId;
|
|
|
|
|
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
ProVariable *m_variable;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ChangeProVariableOpCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ChangeProVariableOpCommand(ProEditorModel *model, ProVariable *variable, ProVariable::VariableOperator newOp)
|
|
|
|
|
: m_newOp(newOp), m_model(model), m_variable(variable)
|
|
|
|
|
{
|
|
|
|
|
m_oldOp = m_variable->variableOperator();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ChangeProVariableOpCommand() { }
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
m_variable->setVariableOperator(m_newOp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
m_variable->setVariableOperator(m_oldOp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
ProVariable::VariableOperator m_oldOp;
|
|
|
|
|
ProVariable::VariableOperator m_newOp;
|
|
|
|
|
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
ProVariable *m_variable;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ChangeProScopeCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ChangeProScopeCommand(ProEditorModel *model, ProBlock *scope, const QString &newExp)
|
|
|
|
|
: m_newExp(newExp), m_model(model), m_scope(scope) {
|
|
|
|
|
m_oldExp = m_model->expressionToString(m_scope);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ChangeProScopeCommand() { }
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
setScopeCondition(m_newExp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
setScopeCondition(m_oldExp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void setScopeCondition(const QString &exp) {
|
|
|
|
|
ProItem *contents = m_model->scopeContents(m_scope);
|
|
|
|
|
QList<ProItem *> items = m_scope->items();
|
|
|
|
|
for (int i=items.count() - 1; i>=0; --i) {
|
|
|
|
|
if (items.at(i) != contents)
|
|
|
|
|
delete items[i];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
items = m_model->stringToExpression(exp);
|
|
|
|
|
items << contents;
|
|
|
|
|
m_scope->setItems(items);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString m_oldExp;
|
|
|
|
|
QString m_newExp;
|
|
|
|
|
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
ProBlock *m_scope;
|
|
|
|
|
};
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
class ChangeProAdvancedCommand : public ProCommand
|
|
|
|
|
{
|
2008-12-02 12:01:29 +01:00
|
|
|
public:
|
|
|
|
|
ChangeProAdvancedCommand(ProEditorModel *model, ProBlock *block, const QString &newExp)
|
|
|
|
|
: m_newExp(newExp), m_model(model), m_block(block) {
|
|
|
|
|
m_oldExp = m_model->expressionToString(m_block);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
~ChangeProAdvancedCommand() { }
|
|
|
|
|
|
|
|
|
|
bool redo() {
|
|
|
|
|
setExpression(m_newExp);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void undo() {
|
|
|
|
|
setExpression(m_oldExp);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
private:
|
|
|
|
|
void setExpression(const QString &exp) {
|
|
|
|
|
qDeleteAll(m_block->items());
|
|
|
|
|
m_block->setItems(m_model->stringToExpression(exp));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString m_oldExp;
|
|
|
|
|
QString m_newExp;
|
|
|
|
|
|
|
|
|
|
ProEditorModel *m_model;
|
|
|
|
|
ProBlock *m_block;
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
} //namespace Internal
|
|
|
|
|
} //namespace Qt4ProjectManager
|
|
|
|
|
|
|
|
|
|
ProEditorModel::ProEditorModel(QObject *parent)
|
|
|
|
|
: QAbstractItemModel(parent)
|
|
|
|
|
{
|
|
|
|
|
m_cmdmanager = new ProCommandManager(this);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProEditorModel::~ProEditorModel()
|
|
|
|
|
{
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProCommandManager *ProEditorModel::cmdManager() const
|
|
|
|
|
{
|
|
|
|
|
return m_cmdmanager;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProEditorModel::setProFiles(QList<ProFile*> proFiles)
|
|
|
|
|
{
|
|
|
|
|
m_changed.clear();
|
|
|
|
|
m_proFiles = proFiles;
|
|
|
|
|
reset();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<ProFile*> ProEditorModel::proFiles() const
|
|
|
|
|
{
|
|
|
|
|
return m_proFiles;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QModelIndex> ProEditorModel::findVariables(const QStringList &varnames, const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
QList<QModelIndex> result;
|
|
|
|
|
|
|
|
|
|
if (varnames.isEmpty())
|
|
|
|
|
return result;
|
|
|
|
|
|
|
|
|
|
if (ProVariable *var = proVariable(parent)) {
|
|
|
|
|
if (varnames.contains(var->variable()))
|
|
|
|
|
result << parent;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
for (int i=0; i<rowCount(parent); ++i) {
|
|
|
|
|
result += findVariables(varnames, index(i, 0, parent));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QModelIndex> ProEditorModel::findBlocks(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
QList<QModelIndex> result;
|
|
|
|
|
|
|
|
|
|
if (proBlock(parent)) {
|
|
|
|
|
result << parent;
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
2008-12-02 12:57:59 +01:00
|
|
|
for (int i = 0; i < rowCount(parent); ++i)
|
2008-12-02 12:01:29 +01:00
|
|
|
result += findBlocks(index(i, 0, parent));
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ProEditorModel::blockName(ProBlock *block) const
|
|
|
|
|
{
|
|
|
|
|
// variables has a name
|
|
|
|
|
if (block->blockKind() & ProBlock::VariableKind) {
|
|
|
|
|
ProVariable *v = static_cast<ProVariable*>(block);
|
|
|
|
|
return v->variable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return expressionToString(block, true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QModelIndex ProEditorModel::index(int row, int column, const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
if (row < 0 || (column != 0))
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
|
|
if (parent.isValid()) {
|
|
|
|
|
ProItem *item = proItem(parent);
|
|
|
|
|
if (item->kind() != ProItem::BlockKind)
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
|
|
|
|
|
ProBlock *block = static_cast<ProBlock*>(item);
|
|
|
|
|
if (block->blockKind() & ProBlock::VariableKind
|
|
|
|
|
|| block->blockKind() & ProBlock::ProFileKind) {
|
|
|
|
|
const QList<ProItem*> items = block->items();
|
|
|
|
|
if (row >= items.count())
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
ProItem *data = items.at(row);
|
|
|
|
|
return createIndex(row, 0, (void*)data);
|
|
|
|
|
} else if (ProBlock *scope = scopeContents(block)) {
|
|
|
|
|
const QList<ProItem*> items = scope->items();
|
|
|
|
|
if (row >= items.count())
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
ProItem *data = items.at(row);
|
|
|
|
|
return createIndex(row, 0, (void*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (row >= m_proFiles.count())
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
ProItem *data = m_proFiles.at(row);
|
|
|
|
|
return createIndex(row, 0, (void*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QModelIndex ProEditorModel::parent(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
ProBlock *p = 0;
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
if (!item) {
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item->kind() == ProItem::BlockKind) {
|
|
|
|
|
ProBlock *block = static_cast<ProBlock *>(item);
|
|
|
|
|
if (block->blockKind() & ProBlock::ProFileKind) {
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
p = block->parent();
|
|
|
|
|
} else if (item->kind() == ProItem::ValueKind) {
|
|
|
|
|
p = static_cast<ProValue *>(item)->variable();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (p->blockKind() & ProBlock::ScopeContentsKind)
|
|
|
|
|
p = p->parent();
|
|
|
|
|
|
|
|
|
|
int row = -1;
|
|
|
|
|
if (p->blockKind() & ProBlock::ProFileKind) {
|
|
|
|
|
row = m_proFiles.indexOf(static_cast<ProFile*>(p));
|
|
|
|
|
} else {
|
|
|
|
|
ProBlock *pp = p->parent();
|
|
|
|
|
row = pp->items().indexOf(p);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (row == -1) {
|
|
|
|
|
return QModelIndex();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProItem *data = p;
|
|
|
|
|
return createIndex(row, 0, (void*)data);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ProEditorModel::rowCount(const QModelIndex &parent) const
|
|
|
|
|
{
|
|
|
|
|
if (parent.isValid()) {
|
|
|
|
|
ProItem *s = proItem(parent);
|
|
|
|
|
if (!s)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
if (s->kind() != ProItem::BlockKind)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProBlock *block = static_cast<ProBlock*>(s);
|
|
|
|
|
|
|
|
|
|
if (block->blockKind() & ProBlock::VariableKind
|
|
|
|
|
|| block->blockKind() & ProBlock::ProFileKind) {
|
|
|
|
|
int rows = block->items().count();
|
|
|
|
|
return rows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ProBlock *scope = scopeContents(block)) {
|
|
|
|
|
int rows = scope->items().count();
|
|
|
|
|
return rows;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return m_proFiles.count();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
int ProEditorModel::columnCount(const QModelIndex &) const
|
|
|
|
|
{
|
|
|
|
|
return 1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant ProEditorModel::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
if (!item) {
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (item->kind() == ProItem::BlockKind) {
|
|
|
|
|
ProBlock *block = static_cast<ProBlock*>(item);
|
|
|
|
|
if (block->blockKind() & ProBlock::ProFileKind) {
|
|
|
|
|
ProFile *pf = static_cast<ProFile*>(item);
|
|
|
|
|
if (role == Qt::DisplayRole) {
|
|
|
|
|
if (m_proFiles.count() > 1)
|
|
|
|
|
return QVariant(pf->displayFileName());
|
|
|
|
|
else
|
|
|
|
|
return QVariant(tr("<Global Scope>"));
|
|
|
|
|
} else if (role == Qt::DecorationRole) {
|
|
|
|
|
return QIcon(":/proparser/images/profile.png");
|
|
|
|
|
}
|
|
|
|
|
} else if (block->blockKind() & ProBlock::ScopeKind) {
|
|
|
|
|
if (role == Qt::DisplayRole)
|
|
|
|
|
return QVariant(blockName(block));
|
|
|
|
|
else if (role == Qt::DecorationRole)
|
|
|
|
|
return QIcon(":/proparser/images/scope.png");
|
|
|
|
|
else if (role == Qt::EditRole)
|
|
|
|
|
return QVariant(expressionToString(block));
|
|
|
|
|
} else if (block->blockKind() & ProBlock::VariableKind) {
|
|
|
|
|
ProVariable *var = static_cast<ProVariable *>(block);
|
|
|
|
|
if (role == Qt::DisplayRole) {
|
|
|
|
|
return QVariant(blockName(block));
|
|
|
|
|
} else if (role == Qt::DecorationRole) {
|
|
|
|
|
if (var->variableOperator() == ProVariable::AddOperator)
|
|
|
|
|
return QIcon(":/proparser/images/append.png");
|
|
|
|
|
else if (var->variableOperator() == ProVariable::RemoveOperator)
|
|
|
|
|
return QIcon(":/proparser/images/remove.png");
|
|
|
|
|
else
|
|
|
|
|
return QIcon(":/proparser/images/set.png");
|
|
|
|
|
} else if (role == Qt::EditRole) {
|
|
|
|
|
return QVariant(var->variable());
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (role == Qt::DisplayRole)
|
|
|
|
|
return QVariant(blockName(block));
|
|
|
|
|
else if (role == Qt::DecorationRole)
|
|
|
|
|
return QIcon(":/proparser/images/other.png");
|
|
|
|
|
else if (role == Qt::EditRole)
|
|
|
|
|
return QVariant(expressionToString(block));
|
|
|
|
|
}
|
|
|
|
|
} else if (item->kind() == ProItem::ValueKind) {
|
|
|
|
|
ProValue *value = static_cast<ProValue*>(item);
|
|
|
|
|
if (role == Qt::DisplayRole) {
|
|
|
|
|
return QVariant(value->value());
|
|
|
|
|
} else if (role == Qt::DecorationRole) {
|
|
|
|
|
return QIcon(":/proparser/images/value.png");
|
|
|
|
|
} else if (role == Qt::EditRole) {
|
|
|
|
|
return QVariant(value->value());
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QVariant();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Qt::ItemFlags ProEditorModel::flags(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
Qt::ItemFlags res = QAbstractItemModel::flags(index);
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
if (item->kind() == ProItem::BlockKind) {
|
|
|
|
|
ProBlock *block = static_cast<ProBlock*>(item);
|
|
|
|
|
if (block->blockKind() == ProBlock::ProFileKind)
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return res | Qt::ItemIsEditable;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QMimeData *ProEditorModel::mimeData(const QModelIndexList &indexes) const
|
|
|
|
|
{
|
|
|
|
|
QModelIndex index = indexes.first();
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
QMimeData *data = new QMimeData();
|
|
|
|
|
QString xml = ProXmlParser::itemToString(item);
|
|
|
|
|
data->setText(xml);
|
|
|
|
|
return data;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProEditorModel::removeModelItem(const QModelIndex &index)
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
int row = index.row();
|
|
|
|
|
QModelIndex parentIndex = index.parent();
|
|
|
|
|
|
|
|
|
|
if (!parentIndex.isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
// get the pro items
|
|
|
|
|
ProBlock *block = proBlock(parentIndex);
|
|
|
|
|
if (!block)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
QList<ProItem *> proitems = block->items();
|
|
|
|
|
proitems.takeAt(row);
|
|
|
|
|
|
|
|
|
|
beginRemoveRows(parentIndex, row, row);
|
|
|
|
|
block->setItems(proitems);
|
|
|
|
|
endRemoveRows();
|
|
|
|
|
markProFileModified(index);
|
|
|
|
|
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProEditorModel::removeItem(const QModelIndex &index)
|
|
|
|
|
{
|
|
|
|
|
bool creategroup = !m_cmdmanager->hasGroup();
|
|
|
|
|
if (creategroup)
|
|
|
|
|
m_cmdmanager->beginGroup(tr("Remove Item"));
|
|
|
|
|
|
|
|
|
|
bool result = m_cmdmanager->command(new ProRemoveCommand(this, index));
|
|
|
|
|
|
|
|
|
|
if (creategroup)
|
|
|
|
|
m_cmdmanager->endGroup();
|
|
|
|
|
markProFileModified(index);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProEditorModel::insertModelItem(ProItem *item, int row, const QModelIndex &parent)
|
|
|
|
|
{
|
|
|
|
|
if (!parent.isValid())
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ProBlock *block = proBlock(parent);
|
|
|
|
|
if (!item || !block)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
QList<ProItem *> proitems = block->items();
|
|
|
|
|
proitems.insert(row, item);
|
|
|
|
|
|
|
|
|
|
if ((block->blockKind() & ProBlock::VariableKind)
|
|
|
|
|
&& item->kind() != ProItem::ValueKind)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
if (item->kind() == ProItem::BlockKind) {
|
|
|
|
|
static_cast<ProBlock*>(item)->setParent(block);
|
|
|
|
|
} else if (item->kind() == ProItem::ValueKind) {
|
|
|
|
|
if (!(block->blockKind() & ProBlock::VariableKind))
|
|
|
|
|
return false;
|
|
|
|
|
static_cast<ProValue*>(item)->
|
|
|
|
|
setVariable(static_cast<ProVariable*>(block));
|
|
|
|
|
} else {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
beginInsertRows(parent, row, row);
|
|
|
|
|
block->setItems(proitems);
|
|
|
|
|
endInsertRows();
|
|
|
|
|
|
|
|
|
|
markProFileModified(parent);
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProEditorModel::insertItem(ProItem *item, int row, const QModelIndex &parent)
|
|
|
|
|
{
|
|
|
|
|
bool creategroup = !m_cmdmanager->hasGroup();
|
|
|
|
|
if (creategroup)
|
|
|
|
|
m_cmdmanager->beginGroup(tr("Insert Item"));
|
|
|
|
|
|
|
|
|
|
bool result = m_cmdmanager->command(new ProAddCommand(this, item, row, parent));
|
|
|
|
|
|
|
|
|
|
if (creategroup)
|
|
|
|
|
m_cmdmanager->endGroup();
|
|
|
|
|
markProFileModified(parent);
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProEditorModel::markProFileModified(QModelIndex index)
|
|
|
|
|
{
|
2008-12-09 11:07:24 +01:00
|
|
|
while (index.isValid()) {
|
|
|
|
|
if (proItem(index)->kind() == ProItem::BlockKind) {
|
2008-12-02 12:01:29 +01:00
|
|
|
ProBlock * block = proBlock(index);
|
2008-12-09 11:07:24 +01:00
|
|
|
if (block->blockKind() == ProBlock::ProFileKind) {
|
2008-12-02 12:01:29 +01:00
|
|
|
ProFile * file = static_cast<ProFile *>(block);
|
|
|
|
|
file->setModified(true);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
index = index.parent();
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProItem *ProEditorModel::proItem(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return 0;
|
|
|
|
|
return reinterpret_cast<ProItem*>(index.internalPointer());
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProVariable *ProEditorModel::proVariable(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
if (item->kind() != ProItem::BlockKind)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProBlock *block = static_cast<ProBlock *>(item);
|
|
|
|
|
if (block->blockKind() != ProBlock::VariableKind)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
return static_cast<ProVariable*>(block);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProBlock *ProEditorModel::proBlock(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
if (!index.isValid())
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProItem *item = proItem(index);
|
|
|
|
|
if (item->kind() != ProItem::BlockKind)
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProBlock *block = static_cast<ProBlock *>(item);
|
|
|
|
|
if (block->blockKind() & ProBlock::ScopeKind)
|
|
|
|
|
block = scopeContents(block);
|
|
|
|
|
|
|
|
|
|
return block;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QString ProEditorModel::expressionToString(ProBlock *block, bool display) const
|
|
|
|
|
{
|
|
|
|
|
QString result;
|
|
|
|
|
QList<ProItem*> items = block->items();
|
2008-12-09 11:07:24 +01:00
|
|
|
for (int i = 0; i < items.count(); ++i) {
|
2008-12-02 12:01:29 +01:00
|
|
|
ProItem *item = items.at(i);
|
2008-12-09 11:07:24 +01:00
|
|
|
switch (item->kind()) {
|
2008-12-02 12:01:29 +01:00
|
|
|
case ProItem::FunctionKind: {
|
|
|
|
|
ProFunction *v = static_cast<ProFunction*>(item);
|
|
|
|
|
result += v->text();
|
|
|
|
|
break; }
|
|
|
|
|
case ProItem::ConditionKind: {
|
|
|
|
|
ProCondition *v = static_cast<ProCondition*>(item);
|
2009-12-09 16:57:32 +01:00
|
|
|
result += v->text();
|
2008-12-09 11:07:24 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
case ProItem::OperatorKind: {
|
|
|
|
|
ProOperator *v = static_cast<ProOperator*>(item);
|
|
|
|
|
if (v->operatorKind() == ProOperator::NotOperator)
|
|
|
|
|
result += QLatin1Char('!');
|
|
|
|
|
else
|
|
|
|
|
result += QLatin1Char('|');
|
2008-12-09 11:07:24 +01:00
|
|
|
break;
|
|
|
|
|
}
|
2008-12-02 12:01:29 +01:00
|
|
|
case ProItem::ValueKind:
|
|
|
|
|
case ProItem::BlockKind:
|
|
|
|
|
break; // ### unhandled
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProItem *ProEditorModel::createExpressionItem(QString &str) const
|
|
|
|
|
{
|
|
|
|
|
ProItem *item = 0;
|
|
|
|
|
|
|
|
|
|
str = str.trimmed();
|
|
|
|
|
if (str.endsWith(')'))
|
|
|
|
|
item = new ProFunction(str);
|
|
|
|
|
else if (!str.isEmpty())
|
|
|
|
|
item = new ProCondition(str);
|
|
|
|
|
|
|
|
|
|
str.clear();
|
|
|
|
|
return item;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
QList<ProItem *> ProEditorModel::stringToExpression(const QString &exp) const
|
|
|
|
|
{
|
|
|
|
|
QList<ProItem*> result;
|
|
|
|
|
int p = 0;
|
|
|
|
|
bool c = false;
|
|
|
|
|
|
|
|
|
|
QString tmpstr;
|
2008-12-09 11:07:24 +01:00
|
|
|
for (int i = 0; i < exp.length(); ++i) {
|
2008-12-02 12:01:29 +01:00
|
|
|
QChar tmpchar = exp.at(i);
|
|
|
|
|
if (tmpchar == '(') ++p;
|
|
|
|
|
else if (tmpchar == ')') --p;
|
|
|
|
|
else if (tmpchar == '\'' || tmpchar == '\"') c = !c;
|
|
|
|
|
else if (!c && !p) {
|
|
|
|
|
if (tmpchar == '|') {
|
|
|
|
|
if (ProItem *item = createExpressionItem(tmpstr))
|
|
|
|
|
result << item;
|
|
|
|
|
result << new ProOperator(ProOperator::OrOperator);
|
|
|
|
|
continue;
|
|
|
|
|
} else if (tmpchar == '!') {
|
|
|
|
|
if (ProItem *item = createExpressionItem(tmpstr))
|
|
|
|
|
result << item;
|
|
|
|
|
result << new ProOperator(ProOperator::NotOperator);
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
tmpstr += tmpchar;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (ProItem *item = createExpressionItem(tmpstr))
|
|
|
|
|
result << item;
|
|
|
|
|
|
|
|
|
|
return result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProBlock *ProEditorModel::scopeContents(ProBlock *block) const
|
|
|
|
|
{
|
|
|
|
|
if (!(block->blockKind() & ProBlock::ScopeKind))
|
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
|
|
ProItem *item = block->items().last();
|
|
|
|
|
if (item->kind() != ProItem::BlockKind)
|
|
|
|
|
return 0;
|
|
|
|
|
ProBlock *scope = static_cast<ProBlock*>(item);
|
|
|
|
|
if (!(scope->blockKind() & ProBlock::ScopeContentsKind))
|
|
|
|
|
return 0;
|
|
|
|
|
return scope;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProScopeFilter::ProScopeFilter(QObject *parent)
|
|
|
|
|
: QSortFilterProxyModel(parent)
|
|
|
|
|
{
|
|
|
|
|
m_checkable = ProScopeFilter::None;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProScopeFilter::setVariableFilter(const QStringList &vars)
|
|
|
|
|
{
|
|
|
|
|
m_vars = vars;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void ProScopeFilter::setCheckable(CheckableType ct)
|
|
|
|
|
{
|
|
|
|
|
m_checkable = ct;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QList<QModelIndex> ProScopeFilter::checkedIndexes() const
|
|
|
|
|
{
|
|
|
|
|
return m_checkStates.keys(true);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
Qt::ItemFlags ProScopeFilter::flags(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
Qt::ItemFlags srcflags = sourceModel()->flags(mapToSource(index));
|
|
|
|
|
srcflags &= ~Qt::ItemIsDragEnabled; //disable drag
|
|
|
|
|
|
|
|
|
|
if (m_checkable == ProScopeFilter::None)
|
|
|
|
|
return srcflags;
|
|
|
|
|
|
|
|
|
|
return (srcflags|Qt::ItemIsUserCheckable);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
QVariant ProScopeFilter::data(const QModelIndex &index, int role) const
|
|
|
|
|
{
|
|
|
|
|
bool checkable =
|
|
|
|
|
m_checkable == ProScopeFilter::Blocks
|
2009-02-11 12:11:21 +01:00
|
|
|
|| (m_checkable == ProScopeFilter::Variable && sourceVariable(index));
|
2008-12-02 12:01:29 +01:00
|
|
|
|
|
|
|
|
if (checkable && role == Qt::CheckStateRole) {
|
|
|
|
|
QModelIndex srcindex = mapToSource(index);
|
|
|
|
|
if (m_checkStates.value(srcindex, false))
|
|
|
|
|
return Qt::Checked;
|
|
|
|
|
else
|
|
|
|
|
return Qt::Unchecked;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QSortFilterProxyModel::data(index, role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProScopeFilter::setData(const QModelIndex &index, const QVariant &value, int role)
|
|
|
|
|
{
|
|
|
|
|
// map to source
|
|
|
|
|
if (m_checkable != ProScopeFilter::None && role == Qt::CheckStateRole) {
|
2008-12-02 12:57:59 +01:00
|
|
|
if (m_checkable == ProScopeFilter::Blocks
|
|
|
|
|
|| (m_checkable == ProScopeFilter::Variable && sourceVariable(index))) {
|
2008-12-02 12:01:29 +01:00
|
|
|
QModelIndex srcindex = mapToSource(index);
|
|
|
|
|
if (value.toInt() == Qt::Checked && !m_checkStates.value(srcindex, false)) {
|
|
|
|
|
m_checkStates.insert(srcindex, true);
|
|
|
|
|
emit dataChanged(index, index);
|
|
|
|
|
} else if (m_checkStates.value(srcindex, true)) {
|
|
|
|
|
m_checkStates.insert(srcindex, false);
|
|
|
|
|
emit dataChanged(index, index);
|
|
|
|
|
}
|
|
|
|
|
return true;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return QSortFilterProxyModel::setData(index, value, role);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
ProVariable *ProScopeFilter::sourceVariable(const QModelIndex &index) const
|
|
|
|
|
{
|
|
|
|
|
ProEditorModel *model = qobject_cast<ProEditorModel*>(sourceModel());
|
|
|
|
|
return model->proVariable(mapToSource(index));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool ProScopeFilter::filterAcceptsRow(int source_row, const QModelIndex &source_parent) const
|
|
|
|
|
{
|
|
|
|
|
ProEditorModel *model = qobject_cast<ProEditorModel*>(sourceModel());
|
|
|
|
|
if (!model)
|
|
|
|
|
return true;
|
|
|
|
|
|
|
|
|
|
QModelIndex index = model->index(source_row, 0, source_parent);
|
|
|
|
|
ProItem *item = model->proItem(index);
|
|
|
|
|
if (item->kind() != ProItem::BlockKind)
|
|
|
|
|
return false;
|
|
|
|
|
|
|
|
|
|
ProBlock *block = static_cast<ProBlock *>(item);
|
|
|
|
|
|
|
|
|
|
if (m_vars.isEmpty())
|
|
|
|
|
return (block->blockKind() & ProBlock::ScopeKind || block->blockKind() & ProBlock::ProFileKind);
|
|
|
|
|
|
|
|
|
|
if (block->blockKind() & ProBlock::VariableKind
|
|
|
|
|
|| block->blockKind() & ProBlock::ScopeKind
|
|
|
|
|
|| block->blockKind() & ProBlock::ProFileKind)
|
|
|
|
|
return !model->findVariables(m_vars, index).isEmpty();
|
|
|
|
|
|
|
|
|
|
return false;
|
|
|
|
|
}
|