File indexing completed on 2024-12-22 04:28:23
0001 /* 0002 SPDX-FileCopyrightText: 2023-2024 Laurent Montel <montel.org> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #include "voskspeechtotextmodel.h" 0008 #include "libvoskspeechtotext_debug.h" 0009 #include <KIO/Global> 0010 #include <KLocalizedString> 0011 #include <QColor> 0012 #include <QDir> 0013 0014 VoskSpeechToTextModel::VoskSpeechToTextModel(QObject *parent) 0015 : QAbstractListModel{parent} 0016 { 0017 updateInstalledLanguage(); 0018 } 0019 0020 VoskSpeechToTextModel::~VoskSpeechToTextModel() = default; 0021 0022 int VoskSpeechToTextModel::rowCount(const QModelIndex &parent) const 0023 { 0024 Q_UNUSED(parent); 0025 return mSpeechToTextInfos.count(); 0026 } 0027 0028 QVariant VoskSpeechToTextModel::headerData(int section, Qt::Orientation orientation, int role) const 0029 { 0030 if (role == Qt::DisplayRole && orientation == Qt::Horizontal) { 0031 switch (static_cast<VoskRoles>(section)) { 0032 case VoskRoles::Identifier: 0033 case VoskRoles::SizeByte: 0034 case VoskRoles::Url: 0035 case VoskRoles::Name: 0036 case VoskRoles::NeedToUpdateLanguage: 0037 case VoskRoles::CheckSum: 0038 return {}; 0039 case VoskRoles::LangText: 0040 return i18n("Language"); 0041 case VoskRoles::Installed: 0042 return i18n("Installed"); 0043 case VoskRoles::InstalledVersion: 0044 return i18n("Installed Version"); 0045 case VoskRoles::AvailableVersion: 0046 return i18n("Available Version"); 0047 case VoskRoles::Size: 0048 return i18n("Size"); 0049 } 0050 } 0051 return {}; 0052 } 0053 0054 QVariant VoskSpeechToTextModel::data(const QModelIndex &index, int role) const 0055 { 0056 if (index.row() < 0 || index.row() >= mSpeechToTextInfos.count()) { 0057 return {}; 0058 } 0059 const auto speechToTextInfo = mSpeechToTextInfos.at(index.row()); 0060 const int col = index.column(); 0061 if (role == Qt::BackgroundRole) { 0062 if (needToUpdateLanguageModel(speechToTextInfo)) { 0063 if (static_cast<VoskRoles>(col) == VoskRoles::InstalledVersion) { 0064 return QColor(Qt::red); 0065 } 0066 } 0067 return {}; 0068 } else if (role == Qt::DisplayRole) { 0069 switch (static_cast<VoskRoles>(col)) { 0070 case VoskRoles::InstalledVersion: { 0071 const QString name{speechToTextInfo.name()}; 0072 if (isInstalled(name)) { 0073 return versionInstalled(name); 0074 } 0075 return {}; 0076 } 0077 case VoskRoles::AvailableVersion: { 0078 return speechToTextInfo.version(); 0079 } 0080 case VoskRoles::NeedToUpdateLanguage: { 0081 return needToUpdateLanguageModel(speechToTextInfo); 0082 } 0083 case VoskRoles::Installed: { 0084 if (isInstalled(speechToTextInfo.name())) { 0085 return i18n("Installed"); 0086 } 0087 return {}; 0088 } 0089 case VoskRoles::Identifier: { 0090 return speechToTextInfo.identifier(); 0091 } 0092 case VoskRoles::LangText: { 0093 return speechToTextInfo.langText(); 0094 } 0095 case VoskRoles::Size: { 0096 return KIO::convertSize(speechToTextInfo.size()); 0097 } 0098 case VoskRoles::SizeByte: { 0099 return speechToTextInfo.size(); 0100 } 0101 case VoskRoles::Url: { 0102 return speechToTextInfo.url(); 0103 } 0104 case VoskRoles::CheckSum: { 0105 return speechToTextInfo.md5(); 0106 } 0107 case VoskRoles::Name: { 0108 return speechToTextInfo.name(); 0109 } 0110 } 0111 } 0112 return {}; 0113 } 0114 0115 bool VoskSpeechToTextModel::needToUpdateLanguageModel(const VoskSpeechToTextInfo &language) const 0116 { 0117 const QString shortName{language.identifier()}; 0118 if (isInstalled(shortName)) { 0119 if (versionInstalled(shortName) != language.version()) { 0120 return true; 0121 } 0122 } 0123 return false; 0124 } 0125 0126 void VoskSpeechToTextModel::clear() 0127 { 0128 if (rowCount() != 0) { 0129 beginResetModel(); 0130 mSpeechToTextInfos.clear(); 0131 endResetModel(); 0132 } 0133 updateInstalledLanguage(); 0134 } 0135 0136 void VoskSpeechToTextModel::updateInstalledLanguage() 0137 { 0138 mLanguageInstalled = VoskEngineUtils::languageLocallyStored(); 0139 qCDebug(LIBVOSKSPEECHTOTEXT_LOG) << "mLanguageInstalled " << mLanguageInstalled; 0140 } 0141 0142 void VoskSpeechToTextModel::removeLanguage(const QString &name) 0143 { 0144 auto index = std::find_if(mLanguageInstalled.begin(), mLanguageInstalled.end(), [name](const VoskEngineUtils::LanguageInstalled &installed) { 0145 return (name == installed.name); 0146 }); 0147 if (index != mLanguageInstalled.end()) { 0148 const QString absoluteLanguageModelPath = (*index).absoluteLanguageModelPath; 0149 if (!QDir(absoluteLanguageModelPath).removeRecursively()) { 0150 qCDebug(LIBVOSKSPEECHTOTEXT_LOG) << "Impossible to delete " << absoluteLanguageModelPath; 0151 return; 0152 } 0153 mLanguageInstalled.removeAll(*index); 0154 beginResetModel(); 0155 endResetModel(); 0156 } 0157 updateInstalledLanguage(); 0158 } 0159 0160 QVector<VoskSpeechToTextInfo> VoskSpeechToTextModel::speechToTextInfos() const 0161 { 0162 return mSpeechToTextInfos; 0163 } 0164 0165 void VoskSpeechToTextModel::setSpeechToTextInfos(const QVector<VoskSpeechToTextInfo> &newSpeechToTextInfo) 0166 { 0167 if (rowCount() != 0) { 0168 beginResetModel(); 0169 mSpeechToTextInfos.clear(); 0170 endResetModel(); 0171 } 0172 if (!newSpeechToTextInfo.isEmpty()) { 0173 beginInsertRows(QModelIndex(), 0, newSpeechToTextInfo.count() - 1); 0174 mSpeechToTextInfos = newSpeechToTextInfo; 0175 endInsertRows(); 0176 } 0177 updateInstalledLanguage(); 0178 } 0179 0180 int VoskSpeechToTextModel::columnCount(const QModelIndex &parent) const 0181 { 0182 Q_UNUSED(parent) 0183 return static_cast<int>(VoskRoles::LastColumn) + 1; 0184 } 0185 0186 bool VoskSpeechToTextModel::isInstalled(const QString &name) const 0187 { 0188 for (const auto &lang : std::as_const(mLanguageInstalled)) { 0189 if (lang.name == name) { 0190 return true; 0191 } 0192 } 0193 return false; 0194 } 0195 0196 QString VoskSpeechToTextModel::versionInstalled(const QString &shortName) const 0197 { 0198 for (const auto &lang : std::as_const(mLanguageInstalled)) { 0199 if (lang.name == shortName) { 0200 return lang.versionStr; 0201 } 0202 } 0203 return {}; 0204 } 0205 0206 #include "moc_voskspeechtotextmodel.cpp"