File indexing completed on 2024-05-12 16:16:10
0001 /* 0002 SPDX-FileCopyrightText: 2022-2023 Laurent Montel <montel@kde.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "translatorengineloader.h" 0008 #include "texttranslator_debug.h" 0009 #include "translatorengineclient.h" 0010 #include <QCoreApplication> 0011 #include <QDir> 0012 #include <QPluginLoader> 0013 using namespace TextTranslator; 0014 class TextTranslator::TranslatorEngineLoaderPrivate 0015 { 0016 public: 0017 QSet<QString> loadedPlugins; 0018 QHash<QString, TranslatorEngineClient *> translatorClients; 0019 }; 0020 0021 TranslatorEngineLoader *TranslatorEngineLoader::self() 0022 { 0023 static TranslatorEngineLoader s_self; 0024 return &s_self; 0025 } 0026 0027 TranslatorEngineLoader::TranslatorEngineLoader(QObject *parent) 0028 : QObject{parent} 0029 , d(new TextTranslator::TranslatorEngineLoaderPrivate) 0030 { 0031 loadPlugins(); 0032 } 0033 0034 TranslatorEngineLoader::~TranslatorEngineLoader() = default; 0035 0036 void TranslatorEngineLoader::loadPlugins() 0037 { 0038 const QStringList libPaths = QCoreApplication::libraryPaths(); 0039 const QString pathSuffix(QStringLiteral("/kf" QT_STRINGIFY(QT_VERSION_MAJOR)) + QStringLiteral("/translator/")); 0040 for (const QString &libPath : libPaths) { 0041 QDir dir(libPath + pathSuffix); 0042 if (!dir.exists()) { 0043 continue; 0044 } 0045 for (const QString &fileName : dir.entryList(QDir::Files)) { 0046 loadPlugin(dir.absoluteFilePath(fileName)); 0047 } 0048 } 0049 if (d->loadedPlugins.isEmpty()) { 0050 qCWarning(TEXTTRANSLATOR_LOG) << "No translator plugins available!"; 0051 } 0052 } 0053 0054 void TranslatorEngineLoader::loadPlugin(const QString &pluginPath) 0055 { 0056 QPluginLoader plugin(pluginPath); 0057 const QString pluginIID = plugin.metaData()[QStringLiteral("IID")].toString(); 0058 if (!pluginIID.isEmpty()) { 0059 if (d->loadedPlugins.contains(pluginIID)) { 0060 qCDebug(TEXTTRANSLATOR_LOG) << "Skipping already loaded" << pluginPath; 0061 return; 0062 } 0063 d->loadedPlugins.insert(pluginIID); 0064 } 0065 0066 if (!plugin.load()) { // We do this separately for better error handling 0067 qCDebug(TEXTTRANSLATOR_LOG) << "Unable to load plugin" << pluginPath << "Error:" << plugin.errorString(); 0068 d->loadedPlugins.remove(pluginIID); 0069 return; 0070 } 0071 TranslatorEngineClient *client = qobject_cast<TranslatorEngineClient *>(plugin.instance()); 0072 if (!client) { 0073 qCWarning(TEXTTRANSLATOR_LOG) << "Invalid plugin loaded" << pluginPath; 0074 plugin.unload(); // don't leave it in memory 0075 return; 0076 } 0077 d->translatorClients.insert(client->name(), client); 0078 } 0079 0080 TranslatorEngineClient *TranslatorEngineLoader::createTranslatorClient(const QString &clientName) 0081 { 0082 auto clientsItr = d->translatorClients.constFind(clientName); 0083 if (clientsItr == d->translatorClients.constEnd()) { 0084 qCWarning(TEXTTRANSLATOR_LOG) << "Client name not found: " << clientName; 0085 Q_EMIT loadingTranslatorFailed(); 0086 return nullptr; 0087 } 0088 return (*clientsItr); 0089 } 0090 0091 QString TranslatorEngineLoader::currentPluginName(const QString &key) const 0092 { 0093 auto clientsItr = d->translatorClients.constFind(key); 0094 if (clientsItr != d->translatorClients.constEnd()) { 0095 return (*clientsItr)->translatedName(); 0096 } 0097 return {}; 0098 } 0099 0100 QMap<QString, QString> TranslatorEngineLoader::translatorEngineInfos() const 0101 { 0102 QMap<QString, QString> map; 0103 QHashIterator<QString, TranslatorEngineClient *> i(d->translatorClients); 0104 while (i.hasNext()) { 0105 i.next(); 0106 map.insert(i.key(), i.value()->translatedName()); 0107 } 0108 return map; 0109 } 0110 0111 QMap<TextTranslator::TranslatorUtil::Language, QString> TranslatorEngineLoader::supportedFromLanguages(const QString &clientName) const 0112 { 0113 QMap<TranslatorUtil::Language, QString> supportedLanguages; 0114 auto clientsItr = d->translatorClients.constFind(clientName); 0115 if (clientsItr == d->translatorClients.constEnd()) { 0116 qCWarning(TEXTTRANSLATOR_LOG) << "Client name not found: " << clientName; 0117 return supportedLanguages; 0118 } 0119 (*clientsItr)->updateListLanguages(); 0120 supportedLanguages = (*clientsItr)->supportedFromLanguages(); 0121 return supportedLanguages; 0122 } 0123 0124 QMap<TextTranslator::TranslatorUtil::Language, QString> TranslatorEngineLoader::supportedToLanguages(const QString &clientName) const 0125 { 0126 QMap<TranslatorUtil::Language, QString> supportedLanguages; 0127 auto clientsItr = d->translatorClients.constFind(clientName); 0128 if (clientsItr == d->translatorClients.constEnd()) { 0129 qCWarning(TEXTTRANSLATOR_LOG) << "Client name not found: " << clientName; 0130 return supportedLanguages; 0131 } 0132 (*clientsItr)->updateListLanguages(); 0133 supportedLanguages = (*clientsItr)->supportedToLanguages(); 0134 return supportedLanguages; 0135 } 0136 0137 bool TranslatorEngineLoader::hasConfigurationDialog(const QString &clientName) const 0138 { 0139 auto clientsItr = d->translatorClients.constFind(clientName); 0140 if (clientsItr == d->translatorClients.constEnd()) { 0141 qCWarning(TEXTTRANSLATOR_LOG) << "Client name not found: " << clientName; 0142 return false; 0143 } 0144 return (*clientsItr)->hasConfigurationDialog(); 0145 } 0146 0147 bool TranslatorEngineLoader::showConfigureDialog(const QString &clientName, QWidget *parentWidget) 0148 { 0149 auto clientsItr = d->translatorClients.constFind(clientName); 0150 if (clientsItr == d->translatorClients.constEnd()) { 0151 qCWarning(TEXTTRANSLATOR_LOG) << "Client name not found: " << clientName; 0152 return false; 0153 } 0154 return (*clientsItr)->showConfigureDialog(parentWidget); 0155 } 0156 0157 QString TranslatorEngineLoader::fallbackFirstEngine() const 0158 { 0159 if (!d->translatorClients.isEmpty()) { 0160 return *d->translatorClients.keyBegin(); 0161 } 0162 qCWarning(TEXTTRANSLATOR_LOG) << "No plugin found ! "; 0163 return QString(); 0164 } 0165 0166 #include "moc_translatorengineloader.cpp"