1/*
2 SPDX-FileCopyrightText: 2010-2018 Dominik Haumann <dhaumann@kde.org>
3
4 SPDX-License-Identifier: LGPL-2.0-or-later
5*/
6
7// Undefine this because we don't want our i18n*() method names to be turned
8// into i18nd*(). This means any translated string in this file should use
9// i18nd("ktexteditor6", "foo") instead of i18n("foo")
10#undef TRANSLATION_DOMAIN
11
12#include "katescripthelpers.h"
13#include "katepartdebug.h"
14
15#include <iostream>
16
17#include <QFile>
18#include <QJSEngine>
19#include <QStandardPaths>
20
21#include <QDebug>
22
23#include <KLocalizedString>
24
25namespace Kate
26{
27namespace Script
28{
29bool readFile(const QString &sourceUrl, QString &sourceCode)
30{
31 sourceCode = QString();
32
33 QFile file(sourceUrl);
34 if (!file.open(flags: QIODevice::ReadOnly)) {
35 qCDebug(LOG_KTE) << QStringLiteral("Unable to find '%1'").arg(a: sourceUrl);
36 return false;
37 } else {
38 QTextStream stream(&file);
39 sourceCode = stream.readAll();
40 file.close();
41 }
42 return true;
43}
44
45} // namespace Script
46
47QString ScriptHelper::read(const QString &name)
48{
49 // get full name of file
50 // skip on errors
51 QString content;
52 QString fullName = QStandardPaths::locate(type: QStandardPaths::GenericDataLocation, fileName: QLatin1String("katepart5/script/files/") + name);
53 if (fullName.isEmpty()) {
54 // retry with resource
55 fullName = QLatin1String(":/ktexteditor/script/files/") + name;
56 if (!QFile::exists(fileName: fullName)) {
57 return content;
58 }
59 }
60
61 // try to read complete file
62 // skip non-existing files
63 Script::readFile(sourceUrl: fullName, sourceCode&: content);
64 return content;
65}
66
67void ScriptHelper::require(const QString &name)
68{
69 // get full name of file
70 // skip on errors
71 QString fullName = QStandardPaths::locate(type: QStandardPaths::GenericDataLocation, fileName: QLatin1String("katepart5/script/libraries/") + name);
72 if (fullName.isEmpty()) {
73 // retry with resource
74 fullName = QLatin1String(":/ktexteditor/script/libraries/") + name;
75 if (!QFile::exists(fileName: fullName)) {
76 return;
77 }
78 }
79
80 // check include guard
81 QJSValue require_guard = m_engine->globalObject().property(QStringLiteral("require_guard"));
82 if (require_guard.property(name: fullName).toBool()) {
83 return;
84 }
85
86 // try to read complete file
87 // skip non-existing files
88 QString code;
89 if (!Script::readFile(sourceUrl: fullName, sourceCode&: code)) {
90 return;
91 }
92
93 // eval in current script engine
94 const QJSValue val = m_engine->evaluate(program: code, fileName: fullName);
95 if (val.isError()) {
96 qCWarning(LOG_KTE) << "error evaluating" << fullName << val.toString() << ", at line" << val.property(QStringLiteral("lineNumber")).toInt();
97 }
98
99 // set include guard
100 require_guard.setProperty(name: fullName, value: QJSValue(true));
101}
102
103void ScriptHelper::debug(const QString &message)
104{
105 // debug in blue to distance from other debug output if necessary
106 std::cerr << "\033[31m" << qPrintable(message) << "\033[0m\n";
107}
108
109// BEGIN code adapted from kdelibs/kross/modules/translation.cpp
110/// helper function to do the substitution from QtScript > QVariant > real values
111// KLocalizedString substituteArguments(const KLocalizedString &kls, const QVariantList &arguments, int max = 99)
112//{
113// KLocalizedString ls = kls;
114// int cnt = qMin(arguments.count(), max); // QString supports max 99
115// for (int i = 0; i < cnt; ++i) {
116// QVariant arg = arguments[i];
117// switch (arg.type()) {
118// case QVariant::Int: ls = ls.subs(arg.toInt()); break;
119// case QVariant::UInt: ls = ls.subs(arg.toUInt()); break;
120// case QVariant::LongLong: ls = ls.subs(arg.toLongLong()); break;
121// case QVariant::ULongLong: ls = ls.subs(arg.toULongLong()); break;
122// case QVariant::Double: ls = ls.subs(arg.toDouble()); break;
123// default: ls = ls.subs(arg.toString()); break;
124// }
125// }
126// return ls;
127//}
128
129/// i18n("text", arguments [optional])
130QString ScriptHelper::_i18n(const QString &text)
131{
132 KLocalizedString ls = ki18n(text: text.toUtf8().constData());
133 return ls.toString(); // substituteArguments(ls, args).toString();
134}
135
136/// i18nc("context", "text", arguments [optional])
137QString ScriptHelper::_i18nc(const QString &textContext, const QString &text)
138{
139 KLocalizedString ls = ki18nc(context: textContext.toUtf8().constData(), text: text.toUtf8().constData());
140 return ls.toString(); // substituteArguments(ls, args).toString();
141}
142
143/// i18np("singular", "plural", number, arguments [optional])
144QString ScriptHelper::_i18np(const QString &trSingular, const QString &trPlural, int number)
145{
146 KLocalizedString ls = ki18np(singular: trSingular.toUtf8().constData(), plural: trPlural.toUtf8().constData()).subs(a: number);
147 return ls.toString(); // substituteArguments(ls, args, 98).toString();
148}
149
150/// i18ncp("context", "singular", "plural", number, arguments [optional])
151QString ScriptHelper::_i18ncp(const QString &trContext, const QString &trSingular, const QString &trPlural, int number)
152{
153 KLocalizedString ls = ki18ncp(context: trContext.toUtf8().data(), singular: trSingular.toUtf8().data(), plural: trPlural.toUtf8().data()).subs(a: number);
154 return ls.toString(); // substituteArguments(ls, args, 98).toString();
155}
156
157// END code adapted from kdelibs/kross/modules/translation.cpp
158
159} // namespace kate
160
161#include "moc_katescripthelpers.cpp"
162

source code of ktexteditor/src/script/katescripthelpers.cpp