diff options
20 files changed, 638 insertions, 261 deletions
diff --git a/demos/symbianpkgrules.pri b/demos/symbianpkgrules.pri index c9cc492..ef6dfd8 100644 --- a/demos/symbianpkgrules.pri +++ b/demos/symbianpkgrules.pri @@ -2,12 +2,13 @@ RSS_RULES ="group_name=\"QtDemos\";" +nokiaVendor = "Nokia, Qt" vendorinfo = \ "; Localised Vendor name" \ - "%{\"Nokia, Qt\"}" \ + "%{$$addLanguageDependentPkgItem(nokiaVendor)}" \ " " \ "; Unique Vendor name" \ - ":\"Nokia, Qt\"" \ + ":\"$$nokiaVendor\"" \ " " demos_deployment.pkg_prerules += vendorinfo diff --git a/doc/src/development/qmake-manual.qdoc b/doc/src/development/qmake-manual.qdoc index 6531d25..c0ed940 100644 --- a/doc/src/development/qmake-manual.qdoc +++ b/doc/src/development/qmake-manual.qdoc @@ -1294,6 +1294,14 @@ test sections in generated bld.inf instead of their regular sections. Note that this only affects automatically generated bld.inf content; the content added via \c BLD_INF_RULES variable is not affected. + \row \o localize_deployment \o Makes \c lupdate tool add fields for + application captions and package file names into generated \c{.ts} + files. Qmake generates properly localized \c{.loc} and \c{.pkg} files + based on available translations. Translation file name bodies must + end with underscore and the language code for deployment localization + to work. E.g. \c{myapp_en.ts}. + \bold{Note:} All languages supported by Qt are not supported by Symbian, + so some \c{.ts} files may be ignored by qmake. \endtable These options have an effect on Linux/Unix platforms: diff --git a/examples/symbianpkgrules.pri b/examples/symbianpkgrules.pri index 0f615c7..fe9b487 100644 --- a/examples/symbianpkgrules.pri +++ b/examples/symbianpkgrules.pri @@ -2,12 +2,13 @@ RSS_RULES ="group_name=\"QtExamples\";" +nokiaVendor = "Nokia, Qt" vendorinfo = \ "; Localised Vendor name" \ - "%{\"Nokia, Qt\"}" \ + "%{$$addLanguageDependentPkgItem(nokiaVendor)}" \ " " \ "; Unique Vendor name" \ - ":\"Nokia, Qt\"" \ + ":\"$$nokiaVendor\"" \ " " examples_deployment.pkg_prerules += vendorinfo diff --git a/mkspecs/common/symbian/appCaptionForTranslation.cpp b/mkspecs/common/symbian/appCaptionForTranslation.cpp new file mode 100644 index 0000000..c295147 --- /dev/null +++ b/mkspecs/common/symbian/appCaptionForTranslation.cpp @@ -0,0 +1,46 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//: Application short caption, currently only relevant for application projects in Symbian. +QT_TRANSLATE_NOOP("QtApplicationCaptions", "Application short caption") + +//: Application long caption, currently only relevant for application projects in Symbian. +QT_TRANSLATE_NOOP("QtApplicationCaptions", "Application long caption") diff --git a/mkspecs/common/symbian/packageNameForTranslation.cpp b/mkspecs/common/symbian/packageNameForTranslation.cpp new file mode 100644 index 0000000..bc4a7f4 --- /dev/null +++ b/mkspecs/common/symbian/packageNameForTranslation.cpp @@ -0,0 +1,47 @@ +/**************************************************************************** +** +** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies). +** All rights reserved. +** Contact: Nokia Corporation (qt-info@nokia.com) +** +** This file is part of the qmake spec of the Qt Toolkit. +** +** $QT_BEGIN_LICENSE:LGPL$ +** No Commercial Usage +** This file contains pre-release code and may not be distributed. +** You may use this file in accordance with the terms and conditions +** contained in the Technology Preview License Agreement accompanying +** this package. +** +** GNU Lesser General Public License Usage +** Alternatively, this file may be used under the terms of the GNU Lesser +** General Public License version 2.1 as published by the Free Software +** Foundation and appearing in the file LICENSE.LGPL included in the +** packaging of this file. Please review the following information to +** ensure the GNU Lesser General Public License version 2.1 requirements +** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** +** In addition, as a special exception, Nokia gives you certain additional +** rights. These rights are described in the Nokia Qt LGPL Exception +** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** +** If you have questions regarding the use of this file, please contact +** Nokia at qt-info@nokia.com. +** +** +** +** +** +** +** +** +** $QT_END_LICENSE$ +** +****************************************************************************/ + +//: Installation package name, currently only relevant for Symbian projects that deploy something. +QT_TRANSLATE_NOOP("QtPackageNames", "Package name") + +//: Smart installer installation package name, currently only relevant for Symbian projects that +//: deploy something. +QT_TRANSLATE_NOOP("QtPackageNames", "Smart installer package name") diff --git a/mkspecs/common/symbian/symbian.conf b/mkspecs/common/symbian/symbian.conf index 69188a8..f8586b0 100644 --- a/mkspecs/common/symbian/symbian.conf +++ b/mkspecs/common/symbian/symbian.conf @@ -130,6 +130,17 @@ QMAKE_LIBS_QT_ENTRY = -lqtmain$${QT_LIBINFIX}.lib QMAKE_LIBS_NO_QT_ENTRY = -llibcrt0.lib QMAKE_LIBS_NO_QT_ENTRY_GCCE = -llibcrt0_gcce.lib +# List of languages that have a Symbian language code mapping provided in localize_deployment.prf +SYMBIAN_SUPPORTED_LANGUAGES = \ + af sq am ar hy bn bg my be ca \ + hr cs da nl en et fi fr gd ka \ + de el gu he hi hu is id ga it \ + ja kn kk ko lo lv lt mk ms ml \ + mr mo mn nb pl pt pa ro ru sr \ + si sk sl so es sw sv tl ta te \ + th bo ti tr tk uk ur vi cy zu \ + nn + # These directories must match what configure uses for QT_INSTALL_PLUGINS and QT_INSTALL_IMPORTS QT_PLUGINS_BASE_DIR = /resource/qt$${QT_LIBINFIX}/plugins QT_IMPORTS_BASE_DIR = /resource/qt/imports @@ -194,17 +205,6 @@ isEmpty(S60_VERSION) { # multiple language compatible dependency statements him/herself. default_deployment.pkg_prerules += pkg_depends_webkit pkg_depends_qt pkg_platform_dependencies - -# Supports S60 3.1, 3.2, 5.0, Symbian^3, and Symbian^4 by default -pkg_platform_dependencies = \ - "; Default HW/platform dependencies" \ - "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ - "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ - "[0x1028315F],0,0,0,{\"S60ProductID\"}" \ - "[0x20022E6D],0,0,0,{\"S60ProductID\"}" \ - "[0x20032DE7],0,0,0,{\"S60ProductID\"}" \ - " " - DEPLOYMENT += default_deployment default_bin_deployment default_resource_deployment default_reg_deployment defineReplace(symbianRemoveSpecialCharacters) { @@ -225,3 +225,44 @@ defineReplace(symbianRemoveSpecialCharacters) { return ($$fixedStr) } +# Determines translations that are Symbian supported +defineTest(matchSymbianLanguages) { + SYMBIAN_MATCHED_LANGUAGES = + SYMBIAN_MATCHED_TRANSLATIONS = + + # Cannot parse .ts file for language here, so detect it from filename. + # Allow two and three character language and country codes. + for(translation, TRANSLATIONS) { + language = $$replace(translation, "^(.*/)?[^/]+_(([^_]{2,3}_)?[^_]{2,3})\\.ts$", \\2) + contains(SYMBIAN_SUPPORTED_LANGUAGES, $$language) { + SYMBIAN_MATCHED_LANGUAGES += $$language + SYMBIAN_MATCHED_TRANSLATIONS += $$translation + } + } + + isEmpty(SYMBIAN_MATCHED_LANGUAGES): SYMBIAN_MATCHED_LANGUAGES = en + + export(SYMBIAN_MATCHED_LANGUAGES) + export(SYMBIAN_MATCHED_TRANSLATIONS) +} + +# Symbian pkg files that define multiple languages require a language specific string to be +# defined for various items, even though the string often needs to be same for all languages. +# This replacement method will generate correct string for such cases based on TRANSLATIONS +# variable. +defineReplace(addLanguageDependentPkgItem) { + localize_deployment:!isEmpty(TRANSLATIONS):isEmpty(SYMBIAN_MATCHED_LANGUAGES) { + matchSymbianLanguages() + } + + pkgItem = $$eval($$1) + pkgLanguageList = + + for(dummyItem, SYMBIAN_MATCHED_LANGUAGES) { + pkgLanguageList += "\"$$pkgItem\"" + } + + isEmpty(pkgLanguageList): pkgLanguageList = "\"$$pkgItem\"" + + return($$join(pkgLanguageList,",",,)) +} diff --git a/mkspecs/features/default_post.prf b/mkspecs/features/default_post.prf index 09c6587..9fb9f10 100644 --- a/mkspecs/features/default_post.prf +++ b/mkspecs/features/default_post.prf @@ -110,3 +110,13 @@ QMAKE_LIBDIR += $$QMAKE_LIBDIR_POST } QMAKE_EXTRA_TARGETS += check } + +# Add special translation sources for projects that require them. +# Note 1: Since lupdate will not parse regular config scopes right, contains checks are used instead. +# Note 2: Checking for last value of TEMPLATE is used instead of simple contains check because +# lupdate doesn't respect "-=" variable assignments and therefore always finds "app" +# as the first value of TEMPLATE variable. +contains(CONFIG, lupdate_run):contains(CONFIG, localize_deployment) { + equals($$list($$last(TEMPLATE)), app): SOURCES += $$[QT_INSTALL_DATA]/mkspecs/common/symbian/appCaptionForTranslation.cpp + SOURCES += $$[QT_INSTALL_DATA]/mkspecs/common/symbian/packageNameForTranslation.cpp +} diff --git a/mkspecs/features/symbian/default_post.prf b/mkspecs/features/symbian/default_post.prf index d9ff03d..ec6ecd0 100644 --- a/mkspecs/features/symbian/default_post.prf +++ b/mkspecs/features/symbian/default_post.prf @@ -52,3 +52,15 @@ isEmpty(TARGET.UID2) { } } } + +# Supports S60 3.1, 3.2, 5.0, Symbian^3, and Symbian^4 by default +platform_product_id = S60ProductID +platform_product_id = $$addLanguageDependentPkgItem(platform_product_id) +pkg_platform_dependencies = \ + "; Default HW/platform dependencies" \ + "[0x102032BE],0,0,0,{$$platform_product_id}" \ + "[0x102752AE],0,0,0,{$$platform_product_id}" \ + "[0x1028315F],0,0,0,{$$platform_product_id}" \ + "[0x20022E6D],0,0,0,{$$platform_product_id}" \ + "[0x20032DE7],0,0,0,{$$platform_product_id}" \ + " " diff --git a/mkspecs/features/symbian/localize_deployment.prf b/mkspecs/features/symbian/localize_deployment.prf new file mode 100644 index 0000000..5f52dbc --- /dev/null +++ b/mkspecs/features/symbian/localize_deployment.prf @@ -0,0 +1,82 @@ +SYMBIAN_LANG.af = 34 #Afrikaans +SYMBIAN_LANG.sq = 35 #Albanian +SYMBIAN_LANG.am = 36 #Amharic +SYMBIAN_LANG.ar = 37 #Arabic +SYMBIAN_LANG.hy = 38 #Armenian +SYMBIAN_LANG.bn = 41 #Bengali +SYMBIAN_LANG.bg = 42 #Bulgarian +SYMBIAN_LANG.my = 43 #Burmese +SYMBIAN_LANG.be = 40 #Byelorussian +SYMBIAN_LANG.ca = 44 #Catalan +SYMBIAN_LANG.hr = 45 #Croatian +SYMBIAN_LANG.cs = 25 #Czech +SYMBIAN_LANG.da = 07 #Danish +SYMBIAN_LANG.nl = 18 #Dutch +SYMBIAN_LANG.en = 01 #English(UK) +SYMBIAN_LANG.et = 49 #Estonian +SYMBIAN_LANG.fi = 09 #Finnish +SYMBIAN_LANG.fr = 02 #French +SYMBIAN_LANG.gd = 52 #Gaelic +SYMBIAN_LANG.ka = 53 #Georgian +SYMBIAN_LANG.de = 03 #German +SYMBIAN_LANG.el = 54 #Greek +SYMBIAN_LANG.gu = 56 #Gujarati +SYMBIAN_LANG.he = 57 #Hebrew +SYMBIAN_LANG.hi = 58 #Hindi +SYMBIAN_LANG.hu = 17 #Hungarian +SYMBIAN_LANG.is = 15 #Icelandic +SYMBIAN_LANG.id = 59 #Indonesian +SYMBIAN_LANG.ga = 60 #Irish +SYMBIAN_LANG.it = 05 #Italian +SYMBIAN_LANG.ja = 32 #Japanese +SYMBIAN_LANG.kn = 62 #Kannada +SYMBIAN_LANG.kk = 63 #Kazakh +SYMBIAN_LANG.ko = 65 #Korean +SYMBIAN_LANG.lo = 66 #Laothian +SYMBIAN_LANG.lv = 67 #Latvian +SYMBIAN_LANG.lt = 68 #Lithuanian +SYMBIAN_LANG.mk = 69 #Macedonian +SYMBIAN_LANG.ms = 70 #Malay +SYMBIAN_LANG.ml = 71 #Malayalam +SYMBIAN_LANG.mr = 72 #Marathi +SYMBIAN_LANG.mo = 73 #Moldavian +SYMBIAN_LANG.mn = 74 #Mongolian +SYMBIAN_LANG.nb = 08 #Norwegian +SYMBIAN_LANG.pl = 27 #Polish +SYMBIAN_LANG.pt = 13 #Portuguese +SYMBIAN_LANG.pa = 77 #Punjabi +SYMBIAN_LANG.ro = 78 #Romanian +SYMBIAN_LANG.ru = 16 #Russian +SYMBIAN_LANG.sr = 79 #Serbian +SYMBIAN_LANG.si = 80 #Singhalese +SYMBIAN_LANG.sk = 26 #Slovak +SYMBIAN_LANG.sl = 28 #Slovenian +SYMBIAN_LANG.so = 81 #Somali +SYMBIAN_LANG.es = 04 #Spanish +SYMBIAN_LANG.sw = 84 #Swahili +SYMBIAN_LANG.sv = 06 #Swedish +SYMBIAN_LANG.tl = 39 #Tagalog +SYMBIAN_LANG.ta = 87 #Tamil +SYMBIAN_LANG.te = 88 #Telugu +SYMBIAN_LANG.th = 33 #Thai +SYMBIAN_LANG.bo = 89 #Tibetan +SYMBIAN_LANG.ti = 90 #Tigrinya +SYMBIAN_LANG.tr = 14 #Turkish +SYMBIAN_LANG.tk = 92 #Turkmen +SYMBIAN_LANG.uk = 93 #Ukrainian +SYMBIAN_LANG.ur = 94 #Urdu +SYMBIAN_LANG.vi = 96 #Vietnamese +SYMBIAN_LANG.cy = 97 #Welsh +SYMBIAN_LANG.zu = 98 #Zulu +SYMBIAN_LANG.nn = 75 #Nynorsk + +isEmpty(SYMBIAN_MATCHED_LANGUAGES) { + matchSymbianLanguages() +} + +!isEmpty(SYMBIAN_MATCHED_TRANSLATIONS) { + # Generate dependencies to .ts files for pkg files + template_pkg_target.depends += $$SYMBIAN_MATCHED_TRANSLATIONS + installer_pkg_target.depends += $$SYMBIAN_MATCHED_TRANSLATIONS + stub_pkg_target.depends += $$SYMBIAN_MATCHED_TRANSLATIONS +} diff --git a/mkspecs/features/symbian/qt.prf b/mkspecs/features/symbian/qt.prf index b5d3d98..c8f97aa 100644 --- a/mkspecs/features/symbian/qt.prf +++ b/mkspecs/features/symbian/qt.prf @@ -25,9 +25,10 @@ INCLUDEPATH = $$PREPEND_INCLUDEPATH $$INCLUDEPATH # Note: Qt libs package with full capabilities has UID3 of 0x2001E61C, # while self-signed version typically has temporary UID3 of 0xE001E61C. contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0xE001E61C):isEmpty(QT_LIBINFIX) { + qt_pkg_name = Qt pkg_depends_qt += \ "; Default dependency to Qt libraries" \ - "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {\"Qt\"}" + "(0x2001E61C), $${QT_MAJOR_VERSION}, $${QT_MINOR_VERSION}, $${QT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(qt_pkg_name)}" # Projects linking to webkit need dependency to webkit contains(QT, webkit): { @@ -38,9 +39,10 @@ contains(CONFIG, qt):!contains(TARGET.UID3, 0x2001E61C):!contains(TARGET.UID3, 0 QT_WEBKIT_PATCH_VERSION = $${QT_PATCH_VERSION} } + webkit_pkg_name = QtWebKit pkg_depends_webkit += \ "; Dependency to Qt Webkit" \ - "(0x200267C2), $${QT_WEBKIT_MAJOR_VERSION}, $${QT_WEBKIT_MINOR_VERSION}, $${QT_WEBKIT_PATCH_VERSION}, {\"QtWebKit\"}" + "(0x200267C2), $${QT_WEBKIT_MAJOR_VERSION}, $${QT_WEBKIT_MINOR_VERSION}, $${QT_WEBKIT_PATCH_VERSION}, {$$addLanguageDependentPkgItem(webkit_pkg_name)}" } else { default_deployment.pkg_prerules -= pkg_depends_webkit } diff --git a/mkspecs/features/symbian/sis_targets.prf b/mkspecs/features/symbian/sis_targets.prf index e838e10..ad81803 100644 --- a/mkspecs/features/symbian/sis_targets.prf +++ b/mkspecs/features/symbian/sis_targets.prf @@ -12,6 +12,17 @@ else:!equals(DEPLOYMENT, default_deployment) { equals(GENERATE_SIS_TARGETS, true) { baseTarget = $$symbianRemoveSpecialCharacters($$basename(TARGET)) + template_pkg_target.target = $${baseTarget}_template.pkg + template_pkg_target.depends += $$_PRO_FILE_ + template_pkg_target.commands = $(MAKE) -f $(MAKEFILE) qmake + installer_pkg_target.target = $${baseTarget}_installer.pkg + installer_pkg_target.depends += $$_PRO_FILE_ + installer_pkg_target.commands = $(MAKE) -f $(MAKEFILE) qmake + stub_pkg_target.target = $${baseTarget}_stub.pkg + stub_pkg_target.depends += $$_PRO_FILE_ + stub_pkg_target.commands = $(MAKE) -f $(MAKEFILE) qmake + QMAKE_EXTRA_TARGETS += template_pkg_target installer_pkg_target stub_pkg_target + symbian-abld|symbian-sbsv2 { symbian-sbsv2 { @@ -35,6 +46,7 @@ equals(GENERATE_SIS_TARGETS, true) { , \ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) + sis_target.depends += $${baseTarget}_template.pkg ok_sis_target.target = ok_sis ok_sis_target.commands = createpackage $$CONVERT_GCCE_PARAM $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \ @@ -54,6 +66,7 @@ equals(GENERATE_SIS_TARGETS, true) { , \ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) + unsigned_sis_target.depends += $${baseTarget}_template.pkg ok_unsigned_sis_target.target = ok_unsigned_sis ok_unsigned_sis_target.commands = createpackage $$CONVERT_GCCE_PARAM $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg $(QT_SIS_TARGET) @@ -67,7 +80,7 @@ equals(GENERATE_SIS_TARGETS, true) { , \ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) - installer_sis_target.depends = sis + installer_sis_target.depends = $${baseTarget}_installer.pkg sis ok_installer_sis_target.target = ok_installer_sis ok_installer_sis_target.commands = createpackage $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \ @@ -79,7 +92,7 @@ equals(GENERATE_SIS_TARGETS, true) { , \ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) - unsigned_installer_sis_target.depends = unsigned_sis + unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis ok_unsigned_installer_sis_target.target = ok_unsigned_installer_sis ok_unsigned_installer_sis_target.commands = createpackage $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg @@ -104,6 +117,7 @@ equals(GENERATE_SIS_TARGETS, true) { , \ $(MAKE) -f $(MAKEFILE) fail_sis_nopkg \ ) + stub_sis_target.depends += $${baseTarget}_stub.pkg ok_stub_sis_target.target = ok_stub_sis ok_stub_sis_target.commands = createpackage -s $(QT_SIS_OPTIONS) $${baseTarget}_stub.pkg \ @@ -154,11 +168,11 @@ equals(GENERATE_SIS_TARGETS, true) { sis_target.target = sis sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_template.pkg \ - $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) - sis_target.depends = first + sis_target.depends = first $${baseTarget}_template.pkg unsigned_sis_target.target = unsigned_sis unsigned_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_template.pkg - unsigned_sis_target.depends = first + unsigned_sis_target.depends = first $${baseTarget}_template.pkg target_sis_target.target = $${sis_destdir}/$${baseTarget}.sis target_sis_target.commands = $(MAKE) -f $(MAKEFILE) sis @@ -166,11 +180,11 @@ equals(GENERATE_SIS_TARGETS, true) { installer_sis_target.target = installer_sis installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) $${baseTarget}_installer.pkg - \ $(QT_SIS_CERTIFICATE) $(QT_SIS_KEY) $(QT_SIS_PASSPHRASE) - installer_sis_target.depends = sis + installer_sis_target.depends = $${baseTarget}_installer.pkg sis unsigned_installer_sis_target.target = unsigned_installer_sis unsigned_installer_sis_target.commands = $$QMAKE_CREATEPACKAGE $(QT_SIS_OPTIONS) -o $${baseTarget}_installer.pkg - unsigned_installer_sis_target.depends = unsigned_sis + unsigned_installer_sis_target.depends = $${baseTarget}_installer.pkg unsigned_sis !isEmpty(sis_destdir):!equals(sis_destdir, "."):!equals(sis_destdir, "./") { sis_target.commands += && $$QMAKE_MOVE $${baseTarget}.sis $$sis_destdir diff --git a/qmake/generators/symbian/symbian_makefile.h b/qmake/generators/symbian/symbian_makefile.h index 94f0145..28a6206 100644 --- a/qmake/generators/symbian/symbian_makefile.h +++ b/qmake/generators/symbian/symbian_makefile.h @@ -79,18 +79,18 @@ public: } } + SymbianLocalizationList symbianLocalizationList; + parseTsFiles(&symbianLocalizationList); + if (generatePkg) { - generatePkgFile(iconFile, false); + generatePkgFile(iconFile, false, symbianLocalizationList); } - // Get the application translations and convert to symbian OS lang code, i.e. decical number - QStringList symbianLangCodes = symbianLangCodesFromTsFiles(); - if (targetType == TypeExe) { if (!this->project->values("CONFIG").contains("no_icon", Qt::CaseInsensitive)) { writeRegRssFile(userRssRules); writeRssFile(numberOfIcons, iconFile); - writeLocFile(symbianLangCodes); + writeLocFile(symbianLocalizationList); } } diff --git a/qmake/generators/symbian/symbiancommon.cpp b/qmake/generators/symbian/symbiancommon.cpp index 9d4f27e..2244a98 100644 --- a/qmake/generators/symbian/symbiancommon.cpp +++ b/qmake/generators/symbian/symbiancommon.cpp @@ -41,6 +41,7 @@ #include "symbiancommon.h" #include <qdebug.h> +#include <qxmlstream.h> // Included from tools/shared #include <symbian/epocroot.h> @@ -151,7 +152,9 @@ QString romPath(const QString& path) return QLatin1String("z:") + path; } -void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocBuild) +void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, + bool epocBuild, + const SymbianLocalizationList &symbianLocalizationList) { QMakeProject *project = generator->project; QString pkgFilename = Option::output_dir + QLatin1Char('/') + @@ -270,8 +273,17 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB // Apply some defaults if specific data does not exist in PKG pre-rules if (languageRules.isEmpty()) { - // language, (*** hardcoded to english atm, should be parsed from TRANSLATIONS) - languageRules << "; Language\n&EN\n\n"; + if (symbianLocalizationList.isEmpty()) { + languageRules << "; Language\n&EN\n\n"; + } else { + QStringList langCodes; + SymbianLocalizationListIterator iter(symbianLocalizationList); + while (iter.hasNext()) { + const SymbianLocalization &loc = iter.next(); + langCodes << loc.symbianLanguageCode; + } + languageRules << QString("; Languages\n&%1\n\n").arg(langCodes.join(",")); + } } else if (headerRules.isEmpty()) { // In case user defines langs, he must take care also about SIS header fprintf(stderr, "Warning: If language is defined with DEPLOYMENT pkg_prerules, also the SIS header must be defined\n"); @@ -320,12 +332,14 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB // Package header QString sisHeader = "; SIS header: name, uid, version\n#{\"%1\"},(%2),%3\n\n"; - QString visualTarget = project->values("DEPLOYMENT.display_name").join(" "); - if (visualTarget.isEmpty()) - visualTarget = generator->escapeFilePath(project->first("TARGET")); - visualTarget = removePathSeparators(visualTarget); - QString wrapperTarget = visualTarget + " installer"; + QString defaultVisualTarget = project->values("DEPLOYMENT.display_name").join(" "); + if (defaultVisualTarget.isEmpty()) + defaultVisualTarget = generator->escapeFilePath(project->first("TARGET")); + defaultVisualTarget = removePathSeparators(defaultVisualTarget); + + QString visualTarget = generatePkgNameForHeader(symbianLocalizationList, defaultVisualTarget, false); + QString wrapperTarget = generatePkgNameForHeader(symbianLocalizationList, defaultVisualTarget, true); if (installerSisHeader.startsWith("0x", Qt::CaseInsensitive)) { tw << sisHeader.arg(wrapperTarget).arg(installerSisHeader).arg(applicationVersion); @@ -344,7 +358,13 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB // Vendor name if (!containsStartWithItem('%', vendorRules)) { - vendorRules << "; Default localized vendor name\n%{\"Vendor\"}\n\n"; + QString vendorStr = QLatin1String("\"Vendor\","); + QString locVendors = vendorStr; + for (int i = 1; i < symbianLocalizationList.size(); i++) { + locVendors.append(vendorStr); + } + locVendors.chop(1); + vendorRules << QString("; Default localized vendor name\n%{%1}\n\n").arg(locVendors); } if (!containsStartWithItem(':', vendorRules)) { vendorRules << "; Default unique vendor name\n:\"Vendor\"\n\n"; @@ -385,6 +405,13 @@ void SymbianCommonGenerator::generatePkgFile(const QString &iconFile, bool epocB t << manufacturerStr << endl; } + // ### FIXME: remove epocBuild check once makefile based mkspecs support localized resource generation + if (epocBuild && symbianLocalizationList.size()) { + // Add localized resources to DEPLOYMENT if default resource deployment is done + addLocalizedResourcesToDeployment("default_resource_deployment.sources", symbianLocalizationList); + addLocalizedResourcesToDeployment("default_reg_deployment.sources", symbianLocalizationList); + } + // deploy files specified by DEPLOYMENT variable QString remoteTestPath; QString zDir; @@ -633,12 +660,9 @@ void SymbianCommonGenerator::writeRssFile(QString &numberOfIcons, QString &iconF } } -void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) +void SymbianCommonGenerator::writeLocFile(const SymbianLocalizationList &symbianLocalizationList) { - QString filename(fixedTarget); - if (!Option::output_dir.isEmpty()) - filename = Option::output_dir + '/' + filename; - filename.append(".loc"); + QString filename = generateLocFileName(); QFile ft(filename); if (ft.open(QIODevice::WriteOnly)) { generatedFiles << ft.fileName(); @@ -658,11 +682,22 @@ void SymbianCommonGenerator::writeLocFile(QStringList &symbianLangCodes) t << "#ifdef LANGUAGE_SC" << endl; t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; t << "#define STRING_r_caption \"" << displayName << "\"" << endl; - foreach(QString lang, symbianLangCodes) { - t << "#elif defined LANGUAGE_" << lang << endl; - t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; - t << "#define STRING_r_caption \"" << displayName << "\"" << endl; + + SymbianLocalizationListIterator iter(symbianLocalizationList); + while (iter.hasNext()) { + const SymbianLocalization &loc = iter.next(); + QString shortCaption = loc.shortCaption; + QString longCaption = loc.longCaption; + if (shortCaption.isEmpty()) + shortCaption = displayName; + if (longCaption.isEmpty()) + longCaption = displayName; + + t << "#elif defined LANGUAGE_" << loc.symbianLanguageCode << endl; + t << "#define STRING_r_short_caption \"" << shortCaption << "\"" << endl; + t << "#define STRING_r_caption \"" << longCaption << "\"" << endl; } + t << "#else" << endl; t << "#define STRING_r_short_caption \"" << displayName << "\"" << endl; t << "#define STRING_r_caption \"" << displayName << "\"" << endl; @@ -803,195 +838,49 @@ void SymbianCommonGenerator::writeCustomDefFile() } } -QStringList SymbianCommonGenerator::symbianLangCodesFromTsFiles() +void SymbianCommonGenerator::parseTsFiles(SymbianLocalizationList *symbianLocalizationList) { - QStringList tsfiles; - QStringList symbianLangCodes; - tsfiles << generator->project->values("TRANSLATIONS"); + if (!generator->project->isActiveConfig("localize_deployment")) { + return; + } - fillQt2S60LangMapTable(); + QStringList symbianTsFiles; - foreach(QString file, tsfiles) { - int extIndex = file.lastIndexOf("."); - int langIndex = file.lastIndexOf("_", (extIndex - file.length())); - langIndex += 1; - QString qtlang = file.mid(langIndex, extIndex - langIndex); - QString s60lang = qt2S60LangMapTable.value(qtlang, QString("SC")); + symbianTsFiles << generator->project->values("SYMBIAN_MATCHED_TRANSLATIONS"); - if (!symbianLangCodes.contains(s60lang) && s60lang != "SC") - symbianLangCodes += s60lang; - } + if (!symbianTsFiles.isEmpty()) { + fillQt2SymbianLocalizationList(symbianLocalizationList); - return symbianLangCodes; + QMutableListIterator<SymbianLocalization> iter(*symbianLocalizationList); + while (iter.hasNext()) { + SymbianLocalization &loc = iter.next(); + static QString matchStrTemplate = QLatin1String(".*_%1\\.ts"); + QString matchStr = matchStrTemplate.arg(loc.qtLanguageCode); + + foreach (QString file, symbianTsFiles) { + QRegExp matcher(matchStr); + if (matcher.exactMatch(file) && parseTsContent(file, &loc)) + break; + } + } + } } -void SymbianCommonGenerator::fillQt2S60LangMapTable() +void SymbianCommonGenerator::fillQt2SymbianLocalizationList(SymbianLocalizationList *symbianLocalizationList) { - qt2S60LangMapTable.reserve(170); // 165 items at time of writing. - qt2S60LangMapTable.insert("ab", "SC"); //Abkhazian // - qt2S60LangMapTable.insert("om", "SC"); //Afan // - qt2S60LangMapTable.insert("aa", "SC"); //Afar // - qt2S60LangMapTable.insert("af", "34"); //Afrikaans //Afrikaans - qt2S60LangMapTable.insert("sq", "35"); //Albanian //Albanian - qt2S60LangMapTable.insert("am", "36"); //Amharic //Amharic - qt2S60LangMapTable.insert("ar", "37"); //Arabic //Arabic - qt2S60LangMapTable.insert("hy", "38"); //Armenian //Armenian - qt2S60LangMapTable.insert("as", "SC"); //Assamese // - qt2S60LangMapTable.insert("ay", "SC"); //Aymara // - qt2S60LangMapTable.insert("az", "SC"); //Azerbaijani // - qt2S60LangMapTable.insert("ba", "SC"); //Bashkir // - qt2S60LangMapTable.insert("eu", "SC"); //Basque // - qt2S60LangMapTable.insert("bn", "41"); //Bengali //Bengali - qt2S60LangMapTable.insert("dz", "SC"); //Bhutani // - qt2S60LangMapTable.insert("bh", "SC"); //Bihari // - qt2S60LangMapTable.insert("bi", "SC"); //Bislama // - qt2S60LangMapTable.insert("br", "SC"); //Breton // - qt2S60LangMapTable.insert("bg", "42"); //Bulgarian //Bulgarian - qt2S60LangMapTable.insert("my", "43"); //Burmese //Burmese - qt2S60LangMapTable.insert("be", "40"); //Byelorussian //Belarussian - qt2S60LangMapTable.insert("km", "SC"); //Cambodian // - qt2S60LangMapTable.insert("ca", "44"); //Catalan //Catalan - qt2S60LangMapTable.insert("zh", "SC"); //Chinese // - qt2S60LangMapTable.insert("co", "SC"); //Corsican // - qt2S60LangMapTable.insert("hr", "45"); //Croatian //Croatian - qt2S60LangMapTable.insert("cs", "25"); //Czech //Czech - qt2S60LangMapTable.insert("da", "07"); //Danish //Danish - qt2S60LangMapTable.insert("nl", "18"); //Dutch //Dutch - qt2S60LangMapTable.insert("en", "01"); //English //English(UK) - qt2S60LangMapTable.insert("eo", "SC"); //Esperanto // - qt2S60LangMapTable.insert("et", "49"); //Estonian //Estonian - qt2S60LangMapTable.insert("fo", "SC"); //Faroese // - qt2S60LangMapTable.insert("fj", "SC"); //Fiji // - qt2S60LangMapTable.insert("fi", "09"); //Finnish //Finnish - qt2S60LangMapTable.insert("fr", "02"); //French //French - qt2S60LangMapTable.insert("fy", "SC"); //Frisian // - qt2S60LangMapTable.insert("gd", "52"); //Gaelic //Gaelic - qt2S60LangMapTable.insert("gl", "SC"); //Galician // - qt2S60LangMapTable.insert("ka", "53"); //Georgian //Georgian - qt2S60LangMapTable.insert("de", "03"); //German //German - qt2S60LangMapTable.insert("el", "54"); //Greek //Greek - qt2S60LangMapTable.insert("kl", "SC"); //Greenlandic // - qt2S60LangMapTable.insert("gn", "SC"); //Guarani // - qt2S60LangMapTable.insert("gu", "56"); //Gujarati //Gujarati - qt2S60LangMapTable.insert("ha", "SC"); //Hausa // - qt2S60LangMapTable.insert("he", "57"); //Hebrew //Hebrew - qt2S60LangMapTable.insert("hi", "58"); //Hindi //Hindi - qt2S60LangMapTable.insert("hu", "17"); //Hungarian //Hungarian - qt2S60LangMapTable.insert("is", "15"); //Icelandic //Icelandic - qt2S60LangMapTable.insert("id", "59"); //Indonesian //Indonesian - qt2S60LangMapTable.insert("ia", "SC"); //Interlingua // - qt2S60LangMapTable.insert("ie", "SC"); //Interlingue // - qt2S60LangMapTable.insert("iu", "SC"); //Inuktitut // - qt2S60LangMapTable.insert("ik", "SC"); //Inupiak // - qt2S60LangMapTable.insert("ga", "60"); //Irish //Irish - qt2S60LangMapTable.insert("it", "05"); //Italian //Italian - qt2S60LangMapTable.insert("ja", "32"); //Japanese //Japanese - qt2S60LangMapTable.insert("jv", "SC"); //Javanese // - qt2S60LangMapTable.insert("kn", "62"); //Kannada //Kannada - qt2S60LangMapTable.insert("ks", "SC"); //Kashmiri // - qt2S60LangMapTable.insert("kk", "63"); //Kazakh //Kazakh - qt2S60LangMapTable.insert("rw", "SC"); //Kinyarwanda // - qt2S60LangMapTable.insert("ky", "SC"); //Kirghiz // - qt2S60LangMapTable.insert("ko", "65"); //Korean //Korean - qt2S60LangMapTable.insert("ku", "SC"); //Kurdish // - qt2S60LangMapTable.insert("rn", "SC"); //Kurundi // - qt2S60LangMapTable.insert("lo", "66"); //Laothian //Laothian - qt2S60LangMapTable.insert("la", "SC"); //Latin // - qt2S60LangMapTable.insert("lv", "67"); //Latvian //Latvian - qt2S60LangMapTable.insert("ln", "SC"); //Lingala // - qt2S60LangMapTable.insert("lt", "68"); //Lithuanian //Lithuanian - qt2S60LangMapTable.insert("mk", "69"); //Macedonian //Macedonian - qt2S60LangMapTable.insert("mg", "SC"); //Malagasy // - qt2S60LangMapTable.insert("ms", "70"); //Malay //Malay - qt2S60LangMapTable.insert("ml", "71"); //Malayalam //Malayalam - qt2S60LangMapTable.insert("mt", "SC"); //Maltese // - qt2S60LangMapTable.insert("mi", "SC"); //Maori // - qt2S60LangMapTable.insert("mr", "72"); //Marathi //Marathi - qt2S60LangMapTable.insert("mo", "73"); //Moldavian //Moldovian - qt2S60LangMapTable.insert("mn", "74"); //Mongolian //Mongolian - qt2S60LangMapTable.insert("na", "SC"); //Nauru // - qt2S60LangMapTable.insert("ne", "SC"); //Nepali // - qt2S60LangMapTable.insert("nb", "08"); //Norwegian //Norwegian - qt2S60LangMapTable.insert("oc", "SC"); //Occitan // - qt2S60LangMapTable.insert("or", "SC"); //Oriya // - qt2S60LangMapTable.insert("ps", "SC"); //Pashto // - qt2S60LangMapTable.insert("fa", "SC"); //Persian // - qt2S60LangMapTable.insert("pl", "27"); //Polish //Polish - qt2S60LangMapTable.insert("pt", "13"); //Portuguese //Portuguese - qt2S60LangMapTable.insert("pa", "77"); //Punjabi //Punjabi - qt2S60LangMapTable.insert("qu", "SC"); //Quechua // - qt2S60LangMapTable.insert("rm", "SC"); //RhaetoRomance // - qt2S60LangMapTable.insert("ro", "78"); //Romanian //Romanian - qt2S60LangMapTable.insert("ru", "16"); //Russian //Russian - qt2S60LangMapTable.insert("sm", "SC"); //Samoan // - qt2S60LangMapTable.insert("sg", "SC"); //Sangho // - qt2S60LangMapTable.insert("sa", "SC"); //Sanskrit // - qt2S60LangMapTable.insert("sr", "79"); //Serbian //Serbian - qt2S60LangMapTable.insert("sh", "SC"); //SerboCroatian // - qt2S60LangMapTable.insert("st", "SC"); //Sesotho // - qt2S60LangMapTable.insert("tn", "SC"); //Setswana // - qt2S60LangMapTable.insert("sn", "SC"); //Shona // - qt2S60LangMapTable.insert("sd", "SC"); //Sindhi // - qt2S60LangMapTable.insert("si", "80"); //Singhalese //Sinhalese - qt2S60LangMapTable.insert("ss", "SC"); //Siswati // - qt2S60LangMapTable.insert("sk", "26"); //Slovak //Slovak - qt2S60LangMapTable.insert("sl", "28"); //Slovenian //Slovenian - qt2S60LangMapTable.insert("so", "81"); //Somali //Somali - qt2S60LangMapTable.insert("es", "04"); //Spanish //Spanish - qt2S60LangMapTable.insert("su", "SC"); //Sundanese // - qt2S60LangMapTable.insert("sw", "84"); //Swahili //Swahili - qt2S60LangMapTable.insert("sv", "06"); //Swedish //Swedish - qt2S60LangMapTable.insert("tl", "39"); //Tagalog //Tagalog - qt2S60LangMapTable.insert("tg", "SC"); //Tajik // - qt2S60LangMapTable.insert("ta", "87"); //Tamil //Tamil - qt2S60LangMapTable.insert("tt", "SC"); //Tatar // - qt2S60LangMapTable.insert("te", "88"); //Telugu //Telugu - qt2S60LangMapTable.insert("th", "33"); //Thai //Thai - qt2S60LangMapTable.insert("bo", "89"); //Tibetan //Tibetan - qt2S60LangMapTable.insert("ti", "90"); //Tigrinya //Tigrinya - qt2S60LangMapTable.insert("to", "SC"); //Tonga // - qt2S60LangMapTable.insert("ts", "SC"); //Tsonga // - qt2S60LangMapTable.insert("tr", "14"); //Turkish //Turkish - qt2S60LangMapTable.insert("tk", "92"); //Turkmen //Turkmen - qt2S60LangMapTable.insert("tw", "SC"); //Twi // - qt2S60LangMapTable.insert("ug", "SC"); //Uigur // - qt2S60LangMapTable.insert("uk", "93"); //Ukrainian //Ukrainian - qt2S60LangMapTable.insert("ur", "94"); //Urdu //Urdu - qt2S60LangMapTable.insert("uz", "SC"); //Uzbek // - qt2S60LangMapTable.insert("vi", "96"); //Vietnamese //Vietnamese - qt2S60LangMapTable.insert("vo", "SC"); //Volapuk // - qt2S60LangMapTable.insert("cy", "97"); //Welsh //Welsh - qt2S60LangMapTable.insert("wo", "SC"); //Wolof // - qt2S60LangMapTable.insert("xh", "SC"); //Xhosa // - qt2S60LangMapTable.insert("yi", "SC"); //Yiddish // - qt2S60LangMapTable.insert("yo", "SC"); //Yoruba // - qt2S60LangMapTable.insert("za", "SC"); //Zhuang // - qt2S60LangMapTable.insert("zu", "98"); //Zulu //Zulu - qt2S60LangMapTable.insert("nn", "75"); //Nynorsk //NorwegianNynorsk - qt2S60LangMapTable.insert("bs", "SC"); //Bosnian // - qt2S60LangMapTable.insert("dv", "SC"); //Divehi // - qt2S60LangMapTable.insert("gv", "SC"); //Manx // - qt2S60LangMapTable.insert("kw", "SC"); //Cornish // - qt2S60LangMapTable.insert("ak", "SC"); //Akan // - qt2S60LangMapTable.insert("kok", "SC"); //Konkani // - qt2S60LangMapTable.insert("gaa", "SC"); //Ga // - qt2S60LangMapTable.insert("ig", "SC"); //Igbo // - qt2S60LangMapTable.insert("kam", "SC"); //Kamba // - qt2S60LangMapTable.insert("syr", "SC"); //Syriac // - qt2S60LangMapTable.insert("byn", "SC"); //Blin // - qt2S60LangMapTable.insert("gez", "SC"); //Geez // - qt2S60LangMapTable.insert("kfo", "SC"); //Koro // - qt2S60LangMapTable.insert("sid", "SC"); //Sidamo // - qt2S60LangMapTable.insert("cch", "SC"); //Atsam // - qt2S60LangMapTable.insert("tig", "SC"); //Tigre // - qt2S60LangMapTable.insert("kaj", "SC"); //Jju // - qt2S60LangMapTable.insert("fur", "SC"); //Friulian // - qt2S60LangMapTable.insert("ve", "SC"); //Venda // - qt2S60LangMapTable.insert("ee", "SC"); //Ewe // - qt2S60LangMapTable.insert("wa", "SC"); //Walamo // - qt2S60LangMapTable.insert("haw", "SC"); //Hawaiian // - qt2S60LangMapTable.insert("kcg", "SC"); //Tyap // - qt2S60LangMapTable.insert("ny", "SC"); //Chewa // + static QString symbianCodePrefix = QLatin1String("SYMBIAN_LANG."); + + QStringList symbianLanguages = generator->project->values("SYMBIAN_MATCHED_LANGUAGES"); + + foreach (QString qtCode, symbianLanguages) { + SymbianLocalization newLoc; + QString symbianCodeVariable = symbianCodePrefix + qtCode; + newLoc.symbianLanguageCode = generator->project->first(symbianCodeVariable); + if (!newLoc.symbianLanguageCode.isEmpty()) { + newLoc.qtLanguageCode = qtCode; + symbianLocalizationList->append(newLoc); + } + } } void SymbianCommonGenerator::parsePreRules(const QString &deploymentVariable, @@ -1057,3 +946,183 @@ void SymbianCommonGenerator::parsePostRules(const QString &deploymentVariable, } } +bool SymbianCommonGenerator::parseTsContent(const QString &tsFilename, SymbianLocalization *loc) +{ + bool retval = true; + QMakeProject *project = generator->project; + QFile tsFile(tsFilename); + + if (tsFile.exists()) { + if (tsFile.open(QIODevice::ReadOnly)) { + static QString applicationCaptionsContext = QLatin1String("QtApplicationCaptions"); + static QString pkgNameContext = QLatin1String("QtPackageNames"); + static QString tsElement = QLatin1String("TS"); + static QString contextElement = QLatin1String("context"); + static QString nameElement = QLatin1String("name"); + static QString messageElement = QLatin1String("message"); + static QString sourceElement = QLatin1String("source"); + static QString translationElement = QLatin1String("translation"); + static QString shortCaptionId = QLatin1String("Application short caption"); + static QString longCaptionId = QLatin1String("Application long caption"); + static QString pkgDisplayNameId = QLatin1String("Package name"); + static QString installerPkgDisplayNameId = QLatin1String("Smart installer package name"); + static QString languageAttribute = QLatin1String("language"); + static QChar underscoreChar = QLatin1Char('_'); + + enum CurrentContext { + ContextUnknown, + ContextUninteresting, + ContextInteresting + }; + + QXmlStreamReader xml(&tsFile); + + while (xml.name() != tsElement) + xml.readNextStartElement(); + + while (xml.readNextStartElement()) { + if (xml.name() == contextElement) { + CurrentContext currentContext = ContextUnknown; + while (xml.readNextStartElement()) { + if (currentContext == ContextUnknown) { + // Expect name element before message elements + if (xml.name() == nameElement) { + QString nameText = xml.readElementText(); + if (nameText == applicationCaptionsContext || nameText == pkgNameContext) { + currentContext = ContextInteresting; + } else { + currentContext = ContextUninteresting; + } + } else { + xml.skipCurrentElement(); + } + } else if (currentContext == ContextInteresting) { + if (xml.name() == messageElement) { + QString source; + QString translation; + while (xml.readNextStartElement()) { + if (xml.name() == sourceElement) { + source = xml.readElementText(); + } else if (xml.name() == translationElement) { + translation = xml.readElementText(); + } else { + xml.skipCurrentElement(); + } + } + + if (source == shortCaptionId) { + if (loc->shortCaption.isEmpty()) { + loc->shortCaption = translation; + } else { + fprintf(stderr, "Warning: Duplicate application short caption defined in (%s).\n", + qPrintable(tsFilename)); + } + } else if (source == longCaptionId) { + if (loc->longCaption.isEmpty()) { + loc->longCaption = translation; + } else { + fprintf(stderr, "Warning: Duplicate application long caption defined in (%s).\n", + qPrintable(tsFilename)); + } + } else if (source == pkgDisplayNameId) { + if (loc->pkgDisplayName.isEmpty()) { + loc->pkgDisplayName = translation; + } else { + fprintf(stderr, "Warning: Duplicate package display name defined in (%s).\n", + qPrintable(tsFilename)); + } + } else if (source == installerPkgDisplayNameId) { + if (loc->installerPkgDisplayName.isEmpty()) { + loc->installerPkgDisplayName = translation; + } else { + fprintf(stderr, "Warning: Duplicate smart installer package display name defined in (%s).\n", + qPrintable(tsFilename)); + } + } + } else { + xml.skipCurrentElement(); + } + } else { + xml.skipCurrentElement(); + } + } + } else { + xml.skipCurrentElement(); + } + } + if (xml.hasError()) { + retval = false; + fprintf(stderr, "ERROR: Encountered error \"%s\" when parsing ts file (%s).\n", + qPrintable(xml.errorString()), qPrintable(tsFilename)); + } + } else { + retval = false; + fprintf(stderr, "Warning: Could not open ts file (%s).\n", qPrintable(tsFilename)); + } + } else { + retval = false; + fprintf(stderr, "Warning: ts file does not exist: (%s), unable to parse it.\n", + qPrintable(tsFilename)); + } + + return retval; +} + +QString SymbianCommonGenerator::generatePkgNameForHeader(const SymbianLocalizationList &symbianLocalizationList, + const QString &defaultName, + bool isForSmartInstaller) +{ + QStringList allNames; + QString noTranslation = defaultName; + + if (isForSmartInstaller) + noTranslation += QLatin1String(" installer"); + + SymbianLocalizationListIterator iter(symbianLocalizationList); + while (iter.hasNext()) { + const SymbianLocalization &loc = iter.next(); + QString currentName; + if (isForSmartInstaller) { + currentName = loc.installerPkgDisplayName; + } else { + currentName = loc.pkgDisplayName; + } + + if (currentName.isEmpty()) + currentName = noTranslation; + + allNames << currentName; + } + + if (!allNames.size()) + allNames << noTranslation; + + return allNames.join("\",\""); + +} + +void SymbianCommonGenerator::addLocalizedResourcesToDeployment(const QString &deploymentFilesVar, + const SymbianLocalizationList &symbianLocalizationList) +{ + QStringList locResources; + foreach (QString defaultResource, generator->project->values(deploymentFilesVar)) { + if (defaultResource.endsWith(".rsc")) { + defaultResource.chop(2); + SymbianLocalizationListIterator iter(symbianLocalizationList); + while (iter.hasNext()) { + const SymbianLocalization &loc = iter.next(); + locResources << QString(defaultResource + loc.symbianLanguageCode); + } + } + } + generator->project->values(deploymentFilesVar) << locResources; +} + +QString SymbianCommonGenerator::generateLocFileName() +{ + QString fileName(fixedTarget); + if (!Option::output_dir.isEmpty()) + fileName = Option::output_dir + QLatin1Char('/') + fileName; + fileName.append(".loc"); + return fileName; +} diff --git a/qmake/generators/symbian/symbiancommon.h b/qmake/generators/symbian/symbiancommon.h index 80f2079..1db5890 100644 --- a/qmake/generators/symbian/symbiancommon.h +++ b/qmake/generators/symbian/symbiancommon.h @@ -48,6 +48,20 @@ #define PRINT_FILE_CREATE_ERROR(filename) fprintf(stderr, "Error: Could not create '%s'\n", qPrintable(filename)); +class SymbianLocalization +{ +public: + QString qtLanguageCode; + QString symbianLanguageCode; + QString shortCaption; + QString longCaption; + QString pkgDisplayName; + QString installerPkgDisplayName; +}; + +typedef QList<SymbianLocalization> SymbianLocalizationList; +typedef QListIterator<SymbianLocalization> SymbianLocalizationListIterator; + class SymbianCommonGenerator { public: @@ -59,6 +73,7 @@ public: TypeSubdirs }; + SymbianCommonGenerator(MakefileGenerator *generator); virtual void init(); @@ -68,7 +83,9 @@ protected: QString removePathSeparators(QString &file); void removeSpecialCharacters(QString& str); void removeEpocSpecialCharacters(QString& str); - void generatePkgFile(const QString &iconFile, bool epocBuild); + void generatePkgFile(const QString &iconFile, + bool epocBuild, + const SymbianLocalizationList &symbianLocalizationList); bool containsStartWithItem(const QChar &c, const QStringList& src); void writeRegRssFile(QMap<QString, QStringList> &useritems); @@ -76,15 +93,15 @@ protected: const QString &listTag, const QString &listItem); void writeRssFile(QString &numberOfIcons, QString &iconfile); - void writeLocFile(QStringList &symbianLangCodes); + void writeLocFile(const SymbianLocalizationList &symbianLocalizationList); void readRssRules(QString &numberOfIcons, QString &iconFile, QMap<QString, QStringList> &userRssRules); void writeCustomDefFile(); - QStringList symbianLangCodesFromTsFiles(); - void fillQt2S60LangMapTable(); + void parseTsFiles(SymbianLocalizationList *symbianLocalizationList); + void fillQt2SymbianLocalizationList(SymbianLocalizationList *symbianLocalizationList); void parsePreRules(const QString &deploymentVariable, const QString &variableSuffix, @@ -95,7 +112,13 @@ protected: void parsePostRules(const QString &deploymentVariable, const QString &variableSuffix, QStringList *rawRuleList); - + bool parseTsContent(const QString &tsFilename, SymbianLocalization *loc); + QString generatePkgNameForHeader(const SymbianLocalizationList &symbianLocalizationList, + const QString &defaultName, + bool isForSmartInstaller); + void addLocalizedResourcesToDeployment(const QString &deploymentFilesVar, + const SymbianLocalizationList &symbianLocalizationList); + QString generateLocFileName(); protected: MakefileGenerator *generator; @@ -106,8 +129,6 @@ protected: QString privateDirUid; QString uid3; TargetType targetType; - - QHash<QString, QString> qt2S60LangMapTable; }; #endif // SYMBIANCOMMON_H diff --git a/qmake/generators/symbian/symmake.cpp b/qmake/generators/symbian/symmake.cpp index 0b0033a..e1426ab 100644 --- a/qmake/generators/symbian/symmake.cpp +++ b/qmake/generators/symbian/symmake.cpp @@ -187,8 +187,8 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) QMap<QString, QStringList> userRssRules; readRssRules(numberOfIcons, iconFile, userRssRules); - // Get the application translations and convert to symbian OS lang code, i.e. decical number - QStringList symbianLangCodes = symbianLangCodesFromTsFiles(); + SymbianLocalizationList symbianLocalizationList; + parseTsFiles(&symbianLocalizationList); // Generate pkg files if there are any actual files to deploy bool generatePkg = false; @@ -205,7 +205,7 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) } if (generatePkg) { - generatePkgFile(iconFile, true); + generatePkgFile(iconFile, true, symbianLocalizationList); } writeBldInfContent(t, generatePkg, iconFile); @@ -242,13 +242,13 @@ bool SymbianMakefileGenerator::writeMakefile(QTextStream &t) writeMkFile(wrapperFileName, false); QString absoluteMmpFileName = Option::output_dir + QLatin1Char('/') + mmpFileName; - writeMmpFile(absoluteMmpFileName, symbianLangCodes); + writeMmpFile(absoluteMmpFileName, symbianLocalizationList); if (targetType == TypeExe) { if (!project->isActiveConfig("no_icon")) { writeRegRssFile(userRssRules); writeRssFile(numberOfIcons, iconFile); - writeLocFile(symbianLangCodes); + writeLocFile(symbianLocalizationList); } } @@ -489,7 +489,7 @@ void SymbianMakefileGenerator::writeMmpFileHeader(QTextStream &t) t << "// ==============================================================================" << endl << endl; } -void SymbianMakefileGenerator::writeMmpFile(QString &filename, QStringList &symbianLangCodes) +void SymbianMakefileGenerator::writeMmpFile(QString &filename, const SymbianLocalizationList &symbianLocalizationList) { QFile ft(filename); if (ft.open(QIODevice::WriteOnly)) { @@ -501,7 +501,7 @@ void SymbianMakefileGenerator::writeMmpFile(QString &filename, QStringList &symb writeMmpFileTargetPart(t); - writeMmpFileResourcePart(t, symbianLangCodes); + writeMmpFileResourcePart(t, symbianLocalizationList); writeMmpFileMacrosPart(t); @@ -643,7 +643,7 @@ void SymbianMakefileGenerator::writeMmpFileTargetPart(QTextStream& t) Application registration resource files should be installed to the \private\10003a3f\import\apps directory. */ -void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes) +void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, const SymbianLocalizationList &symbianLocalizationList) { if ((targetType == TypeExe) && !project->isActiveConfig("no_icon")) { @@ -653,8 +653,10 @@ void SymbianMakefileGenerator::writeMmpFileResourcePart(QTextStream& t, QStringL t << "SOURCEPATH\t\t\t. " << endl; t << "LANG SC "; // no endl - foreach(QString lang, symbianLangCodes) { - t << lang << " "; // no endl + SymbianLocalizationListIterator iter(symbianLocalizationList); + while (iter.hasNext()) { + const SymbianLocalization &loc = iter.next(); + t << loc.symbianLanguageCode << " "; // no endl } t << endl; t << MMP_START_RESOURCE "\t\t" << locTarget << endl; @@ -1108,3 +1110,18 @@ void SymbianMakefileGenerator::generateDistcleanTargets(QTextStream& t) t << "distclean: clean dodistclean" << endl; t << endl; } + +// Returns a string that can be used as a dependency to loc file on other targets +QString SymbianMakefileGenerator::generateLocFileTarget(QTextStream& t, const QString& locCmd) +{ + QString locFile; + if (targetType == TypeExe && !project->isActiveConfig("no_icon")) { + locFile = Option::fixPathToLocalOS(generateLocFileName()); + t << locFile << QLatin1String(": ") << project->values("SYMBIAN_MATCHED_TRANSLATIONS").join(" ") << endl; + t << locCmd << endl; + t << endl; + locFile += QLatin1Char(' '); + } + + return locFile; +}
\ No newline at end of file diff --git a/qmake/generators/symbian/symmake.h b/qmake/generators/symbian/symmake.h index a1a8e88..aba11de 100644 --- a/qmake/generators/symbian/symmake.h +++ b/qmake/generators/symbian/symmake.h @@ -97,11 +97,11 @@ protected: static bool removeDuplicatedStrings(QStringList& stringList); void writeMmpFileHeader(QTextStream &t); - void writeMmpFile(QString &filename, QStringList &symbianLangCodes); + void writeMmpFile(QString &filename, const SymbianLocalizationList &symbianLocalizationList); void writeMmpFileMacrosPart(QTextStream& t); void addMacro(QTextStream& t, const QString& value); void writeMmpFileTargetPart(QTextStream& t); - void writeMmpFileResourcePart(QTextStream& t, QStringList &symbianLangCodes); + void writeMmpFileResourcePart(QTextStream& t, const SymbianLocalizationList &symbianLocalizationList); void writeMmpFileSystemIncludePart(QTextStream& t); void writeMmpFileIncludePart(QTextStream& t); void writeMmpFileLibraryPart(QTextStream& t); @@ -131,6 +131,7 @@ protected: const QString& itemSuffix); void generateDistcleanTargets(QTextStream& t); + QString generateLocFileTarget(QTextStream& t, const QString& locCmd); // Subclass implements virtual void writeBldInfExtensionRulesPart(QTextStream& t, const QString &iconTargetFile) = 0; diff --git a/qmake/generators/symbian/symmake_abld.cpp b/qmake/generators/symbian/symmake_abld.cpp index f895109..7059a52 100644 --- a/qmake/generators/symbian/symmake_abld.cpp +++ b/qmake/generators/symbian/symmake_abld.cpp @@ -267,12 +267,14 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool t << "\tbldmake bldfiles" << endl; t << endl; - t << "debug: $(ABLD)" << endl; + QString locFileDep = generateLocFileTarget(t, qmakeCmd); + + t << "debug: " << locFileDep << "$(ABLD)" << endl; foreach(QString item, debugPlatforms) { t << "\t$(ABLD)" << testClause << " build " << item << " udeb" << endl; } t << endl; - t << "release: $(ABLD)" << endl; + t << "release: " << locFileDep << "$(ABLD)" << endl; foreach(QString item, releasePlatforms) { t << "\t$(ABLD)" << testClause << " build " << item << " urel" << endl; } @@ -280,12 +282,12 @@ void SymbianAbldMakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, bool // For more specific builds, targets are in this form: build-platform, e.g. release-armv5 foreach(QString item, debugPlatforms) { - t << "debug-" << item << ": $(ABLD)" << endl; + t << "debug-" << item << ": " << locFileDep << "$(ABLD)" << endl; t << "\t$(ABLD)" << testClause << " build " << item << " udeb" << endl; } foreach(QString item, releasePlatforms) { - t << "release-" << item << ": $(ABLD)" << endl; + t << "release-" << item << ": " << locFileDep << "$(ABLD)" << endl; t << "\t$(ABLD)" << testClause << " build " << item << " urel" << endl; } diff --git a/qmake/generators/symbian/symmake_sbsv2.cpp b/qmake/generators/symbian/symmake_sbsv2.cpp index d650e08..b3f8ba2 100644 --- a/qmake/generators/symbian/symmake_sbsv2.cpp +++ b/qmake/generators/symbian/symmake_sbsv2.cpp @@ -386,8 +386,9 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << endl; QString currentClause; + QString locFileDep = generateLocFileTarget(t, qmakeCmd); - t << "debug: " << BLD_INF_FILENAME << endl; + t << "debug: " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)"; foreach(QString clause, debugClauses) { t << clause; @@ -399,7 +400,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo t << clause; } t << endl; - t << "release: " << BLD_INF_FILENAME << endl; + t << "release: " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)"; foreach(QString clause, releaseClauses) { t << clause; @@ -431,7 +432,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo else // use generic arm clause clause = configClause(item, debugBuild, defaultRvctCompilerVersion, genericArmClause); - t << "debug-" << item << ": " << BLD_INF_FILENAME << endl; + t << "debug-" << item << ": " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)" << clause << endl; t << "clean-debug-" << item << ": " << BLD_INF_FILENAME << endl; t << "\t$(SBS) reallyclean" << clause << endl; @@ -444,7 +445,7 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo else // use generic arm clause clause = configClause(item, releaseBuild, defaultRvctCompilerVersion, genericArmClause); - t << "release-" << item << ": " << BLD_INF_FILENAME << endl; + t << "release-" << item << ": " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)" << clause << endl; t << "clean-release-" << item << ": " << BLD_INF_FILENAME << endl; t << "\t$(SBS) reallyclean" << clause << endl; @@ -454,11 +455,11 @@ void SymbianSbsv2MakefileGenerator::writeWrapperMakefile(QFile& wrapperFile, boo foreach(QString compilerVersion, allArmCompilerVersions) { QString debugClause = configClause(item, debugBuild, compilerVersion, armClause); QString releaseClause = configClause(item, releaseBuild, compilerVersion, armClause); - t << "debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "debug-" << item << "-" << compilerVersion << ": " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)" << debugClause << endl; t << "clean-debug-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; t << "\t$(SBS) reallyclean" << debugClause << endl; - t << "release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; + t << "release-" << item << "-" << compilerVersion << ": " << locFileDep << BLD_INF_FILENAME << endl; t << "\t$(SBS)" << releaseClause << endl; t << "clean-release-" << item << "-" << compilerVersion << ": " << BLD_INF_FILENAME << endl; t << "\t$(SBS) reallyclean" << releaseClause << endl; diff --git a/src/s60installs/s60installs.pro b/src/s60installs/s60installs.pro index 65b8781..a236028 100644 --- a/src/s60installs/s60installs.pro +++ b/src/s60installs/s60installs.pro @@ -191,11 +191,9 @@ symbian: { qtlibraries.sources += $$QMAKE_LIBDIR_QT/QtOpenVG$${QT_LIBINFIX}.dll graphicssystems_plugins.sources += $$QT_BUILD_TREE/plugins/graphicssystems/qvggraphicssystem$${QT_LIBINFIX}.dll # OpenVG requires Symbian^3 or later - pkg_platform_dependencies -= \ - "[0x101F7961],0,0,0,{\"S60ProductID\"}" \ - "[0x102032BE],0,0,0,{\"S60ProductID\"}" \ - "[0x102752AE],0,0,0,{\"S60ProductID\"}" \ - "[0x1028315F],0,0,0,{\"S60ProductID\"}" + pkg_platform_dependencies = \ + "[0x20022E6D],0,0,0,{\"S60ProductID\"}" \ + "[0x20032DE7],0,0,0,{\"S60ProductID\"}" } contains(QT_CONFIG, opengl) { diff --git a/tools/linguist/lupdate/main.cpp b/tools/linguist/lupdate/main.cpp index 49906e0..76a8756 100644 --- a/tools/linguist/lupdate/main.cpp +++ b/tools/linguist/lupdate/main.cpp @@ -350,6 +350,10 @@ static void processProjects( ProFileEvaluator visitor; visitor.setVerbose(options & Verbose); + QHash<QString, QStringList> lupdateConfig; + lupdateConfig.insert(QLatin1String("CONFIG"), QStringList(QLatin1String("lupdate_run"))); + visitor.addVariables(lupdateConfig); + QFileInfo pfi(proFile); ProFile pro(pfi.absoluteFilePath()); if (!visitor.queryProFile(&pro) || !visitor.accept(&pro)) { |