File indexing completed on 2024-04-28 15:28:39

0001 /* This file is part of the KDE libraries
0002     Copyright (C) 2005, 2006 Ian Reinhart Geiser <geiseri@kde.org>
0003     Copyright (C) 2005, 2006 Matt Broadstone <mbroadst@gmail.com>
0004     Copyright (C) 2005, 2006 Richard J. Moore <rich@kde.org>
0005     Copyright (C) 2005, 2006 Erik L. Bunce <kde@bunce.us>
0006 
0007     This library is free software; you can redistribute it and/or
0008     modify it under the terms of the GNU Library General Public
0009     License as published by the Free Software Foundation; either
0010     version 2 of the License, or (at your option) any later version.
0011 
0012     This library is distributed in the hope that it will be useful,
0013     but WITHOUT ANY WARRANTY; without even the implied warranty of
0014     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
0015     Library General Public License for more details.
0016 
0017     You should have received a copy of the GNU Library General Public License
0018     along with this library; see the file COPYING.LIB.  If not, write to
0019     the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
0020     Boston, MA 02110-1301, USA.
0021 */
0022 #include "kjs_object_model.h"
0023 
0024 #include <QPixmap>
0025 #include <QDebug>
0026 
0027 #include <kjs/object.h>
0028 #include <kjs/interpreter.h>
0029 #include <kjs/PropertyNameArray.h>
0030 
0031 struct Node {
0032     QByteArray name;
0033     KJS::JSObject *instance;
0034     Node *parent;
0035 };
0036 
0037 KJSObjectModel::KJSObjectModel(KJS::Interpreter *js, QObject *parent):
0038     QAbstractItemModel(parent), m_js(js)
0039 {
0040 }
0041 
0042 void KJSObjectModel::updateModel(KJS::JSObject *root)
0043 {
0044     m_root = root;
0045     reset();
0046 }
0047 
0048 KJSObjectModel::~KJSObjectModel()
0049 {
0050 }
0051 
0052 Qt::ItemFlags KJSObjectModel::flags(const QModelIndex &index) const
0053 {
0054     if (!index.isValid()) {
0055         return Qt::ItemIsEnabled;
0056     }
0057     return Qt::ItemIsEnabled | Qt::ItemIsSelectable;
0058 }
0059 
0060 int KJSObjectModel::rowCount(const QModelIndex &parent) const
0061 {
0062     KJS::ExecState *exec = m_js->globalExec();
0063     KJS::PropertyNameArray props;
0064     if (!parent.isValid()) {
0065         m_root->getPropertyNames(exec, props);
0066     } else {
0067         Node *item = static_cast<Node *>(parent.internalPointer());
0068         item->instance->getPropertyNames(exec, props);
0069     }
0070     return props.size();
0071 }
0072 
0073 int KJSObjectModel::columnCount(const QModelIndex &parent) const
0074 {
0075     Q_UNUSED(parent);
0076     return 1;
0077 }
0078 
0079 QVariant KJSObjectModel::headerData(int section, Qt::Orientation orientation, int role) const
0080 {
0081     if (orientation == Qt::Horizontal && role == Qt::DisplayRole) {
0082         if (section == 0) {
0083             return "Object Name";
0084         } else {
0085             return "Value";
0086         }
0087     }
0088     return QVariant();
0089 }
0090 
0091 QModelIndex KJSObjectModel::index(int row, int column, const QModelIndex &parent) const
0092 {
0093     KJS::JSObject *parentInstance = nullptr;
0094     Node *childItem = nullptr;
0095     KJS::ExecState *exec = m_js->globalExec();
0096 
0097     if (!parent.isValid()) {
0098         if (m_root) {
0099             parentInstance = m_root;
0100         } else {
0101             return QModelIndex();
0102         }
0103     } else {
0104         parentInstance = static_cast<Node *>(parent.internalPointer())->instance;
0105     }
0106     int idx = 0;
0107     KJS::PropertyNameArray props;
0108     parentInstance->getPropertyNames(exec, props);
0109     for (KJS::PropertyNameArrayIterator ref = props.begin(); ref != props.end(); ref++) {
0110         if (idx == row) {
0111             childItem = new Node;
0112             childItem->name = ref->ascii(); //### M.O.: this is wrong, can be unicode.
0113             childItem->instance = parentInstance->get(exec,
0114                                   childItem->name.constData())->toObject(exec);
0115             childItem->parent = static_cast<Node *>(parent.internalPointer());
0116             break;
0117         }
0118         ++idx;
0119     }
0120     if (childItem) {
0121         return createIndex(row, column, childItem);
0122     }
0123 
0124     return QModelIndex();
0125 }
0126 
0127 QModelIndex KJSObjectModel::parent(const QModelIndex &index) const
0128 {
0129     if (!index.isValid()) {
0130         Node *node = new Node;
0131         node->instance = m_root;
0132         node->name = "Objects";
0133         node->parent = nullptr;
0134         return createIndex(0, index.column(), node);
0135     }
0136 
0137     Node *parentItem = static_cast<Node *>(index.internalPointer())->parent;
0138     if (parentItem) {
0139         Node *node = new Node;
0140         node->instance = parentItem->instance;
0141         node->name = parentItem->name;
0142         node->parent = parentItem->parent;
0143         return createIndex(0, index.column(), node);
0144     } else {
0145         return QModelIndex();
0146     }
0147 }
0148 
0149 QVariant KJSObjectModel::data(const QModelIndex &index, int role) const
0150 {
0151     if (!index.isValid()) {
0152         return QVariant();
0153     }
0154 
0155     Node *item = static_cast<Node *>(index.internalPointer());
0156     KJS::JSObject *instance = item->instance;
0157 
0158     if (role == Qt::DecorationRole) {
0159         if (instance->implementsConstruct()) {
0160             return QPixmap(":/images/class.png");
0161         } else if (instance->implementsCall()) {
0162             return QPixmap(":/images/method.png");
0163         } else {
0164             return QPixmap(":/images/property.png");
0165         }
0166     }
0167     if (role == Qt::ForegroundRole) {
0168         if (instance->implementsConstruct()) {
0169             return QColor("blue");
0170         } else if (instance->implementsCall()) {
0171             return QColor("green");
0172         } else {
0173             return QColor("black");
0174         }
0175     }
0176     if (role == Qt::DisplayRole) {
0177         return item->name;
0178     }
0179     return QVariant();
0180 }
0181 
0182 #include "moc_kjs_object_model.cpp"