Translations deployment for MAC & Linux has fixed (#1119)

* Translations load refactoring

* Translations: Added MAC support

* Translations: fixed getting of translation folders

* Fixed code style, documented some methods
This commit is contained in:
a1ext 2019-01-20 20:00:23 +03:00 committed by Itay Cohen
parent 04ed78444d
commit 73cf41b81e
9 changed files with 140 additions and 59 deletions

View File

@ -75,7 +75,10 @@ script:
after_success:
- export CUTTER_VERSION=$(python ../scripts/get_version.py)
- lrelease ../src/Cutter.pro
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
mkdir -p Cutter.app/Contents/Resources/translations &&
cp ../src/translations/*.qm Cutter.app/Contents/Resources/translations/ &&
macdeployqt Cutter.app -executable=Cutter.app/Contents/MacOS/Cutter -libpath="../Frameworks" &&
macdeployqt Cutter.app -executable=Cutter.app/Contents/MacOS/Cutter -libpath="../Frameworks" &&
"$TRAVIS_BUILD_DIR/scripts/appbundle_embed_python.sh" "$PYTHON_FRAMEWORK_DIR/Python.framework" Cutter.app Cutter.app/Contents/MacOS/Cutter &&
@ -98,6 +101,8 @@ after_success:
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
make INSTALL_ROOT=appdir install &&
cp -r /usr/share/radare2 appdir/usr/share/ &&
mkdir -p appdir/usr/bin/translations &&
cp ../src/translations/*.qm appdir/usr/bin/translations/ &&
"$TRAVIS_BUILD_DIR/scripts/appimage_embed_python.sh" "$CUSTOM_PYTHON_PREFIX" appdir &&
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" &&
chmod a+x linuxdeployqt*.AppImage &&

View File

@ -25,8 +25,6 @@
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
{
// Setup application information
setOrganizationName("Cutter");
setApplicationName("Cutter");
setApplicationVersion(CUTTER_VERSION_FULL);
setWindowIcon(QIcon(":/img/cutter.svg"));
setAttribute(Qt::AA_DontShowIconsInMenus);
@ -34,45 +32,10 @@ CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First
// Load translations
QTranslator *t = new QTranslator;
QTranslator *qtBaseTranslator = new QTranslator;
QTranslator *qtTranslator = new QTranslator;
QString language = Config()->getCurrLocale().bcp47Name();
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
QLocale::AnyCountry);
QString langPrefix;
if (language != "en") {
for (const QLocale &it : allLocales) {
langPrefix = it.bcp47Name();
if (langPrefix == language) {
const QString &cutterTranslationPath = QCoreApplication::applicationDirPath() + QDir::separator()
+ "translations" + QDir::separator() + QString("cutter_%1.qm").arg(langPrefix);
if (t->load(cutterTranslationPath)) {
installTranslator(t);
}
QApplication::setLayoutDirection(it.textDirection());
QLocale::setDefault(it);
QString translationsPath(QLibraryInfo::location(QLibraryInfo::TranslationsPath));
if (qtTranslator->load(it, "qt", "_", translationsPath)) {
installTranslator(qtTranslator);
} else {
delete qtTranslator;
}
if (qtBaseTranslator->load(it, "qtbase", "_", translationsPath)) {
installTranslator(qtBaseTranslator);
} else {
delete qtBaseTranslator;
}
break;
}
}
if (!loadTranslations()) {
qWarning() << "Cannot load translations";
}
// Load fonts
int ret = QFontDatabase::addApplicationFont(":/fonts/Anonymous Pro.ttf");
if (ret == -1) {
@ -264,3 +227,61 @@ void CutterApplication::loadPlugins()
Core()->setCutterPlugins(plugins);
}
bool CutterApplication::loadTranslations()
{
const QString &language = Config()->getCurrLocale().bcp47Name();
if (language == QStringLiteral("en") || language.startsWith(QStringLiteral("en-"))) {
return true;
}
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
QLocale::AnyCountry);
bool cutterTrLoaded = false;
for (const QLocale &it : allLocales) {
const QString &langPrefix = it.bcp47Name();
if (langPrefix == language) {
QApplication::setLayoutDirection(it.textDirection());
QLocale::setDefault(it);
QTranslator *trCutter = new QTranslator;
QTranslator *trQtBase = new QTranslator;
QTranslator *trQt = new QTranslator;
const QStringList &cutterTrPaths = Config()->getTranslationsDirectories();
for (const auto &trPath : cutterTrPaths) {
if (trCutter && trCutter->load(it, QLatin1String("cutter"), QLatin1String("_"), trPath)) {
installTranslator(trCutter);
cutterTrLoaded = true;
trCutter = nullptr;
}
if (trQt && trQt->load(it, "qt", "_", trPath)) {
installTranslator(trQt);
trQt = nullptr;
}
if (trQtBase && trQtBase->load(it, "qtbase", "_", trPath)) {
installTranslator(trQtBase);
trQtBase = nullptr;
}
}
if (trCutter) {
delete trCutter;
}
if (trQt) {
delete trQt;
}
if (trQtBase) {
delete trQtBase;
}
return true;
}
}
if (!cutterTrLoaded) {
qWarning() << "Cannot load Cutter's translation for " << language;
}
return false;
}

View File

@ -26,6 +26,13 @@ public:
protected:
bool event(QEvent *e);
private:
/*!
* \brief Load and translations depending on Language settings
* \return true on success
*/
bool loadTranslations();
private:
bool m_FileAlreadyDropped;
MainWindow *mainWindow;

View File

@ -7,6 +7,10 @@ int main(int argc, char *argv[])
qRegisterMetaType<QList<StringDescription>>();
qRegisterMetaType<QList<FunctionDescription>>();
// Application info setup, required to be set before any instance of QSettings will be instantiated
QCoreApplication::setOrganizationName("Cutter");
QCoreApplication::setApplicationName("Cutter");
CutterApplication a(argc, argv);
int ret = a.exec();

View File

@ -5,6 +5,7 @@
#include <QFontDatabase>
#include <QFile>
#include <QApplication>
#include <QLibraryInfo>
#include "common/ColorSchemeFileSaver.h"
@ -54,6 +55,13 @@ static const QHash<QString, QVariant> asmOptions = {
Configuration::Configuration() : QObject()
{
mPtr = this;
if (!s.isWritable()) {
QMessageBox::critical(nullptr,
tr("Critical!"),
tr("!!! Settings are not writable! Make sure you have a write access to \"%1\"")
.arg(s.fileName())
);
}
loadInitial();
}
@ -74,7 +82,7 @@ void Configuration::loadInitial()
QString Configuration::getDirProjects()
{
auto projectsDir = s.value("dir.projects").toString();
if (projectsDir == "") {
if (projectsDir.isEmpty()) {
projectsDir = Core()->getConfig("dir.projects");
setDirProjects(projectsDir);
}
@ -126,7 +134,7 @@ QLocale Configuration::getCurrLocale() const
/*!
* \brief sets Cutter's locale
* \param l - a QLocale object describes the locate to confugre
* \param l - a QLocale object describes the locate to configure
*/
void Configuration::setLocale(const QLocale &l)
{
@ -136,18 +144,20 @@ void Configuration::setLocale(const QLocale &l)
/*!
* \brief set Cutter's interface language by a given locale name
* \param language - a string represents the name of a locale language
* \return true on success
*/
void Configuration::setLocaleByName(const QString &language)
bool Configuration::setLocaleByName(const QString &language)
{
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
const auto &allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
QLocale::AnyCountry);
for (auto &it : allLocales) {
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
setLocale(it);
break;
return true;
}
}
return false;
}
bool Configuration::windowColorIsDark()
@ -454,10 +464,23 @@ void Configuration::setConfig(const QString &key, const QVariant &value)
*/
QStringList Configuration::getAvailableTranslations()
{
QDir dir(QCoreApplication::applicationDirPath() + QDir::separator() +
"translations");
QStringList fileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files,
QDir::Name);
const auto &trDirs = getTranslationsDirectories();
QSet<QString> fileNamesSet;
for (const auto &trDir : trDirs) {
QDir dir(trDir);
if (!dir.exists()) {
continue;
}
const QStringList &currTrFileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files,
QDir::Name);
for (const auto &trFile : currTrFileNames) {
fileNamesSet << trFile;
}
}
QStringList fileNames = fileNamesSet.toList();
qSort(fileNames);
QStringList languages;
QString currLanguageName;
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
@ -475,7 +498,7 @@ QStringList Configuration::getAvailableTranslations()
}
}
}
return languages << "English";
return languages << QLatin1String("English");
}
/*!
@ -492,3 +515,17 @@ bool Configuration::isFirstExecution()
return true;
}
}
QStringList Configuration::getTranslationsDirectories() const
{
static const QString cutterTranslationPath = QCoreApplication::applicationDirPath() + QDir::separator()
+ QLatin1String("translations");
return {
cutterTranslationPath,
QLibraryInfo::location(QLibraryInfo::TranslationsPath),
#ifdef Q_OS_MAC
QStringLiteral("%1/../Resources/translations").arg(QCoreApplication::applicationDirPath()),
#endif // Q_OS_MAC
};
}

View File

@ -50,7 +50,7 @@ public:
// Languages
QLocale getCurrLocale() const;
void setLocale(const QLocale &l);
void setLocaleByName(const QString &language);
bool setLocaleByName(const QString &language);
QStringList getAvailableTranslations();
// Fonts
@ -107,7 +107,12 @@ public:
*/
void setConfig(const QString &key, const QVariant &value);
bool isFirstExecution();
/*!
* \brief Get list of available translation directories (depends on configuration and OS)
* \return list of directories
*/
QStringList getTranslationsDirectories() const;
signals:
void fontsUpdated();

View File

@ -16,6 +16,7 @@ WelcomeDialog::WelcomeDialog(QWidget *parent) :
ui(new Ui::WelcomeDialog)
{
ui->setupUi(this);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
ui->logoSvgWidget->load(Config()->getLogoFile());
ui->versionLabel->setText("<font color='#a4a9b2'>" + tr("Version ") + CUTTER_VERSION_FULL + "</font>");
ui->themeComboBox->setCurrentIndex(Config()->getTheme());

View File

@ -185,12 +185,12 @@ void AppearanceOptionsWidget::on_deleteButton_clicked()
void AppearanceOptionsWidget::onLanguageComboBoxCurrentIndexChanged(int index)
{
QString language = ui->languageComboBox->itemText(index).toLower();
Config()->setLocaleByName(language);
if (Config()->setLocaleByName(language)) {
QMessageBox::information(this,
tr("Language settings"),
tr("Language will be changed after next application start."));
return;
}
QMessageBox mb;
mb.setWindowTitle(tr("Language settings"));
mb.setText(tr("Language will be changed after next application start."));
mb.setIcon(QMessageBox::Information);
mb.setStandardButtons(QMessageBox::Ok);
mb.exec();
qWarning() << tr("Cannot set language, not found in available ones");
}

View File

@ -20,6 +20,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
{
setAttribute(Qt::WA_DeleteOnClose);
ui->setupUi(this);
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
QList<PreferenceCategory> prefs {