mirror of
https://github.com/rizinorg/cutter.git
synced 2025-01-31 08:37:26 +00:00
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:
parent
04ed78444d
commit
73cf41b81e
@ -75,7 +75,10 @@ script:
|
|||||||
|
|
||||||
after_success:
|
after_success:
|
||||||
- export CUTTER_VERSION=$(python ../scripts/get_version.py)
|
- export CUTTER_VERSION=$(python ../scripts/get_version.py)
|
||||||
|
- lrelease ../src/Cutter.pro
|
||||||
- if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then
|
- 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" &&
|
||||||
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 &&
|
"$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
|
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then
|
||||||
make INSTALL_ROOT=appdir install &&
|
make INSTALL_ROOT=appdir install &&
|
||||||
cp -r /usr/share/radare2 appdir/usr/share/ &&
|
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 &&
|
"$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" &&
|
wget -c "https://github.com/probonopd/linuxdeployqt/releases/download/continuous/linuxdeployqt-continuous-x86_64.AppImage" &&
|
||||||
chmod a+x linuxdeployqt*.AppImage &&
|
chmod a+x linuxdeployqt*.AppImage &&
|
||||||
|
@ -25,8 +25,6 @@
|
|||||||
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
|
CutterApplication::CutterApplication(int &argc, char **argv) : QApplication(argc, argv)
|
||||||
{
|
{
|
||||||
// Setup application information
|
// Setup application information
|
||||||
setOrganizationName("Cutter");
|
|
||||||
setApplicationName("Cutter");
|
|
||||||
setApplicationVersion(CUTTER_VERSION_FULL);
|
setApplicationVersion(CUTTER_VERSION_FULL);
|
||||||
setWindowIcon(QIcon(":/img/cutter.svg"));
|
setWindowIcon(QIcon(":/img/cutter.svg"));
|
||||||
setAttribute(Qt::AA_DontShowIconsInMenus);
|
setAttribute(Qt::AA_DontShowIconsInMenus);
|
||||||
@ -34,43 +32,8 @@ 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
|
// WARN!!! Put initialization code below this line. Code above this line is mandatory to be run First
|
||||||
// Load translations
|
// Load translations
|
||||||
QTranslator *t = new QTranslator;
|
if (!loadTranslations()) {
|
||||||
QTranslator *qtBaseTranslator = new QTranslator;
|
qWarning() << "Cannot load translations";
|
||||||
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;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load fonts
|
// Load fonts
|
||||||
@ -264,3 +227,61 @@ void CutterApplication::loadPlugins()
|
|||||||
|
|
||||||
Core()->setCutterPlugins(plugins);
|
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;
|
||||||
|
}
|
@ -26,6 +26,13 @@ public:
|
|||||||
protected:
|
protected:
|
||||||
bool event(QEvent *e);
|
bool event(QEvent *e);
|
||||||
|
|
||||||
|
private:
|
||||||
|
/*!
|
||||||
|
* \brief Load and translations depending on Language settings
|
||||||
|
* \return true on success
|
||||||
|
*/
|
||||||
|
bool loadTranslations();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool m_FileAlreadyDropped;
|
bool m_FileAlreadyDropped;
|
||||||
MainWindow *mainWindow;
|
MainWindow *mainWindow;
|
||||||
|
@ -7,6 +7,10 @@ int main(int argc, char *argv[])
|
|||||||
qRegisterMetaType<QList<StringDescription>>();
|
qRegisterMetaType<QList<StringDescription>>();
|
||||||
qRegisterMetaType<QList<FunctionDescription>>();
|
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);
|
CutterApplication a(argc, argv);
|
||||||
|
|
||||||
int ret = a.exec();
|
int ret = a.exec();
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
#include <QFontDatabase>
|
#include <QFontDatabase>
|
||||||
#include <QFile>
|
#include <QFile>
|
||||||
#include <QApplication>
|
#include <QApplication>
|
||||||
|
#include <QLibraryInfo>
|
||||||
|
|
||||||
#include "common/ColorSchemeFileSaver.h"
|
#include "common/ColorSchemeFileSaver.h"
|
||||||
|
|
||||||
@ -54,6 +55,13 @@ static const QHash<QString, QVariant> asmOptions = {
|
|||||||
Configuration::Configuration() : QObject()
|
Configuration::Configuration() : QObject()
|
||||||
{
|
{
|
||||||
mPtr = this;
|
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();
|
loadInitial();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -74,7 +82,7 @@ void Configuration::loadInitial()
|
|||||||
QString Configuration::getDirProjects()
|
QString Configuration::getDirProjects()
|
||||||
{
|
{
|
||||||
auto projectsDir = s.value("dir.projects").toString();
|
auto projectsDir = s.value("dir.projects").toString();
|
||||||
if (projectsDir == "") {
|
if (projectsDir.isEmpty()) {
|
||||||
projectsDir = Core()->getConfig("dir.projects");
|
projectsDir = Core()->getConfig("dir.projects");
|
||||||
setDirProjects(projectsDir);
|
setDirProjects(projectsDir);
|
||||||
}
|
}
|
||||||
@ -126,7 +134,7 @@ QLocale Configuration::getCurrLocale() const
|
|||||||
|
|
||||||
/*!
|
/*!
|
||||||
* \brief sets Cutter's locale
|
* \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)
|
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
|
* \brief set Cutter's interface language by a given locale name
|
||||||
* \param language - a string represents the name of a locale language
|
* \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);
|
QLocale::AnyCountry);
|
||||||
|
|
||||||
for (auto &it : allLocales) {
|
for (auto &it : allLocales) {
|
||||||
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
if (QString::compare(it.nativeLanguageName(), language, Qt::CaseInsensitive) == 0) {
|
||||||
setLocale(it);
|
setLocale(it);
|
||||||
break;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Configuration::windowColorIsDark()
|
bool Configuration::windowColorIsDark()
|
||||||
@ -454,10 +464,23 @@ void Configuration::setConfig(const QString &key, const QVariant &value)
|
|||||||
*/
|
*/
|
||||||
QStringList Configuration::getAvailableTranslations()
|
QStringList Configuration::getAvailableTranslations()
|
||||||
{
|
{
|
||||||
QDir dir(QCoreApplication::applicationDirPath() + QDir::separator() +
|
const auto &trDirs = getTranslationsDirectories();
|
||||||
"translations");
|
|
||||||
QStringList fileNames = dir.entryList(QStringList("cutter_*.qm"), QDir::Files,
|
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);
|
QDir::Name);
|
||||||
|
for (const auto &trFile : currTrFileNames) {
|
||||||
|
fileNamesSet << trFile;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
QStringList fileNames = fileNamesSet.toList();
|
||||||
|
qSort(fileNames);
|
||||||
QStringList languages;
|
QStringList languages;
|
||||||
QString currLanguageName;
|
QString currLanguageName;
|
||||||
auto allLocales = QLocale::matchingLocales(QLocale::AnyLanguage, QLocale::AnyScript,
|
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;
|
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
|
||||||
|
};
|
||||||
|
}
|
||||||
|
@ -50,7 +50,7 @@ public:
|
|||||||
// Languages
|
// Languages
|
||||||
QLocale getCurrLocale() const;
|
QLocale getCurrLocale() const;
|
||||||
void setLocale(const QLocale &l);
|
void setLocale(const QLocale &l);
|
||||||
void setLocaleByName(const QString &language);
|
bool setLocaleByName(const QString &language);
|
||||||
QStringList getAvailableTranslations();
|
QStringList getAvailableTranslations();
|
||||||
|
|
||||||
// Fonts
|
// Fonts
|
||||||
@ -108,6 +108,11 @@ public:
|
|||||||
void setConfig(const QString &key, const QVariant &value);
|
void setConfig(const QString &key, const QVariant &value);
|
||||||
bool isFirstExecution();
|
bool isFirstExecution();
|
||||||
|
|
||||||
|
/*!
|
||||||
|
* \brief Get list of available translation directories (depends on configuration and OS)
|
||||||
|
* \return list of directories
|
||||||
|
*/
|
||||||
|
QStringList getTranslationsDirectories() const;
|
||||||
|
|
||||||
signals:
|
signals:
|
||||||
void fontsUpdated();
|
void fontsUpdated();
|
||||||
|
@ -16,6 +16,7 @@ WelcomeDialog::WelcomeDialog(QWidget *parent) :
|
|||||||
ui(new Ui::WelcomeDialog)
|
ui(new Ui::WelcomeDialog)
|
||||||
{
|
{
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
||||||
ui->logoSvgWidget->load(Config()->getLogoFile());
|
ui->logoSvgWidget->load(Config()->getLogoFile());
|
||||||
ui->versionLabel->setText("<font color='#a4a9b2'>" + tr("Version ") + CUTTER_VERSION_FULL + "</font>");
|
ui->versionLabel->setText("<font color='#a4a9b2'>" + tr("Version ") + CUTTER_VERSION_FULL + "</font>");
|
||||||
ui->themeComboBox->setCurrentIndex(Config()->getTheme());
|
ui->themeComboBox->setCurrentIndex(Config()->getTheme());
|
||||||
|
@ -185,12 +185,12 @@ void AppearanceOptionsWidget::on_deleteButton_clicked()
|
|||||||
void AppearanceOptionsWidget::onLanguageComboBoxCurrentIndexChanged(int index)
|
void AppearanceOptionsWidget::onLanguageComboBoxCurrentIndexChanged(int index)
|
||||||
{
|
{
|
||||||
QString language = ui->languageComboBox->itemText(index).toLower();
|
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;
|
qWarning() << tr("Cannot set language, not found in available ones");
|
||||||
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();
|
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,7 @@ PreferencesDialog::PreferencesDialog(QWidget *parent)
|
|||||||
{
|
{
|
||||||
setAttribute(Qt::WA_DeleteOnClose);
|
setAttribute(Qt::WA_DeleteOnClose);
|
||||||
ui->setupUi(this);
|
ui->setupUi(this);
|
||||||
|
setWindowFlag(Qt::WindowContextHelpButtonHint, false);
|
||||||
|
|
||||||
QList<PreferenceCategory> prefs {
|
QList<PreferenceCategory> prefs {
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user