From 4a8df2a16c929f179fe69f1c3e867c03780874c5 Mon Sep 17 00:00:00 2001
From: Mladen Milinkovic <maxrd2@smoothware.net>
Date: Fri, 8 Oct 2021 12:11:01 +0200
Subject: [PATCH] Replaced Kross with QJSEngine

Kross has been unmaintained for some time now. Existing javascript files
should continue working as they did, python/ruby scripts/support was
removed completely.

https://phabricator.kde.org/T12263
---
 CMakeLists.txt                           |  4 +-
 src/CMakeLists.txt                       |  4 +-
 src/scripting/scripting_rangelist.cpp    |  4 +-
 src/scripting/scripting_rangelist.h      |  4 +-
 src/scripting/scripting_subtitle.cpp     | 46 ++++++------
 src/scripting/scripting_subtitle.h       | 46 ++++++------
 src/scripting/scripting_subtitleline.cpp |  4 +-
 src/scripting/scripting_subtitleline.h   |  4 +-
 src/scripting/scriptsmanager.cpp         | 90 +++++++++---------------
 9 files changed, 90 insertions(+), 116 deletions(-)

diff --git a/CMakeLists.txt b/CMakeLists.txt
index d0be29b7..dae78044 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -28,11 +28,11 @@ include(ECMAddTests) # build tests
 include(FeatureSummary)
 
 find_package(Qt5 ${QT_MIN_VERSION} CONFIG REQUIRED COMPONENTS
-	Core Widgets Gui Test)
+	Core Widgets Gui Test Qml)
 
 find_package(KF5 ${KF5_MIN_VERSION} REQUIRED COMPONENTS
 	Auth Config ConfigWidgets CoreAddons I18n KIO XmlGui
-	Sonnet Kross Codecs TextWidgets WidgetsAddons)
+	Sonnet Codecs TextWidgets WidgetsAddons)
 
 #PO_SUBDIR
 add_subdirectory(src)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 1cb70987..1ecbf0a2 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -100,11 +100,11 @@ qt5_add_resources(subtitlecomposer_RES_SRC ${subtitlecomposer_RES})
 
 add_library(subtitlecomposer-lib STATIC ${subtitlecomposer_SRCS})
 target_link_libraries(subtitlecomposer-lib
-	Qt5::Core Qt5::Widgets Qt5::WidgetsPrivate Qt5::Gui
+	Qt5::Core Qt5::Widgets Qt5::WidgetsPrivate Qt5::Gui Qt5::Qml
 	KF5::CoreAddons KF5::WidgetsAddons KF5::TextWidgets KF5::Codecs
 	KF5::SonnetCore KF5::SonnetUi
 	KF5::KIOCore KF5::KIOFileWidgets KF5::KIOWidgets KF5::KIONTLM
-	KF5::KrossCore KF5::KrossUi KF5::XmlGui KF5::I18n
+	KF5::XmlGui KF5::I18n
 	${FFMPEG_LIBRARIES}
 	${OPENAL_LIBRARY}
 	${ICU_LIBRARIES}
diff --git a/src/scripting/scripting_rangelist.cpp b/src/scripting/scripting_rangelist.cpp
index 8135d04e..639229fd 100644
--- a/src/scripting/scripting_rangelist.cpp
+++ b/src/scripting/scripting_rangelist.cpp
@@ -80,7 +80,7 @@ Scripting::RangeList::trimToIndex(int index)
 }
 
 void
-Scripting::RangeList::trimToRange(const QObject *object)
+Scripting::RangeList::trimToRange(QObject *object)
 {
 	if(const Scripting::Range * range = qobject_cast<const Scripting::Range *>(object))
 		m_backend.trimToRange(range->m_backend);
@@ -95,7 +95,7 @@ Scripting::RangeList::addIndex(int index)
 }
 
 QObject *
-Scripting::RangeList::addRange(const QObject *object)
+Scripting::RangeList::addRange(QObject *object)
 {
 	if(const Scripting::Range * range = qobject_cast<const Scripting::Range *>(object))
 		m_backend << range->m_backend;
diff --git a/src/scripting/scripting_rangelist.h b/src/scripting/scripting_rangelist.h
index 57686afe..e0be47a6 100644
--- a/src/scripting/scripting_rangelist.h
+++ b/src/scripting/scripting_rangelist.h
@@ -36,10 +36,10 @@ public slots:
 	void clear();
 
 	void trimToIndex(int index);
-	void trimToRange(const QObject *range);
+	void trimToRange(QObject *range);
 
 	QObject * addIndex(int index);
-	QObject * addRange(const QObject *range);
+	QObject * addRange(QObject *range);
 
 	void shiftIndexesForwards(int fromIndex, int delta, bool fillSplitGap);
 	void shiftIndexesBackwards(int fromIndex, int delta);
diff --git a/src/scripting/scripting_subtitle.cpp b/src/scripting/scripting_subtitle.cpp
index 1bc8bb13..f8cb94a4 100644
--- a/src/scripting/scripting_subtitle.cpp
+++ b/src/scripting/scripting_subtitle.cpp
@@ -117,64 +117,64 @@ Scripting::Subtitle::removeLine(int index, int target)
 }
 
 void
-Scripting::Subtitle::removeLines(const QObject *ranges, int target)
+Scripting::Subtitle::removeLines(QObject *ranges, int target)
 {
 	static const int opDefault = Both;
 	m_backend->removeLines(toRangesList(ranges), toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::swapTexts(const QObject *ranges)
+Scripting::Subtitle::swapTexts(QObject *ranges)
 {
 	m_backend->swapTexts(toRangesList(ranges));
 }
 
 void
-Scripting::Subtitle::splitLines(const QObject *ranges)
+Scripting::Subtitle::splitLines(QObject *ranges)
 {
 	m_backend->splitLines(toRangesList(ranges));
 }
 
 void
-Scripting::Subtitle::joinLines(const QObject *ranges)
+Scripting::Subtitle::joinLines(QObject *ranges)
 {
 	m_backend->joinLines(toRangesList(ranges));
 }
 
 void
-Scripting::Subtitle::shiftLines(const QObject *ranges, int msecs)
+Scripting::Subtitle::shiftLines(QObject *ranges, int msecs)
 {
 	m_backend->shiftLines(toRangesList(ranges), msecs);
 }
 
 void
-Scripting::Subtitle::adjustLines(const QObject *object, int firstTime, int lastTime)
+Scripting::Subtitle::adjustLines(QObject *object, int firstTime, int lastTime)
 {
 	if(const Scripting::Range * range = qobject_cast<const Scripting::Range *>(object))
 		m_backend->adjustLines(range->m_backend, firstTime, lastTime);
 }
 
 void
-Scripting::Subtitle::sortLines(const QObject *object)
+Scripting::Subtitle::sortLines(QObject *object)
 {
 	if(const Scripting::Range * range = qobject_cast<const Scripting::Range *>(object))
 		m_backend->sortLines(range->m_backend);
 }
 
 void
-Scripting::Subtitle::applyDurationLimits(const QObject *ranges, int minDuration, int maxDuration, bool canOverlap)
+Scripting::Subtitle::applyDurationLimits(QObject *ranges, int minDuration, int maxDuration, bool canOverlap)
 {
 	m_backend->applyDurationLimits(toRangesList(ranges), minDuration, maxDuration, canOverlap);
 }
 
 void
-Scripting::Subtitle::setMaximumDurations(const QObject *ranges)
+Scripting::Subtitle::setMaximumDurations(QObject *ranges)
 {
 	m_backend->setMaximumDurations(toRangesList(ranges));
 }
 
 void
-Scripting::Subtitle::setAutoDurations(const QObject *ranges, int msecsPerChar, int msecsPerWord, int msecsPerLine, bool canOverlap, int calculationTarget)
+Scripting::Subtitle::setAutoDurations(QObject *ranges, int msecsPerChar, int msecsPerWord, int msecsPerLine, bool canOverlap, int calculationTarget)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 
@@ -182,87 +182,87 @@ Scripting::Subtitle::setAutoDurations(const QObject *ranges, int msecsPerChar, i
 }
 
 void
-Scripting::Subtitle::fixOverlappingLines(const QObject *ranges, int minInterval)
+Scripting::Subtitle::fixOverlappingLines(QObject *ranges, int minInterval)
 {
 	m_backend->fixOverlappingLines(toRangesList(ranges), minInterval);
 }
 
 void
-Scripting::Subtitle::fixPunctuation(const QObject *ranges, bool spaces, bool quotes, bool englishI, bool ellipsis, int target)
+Scripting::Subtitle::fixPunctuation(QObject *ranges, bool spaces, bool quotes, bool englishI, bool ellipsis, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->fixPunctuation(toRangesList(ranges), spaces, quotes, englishI, ellipsis, toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::lowerCase(const QObject *ranges, int target)
+Scripting::Subtitle::lowerCase(QObject *ranges, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->lowerCase(toRangesList(ranges), toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::upperCase(const QObject *ranges, int target)
+Scripting::Subtitle::upperCase(QObject *ranges, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->upperCase(toRangesList(ranges), toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::titleCase(const QObject *ranges, bool lowerFirst, int target)
+Scripting::Subtitle::titleCase(QObject *ranges, bool lowerFirst, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->titleCase(toRangesList(ranges), lowerFirst, toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::sentenceCase(const QObject *ranges, bool lowerFirst, int target)
+Scripting::Subtitle::sentenceCase(QObject *ranges, bool lowerFirst, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->sentenceCase(toRangesList(ranges), lowerFirst, toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::breakLines(const QObject *ranges, int minLengthForLineBreak, int target)
+Scripting::Subtitle::breakLines(QObject *ranges, int minLengthForLineBreak, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->breakLines(toRangesList(ranges), minLengthForLineBreak, toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::unbreakTexts(const QObject *ranges, int target)
+Scripting::Subtitle::unbreakTexts(QObject *ranges, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->unbreakTexts(toRangesList(ranges), toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::simplifyTextWhiteSpace(const QObject *ranges, int target)
+Scripting::Subtitle::simplifyTextWhiteSpace(QObject *ranges, int target)
 {
 	const int opDefault = app()->translationMode() ? Both : Primary;
 	m_backend->simplifyTextWhiteSpace(toRangesList(ranges), toTextTarget(target, opDefault));
 }
 
 void
-Scripting::Subtitle::setMarked(const QObject *ranges, bool value)
+Scripting::Subtitle::setMarked(QObject *ranges, bool value)
 {
 	m_backend->setMarked(toRangesList(ranges), value);
 }
 
 void
-Scripting::Subtitle::clearErrors(const QObject *ranges, int errorFlags)
+Scripting::Subtitle::clearErrors(QObject *ranges, int errorFlags)
 {
 	m_backend->clearErrors(toRangesList(ranges), errorFlags);
 }
 
 void
-Scripting::Subtitle::checkErrors(const QObject *ranges, int errorFlags)
+Scripting::Subtitle::checkErrors(QObject *ranges, int errorFlags)
 {
 	m_backend->checkErrors(toRangesList(ranges), errorFlags);
 }
 
 void
-Scripting::Subtitle::recheckErrors(const QObject *ranges)
+Scripting::Subtitle::recheckErrors(QObject *ranges)
 {
 	m_backend->recheckErrors(toRangesList(ranges));
 }
diff --git a/src/scripting/scripting_subtitle.h b/src/scripting/scripting_subtitle.h
index 57631b7e..6a368845 100644
--- a/src/scripting/scripting_subtitle.h
+++ b/src/scripting/scripting_subtitle.h
@@ -41,41 +41,41 @@ public slots:
 
 	SubtitleLine * insertNewLine(int index, bool timeAfter, int target = -1);
 	void removeLine(int index, int target = -1);
-	void removeLines(const QObject *ranges, int target = -1);
+	void removeLines(QObject *ranges, int target = -1);
 
-	void swapTexts(const QObject *ranges);
+	void swapTexts(QObject *ranges);
 
-	void splitLines(const QObject *ranges);
-	void joinLines(const QObject *ranges);
+	void splitLines(QObject *ranges);
+	void joinLines(QObject *ranges);
 
-	void shiftLines(const QObject *ranges, int msecs);
-	void adjustLines(const QObject *range, int firstTime, int lastTime);
-	void sortLines(const QObject *range);
+	void shiftLines(QObject *ranges, int msecs);
+	void adjustLines(QObject *range, int firstTime, int lastTime);
+	void sortLines(QObject *range);
 
-	void applyDurationLimits(const QObject *ranges, int minDuration, int maxDuration, bool canOverlap);
-	void setMaximumDurations(const QObject *ranges);
-	void setAutoDurations(const QObject *ranges, int msecsPerChar, int msecsPerWord, int msecsPerLine, bool canOverlap, int calculationTarget = -1);
+	void applyDurationLimits(QObject *ranges, int minDuration, int maxDuration, bool canOverlap);
+	void setMaximumDurations(QObject *ranges);
+	void setAutoDurations(QObject *ranges, int msecsPerChar, int msecsPerWord, int msecsPerLine, bool canOverlap, int calculationTarget = -1);
 
-	void fixOverlappingLines(const QObject *ranges, int minInterval = 100);
+	void fixOverlappingLines(QObject *ranges, int minInterval = 100);
 
-	void fixPunctuation(const QObject *ranges, bool spaces, bool quotes, bool englishI, bool ellipsis, int target = -1);
+	void fixPunctuation(QObject *ranges, bool spaces, bool quotes, bool englishI, bool ellipsis, int target = -1);
 
-	void lowerCase(const QObject *ranges, int target = -1);
-	void upperCase(const QObject *ranges, int target = -1);
-	void titleCase(const QObject *ranges, bool lowerFirst, int target = -1);
-	void sentenceCase(const QObject *ranges, bool lowerFirst, int target = -1);
+	void lowerCase(QObject *ranges, int target = -1);
+	void upperCase(QObject *ranges, int target = -1);
+	void titleCase(QObject *ranges, bool lowerFirst, int target = -1);
+	void sentenceCase(QObject *ranges, bool lowerFirst, int target = -1);
 
-	void breakLines(const QObject *ranges, int minLengthForLineBreak, int target = -1);
-	void unbreakTexts(const QObject *ranges, int target = -1);
-	void simplifyTextWhiteSpace(const QObject *ranges, int target = -1);
+	void breakLines(QObject *ranges, int minLengthForLineBreak, int target = -1);
+	void unbreakTexts(QObject *ranges, int target = -1);
+	void simplifyTextWhiteSpace(QObject *ranges, int target = -1);
 
-	void setMarked(const QObject *ranges, bool value);
+	void setMarked(QObject *ranges, bool value);
 
-	void clearErrors(const QObject *ranges, int errorFlags);
+	void clearErrors(QObject *ranges, int errorFlags);
 
-	void checkErrors(const QObject *ranges, int errorFlags);
+	void checkErrors(QObject *ranges, int errorFlags);
 
-	void recheckErrors(const QObject *ranges);
+	void recheckErrors(QObject *ranges);
 
 private:
 	static SubtitleComposer::RangeList toRangesList(const QObject *object);
diff --git a/src/scripting/scripting_subtitleline.cpp b/src/scripting/scripting_subtitleline.cpp
index e1ebc8ff..fd8fba10 100644
--- a/src/scripting/scripting_subtitleline.cpp
+++ b/src/scripting/scripting_subtitleline.cpp
@@ -81,7 +81,7 @@ Scripting::SubtitleLine::primaryText() const
 }
 
 void
-Scripting::SubtitleLine::setPrimaryText(const QObject *object)
+Scripting::SubtitleLine::setPrimaryText(QObject *object)
 {
 	const Scripting::SString *string = qobject_cast<const Scripting::SString *>(object);
 	if(string)
@@ -139,7 +139,7 @@ Scripting::SubtitleLine::secondaryText() const
 }
 
 void
-Scripting::SubtitleLine::setSecondaryText(const QObject *object)
+Scripting::SubtitleLine::setSecondaryText(QObject *object)
 {
 	if(app()->translationMode()) {
 		const Scripting::SString *string = qobject_cast<const Scripting::SString *>(object);
diff --git a/src/scripting/scripting_subtitleline.h b/src/scripting/scripting_subtitleline.h
index 81d5c003..bf9aed47 100644
--- a/src/scripting/scripting_subtitleline.h
+++ b/src/scripting/scripting_subtitleline.h
@@ -36,7 +36,7 @@ public slots:
 	int primaryLines() const;
 
 	QObject * primaryText() const;
-	void setPrimaryText(const QObject *text);
+	void setPrimaryText(QObject *text);
 	QString plainPrimaryText() const;
 	void setPlainPrimaryText(const QString &plainText);
 	QString richPrimaryText() const;
@@ -47,7 +47,7 @@ public slots:
 	int secondaryLines() const;
 
 	QObject * secondaryText() const;
-	void setSecondaryText(const QObject *text);
+	void setSecondaryText(QObject *text);
 	QString plainSecondaryText() const;
 	void setPlainSecondaryText(const QString &plainText);
 	QString richSecondaryText() const;
diff --git a/src/scripting/scriptsmanager.cpp b/src/scripting/scriptsmanager.cpp
index 6d7e2812..096b2149 100644
--- a/src/scripting/scriptsmanager.cpp
+++ b/src/scripting/scriptsmanager.cpp
@@ -17,6 +17,7 @@
 #include "actions/useraction.h"
 #include "actions/useractionnames.h"
 #include "dialogs/textinputdialog.h"
+#include "helpers/common.h"
 #include "helpers/fileloadhelper.h"
 #include "helpers/filetrasher.h"
 #include "gui/treeview/treeview.h"
@@ -25,10 +26,12 @@
 #include <QStandardPaths>
 #include <QDialog>
 #include <QFileDialog>
+#include <QJSEngine>
 #include <QMenuBar>
 #include <QMenu>
 #include <QDesktopServices>
 #include <QKeyEvent>
+#include <QStringBuilder>
 
 #include <KMessageBox>
 #include <KRun>
@@ -40,10 +43,6 @@
 #include <KIO/JobUiDelegate>
 #endif
 
-#include <kross/core/manager.h>
-#include <kross/core/interpreter.h>
-#include <kross/core/action.h>
-
 namespace SubtitleComposer {
 class InstalledScriptsModel : public QStringListModel
 {
@@ -194,16 +193,8 @@ ScriptsManager::mimeTypes()
 {
 	static QStringList mimeTypes;
 
-	if(mimeTypes.isEmpty()) {
-		QHash<QString, Kross::InterpreterInfo *> infos = Kross::Manager::self().interpreterInfos();
-		for(QHash<QString, Kross::InterpreterInfo *>::ConstIterator it = infos.constBegin(), end = infos.constEnd(); it != end; ++it) {
-			QStringList intMimeTypes = it.value()->mimeTypes();
-			for(QStringList::ConstIterator it = intMimeTypes.constBegin(), end = intMimeTypes.constEnd(); it != end; ++it)
-				mimeTypes << *it;
-		}
-		if(!mimeTypes.contains("application/javascript") && !mimeTypes.contains("text/javascript") && !mimeTypes.contains("application/x-javascript"))
-			mimeTypes.prepend("application/javascript");
-	}
+	if(mimeTypes.isEmpty())
+		mimeTypes.append("application/javascript");
 
 	return mimeTypes;
 }
@@ -331,45 +322,40 @@ ScriptsManager::runScript(const QString &sN)
 		return;
 	}
 
-	Kross::Action krossAction(0, "Kross::Action");
-
-	Scripting::RangesModule *rangesModule = new Scripting::RangesModule;
-	Scripting::StringsModule *stringsModule = new Scripting::StringsModule;
-	Scripting::SubtitleModule *subtitleModule = new Scripting::SubtitleModule;
-	Scripting::SubtitleLineModule *subtitleLineModule = new Scripting::SubtitleLineModule;
-	Debug *debug = new Debug();
+	QJSEngine jse;
+	jse.installExtensions(QJSEngine::ConsoleExtension);
+	jse.globalObject().setProperty("ranges", jse.newQObject(new Scripting::RangesModule));
+	jse.globalObject().setProperty("strings", jse.newQObject(new Scripting::StringsModule));
+	jse.globalObject().setProperty("subtitle", jse.newQObject(new Scripting::SubtitleModule));
+	jse.globalObject().setProperty("subtitleline", jse.newQObject(new Scripting::SubtitleLineModule));
+	jse.globalObject().setProperty("debug", jse.newQObject(new Debug()));
 
-	krossAction.addObject(rangesModule, "ranges");
-	krossAction.addObject(stringsModule, "strings");
-	krossAction.addObject(subtitleModule, "subtitle");
-	krossAction.addObject(subtitleLineModule, "subtitleline");
-	krossAction.addObject(debug, "debug");
-
-	krossAction.setFile(m_scripts[scriptName]);
-	if(krossAction.interpreter().isEmpty() && scriptName.right(3) == QLatin1String(".js"))
-		krossAction.setInterpreter("qtscript");
-	// default javascript interpreter has weird (crash inducing) bugs
-	else if(krossAction.interpreter() == QLatin1String("javascript"))
-		krossAction.setInterpreter("qtscript");
+	QString script;
+	{
+		QFile jsf(m_scripts[scriptName]);
+		if(!jsf.open(QFile::ReadOnly | QFile::Text)) {
+			KMessageBox::error(app()->mainWindow(), i18n("Error opening script %1.", m_scripts[scriptName]), i18n("Error Running Script"));
+			return;
+		}
+		script = QTextStream(&jsf).readAll();
+	}
 
+	QJSValue res;
 	{
 		// everything done by the script will be undoable in a single step
 		SubtitleCompositeActionExecutor executor(app()->subtitle(), scriptName);
 		// execute the script file
-		krossAction.trigger();
+		res = jse.evaluate(script, scriptName);
 	}
 
-	delete rangesModule;
-	delete stringsModule;
-	delete subtitleModule;
-	delete subtitleLineModule;
-	delete debug;
-
-	if(krossAction.hadError()) {
-		if(krossAction.errorTrace().isNull())
-			KMessageBox::error(app()->mainWindow(), krossAction.errorMessage(), i18n("Error Running Script"));
-		else
-			KMessageBox::detailedError(app()->mainWindow(), krossAction.errorMessage(), krossAction.errorTrace(), i18n("Error Running Script"));
+	if(!res.isUndefined()) {
+		if(res.isError()) {
+			const QString details = i18n("Path: %1", m_scripts[scriptName]) % "\n"
+				% res.property($("stack")).toString();
+			KMessageBox::detailedError(app()->mainWindow(), res.toString(), details, i18n("Error Running Script"));
+		} else {
+			KMessageBox::error(app()->mainWindow(), res.toString(), i18n("Error Running Script"));
+		}
 	}
 }
 
@@ -419,17 +405,6 @@ ScriptsManager::reloadScripts()
 	toolsMenu->addAction(app()->action(ACT_SCRIPTS_MANAGER));
 	toolsMenu->addSeparator();
 
-	qDebug() << "KROSS interpreters:" << Kross::Manager::self().interpreters();
-	QStringList scriptExtensions;
-	foreach(const QString interpreter, Kross::Manager::self().interpreters()) {
-		if(interpreter == QStringLiteral("qtscript"))
-			scriptExtensions.append(QStringLiteral(".js"));
-		else if(interpreter == QStringLiteral("ruby"))
-			scriptExtensions.append(QStringLiteral(".rb"));
-		else if(interpreter == QStringLiteral("python"))
-			scriptExtensions.append(QStringLiteral(".py"));
-	}
-
 	QStringList scriptDirs = QStandardPaths::locateAll(QStandardPaths::AppDataLocation, "scripts", QStandardPaths::LocateDirectory);
 	QStringList scriptNames;
 	int index = 0, newCurrentIndex = -1;
@@ -446,8 +421,7 @@ ScriptsManager::reloadScripts()
 
 			m_scripts[name] = path;
 
-			QString suffix = name.right(3);
-			if(scriptExtensions.contains(suffix)) {
+			if(name.right(3) == $(".js")) {
 				QAction *scriptAction = toolsMenu->addAction(name);
 				scriptAction->setObjectName(name);
 				actionCollection->addAction(name, scriptAction);
-- 
GitLab

