File indexing completed on 2024-10-06 03:40:27
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 <QJSEngine> 0010 #include <QPlainTextEdit> 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 QJSEngine(this)) 0046 { 0047 } 0048 0049 bool ScriptableReparentingProxyModel::isDescendantOf(const QModelIndex &ancestor, const QModelIndex &descendant) const 0050 { 0051 if (!m_implementationFunction.isCallable()) { 0052 return KReparentingProxyModel::isDescendantOf(ancestor, descendant); 0053 } 0054 0055 QJSValue returnValue = m_implementationFunction.call({ancestor.data().toInt(), descendant.data().toInt()}); 0056 0057 if (!returnValue.isBool()) { 0058 return KReparentingProxyModel::isDescendantOf(ancestor, descendant); 0059 } 0060 0061 return returnValue.toBool(); 0062 } 0063 0064 void ScriptableReparentingProxyModel::setImplementation(const QString &implementation) 0065 { 0066 beginChangeRule(); 0067 m_implementationFunction = m_scriptEngine->evaluate(implementation); 0068 m_implementationFunction = m_scriptEngine->globalObject().property(QStringLiteral("isDescendantOf")); 0069 endChangeRule(); 0070 } 0071 0072 ScriptableReparentingWidget::ScriptableReparentingWidget(QAbstractItemModel *rootModel, QWidget *parent, Qt::WindowFlags f) 0073 : QWidget(parent, f) 0074 , m_reparentingProxyModel(new ScriptableReparentingProxyModel(this)) 0075 { 0076 QVBoxLayout *mainLayout = new QVBoxLayout(this); 0077 QSplitter *splitter = new QSplitter(Qt::Vertical, this); 0078 mainLayout->addWidget(splitter); 0079 0080 m_treeView = new QTreeView(splitter); 0081 QWidget *container = new QWidget(splitter); 0082 QVBoxLayout *layout = new QVBoxLayout(container); 0083 m_textEdit = new QPlainTextEdit(container); 0084 m_textEdit->setFont(QFont(QStringLiteral("monospace"))); 0085 0086 m_comboBox = new QComboBox(container); 0087 for (int i = 0; i < int(sizeof threadingFunctionNames / sizeof *threadingFunctionNames); ++i) { 0088 m_comboBox->addItem(*(threadingFunctionNames + i), *(threadingFunctionBodies + i)); 0089 } 0090 layout->addWidget(m_comboBox); 0091 connect(m_comboBox, SIGNAL(currentIndexChanged(int)), SLOT(setExampleFunction(int))); 0092 0093 layout->addWidget(new QLabel(QStringLiteral("function isDescendantOf (ancestor, descendant) {"), container)); 0094 QHBoxLayout *indentedLayout = new QHBoxLayout; 0095 indentedLayout->addSpacing(30); 0096 indentedLayout->addWidget(m_textEdit); 0097 layout->addLayout(indentedLayout); 0098 layout->addWidget(new QLabel(QStringLiteral("}"), container)); 0099 0100 m_reparentingProxyModel->setSourceModel(rootModel); 0101 m_treeView->setModel(m_reparentingProxyModel); 0102 0103 splitter->setStretchFactor(0, 100); 0104 0105 connect(m_textEdit, SIGNAL(textChanged()), SLOT(textChanged())); 0106 textChanged(); 0107 } 0108 0109 void ScriptableReparentingWidget::setExampleFunction(int index) 0110 { 0111 m_textEdit->setPlainText(m_comboBox->itemData(index).toString()); 0112 } 0113 0114 void ScriptableReparentingWidget::textChanged() 0115 { 0116 m_reparentingProxyModel->setImplementation("function isDescendantOf (ancestor, descendant) { " + m_textEdit->toPlainText() + " }"); 0117 m_treeView->expandAll(); 0118 } 0119 0120 #include "moc_scriptablereparentingwidget.cpp"