1// SPDX-FileCopyrightText: 2023 UnionTech Software Technology Co., Ltd.
2//
3// SPDX-License-Identifier: GPL-3.0-or-later
4
5#include "language.h"
6#include "util/custompaths.h"
7#include "dialog/contextdialog.h"
8
9#include <QJsonDocument>
10#include <QFile>
11#include <QDebug>
12#include <QJsonObject>
13#include <QJsonArray>
14#include <QFileInfo>
15#include <QMimeDatabase>
16
17namespace support_file {
18
19namespace documents {
20inline static QJsonDocument languageGlobal;
21inline static QJsonDocument languageUser;
22bool languageIsLoaded();
23} //namespace documents
24
25bool documents::languageIsLoaded()
26{
27 return !languageGlobal.isEmpty() && !languageUser.isEmpty();
28}
29
30QString Language::globalPath()
31{
32 auto result = CustomPaths::endSeparator(CustomPaths::global(CustomPaths::Configures));
33 return result + "language.support";
34}
35
36QString Language::userPath()
37{
38 auto result = CustomPaths::endSeparator(CustomPaths::user(CustomPaths::Configures));
39 return result + "language.support";
40}
41
42void Language::initialize()
43{
44 if (!documents::languageGlobal.isEmpty()) {
45 return;
46 }
47
48 QJsonParseError err;
49 QFile file(globalPath());
50 if (file.open(QFile::ReadOnly)) {
51 auto data = file.readAll();
52 documents::languageGlobal = QJsonDocument::fromJson(data, &err);
53 file.close();
54 }
55
56 if (documents::languageGlobal.isEmpty()) {
57 ContextDialog::ok(QObject::tr("The format of the language configuration file is incorrect or damaged. "
58 "Check that the file is released correctly. "
59 "If it cannot be solved, reinstall the software to solve the problem"));
60 qCritical() << QString("Failed, %0 jsonDoc is Empty. ").arg(globalPath())
61 + "errorString: " + err.errorString();
62 abort();
63 }
64}
65
66bool Language::recovery()
67{
68 return true;
69}
70
71QStringList Language::ids()
72{
73 Language::initialize();
74 return documents::languageGlobal.object().keys();
75}
76
77QString Language::id(const QString &filePath)
78{
79 Language::initialize();
80 auto jsonObj = documents::languageGlobal.object();
81 QFileInfo info(filePath);
82 for (auto id : ids()) {
83 auto langObjChild = jsonObj.value(id).toObject();
84 QJsonArray suffixArray = langObjChild.value(Key_2::get()->suffix).toArray();
85 QJsonArray baseArray = langObjChild.value(Key_2::get()->base).toArray();
86 QJsonArray mimeArray = langObjChild.value(Key_2::get()->mimeType).toArray();
87
88 for (auto suffix : suffixArray) {
89 if (info.fileName().endsWith(suffix.toString()))
90 return id;
91
92 if (info.suffix() == suffix.toString())
93 return id;
94 }
95
96 for (auto base : baseArray) {
97
98 if (info.fileName() == base.toString()
99 || info.fileName().toLower() == base.toString().toLower()) {
100 return id;
101 }
102 }
103
104 QMimeDatabase mimeDB;
105 for (auto mime : mimeArray) {
106 if (mimeDB.mimeTypeForFile(info).name() == mime.toString()) {
107 return id;
108 }
109 }
110 }
111
112 return "";
113}
114
115QString Language::idAlias(const QString &id)
116{
117 if (id == "cpp")
118 return "C/C++";
119 else if (id == "java")
120 return "Java";
121 else if (id == "python")
122 return "Python";
123 return "";
124}
125
126QMap<int, QString> Language::tokenWords(const QString &id)
127{
128 QMap<int, QString> result;
129 auto idObj = documents::languageGlobal.object().value(id).toObject();
130 auto tokenChildObj = idObj.value(Key_2::get()->tokenWords).toObject();
131
132 for (auto key: tokenChildObj.keys()) {
133 result[key.toInt()] = tokenChildObj.value(key).toString();
134 }
135
136 return result;
137}
138
139QSet<QString> Language::suffixs(const QString &id)
140{
141 QSet<QString> result;
142 auto idObj = documents::languageGlobal.object().value(id).toObject();
143 auto suffixArray = idObj.value(Key_2::get()->suffix).toArray();
144 for (auto value : suffixArray) {
145 result.insert(value.toString());
146 }
147 return result;
148}
149
150QSet<QString> Language::bases(const QString &id)
151{
152 QSet<QString> result;
153 auto idObj = documents::languageGlobal.object().value(id).toObject();
154 auto baseArray = idObj.value(Key_2::get()->base).toArray();
155 for (auto value : baseArray) {
156 result.insert(value.toString());
157 }
158 return result;
159}
160
161QSet<QString> Language::mimeTypes(const QString &id)
162{
163 QSet<QString> result;
164 auto idObj = documents::languageGlobal.object().value(id).toObject();
165 auto baseArray = idObj.value(Key_2::get()->mimeType).toArray();
166 for (auto value : baseArray) {
167 result.insert(value.toString());
168 }
169 return result;
170}
171
172} // namespace support_file
173