#include "qcd_model.h" #include "cdutils_interface.h" #include "cdutils_core.h" #include "piqt.h" #include #include #include #include "qvariantedit.h" #include "qad_types.h" using namespace CDUtils; // CDKItem CDItem::CDItem(CDUtils::Interface * i, int index, CDItem::CDItemType type, CDItem *parent) { interface = i; index_ = index; parent_ = parent; type_ = type; } CDItem::~CDItem() { qDeleteAll(childs); } QVariant CDItem::data(int column, int role) const { if (role == Qt::BackgroundRole) { switch (type_) { case ItemCDType: { CDType & t = interface->section(buildPath())[index_]; if (t.errorString().isEmpty()) return QBrush(QColor(255, 250, 230)); else return QBrush(QColor(255, 128, 128)); } case ItemCDSection: return QBrush(QColor(230, 250, 230)); } } if (role == Qt::CheckStateRole && type_ == ItemCDType && column == 4) { CDType & t = interface->section(buildPath())[index_]; if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked; else QVariant(); } if (role == Qt::ToolTipRole && type_ == ItemCDType) { CDType & t = interface->section(buildPath())[index_]; return PI2QString(t.errorString()); } if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); PIDeque path = buildPath(); CDSection & rs = interface->section(path); CDSection s; switch (type_) { case ItemCDType: switch (column) { case 0: return QString::number(index_); case 1: return PI2QString(rs[index_].name()); case 2: return stringType(rs[index_].type()); case 3: return PI2QString(rs[index_].formula()); case 4: return value(rs[index_], role); case 5: return PI2QString(rs[index_].comment()); default: break; } break; case ItemCDSection: s = rs.section(index_); // piCout << rs.name << rs.alias << s.name << s.alias; switch (column) { case 0: return QString("[") + QString::number(index_) + QString("]"); case 1: return PI2QString(s.alias); case 2: return PI2QString(s.name); default: break; } break; } return QVariant(); } QVariant CDItem::value(CDType t, int role) const { if (t.type() == "f") return t.toDouble(); if (t.type() == "n") return t.toInt(); if (t.type() == "b") return t.toBool(); if (t.type() == "e") { QAD::Enum et = PI2QADEnum(t.enumValues()); et.selectValue(t.toInt()); if (role == Qt::EditRole) return QVariant::fromValue(et); else return et.selectedName(); } return PI2QString(t.value()); } bool CDItem::setData(int column, const QVariant &value) { if ((column == 3 || column == 4) && type_ == ItemCDType) { interface->section(buildPath())[index_].setValue(Q2PIString(value.toString())); interface->calculate(); return true; } return false; } PIDeque CDItem::buildPath() const { PIDeque path; CDItem * p = parent_; while (p) { path.push_front(p->index_); p = p->parent_; } path.take_front(); return path; } QString CDItem::stringType(const PIString & t) const { QString n = PI2QString(t); if (n.isEmpty()) return QString(""); switch (n[0].toLatin1()) { case 'l': return QString("list"); break; case 'b': return QString("bool"); break; case 'n': return QString("int"); break; case 'f': return QString("double"); break; case 'c': return QString("color"); break; case 'r': return QString("rect"); break; case 'a': return QString("rect"); break; case 'p': return QString("point"); break; case 'v': return QString("vector"); break; case 'i': return QString("IP"); break; case 'e': return QString("enum"); break; case 'F': return QString("file"); break; case 'D': return QString("dir"); break; } return QString("string"); } // CDKDelegate CDDelegate::CDDelegate(QObject *parent) : QStyledItemDelegate(parent) { } QWidget *CDDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { return new QVariantEdit(parent); } void CDDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QVariantEdit *edit = static_cast(editor); edit->setValue(index.model()->data(index, Qt::EditRole)); } void CDDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QVariantEdit *edit = static_cast(editor); QVariant v = edit->value(); if (v.canConvert()) { QAD::Enum et = v.value(); model->setData(index, et.selectedValue(), Qt::EditRole); } else model->setData(index, v, Qt::EditRole); } void CDDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } QSize CDDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize s = QStyledItemDelegate::sizeHint(option, index); s.setWidth(s.width() + 20); return s; } // CDItemModel CDItemModel::CDItemModel(int type_, QObject *parent) : QAbstractItemModel(parent) { interface = new Interface((CDType::cdT)type_); root = 0; internalRebuild(); } CDItemModel::~CDItemModel() { delete root; delete interface; } QVariant CDItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); CDItem *item = getItem(index); return item->data(index.column(), role); } QVariant CDItemModel::headerData(int section, Qt::Orientation orientation, int role) const { if (orientation == Qt::Horizontal && role == Qt::DisplayRole) { switch (section) { case 0: return trUtf8("Index"); case 1: return trUtf8("Name"); case 2: return trUtf8("Type"); case 3: return trUtf8("Expression"); case 4: return trUtf8("Value"); case 5: return trUtf8("Comment"); } } return QVariant(); } QModelIndex CDItemModel::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid() && parent.column() != 0) return QModelIndex(); CDItem * p = getItem(parent); CDItem * c = p->childs.value(row, 0); if (c) return createIndex(row, column, c); else return QModelIndex(); } QModelIndex CDItemModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); CDItem * c = getItem(index); CDItem * p = c->parent_; if (p == root) return QModelIndex(); return createIndex(p->parent_->childs.indexOf(p), 0, p); } int CDItemModel::rowCount(const QModelIndex &parent) const { CDItem *p = getItem(parent); return p->childs.count(); } int CDItemModel::columnCount(const QModelIndex &parent) const { return 6; } Qt::ItemFlags CDItemModel::flags(const QModelIndex & index) const { if (!index.isValid()) return 0; Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; CDItem * item = getItem(index); if (!item) return 0; CDType & t(interface->section(item->buildPath())[item->index_]); if ((index.column() == 3 || index.column() == 4) && (item->type_ == CDItem::ItemCDType) && (t.cd_type() == CDType::cdK)) f |= Qt::ItemIsEditable; if (item->type_ == CDItem::ItemCDType && index.column() == 4) { if (t.type() == "b") { f |= Qt::ItemIsUserCheckable; // piCout << "ItemIsUserCheckable"; } } return f; } bool CDItemModel::setData(const QModelIndex & index, const QVariant &value, int role) { if (role == Qt::CheckStateRole && index.column() == 4) { CDItem * item = getItem(index); if (item->type_ == CDItem::ItemCDType) { CDType t = interface->section(item->buildPath())[item->index_]; if (t.type() == "b") { bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool()))); QModelIndex rin(CDItemModel::index(index.row(), 3, index.parent())); emit dataChanged(rin, rin); return result; } } } if (role != Qt::EditRole) return false; CDItem * item = getItem(index); bool result = item->setData(index.column(), value); if (result) { QModelIndex rin(CDItemModel::index(index.row(), 3, index.parent())); emit dataChanged(rin, rin); emit dataChanged(index, index); } return result; } void CDItemModel::rebuildModel() { beginResetModel(); internalRebuild(); endResetModel(); } void CDItemModel::buildItem(CDItem *it, CDSection & r) { //piCout << "build item" << r.name << r.alias; PIMap::iterator i; for (i = r.cd.begin(); i != r.cd.end(); ++i) { it->childs << new CDItem(interface, i.key(), CDItem::ItemCDType, it); } PIMap::iterator j; for (j = r.s.begin(); j != r.s.end(); ++j) { it->childs << new CDItem(interface, j.key(), CDItem::ItemCDSection, it); buildItem(it->childs.back(), j.value()); } } void CDItemModel::updateModel() { beginResetModel(); endResetModel(); } void CDItemModel::internalRebuild() { //qDebug() << "[CDKItemModel]" << "internalRebuild()"; if (root) delete root; root = new CDItem(interface, 0, CDItem::ItemCDSection, 0); CDSection & r = interface->root(); buildItem(root, r); } CDItem * CDItemModel::getItem(const QModelIndex &index) const { if (index.isValid()) { CDItem * item = static_cast(index.internalPointer()); if (item) return item; } return root; }