mirror of
https://github.com/vicr123/the-libs.git
synced 2025-01-22 10:22:03 -05:00
Add tltrdesktop utility
This commit is contained in:
parent
1899e0fb68
commit
a0e6373fd6
10 changed files with 473 additions and 1 deletions
|
@ -6,3 +6,6 @@ include(installtranslations.pri)
|
|||
|
||||
# Check if this is a Blueprint build
|
||||
include(checkblueprint.pri)
|
||||
|
||||
# Generate .desktop translations
|
||||
include(processdesktoptranslations.pri)
|
||||
|
|
|
@ -29,4 +29,5 @@ isEmpty(SKIP_GENTRANSLATION) {
|
|||
}
|
||||
|
||||
DISTFILES += \
|
||||
$$PWD/checkblueprint.pri
|
||||
$$PWD/checkblueprint.pri \
|
||||
$$PWD/processdesktoptranslations.pri
|
||||
|
|
33
lib/prifiles/processdesktoptranslations.pri
Normal file
33
lib/prifiles/processdesktoptranslations.pri
Normal file
|
@ -0,0 +1,33 @@
|
|||
unix:!macx {
|
||||
desktopgen.output = ${QMAKE_FILE_BASE}.desktop
|
||||
desktopgen.commands = tltrdesktop --desktop-generate --desktop-template ${QMAKE_FILE_NAME} --json-directory $$_PRO_FILE_PWD_/translations/desktop/${QMAKE_FILE_NAME}/ --desktop-output ${QMAKE_FILE_OUT}
|
||||
desktopgen.input = DESKTOP_FILE
|
||||
desktopgen.CONFIG = no_link target_predeps
|
||||
desktopgen.variable_out = DESKTOP_FILE_GENERATED
|
||||
|
||||
desktopgenbp.output = ${QMAKE_FILE_BASE}.desktop
|
||||
desktopgenbp.commands = tltrdesktop --desktop-generate --desktop-template ${QMAKE_FILE_NAME} --json-directory $$_PRO_FILE_PWD_/translations/desktop/${QMAKE_FILE_NAME}/ --desktop-output ${QMAKE_FILE_OUT}
|
||||
desktopgenbp.input = DESKTOP_FILE_BLUEPRINT
|
||||
desktopgenbp.CONFIG = no_link target_predeps
|
||||
desktopgenbp.variable_out = DESKTOP_FILE_BLUEPRINT_GENERATED
|
||||
|
||||
QMAKE_EXTRA_COMPILERS = desktopgen desktopgenbp
|
||||
|
||||
!isEmpty(DESKTOP_FILE):!blueprint {
|
||||
desktop.files = DESKTOP_FILE_GENERATED
|
||||
desktop.path = /usr/share/applications
|
||||
desktop.extra = $$QMAKE_COPY $${OUT_PWD}/$$DESKTOP_FILE $(INSTALL_ROOT)/usr/share/applications
|
||||
INSTALLS += desktop
|
||||
|
||||
message(Will install $$DESKTOP_FILE as the desktop file)
|
||||
}
|
||||
|
||||
!isEmpty(DESKTOP_FILE_BLUEPRINT):blueprint {
|
||||
desktop.files = DESKTOP_FILE_GENERATED_BLUEPRINT
|
||||
desktop.path = /usr/share/applications
|
||||
desktop.extra = $$QMAKE_COPY $${OUT_PWD}/$$DESKTOP_FILE_BLUEPRINT $(INSTALL_ROOT)/usr/share/applications
|
||||
INSTALLS += desktop
|
||||
|
||||
message(Will install $$DESKTOP_FILE_BLUEPRINT as the desktop file)
|
||||
}
|
||||
}
|
|
@ -7,6 +7,10 @@ unittest.depends = library
|
|||
|
||||
SUBDIRS += library
|
||||
|
||||
unix:!macx {
|
||||
SUBDIRS += tltrdesktop
|
||||
}
|
||||
|
||||
#!android {
|
||||
# unittest
|
||||
#}
|
||||
|
|
102
tltrdesktop/desktopfile.cpp
Normal file
102
tltrdesktop/desktopfile.cpp
Normal file
|
@ -0,0 +1,102 @@
|
|||
/****************************************
|
||||
*
|
||||
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
||||
* Copyright (C) 2021 Victor Tran
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#include "desktopfile.h"
|
||||
|
||||
#include <QFile>
|
||||
#include <QTextStream>
|
||||
|
||||
struct DesktopFilePrivate {
|
||||
QStringList lines;
|
||||
QStringList outputLines;
|
||||
int currentLine = -1;
|
||||
|
||||
bool lineWritten = true;
|
||||
|
||||
QString currentLineText();
|
||||
};
|
||||
|
||||
DesktopFile::DesktopFile(QString file) {
|
||||
d = new DesktopFilePrivate();
|
||||
|
||||
QFile f(file);
|
||||
f.open(QFile::ReadOnly);
|
||||
d->lines = QString(f.readAll()).split('\n');
|
||||
}
|
||||
|
||||
DesktopFile::~DesktopFile() {
|
||||
delete d;
|
||||
}
|
||||
|
||||
bool DesktopFile::nextLine() {
|
||||
if (!d->lineWritten) {
|
||||
//Copy this line verbatim to the output if it's not a translator's comment
|
||||
if (!d->currentLineText().startsWith("#T:")) d->outputLines.append(d->currentLineText());
|
||||
}
|
||||
|
||||
d->currentLine++;
|
||||
d->lineWritten = false;
|
||||
return d->lines.count() > d->currentLine;
|
||||
}
|
||||
|
||||
bool DesktopFile::isKeyValue() {
|
||||
return d->currentLineText().contains("=");
|
||||
}
|
||||
|
||||
QString DesktopFile::key() {
|
||||
QString key = d->currentLineText().left(d->currentLineText().indexOf("="));
|
||||
if (key.endsWith("[]")) key.chop(2);
|
||||
return key;
|
||||
}
|
||||
|
||||
QString DesktopFile::value() {
|
||||
return d->currentLineText().mid(d->currentLineText().indexOf("=") + 1);
|
||||
}
|
||||
|
||||
QString DesktopFile::comment() {
|
||||
if (d->currentLine == 0) return "";
|
||||
QString previousLine = d->lines.value(d->currentLine - 1);
|
||||
if (!previousLine.startsWith("#T:")) return "";
|
||||
return previousLine.mid(3);
|
||||
}
|
||||
|
||||
bool DesktopFile::isLineTranslatable() {
|
||||
if (!isKeyValue()) return false;
|
||||
return d->currentLineText().left(d->currentLineText().indexOf("=")).endsWith("[]");
|
||||
}
|
||||
|
||||
void DesktopFile::insert(QString key, QString value, QString locale) {
|
||||
QString line = QStringLiteral("%1%2=%3").arg(key);
|
||||
if (locale.isEmpty()) {
|
||||
line = line.arg("");
|
||||
} else {
|
||||
line = line.arg(QStringLiteral("[%1]").arg(locale));
|
||||
}
|
||||
line = line.arg(value);
|
||||
d->outputLines.append(line);
|
||||
d->lineWritten = true;
|
||||
}
|
||||
|
||||
QString DesktopFile::outputText() {
|
||||
return d->outputLines.join("\n");
|
||||
}
|
||||
|
||||
QString DesktopFilePrivate::currentLineText() {
|
||||
return lines.at(currentLine);
|
||||
}
|
46
tltrdesktop/desktopfile.h
Normal file
46
tltrdesktop/desktopfile.h
Normal file
|
@ -0,0 +1,46 @@
|
|||
/****************************************
|
||||
*
|
||||
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
||||
* Copyright (C) 2021 Victor Tran
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#ifndef DESKTOPFILE_H
|
||||
#define DESKTOPFILE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct DesktopFilePrivate;
|
||||
class DesktopFile {
|
||||
public:
|
||||
DesktopFile(QString file);
|
||||
~DesktopFile();
|
||||
|
||||
bool nextLine();
|
||||
bool isKeyValue();
|
||||
QString key();
|
||||
QString value();
|
||||
QString comment();
|
||||
bool isLineTranslatable();
|
||||
|
||||
void insert(QString key, QString value, QString locale = "");
|
||||
|
||||
QString outputText();
|
||||
|
||||
private:
|
||||
DesktopFilePrivate* d;
|
||||
};
|
||||
|
||||
#endif // DESKTOPFILE_H
|
80
tltrdesktop/jsonfile.cpp
Normal file
80
tltrdesktop/jsonfile.cpp
Normal file
|
@ -0,0 +1,80 @@
|
|||
/****************************************
|
||||
*
|
||||
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
||||
* Copyright (C) 2021 Victor Tran
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#include "jsonfile.h"
|
||||
|
||||
#include <QJsonDocument>
|
||||
#include <QJsonObject>
|
||||
#include <QFile>
|
||||
|
||||
struct JsonFilePrivate {
|
||||
uint refcount = 0;
|
||||
QJsonObject rootObject;
|
||||
};
|
||||
|
||||
JsonFile::JsonFile() {
|
||||
d = new JsonFilePrivate();
|
||||
d->refcount++;
|
||||
}
|
||||
|
||||
JsonFile::JsonFile(QString file) {
|
||||
d = new JsonFilePrivate();
|
||||
d->refcount++;
|
||||
|
||||
QFile f(file);
|
||||
f.open(QFile::ReadOnly);
|
||||
d->rootObject = QJsonDocument::fromJson(f.readAll()).object();
|
||||
}
|
||||
|
||||
JsonFile::JsonFile(const JsonFile& other) {
|
||||
this->d = other.d;
|
||||
d->refcount++;
|
||||
}
|
||||
|
||||
JsonFile::~JsonFile() {
|
||||
d->refcount--;
|
||||
if (d->refcount == 0) delete d;
|
||||
}
|
||||
|
||||
void JsonFile::insertString(QString key, QString message, QString description) {
|
||||
QJsonObject stringObject;
|
||||
stringObject.insert("message", message);
|
||||
if (!description.isEmpty()) stringObject.insert("description", description);
|
||||
d->rootObject.insert(key, stringObject);
|
||||
}
|
||||
|
||||
QString JsonFile::message(QString key) const {
|
||||
QJsonValue stringValue = d->rootObject.value(key);
|
||||
if (!stringValue.isObject()) return "";
|
||||
|
||||
return stringValue.toObject().value("message").toString();
|
||||
}
|
||||
|
||||
QByteArray JsonFile::output() {
|
||||
return QJsonDocument(d->rootObject).toJson();
|
||||
}
|
||||
|
||||
JsonFile& JsonFile::operator =(const JsonFile& other) {
|
||||
d->refcount--;
|
||||
if (d->refcount == 0) delete d;
|
||||
|
||||
d = other.d;
|
||||
d->refcount++;
|
||||
return *this;
|
||||
}
|
45
tltrdesktop/jsonfile.h
Normal file
45
tltrdesktop/jsonfile.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
/****************************************
|
||||
*
|
||||
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
||||
* Copyright (C) 2021 Victor Tran
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#ifndef JSONFILE_H
|
||||
#define JSONFILE_H
|
||||
|
||||
#include <QString>
|
||||
|
||||
struct JsonFilePrivate;
|
||||
|
||||
class JsonFile {
|
||||
public:
|
||||
JsonFile();
|
||||
JsonFile(QString file);
|
||||
JsonFile(const JsonFile& other);
|
||||
~JsonFile();
|
||||
|
||||
void insertString(QString key, QString message, QString description = "");
|
||||
QString message(QString key) const;
|
||||
|
||||
QByteArray output();
|
||||
|
||||
JsonFile& operator=(const JsonFile& other);
|
||||
|
||||
private:
|
||||
JsonFilePrivate* d;
|
||||
};
|
||||
|
||||
#endif // JSONFILE_H
|
136
tltrdesktop/main.cpp
Normal file
136
tltrdesktop/main.cpp
Normal file
|
@ -0,0 +1,136 @@
|
|||
/****************************************
|
||||
*
|
||||
* INSERT-PROJECT-NAME-HERE - INSERT-GENERIC-NAME-HERE
|
||||
* Copyright (C) 2021 Victor Tran
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*
|
||||
* *************************************/
|
||||
#include <QCoreApplication>
|
||||
#include <QTextStream>
|
||||
#include <QCommandLineParser>
|
||||
#include <QDir>
|
||||
|
||||
#include "desktopfile.h"
|
||||
#include "jsonfile.h"
|
||||
|
||||
void genJsonFile(QString desktopFile, QDir outputDirectory) {
|
||||
QTextStream output(stdout);
|
||||
|
||||
JsonFile file;
|
||||
DesktopFile desktop(desktopFile);
|
||||
while (desktop.nextLine()) {
|
||||
if (desktop.isLineTranslatable()) {
|
||||
//Export this line to the translation file
|
||||
file.insertString(desktop.key(), desktop.value(), desktop.comment());
|
||||
}
|
||||
}
|
||||
|
||||
//Write the output to en.json
|
||||
QString outputFile = outputDirectory.absoluteFilePath("en.json");
|
||||
output << "Generating file " << outputFile << "...\n";
|
||||
|
||||
QFile f(outputFile);
|
||||
f.open(QFile::WriteOnly);
|
||||
f.write(file.output());
|
||||
f.close();
|
||||
}
|
||||
|
||||
void genDesktopFile(QString templateFile, QDir jsonDirectory, QString outputFile) {
|
||||
QTextStream output(stdout);
|
||||
QMap<QString, JsonFile> jsonFiles;
|
||||
for (const QFileInfo& file : jsonDirectory.entryInfoList({"*.json"}, QDir::Files)) {
|
||||
JsonFile jsonFile(file.absoluteFilePath());
|
||||
jsonFiles.insert(file.baseName(), jsonFile);
|
||||
}
|
||||
|
||||
DesktopFile desktop(templateFile);
|
||||
while (desktop.nextLine()) {
|
||||
if (desktop.isLineTranslatable()) {
|
||||
//Insert the translations into the desktop file
|
||||
//First, insert the translation without a locale
|
||||
desktop.insert(desktop.key(), desktop.value());
|
||||
|
||||
for (const QString& locale : jsonFiles.keys()) {
|
||||
QString value = jsonFiles.value(locale).message(desktop.key());
|
||||
desktop.insert(desktop.key(), value, locale);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Output to the output file
|
||||
output << "Generating file " << outputFile << "...\n";
|
||||
|
||||
QFile f(outputFile);
|
||||
f.open(QFile::WriteOnly);
|
||||
f.write(desktop.outputText().toUtf8());
|
||||
f.close();
|
||||
}
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
QCoreApplication a(argc, argv);
|
||||
|
||||
QCommandLineParser parser;
|
||||
parser.addOption({{"j", "json-generate"}, "Generate JSON Translation files from .desktop files"});
|
||||
parser.addOption({{"k", "desktop-generate"}, "Generate .desktop files from JSON Translation files"});
|
||||
parser.addOption({{"d", "json-directory"}, "Directory of JSON Translation files", "json-directory"});
|
||||
parser.addOption({{"t", "desktop-template"}, ".desktop template file", "desktop template"});
|
||||
parser.addOption({{"o", "desktop-output"}, ".desktop output file", "desktop output"});
|
||||
QCommandLineOption helpOption = parser.addHelpOption();
|
||||
parser.parse(a.arguments());
|
||||
|
||||
QTextStream output(stdout);
|
||||
QTextStream eoutput(stderr);
|
||||
if (parser.isSet(helpOption)) {
|
||||
output << parser.helpText() << "\n";
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool genJson = parser.isSet("json-generate");
|
||||
bool genDesktop = parser.isSet("desktop-generate");
|
||||
if (!genJson && !genDesktop) {
|
||||
eoutput << "error: At least one of --json-generate or --desktop-generate must be specified.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parser.isSet("desktop-template")) {
|
||||
eoutput << "error: A desktop template file must be specified with --desktop-template.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parser.isSet("json-directory")) {
|
||||
eoutput << "error: A JSON output directory must be specified with --json-directory.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parser.isSet("desktop-output") && genDesktop) {
|
||||
eoutput << "error: A .desktop output file must be specified with --desktop-output.\n";
|
||||
return 1;
|
||||
}
|
||||
|
||||
QString desktopTemplate = parser.value("desktop-template");
|
||||
QDir outputDirectory(parser.value("json-directory"));
|
||||
if (!outputDirectory.exists()) outputDirectory.mkpath(".");
|
||||
|
||||
if (genJson) {
|
||||
//Generate the en JSON file from a .desktop file
|
||||
genJsonFile(desktopTemplate, outputDirectory);
|
||||
}
|
||||
if (genDesktop) {
|
||||
//Generate the final .desktop file from JSON files
|
||||
genDesktopFile(desktopTemplate, outputDirectory, parser.value("desktop-output"));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
22
tltrdesktop/tltrdesktop.pro
Normal file
22
tltrdesktop/tltrdesktop.pro
Normal file
|
@ -0,0 +1,22 @@
|
|||
QT -= gui
|
||||
|
||||
CONFIG += c++11 console
|
||||
CONFIG -= app_bundle
|
||||
|
||||
# You can make your code fail to compile if it uses deprecated APIs.
|
||||
# In order to do so, uncomment the following line.
|
||||
#DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0x060000 # disables all the APIs deprecated before Qt 6.0.0
|
||||
|
||||
SOURCES += \
|
||||
desktopfile.cpp \
|
||||
jsonfile.cpp \
|
||||
main.cpp
|
||||
|
||||
unix:!macx {
|
||||
target.path = /usr/bin
|
||||
INSTALLS += target
|
||||
}
|
||||
|
||||
HEADERS += \
|
||||
desktopfile.h \
|
||||
jsonfile.h
|
Loading…
Reference in a new issue