Skip to content

Commit

Permalink
feat: Handle QTextEdit in the ScriptDialogItem (#141)
Browse files Browse the repository at this point in the history
Fixes #27
to use the syntax highlighting of the "data.foo" widget, just use the name of the extension like "cpp", "js" or "py" in the "data.fooSyntax" property
  • Loading branch information
smnppKDAB authored Aug 7, 2024
1 parent c49732a commit 77af0b7
Show file tree
Hide file tree
Showing 5 changed files with 114 additions and 31 deletions.
18 changes: 13 additions & 5 deletions examples/ex_script_dialog.qml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,12 @@ ScriptDialog {
// Defined the possible choices for the comboBoxfine
data.comboBoxModel = ["1", "2", "3"]
data.comboBox = "2"
// Initialize textEdit and plainTextEdit with example text and syntax
data.textEdit = "// Example C++ code\nint main() {\n return 0;\n}"
data.textEditSyntax = "cpp"
data.plainTextEdit = "// Example JavaScript code\nfunction hello() {\n console.log('Hello');\n}"
data.plainTextEditSyntax = "js"

}

function showData() {
Expand All @@ -36,6 +42,8 @@ ScriptDialog {
Message.log("SpinBox data: " + data.spinBox)
Message.log("DoubleSpinBox data: " + data.doubleSpinBox)
Message.log("ComboBox data: " + data.comboBox)
Message.log("TextEdit data: " + data.textEdit)
Message.log("PlainTextEdit data: " + data.plainTextEdit)
}

// Function called when the user click on the OK button
Expand All @@ -46,21 +54,21 @@ ScriptDialog {

// Function called when the user click on the Cancel button
onRejected: {
// Logging when the Cancel button is clicked
// Logging when the Cancel button is clicked
Message.log("Cancel button is clicked")
}

// Function called when a button is clicked
onClicked:(name)=>{
if (name == "pushButton"){
onClicked: (name) => {
if (name === "pushButton") {
Message.log("PushButton is clicked")
}
else if (name == "toolButton"){
} else if (name === "toolButton") {
Message.log("ToolButton is clicked")
}
}
// Function to automatically test the script, useful for automated testing
// It runs the script without user interaction

function test_script() {
showData();
close();
Expand Down
59 changes: 33 additions & 26 deletions examples/ex_script_dialog.ui
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,8 @@
<rect>
<x>0</x>
<y>0</y>
<width>407</width>
<height>374</height>
<width>291</width>
<height>471</height>
</rect>
</property>
<property name="windowTitle">
Expand All @@ -28,6 +28,23 @@
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<property name="text">
<string>toolButton</string>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="toolButton">
<property name="enabled">
<bool>true</bool>
</property>
<property name="text">
<string>ToolButton</string>
</property>
</widget>
</item>
<item row="2" column="0">
<widget class="QLabel" name="label">
<property name="text">
Expand Down Expand Up @@ -100,47 +117,37 @@
<item row="7" column="1">
<widget class="QComboBox" name="comboBox"/>
</item>
<item row="8" column="1">
<spacer name="verticalSpacer">
<property name="orientation">
<enum>Qt::Vertical</enum>
</property>
<property name="sizeHint" stdset="0">
<size>
<width>20</width>
<height>249</height>
</size>
</property>
</spacer>
</item>
<item row="12" column="0">
<item row="11" column="0">
<widget class="QLabel" name="label_3">
<property name="text">
<string>dialogButtonBox</string>
</property>
</widget>
</item>
<item row="12" column="1">
<item row="11" column="1">
<widget class="QDialogButtonBox" name="buttonBox">
<property name="standardButtons">
<set>QDialogButtonBox::Cancel|QDialogButtonBox::Ok</set>
</property>
</widget>
</item>
<item row="1" column="1">
<widget class="QToolButton" name="toolButton">
<property name="enabled">
<bool>true</bool>
</property>
<item row="8" column="1">
<widget class="QTextEdit" name="textEdit"/>
</item>
<item row="9" column="1">
<widget class="QPlainTextEdit" name="plainTextEdit"/>
</item>
<item row="8" column="0">
<widget class="QLabel" name="label_10">
<property name="text">
<string>ToolButton</string>
<string>textEdit</string>
</property>
</widget>
</item>
<item row="1" column="0">
<widget class="QLabel" name="label_9">
<item row="9" column="0">
<widget class="QLabel" name="label_11">
<property name="text">
<string>toolButton</string>
<string>plainTextEdit</string>
</property>
</widget>
</item>
Expand Down
1 change: 1 addition & 0 deletions src/core/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ target_link_libraries(
PUBLIC nlohmann_json::nlohmann_json
pugixml::pugixml
kdalgorithms
KF5SyntaxHighlighting
Qt::Core
Qt::CorePrivate
Qt::Qml
Expand Down
60 changes: 60 additions & 0 deletions src/core/scriptdialogitem.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,13 @@
#include "settings.h"
#include "utils/log.h"

#include <definition.h>
#include <repository.h>
#include <syntaxhighlighter.h>
#include <theme.h>

#include <QAbstractItemModel>
#include <QApplication>
#include <QCheckBox>
#include <QComboBox>
#include <QCompleter>
Expand All @@ -29,10 +35,12 @@
#include <QJsonValue>
#include <QLineEdit>
#include <QMessageBox>
#include <QPlainTextEdit>
#include <QPushButton>
#include <QQmlContext>
#include <QRadioButton>
#include <QSpinBox>
#include <QTextEdit>
#include <QToolButton>
#include <QUiLoader>
#include <QVBoxLayout>
Expand Down Expand Up @@ -552,6 +560,22 @@ void ScriptDialogItem::createProperties(QWidget *dialogWidget)
completer->setModel(comboBox->model());
comboBox->setCompleter(completer);
}
} else if (auto textEdit = qobject_cast<QTextEdit *>(widget)) {
m_data->addProperty(widget->objectName().toLocal8Bit(), "QString", QMetaType::QString,
textEdit->toPlainText());
connect(textEdit, &QTextEdit::textChanged, this, [this, textEdit]() {
m_data->setProperty(sender()->objectName().toLocal8Bit(), textEdit->toPlainText());
});
m_data->addProperty((widget->objectName() + "Syntax").toLocal8Bit(), "QString", QMetaType::QString,
QString());
} else if (auto plainTextEdit = qobject_cast<QPlainTextEdit *>(widget)) {
m_data->addProperty(widget->objectName().toLocal8Bit(), "QString", QMetaType::QString,
plainTextEdit->toPlainText());
connect(plainTextEdit, &QPlainTextEdit::textChanged, this, [this, plainTextEdit]() {
m_data->setProperty(sender()->objectName().toLocal8Bit(), plainTextEdit->toPlainText());
});
m_data->addProperty((widget->objectName() + "Syntax").toLocal8Bit(), "QString", QMetaType::QString,
QString());
}
}

Expand Down Expand Up @@ -580,6 +604,16 @@ void ScriptDialogItem::changeValue(const QString &key, const QVariant &value)
} else if (auto comboBox = qobject_cast<QComboBox *>(widget)) {
comboBox->setCurrentText(value.toString());
return;
} else if (auto textEdit = qobject_cast<QTextEdit *>(widget)) {
QString valueString = value.toString();
if (textEdit->toPlainText() != valueString)
textEdit->setPlainText(value.toString());
return;
} else if (auto plainTextEdit = qobject_cast<QPlainTextEdit *>(widget)) {
QString valueString = value.toString();
if (plainTextEdit->toPlainText() != valueString)
plainTextEdit->setPlainText(value.toString());
return;
}

// It may be a combobox model
Expand All @@ -593,6 +627,16 @@ void ScriptDialogItem::changeValue(const QString &key, const QVariant &value)
return;
}

// It may be a syntax rule
if (key.endsWith("Syntax")) {
if (auto textEdit = findChild<QTextEdit *>(key.left(key.length() - 6))) {
applySyntaxHighlighting(textEdit->document(), value.toString());
} else if (auto plainTextEdit = findChild<QPlainTextEdit *>(key.left(key.length() - 6))) {
applySyntaxHighlighting(plainTextEdit->document(), value.toString());
}
return;
}

if (!widget) {
spdlog::warn("No widget found for the key '{}'.", key.toStdString());
} else {
Expand All @@ -601,6 +645,22 @@ void ScriptDialogItem::changeValue(const QString &key, const QVariant &value)
}
}

void ScriptDialogItem::applySyntaxHighlighting(QTextDocument *document, const QString &syntax)
{
if (!syntax.isEmpty()) {
auto highlighter = new KSyntaxHighlighting::SyntaxHighlighter(document);
static KSyntaxHighlighting::Repository repository;
highlighter->setTheme(repository.themeForPalette(QApplication::palette()));
const auto definition = repository.definitionForFileName("." + syntax);
if (!definition.isValid()) {
qWarning() << "No valid syntax definition for file extension" << syntax;
delete highlighter;
return;
}
highlighter->setDefinition(definition);
}
}

void ScriptDialogItem::appendChild(QQmlListProperty<QObject> *list, QObject *obj)
{
if (auto that = qobject_cast<ScriptDialogItem *>(list->object)) {
Expand Down
7 changes: 7 additions & 0 deletions src/core/scriptdialogitem.h
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,11 @@
#include <vector>

class ScriptProgressDialog;
class QTextDocument;

namespace KSyntaxHighlighting {
class SyntaxHighlighter;
}

namespace Core {

Expand Down Expand Up @@ -85,6 +90,8 @@ public slots:
static qsizetype countChildren(QQmlListProperty<QObject> *list);
static void clearChildren(QQmlListProperty<QObject> *list);

void applySyntaxHighlighting(QTextDocument *document, const QString &syntax);

private:
DynamicObject *m_data;
std::vector<QObject *> m_children;
Expand Down

0 comments on commit 77af0b7

Please sign in to comment.