#include "qcd_kmodel.h" #include "cdutils_k.h" #include "piqt.h" #include #include #include #include "qvariantedit.h" using namespace CDUtils; CDKItemModel::CDKItemModel(QObject *parent) : QAbstractItemModel(parent) { root = 0; internalRebuild(); } CDKItemModel::~CDKItemModel() { delete root; } QVariant CDKItemModel::data(const QModelIndex &index, int role) const { if (!index.isValid()) return QVariant(); CDKItem *item = getItem(index); return item->data(index.column(), role); } QVariant CDKItemModel::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 CDKItemModel::index(int row, int column, const QModelIndex &parent) const { if (parent.isValid() && parent.column() != 0) return QModelIndex(); CDKItem * p = getItem(parent); CDKItem * c = p->childs.value(row, 0); if (c) return createIndex(row, column, c); else return QModelIndex(); } QModelIndex CDKItemModel::parent(const QModelIndex &index) const { if (!index.isValid()) return QModelIndex(); CDKItem * c = getItem(index); CDKItem * p = c->parent_; if (p == root) return QModelIndex(); return createIndex(p->parent_->childs.indexOf(p), 0, p); } int CDKItemModel::rowCount(const QModelIndex &parent) const { CDKItem *p = getItem(parent); return p->childs.count(); } int CDKItemModel::columnCount(const QModelIndex &parent) const { return 6; } Qt::ItemFlags CDKItemModel::flags(const QModelIndex &index) const { if (!index.isValid()) return 0; Qt::ItemFlags f = Qt::ItemIsEnabled | Qt::ItemIsSelectable; CDKItem * item = getItem(index); if ((index.column() == 3 || index.column() == 4) && item->type_ == CDKItem::ItemCDType) f |= Qt::ItemIsEditable; if (item->type_ == CDKItem::ItemCDType && index.column() == 4) { CDType t = K.section(item->buildPath())[item->index_]; if (t.type() == "b") { f |= Qt::ItemIsUserCheckable; // piCout << "ItemIsUserCheckable"; } } return f; } bool CDKItemModel::setData(const QModelIndex &index, const QVariant &value, int role) { if (role == Qt::CheckStateRole && index.column() == 4) { CDKItem * item = getItem(index); if (item->type_ == CDKItem::ItemCDType) { CDType t = K.section(item->buildPath())[item->index_]; if (t.type() == "b") { bool result = item->setData(index.column(), PI2QString(PIString::fromBool(value.toBool()))); return result; } } } if (role != Qt::EditRole) return false; CDKItem * item = getItem(index); bool result = item->setData(index.column(), value); if (result) emit dataChanged(index, index); return result; } void CDKItemModel::rebuildModel() { beginResetModel(); internalRebuild(); endResetModel(); } void CDKItemModel::buildItem(CDKItem *it, CDSection & r) { //piCout << "build item" << r.name << r.alias; PIMap::iterator i; for (i = r.k.begin(); i != r.k.end(); ++i) { it->childs << new CDKItem(i.key(), CDKItem::ItemCDType, it); } PIMap::iterator j; for (j = r.s.begin(); j != r.s.end(); ++j) { it->childs << new CDKItem(j.key(), CDKItem::ItemCDSection, it); buildItem(it->childs.back(), j.value()); } } void CDKItemModel::updateModel() { beginResetModel(); endResetModel(); } void CDKItemModel::internalRebuild() { //qDebug() << "[CDKItemModel]" << "internalRebuild()"; if (root) delete root; root = new CDKItem(0, CDKItem::ItemCDSection, 0); CDSection & r = K.root(); buildItem(root, r); } CDKItem * CDKItemModel::getItem(const QModelIndex &index) const { if (index.isValid()) { CDKItem * item = static_cast(index.internalPointer()); if (item) return item; } return root; } // CDKItem CDKItem::CDKItem(int index, CDKItem::CDKItemType type, CDKItem *parent) { index_ = index; parent_ = parent; type_ = type; } CDKItem::~CDKItem() { qDeleteAll(childs); } QVariant CDKItem::data(int column, int role) const { if (role == Qt::BackgroundRole) { switch (type_) { case ItemCDType: { CDType & t = K.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 = K.section(buildPath())[index_]; if (t.type() == "b") return t.toBool() ? Qt::Checked : Qt::Unchecked; else QVariant(); } if (role == Qt::ToolTipRole && type_ == ItemCDType) { CDType & t = K.section(buildPath())[index_]; return PI2QString(t.errorString()); } if (role != Qt::DisplayRole && role != Qt::EditRole) return QVariant(); PIDeque path = buildPath(); CDSection & rs = K.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 CDKItem::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") { QVariantEdit::EnumType et; et.enum_list = PI2QStringList(t.enumValues()); et.value = et.enum_list.at(t.toInt());//et.enum_list.indexOf(""); if (role == Qt::EditRole)return QVariant::fromValue(et); else return et.value; } return PI2QString(t.value()); } bool CDKItem::setData(int column, const QVariant &value) { if ((column == 3 || column == 4) && type_ == ItemCDType) { K.section(buildPath())[index_].setValue(Q2PIString(value.toString())); return true; } return false; } PIDeque CDKItem::buildPath() const { PIDeque path; CDKItem * p = parent_; while (p) { path.push_front(p->index_); p = p->parent_; } path.take_front(); return path; } QString CDKItem::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("double"); } // CDKDelegate CDKDelegate::CDKDelegate(QObject *parent) : QStyledItemDelegate(parent) { } QWidget *CDKDelegate::createEditor(QWidget *parent, const QStyleOptionViewItem &option, const QModelIndex &index) const { return new QVariantEdit(parent); } void CDKDelegate::setEditorData(QWidget *editor, const QModelIndex &index) const { QVariantEdit *edit = static_cast(editor); edit->setValue(index.model()->data(index, Qt::EditRole)); } void CDKDelegate::setModelData(QWidget *editor, QAbstractItemModel *model, const QModelIndex &index) const { QVariantEdit *edit = static_cast(editor); QVariant v = edit->value(); if (v.canConvert()) { QVariantEdit::EnumType et = v.value(); model->setData(index, et.enum_list.indexOf(et.value), Qt::EditRole); } else model->setData(index, v, Qt::EditRole); } void CDKDelegate::updateEditorGeometry(QWidget *editor, const QStyleOptionViewItem &option, const QModelIndex &index) const { editor->setGeometry(option.rect); } QSize CDKDelegate::sizeHint(const QStyleOptionViewItem &option, const QModelIndex &index) const { QSize s = QStyledItemDelegate::sizeHint(option, index); s.setWidth(s.width() + 20); return s; }