File indexing completed on 2024-04-21 11:36:29

0001 /*
0002     SPDX-FileCopyrightText: 2010-2018 Dominik Haumann <dhaumann@kde.org>
0003 
0004     SPDX-License-Identifier: LGPL-2.0-or-later
0005 */
0006 
0007 // Undefine this because we don't want our i18n*() method names to be turned
0008 // into i18nd*(). This means any translated string in this file should use
0009 // i18nd("ktexteditor5", "foo") instead of i18n("foo")
0010 #undef TRANSLATION_DOMAIN
0011 
0012 #include "katescripthelpers.h"
0013 #include "katedocument.h"
0014 #include "katepartdebug.h"
0015 #include "katescript.h"
0016 #include "katescriptdocument.h"
0017 #include "katescriptview.h"
0018 #include "kateview.h"
0019 
0020 #include <iostream>
0021 
0022 #include <QFile>
0023 #include <QJSEngine>
0024 #include <QStandardPaths>
0025 
0026 #include <QDebug>
0027 
0028 #include <KLocalizedString>
0029 
0030 namespace Kate
0031 {
0032 namespace Script
0033 {
0034 bool readFile(const QString &sourceUrl, QString &sourceCode)
0035 {
0036     sourceCode = QString();
0037 
0038     QFile file(sourceUrl);
0039     if (!file.open(QIODevice::ReadOnly)) {
0040         qCDebug(LOG_KTE) << QStringLiteral("Unable to find '%1'").arg(sourceUrl);
0041         return false;
0042     } else {
0043         QTextStream stream(&file);
0044         stream.setCodec("UTF-8");
0045         sourceCode = stream.readAll();
0046         file.close();
0047     }
0048     return true;
0049 }
0050 
0051 } // namespace Script
0052 
0053 QString ScriptHelper::read(const QString &name)
0054 {
0055     // get full name of file
0056     // skip on errors
0057     QString content;
0058     QString fullName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("katepart5/script/files/") + name);
0059     if (fullName.isEmpty()) {
0060         // retry with resource
0061         fullName = QLatin1String(":/ktexteditor/script/files/") + name;
0062         if (!QFile::exists(fullName)) {
0063             return content;
0064         }
0065     }
0066 
0067     // try to read complete file
0068     // skip non-existing files
0069     Script::readFile(fullName, content);
0070     return content;
0071 }
0072 
0073 void ScriptHelper::require(const QString &name)
0074 {
0075     // get full name of file
0076     // skip on errors
0077     QString fullName = QStandardPaths::locate(QStandardPaths::GenericDataLocation, QLatin1String("katepart5/script/libraries/") + name);
0078     if (fullName.isEmpty()) {
0079         // retry with resource
0080         fullName = QLatin1String(":/ktexteditor/script/libraries/") + name;
0081         if (!QFile::exists(fullName)) {
0082             return;
0083         }
0084     }
0085 
0086     // check include guard
0087     QJSValue require_guard = m_engine->globalObject().property(QStringLiteral("require_guard"));
0088     if (require_guard.property(fullName).toBool()) {
0089         return;
0090     }
0091 
0092     // try to read complete file
0093     // skip non-existing files
0094     QString code;
0095     if (!Script::readFile(fullName, code)) {
0096         return;
0097     }
0098 
0099     // eval in current script engine
0100     const QJSValue val = m_engine->evaluate(code, fullName);
0101     if (val.isError()) {
0102         qCWarning(LOG_KTE) << "error evaluating" << fullName << val.toString() << ", at line" << val.property(QStringLiteral("lineNumber")).toInt();
0103     }
0104 
0105     // set include guard
0106     require_guard.setProperty(fullName, QJSValue(true));
0107 }
0108 
0109 void ScriptHelper::debug(const QString &message)
0110 {
0111     // debug in blue to distance from other debug output if necessary
0112     std::cerr << "\033[31m" << qPrintable(message) << "\033[0m\n";
0113 }
0114 
0115 // BEGIN code adapted from kdelibs/kross/modules/translation.cpp
0116 /// helper function to do the substitution from QtScript > QVariant > real values
0117 // KLocalizedString substituteArguments(const KLocalizedString &kls, const QVariantList &arguments, int max = 99)
0118 //{
0119 //    KLocalizedString ls = kls;
0120 //    int cnt = qMin(arguments.count(), max);   // QString supports max 99
0121 //    for (int i = 0; i < cnt; ++i) {
0122 //        QVariant arg = arguments[i];
0123 //        switch (arg.type()) {
0124 //        case QVariant::Int: ls = ls.subs(arg.toInt()); break;
0125 //        case QVariant::UInt: ls = ls.subs(arg.toUInt()); break;
0126 //        case QVariant::LongLong: ls = ls.subs(arg.toLongLong()); break;
0127 //        case QVariant::ULongLong: ls = ls.subs(arg.toULongLong()); break;
0128 //        case QVariant::Double: ls = ls.subs(arg.toDouble()); break;
0129 //        default: ls = ls.subs(arg.toString()); break;
0130 //        }
0131 //    }
0132 //    return ls;
0133 //}
0134 
0135 /// i18n("text", arguments [optional])
0136 QString ScriptHelper::_i18n(const QString &text)
0137 {
0138     KLocalizedString ls = ki18n(text.toUtf8().constData());
0139     return ls.toString(); // substituteArguments(ls, args).toString();
0140 }
0141 
0142 /// i18nc("context", "text", arguments [optional])
0143 QString ScriptHelper::_i18nc(const QString &textContext, const QString &text)
0144 {
0145     KLocalizedString ls = ki18nc(textContext.toUtf8().constData(), text.toUtf8().constData());
0146     return ls.toString(); // substituteArguments(ls, args).toString();
0147 }
0148 
0149 /// i18np("singular", "plural", number, arguments [optional])
0150 QString ScriptHelper::_i18np(const QString &trSingular, const QString &trPlural, int number)
0151 {
0152     KLocalizedString ls = ki18np(trSingular.toUtf8().constData(), trPlural.toUtf8().constData()).subs(number);
0153     return ls.toString(); // substituteArguments(ls, args, 98).toString();
0154 }
0155 
0156 /// i18ncp("context", "singular", "plural", number, arguments [optional])
0157 QString ScriptHelper::_i18ncp(const QString &trContext, const QString &trSingular, const QString &trPlural, int number)
0158 {
0159     KLocalizedString ls = ki18ncp(trContext.toUtf8().data(), trSingular.toUtf8().data(), trPlural.toUtf8().data()).subs(number);
0160     return ls.toString(); // substituteArguments(ls, args, 98).toString();
0161 }
0162 
0163 // END code adapted from kdelibs/kross/modules/translation.cpp
0164 
0165 } // namespace kate
0166 
0167 #include "moc_katescripthelpers.cpp"