File indexing completed on 2024-04-21 03:45:28
0001 /* 0002 SPDX-FileCopyrightText: 2003-2008 Cies Breijs <cies AT kde DOT nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "inspector.h" 0008 0009 #include "interpreter/translator.h" // for getting the translated ArgumentSeparator 0010 0011 #include <QDebug> 0012 #include <QFontDatabase> 0013 #include <QHeaderView> 0014 #include <QTabWidget> 0015 #include <QTableWidget> 0016 #include <QTreeWidget> 0017 #include <QHBoxLayout> 0018 0019 #include <KLocalizedString> 0020 #include <qwidget.h> 0021 0022 0023 Inspector::Inspector(QWidget *parent) 0024 : QWidget(parent) 0025 { 0026 mainLayout = new QHBoxLayout(this); 0027 mainLayout->setSpacing(0); 0028 mainLayout->setContentsMargins(0, 0, 0, 0); 0029 tabWidget = new QTabWidget(this); 0030 tabWidget->setDocumentMode(true); 0031 0032 variableTab = new QWidget(); 0033 variableLayout = new QHBoxLayout(variableTab); 0034 variableTable = new QTableWidget(variableTab); 0035 variableTable->setAlternatingRowColors(true); 0036 variableLayout->addWidget(variableTable); 0037 tabWidget->addTab(variableTab, i18n("Variables")); 0038 0039 functionTab = new QWidget(); 0040 functionLayout = new QHBoxLayout(functionTab); 0041 functionTable = new QTableWidget(functionTab); 0042 functionTable->setAlternatingRowColors(true); 0043 functionLayout->addWidget(functionTable); 0044 tabWidget->addTab(functionTab, i18n("Functions")); 0045 0046 treeTab = new QWidget(); 0047 treeLayout = new QHBoxLayout(treeTab); 0048 treeView = new QTreeWidget(treeTab); 0049 treeView->header()->setVisible(false); 0050 treeLayout->addWidget(treeView); 0051 tabWidget->addTab(treeTab, i18n("Tree")); 0052 0053 mainLayout->addWidget(tabWidget); 0054 0055 // our syntax highlighter (this does not do any markings) 0056 highlighter = new Highlighter(); 0057 0058 // // the maps used when marking table/tree items later 0059 // variableMap = new QHash<QString, QTableWidgetItem*>(); 0060 // functionMap = new QHash<QString, QTableWidgetItem*>(); 0061 // treeMap = new QHash<TreeNode*, QTableWidgetItem*>(); 0062 0063 currentlyMarkedTreeItem = nullptr; 0064 0065 disable(); 0066 0067 clear(); 0068 } 0069 0070 Inspector::~Inspector() 0071 { 0072 delete highlighter; 0073 } 0074 0075 0076 void Inspector::disable() 0077 { 0078 variableTable->setEnabled(false); 0079 functionTable->setEnabled(false); 0080 treeView->setEnabled(false); 0081 // enabling happened when the inspector gets filled with data 0082 } 0083 0084 void Inspector::clear() 0085 { 0086 clearAllMarks(); 0087 0088 // Question: is the code duplication below enough 0089 // for a subclass-of-QTableWidget based approach? 0090 0091 variableMap.clear(); 0092 variableTableEmpty = true; 0093 variableTable->clear(); 0094 QStringList headers; 0095 headers << i18n("name") << i18n("value") << i18n("type"); 0096 variableTable->setColumnCount(3); 0097 variableTable->setHorizontalHeaderLabels(headers); 0098 variableTable->setSelectionMode(QAbstractItemView::SingleSelection); 0099 variableTable->setSelectionBehavior(QAbstractItemView::SelectRows); 0100 variableTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); 0101 variableTable->verticalHeader()->setVisible(false); 0102 variableTable->setShowGrid(false); 0103 variableTable->setRowCount(1); 0104 QTableWidgetItem* emptyItem; 0105 emptyItem = new QTableWidgetItem(i18n("No variables")); 0106 variableTable->setItem(0, 0, emptyItem); 0107 variableTable->resizeColumnsToContents(); 0108 0109 functionMap.clear(); 0110 functionTableEmpty = true; 0111 functionTable->clear(); 0112 headers.clear(); 0113 headers << i18n("name") << i18n("parameters"); 0114 functionTable->setColumnCount(2); 0115 functionTable->setHorizontalHeaderLabels(headers); 0116 functionTable->setSelectionMode(QAbstractItemView::SingleSelection); 0117 functionTable->setSelectionBehavior(QAbstractItemView::SelectRows); 0118 functionTable->horizontalHeader()->setDefaultAlignment(Qt::AlignLeft); 0119 functionTable->verticalHeader()->setVisible(false); 0120 functionTable->setShowGrid(false); 0121 functionTable->setRowCount(1); 0122 emptyItem = new QTableWidgetItem(i18n("No learned functions")); 0123 functionTable->setItem(0, 0, emptyItem); 0124 functionTable->resizeColumnsToContents(); 0125 0126 // Treeview gets cleared in updateTree() 0127 disable(); 0128 } 0129 0130 0131 void Inspector::updateVariable(const QString& name, const Value& value) 0132 { 0133 // Check if the variable has already been added to the table 0134 int row = findVariable(name); 0135 if (row == -1) { 0136 // We are dealing with a new variable 0137 if (variableTableEmpty) { // Check whether we have to add a new row 0138 variableTableEmpty = false; 0139 } else { 0140 variableTable->insertRow(0); 0141 } 0142 row = 0; 0143 } 0144 0145 QTableWidgetItem* nameItem; 0146 nameItem = new QTableWidgetItem(name); 0147 nameItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0148 QTextCharFormat* format = highlighter->formatForStatement(name); 0149 nameItem->setFont(format->font()); 0150 nameItem->setForeground(format->foreground()); 0151 variableTable->setItem(row, 0, nameItem); 0152 variableMap[name] = nameItem; 0153 0154 QTableWidgetItem* valueItem; 0155 valueItem = new QTableWidgetItem(value.string()); 0156 valueItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0157 // TODO variable coloring when tokens are available in the inspector! 0158 // format = highlighter->formatForStatement(value.string()); 0159 // valueItem->setFont(format->font()); 0160 // valueItem->setForeground(format->foreground()); 0161 0162 QTableWidgetItem* typeItem; 0163 switch (value.type()) { 0164 case Value::Empty: { 0165 typeItem = new QTableWidgetItem(i18nc("undefined type of a variable","empty")); 0166 QFont font = typeItem->font(); 0167 font.setItalic(true); 0168 typeItem->setFont(font); 0169 } 0170 break; 0171 case Value::Bool: 0172 typeItem = new QTableWidgetItem(i18n("boolean")); 0173 break; 0174 case Value::Number: 0175 typeItem = new QTableWidgetItem(i18n("number")); 0176 break; 0177 case Value::String: 0178 typeItem = new QTableWidgetItem(i18n("string")); 0179 break; 0180 default: 0181 // should never happen 0182 typeItem = new QTableWidgetItem(QStringLiteral("ERROR! please report to KTurtle developers")); 0183 break; 0184 } 0185 typeItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0186 variableTable->setItem(row, 1, valueItem); 0187 variableTable->setItem(row, 2, typeItem); 0188 0189 variableTable->sortItems(0); 0190 variableTable->resizeColumnsToContents(); 0191 variableTable->setEnabled(true); 0192 } 0193 0194 void Inspector::updateFunction(const QString& name, const QStringList& parameters) 0195 { 0196 // When there is already a the 'Nothing to show' line re-use that one and don't add another 0197 if (functionTableEmpty) { 0198 functionTableEmpty = false; 0199 } else { 0200 functionTable->insertRow(0); 0201 } 0202 0203 QTableWidgetItem* nameItem = new QTableWidgetItem(name); 0204 nameItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0205 functionTable->setItem(0, 0, nameItem); 0206 functionMap[name] = nameItem; 0207 0208 QTableWidgetItem* paramItem; 0209 if (parameters.empty()) { 0210 paramItem = new QTableWidgetItem(i18n("None")); 0211 QFont font = paramItem->font(); 0212 font.setItalic(true); 0213 paramItem->setFont(font); 0214 } else { 0215 QString paramList = parameters.join(Translator::instance()->default2localized(QStringLiteral(","))); 0216 paramItem = new QTableWidgetItem(paramList); 0217 } 0218 0219 paramItem->setFlags(Qt::ItemIsSelectable | Qt::ItemIsEnabled); 0220 functionTable->setItem(0, 1, paramItem); 0221 functionTable->sortItems(0); 0222 functionTable->resizeColumnsToContents(); 0223 functionTable->setEnabled(true); 0224 } 0225 0226 void Inspector::updateTree(TreeNode* rootNode) 0227 { 0228 treeMap.clear(); 0229 treeView->clear(); 0230 QTreeWidgetItem* rootItem = walkTree(rootNode); 0231 const auto rootItemChildren = rootItem->takeChildren(); 0232 for (QTreeWidgetItem* item : rootItemChildren) { 0233 treeView->addTopLevelItem(item); 0234 } 0235 delete rootItem; 0236 treeView->expandAll(); 0237 treeView->setEnabled(true); 0238 } 0239 0240 QTreeWidgetItem* Inspector::walkTree(TreeNode* node) 0241 { 0242 QTreeWidgetItem* result = new QTreeWidgetItem(); 0243 result->setText(0, node->token()->look()); 0244 QTextCharFormat* format = highlighter->tokenToFormat(node->token()); 0245 if (format) { 0246 result->setForeground(0, format->foreground()); 0247 QFont font(QFontDatabase::systemFont(QFontDatabase::FixedFont)); 0248 font.setBold(format->font().bold()); 0249 result->setFont(0, font); 0250 } 0251 treeMap[node] = result; 0252 if (node->hasChildren()) { 0253 for (uint i = 0; i < node->childCount(); i++) { 0254 result->addChild(walkTree(node->child(i))); 0255 } 0256 } 0257 return result; 0258 } 0259 0260 int Inspector::findVariable(const QString& name) 0261 { 0262 QTableWidgetItem* item = variableMap[name]; 0263 if (!item) return -1; 0264 return item->row(); 0265 0266 // old implementation before we had a variableMap 0267 0268 // // This function will search for a specified variable and return the row number of this variable. 0269 // QList<QTableWidgetItem*> matches = variableTable->findItems(name, Qt::MatchExactly); 0270 // QList<QTableWidgetItem*>::iterator i; 0271 // for (i = matches.begin(); i != matches.end(); ++i) { 0272 // if ((*i)->column() == 0) // only check the first column 0273 // return (*i)->row(); 0274 // } 0275 // return -1; 0276 } 0277 0278 void Inspector::markVariable(const QString& name) 0279 { 0280 Q_UNUSED(name); 0281 //qDebug() << variableMap[name]->row(); 0282 } 0283 0284 void Inspector::markFunction(const QString& name) 0285 { 0286 Q_UNUSED(name); 0287 //qDebug() << functionMap[name]->row(); 0288 } 0289 0290 void Inspector::markTreeNode(TreeNode* node) 0291 { 0292 // //qDebug() << treeMap[node]->text(0); 0293 clearTreeMark(); 0294 currentlyMarkedTreeItem = treeMap[node]; 0295 previousTreeBackground = currentlyMarkedTreeItem->background(0); 0296 currentlyMarkedTreeItem->setBackground(0, QBrush(WORD_HIGHLIGHT_COLOR)); 0297 } 0298 0299 void Inspector::clearTreeMark() 0300 { 0301 if (!currentlyMarkedTreeItem) return; 0302 currentlyMarkedTreeItem->setBackground(0, previousTreeBackground); 0303 currentlyMarkedTreeItem = nullptr; 0304 } 0305 0306 void Inspector::clearAllMarks() 0307 { 0308 clearTreeMark(); 0309 } 0310 0311 #include "moc_inspector.cpp"