File indexing completed on 2024-04-28 07:46:35

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