File indexing completed on 2024-11-03 09:57:24
0001 /* 0002 SPDX-FileCopyrightText: 2009 Stephen Kelly <steveire@gmail.com> 0003 0004 SPDX-License-Identifier: LGPL-2.0-or-later 0005 */ 0006 0007 #include "scriptablereparentingwidget.h" 0008 0009 #include <QPlainTextEdit> 0010 #include <QScriptEngine> 0011 #include <QTreeView> 0012 #include <QVBoxLayout> 0013 0014 #include <QComboBox> 0015 #include <QLabel> 0016 #include <QSplitter> 0017 0018 static const char *const threadingFunctionNames[] = {"None", "Flat List", "Straight Line Tree", "Dragon Teeth 1", "Dragon Teeth 2", "Specified parents 1"}; 0019 0020 static const char *const threadingFunctionBodies[] = {"", 0021 "return false;", 0022 "return true;", 0023 "if (descendant % 3 ==1)\n" 0024 " return false;\n" 0025 "return true;", 0026 "if (descendant % 4 ==1)\n" 0027 " return false;\n" 0028 "return true;", 0029 "var threaddata = [[1, 2, 3, 4],\n" 0030 " [13, 14, 15],\n" 0031 " [13, 16, 17],\n" 0032 " [5, 6]];\n" 0033 "\n" 0034 "for (var i = 0; i < threaddata.length; ++i)\n" 0035 "{\n" 0036 " var a = threaddata[i].indexOf(ancestor);\n" 0037 " var d = threaddata[i].indexOf(descendant);\n" 0038 " if (a >= 0 && d >= 0)\n" 0039 " return a < d;\n" 0040 "}\n" 0041 "return false;"}; 0042 0043 ScriptableReparentingProxyModel::ScriptableReparentingProxyModel(QObject *parent) 0044 : KReparentingProxyModel(parent) 0045 , m_scriptEngine(new QScriptEngine(this)) 0046 { 0047 } 0048 0049 bool ScriptableReparentingProxyModel::isDescendantOf(const QModelIndex &ancestor, const QModelIndex &descendant) const 0050 { 0051 if (!m_implementationFunction.isValid()) { 0052 return KReparentingProxyModel::isDescendantOf(ancestor, descendant); 0053 } 0054 0055 QScriptValueList arguments = QScriptValueList() << ancestor.data().toInt() << descendant.data().toInt(); 0056 QScriptValue returnValue = m_implementationFunction.call(QScriptValue(), arguments); 0057 0058 if (!returnValue.isBool()) { 0059 return KReparentingProxyModel::isDescendantOf(ancestor, descendant); 0060 } 0061 0062 return returnValue.toBool(); 0063 } 0064 0065 void ScriptableReparentingProxyModel::setImplementation(const QString &implementation) 0066 { 0067 beginChangeRule(); 0068 m_implementationFunction = m_scriptEngine->evaluate(implementation); 0069 m_implementationFunction = m_scriptEngine->globalObject().property(QStringLiteral("isDescendantOf")); 0070 endChangeRule(); 0071 } 0072 0073 ScriptableReparentingWidget::ScriptableReparentingWidget(QAbstractItemModel *rootModel, QWidget *parent, Qt::WindowFlags f) 0074 : QWidget(parent, f) 0075 , m_reparentingProxyModel(new ScriptableReparentingProxyModel(this)) 0076 { 0077 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0078 QSplitter *splitter = new QSplitter(Qt::Vertical, this); 0079 mainLayout->addWidget(splitter); 0080 0081 m_treeView = new QTreeView(splitter); 0082 QWidget *container = new QWidget(splitter); 0083 QVBoxLayout *layout = new QVBoxLayout(container); 0084 m_textEdit = new QPlainTextEdit(container); 0085 m_textEdit->setFont(QFont(QStringLiteral("monospace"))); 0086 0087 m_comboBox = new QComboBox(container); 0088 for (int i = 0; i < int(sizeof threadingFunctionNames / sizeof *threadingFunctionNames); ++i) { 0089 m_comboBox->addItem(*(threadingFunctionNames + i), *(threadingFunctionBodies + i)); 0090 } 0091 layout->addWidget(m_comboBox); 0092 connect(m_comboBox, SIGNAL(currentIndexChanged(int)), SLOT(setExampleFunction(int))); 0093 0094 layout->addWidget(new QLabel(QStringLiteral("function isDescendantOf (ancestor, descendant) {"), container)); 0095 QHBoxLayout *indentedLayout = new QHBoxLayout; 0096 indentedLayout->addSpacing(30); 0097 indentedLayout->addWidget(m_textEdit); 0098 layout->addLayout(indentedLayout); 0099 layout->addWidget(new QLabel(QStringLiteral("}"), container)); 0100 0101 m_reparentingProxyModel->setSourceModel(rootModel); 0102 m_treeView->setModel(m_reparentingProxyModel); 0103 0104 splitter->setStretchFactor(0, 100); 0105 0106 connect(m_textEdit, SIGNAL(textChanged()), SLOT(textChanged())); 0107 textChanged(); 0108 } 0109 0110 void ScriptableReparentingWidget::setExampleFunction(int index) 0111 { 0112 m_textEdit->setPlainText(m_comboBox->itemData(index).toString()); 0113 } 0114 0115 void ScriptableReparentingWidget::textChanged() 0116 { 0117 m_reparentingProxyModel->setImplementation("function isDescendantOf (ancestor, descendant) { " + m_textEdit->toPlainText() + " }"); 0118 m_treeView->expandAll(); 0119 } 0120 0121 #include "moc_scriptablereparentingwidget.cpp"